From owner-svn-src-all@FreeBSD.ORG Wed Mar 18 20:42:00 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 99E72106564A; Wed, 18 Mar 2009 20:42:00 +0000 (UTC) (envelope-from ambrisko@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 867FE8FC14; Wed, 18 Mar 2009 20:42:00 +0000 (UTC) (envelope-from ambrisko@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n2IKg0Cc037145; Wed, 18 Mar 2009 20:42:00 GMT (envelope-from ambrisko@svn.freebsd.org) Received: (from ambrisko@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n2IKg0mE037140; Wed, 18 Mar 2009 20:42:00 GMT (envelope-from ambrisko@svn.freebsd.org) Message-Id: <200903182042.n2IKg0mE037140@svn.freebsd.org> From: Doug Ambrisko Date: Wed, 18 Mar 2009 20:42:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-6@freebsd.org X-SVN-Group: stable-6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r189986 - in stable/6/sys: . dev/mfi X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Mar 2009 20:42:01 -0000 Author: ambrisko Date: Wed Mar 18 20:42:00 2009 New Revision: 189986 URL: http://svn.freebsd.org/changeset/base/189986 Log: MF7: r185034 which brings in new HW support, fix some bugs in the API for the management ioctl. Submitted by: LSI Modified: stable/6/sys/ (props changed) stable/6/sys/dev/mfi/mfi.c stable/6/sys/dev/mfi/mfi_ioctl.h stable/6/sys/dev/mfi/mfi_pci.c stable/6/sys/dev/mfi/mfireg.h stable/6/sys/dev/mfi/mfivar.h Modified: stable/6/sys/dev/mfi/mfi.c ============================================================================== --- stable/6/sys/dev/mfi/mfi.c Wed Mar 18 20:22:21 2009 (r189985) +++ stable/6/sys/dev/mfi/mfi.c Wed Mar 18 20:42:00 2009 (r189986) @@ -163,7 +163,11 @@ static void mfi_enable_intr_ppc(struct mfi_softc *sc) { MFI_WRITE4(sc, MFI_ODCR0, 0xFFFFFFFF); - MFI_WRITE4(sc, MFI_OMSK, ~MFI_1078_EIM); + if (sc->mfi_flags & MFI_FLAGS_1078) { + MFI_WRITE4(sc, MFI_OMSK, ~MFI_1078_EIM); + } else if (sc->mfi_flags & MFI_FLAGS_GEN2) { + MFI_WRITE4(sc, MFI_OMSK, ~MFI_GEN2_EIM); + } } static int32_t @@ -171,14 +175,14 @@ mfi_read_fw_status_xscale(struct mfi_sof { return MFI_READ4(sc, MFI_OMSG0); } - + static int32_t mfi_read_fw_status_ppc(struct mfi_softc *sc) { return MFI_READ4(sc, MFI_OSP0); } -static int +static int mfi_check_clear_intr_xscale(struct mfi_softc *sc) { int32_t status; @@ -189,28 +193,35 @@ mfi_check_clear_intr_xscale(struct mfi_s MFI_WRITE4(sc, MFI_OSTS, status); return 0; - } +} -static int +static int mfi_check_clear_intr_ppc(struct mfi_softc *sc) { int32_t status; status = MFI_READ4(sc, MFI_OSTS); - if (!status) - return 1; + if (sc->mfi_flags & MFI_FLAGS_1078) { + if (!(status & MFI_1078_RM)) { + return 1; + } + } else if (sc->mfi_flags & MFI_FLAGS_GEN2) { + if (!(status & MFI_GEN2_RM)) { + return 1; + } + } MFI_WRITE4(sc, MFI_ODCR0, status); return 0; - } +} -static void +static void mfi_issue_cmd_xscale(struct mfi_softc *sc,uint32_t bus_add,uint32_t frame_cnt) { MFI_WRITE4(sc, MFI_IQP,(bus_add >>3)|frame_cnt); } - -static void + +static void mfi_issue_cmd_ppc(struct mfi_softc *sc,uint32_t bus_add,uint32_t frame_cnt) { MFI_WRITE4(sc, MFI_IQP, (bus_add |frame_cnt <<1)|1 ); @@ -1399,6 +1410,8 @@ mfi_bio_complete(struct mfi_command *cm) device_printf(sc->mfi_dev, "I/O error, status= %d " "scsi_status= %d\n", hdr->cmd_status, hdr->scsi_status); mfi_print_sense(cm->cm_sc, cm->cm_sense); + } else if (cm->cm_error != 0) { + bio->bio_flags |= BIO_ERROR; } mfi_release_command(cm); @@ -1815,6 +1828,9 @@ mfi_check_command_post(struct mfi_softc case MFI_DCMD_CFG_ADD: mfi_ldprobe(sc); break; + case MFI_DCMD_CFG_FOREIGN_IMPORT: + mfi_ldprobe(sc); + break; } } @@ -1904,7 +1920,7 @@ mfi_ioctl(struct cdev *dev, u_long cmd, struct mfi_ioc_aen *aen; struct mfi_command *cm = NULL; uint32_t context; - uint8_t *sense_ptr; + union mfi_sense_ptr sense_ptr; uint8_t *data = NULL, *temp; int i; struct mfi_ioc_passthru *iop = (struct mfi_ioc_passthru *)arg; @@ -1986,8 +2002,9 @@ mfi_ioctl(struct cdev *dev, u_long cmd, context = cm->cm_frame->header.context; bcopy(ioc->mfi_frame.raw, cm->cm_frame, - 2 * MFI_DCMD_FRAME_SIZE); /* this isn't quite right */ - cm->cm_total_frame_size = (sizeof(union mfi_sgl) * ioc->mfi_sge_count) + ioc->mfi_sgl_off; + 2 * MFI_DCMD_FRAME_SIZE); /* this isn't quite right */ + cm->cm_total_frame_size = (sizeof(union mfi_sgl) + * ioc->mfi_sge_count) + ioc->mfi_sgl_off; if (ioc->mfi_sge_count) { cm->cm_sg = (union mfi_sgl *)&cm->cm_frame->bytes[ioc->mfi_sgl_off]; @@ -2001,7 +2018,8 @@ mfi_ioctl(struct cdev *dev, u_long cmd, if (cm->cm_flags == 0) cm->cm_flags |= MFI_CMD_DATAIN | MFI_CMD_DATAOUT; cm->cm_len = cm->cm_frame->header.data_len; - if (cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT)) { + if (cm->cm_len && + (cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT))) { cm->cm_data = data = malloc(cm->cm_len, M_MFIBUF, M_WAITOK | M_ZERO); if (cm->cm_data == NULL) { @@ -2051,6 +2069,11 @@ mfi_ioctl(struct cdev *dev, u_long cmd, if (cm->cm_frame->header.cmd == MFI_CMD_DCMD) locked = mfi_config_lock(sc, cm->cm_frame->dcmd.opcode); + if (cm->cm_frame->header.cmd == MFI_CMD_PD_SCSI_IO) { + cm->cm_frame->pass.sense_addr_lo = cm->cm_sense_busaddr; + cm->cm_frame->pass.sense_addr_hi = 0; + } + mtx_lock(&sc->mfi_io_lock); error = mfi_check_command_pre(sc, cm); if (error) { @@ -2102,10 +2125,20 @@ mfi_ioctl(struct cdev *dev, u_long cmd, } if (ioc->mfi_sense_len) { - /* copy out sense */ - sense_ptr = &((struct mfi_ioc_packet*)arg) - ->mfi_frame.raw[0]; - error = copyout(cm->cm_sense, sense_ptr, + /* get user-space sense ptr then copy out sense */ + bcopy(&((struct mfi_ioc_packet*)arg) + ->mfi_frame.raw[ioc->mfi_sense_off], + &sense_ptr.sense_ptr_data[0], + sizeof(sense_ptr.sense_ptr_data)); +#ifdef __amd64__ + if (cmd != MFI_CMD) { + /* + * not 64bit native so zero out any address + * over 32bit */ + sense_ptr.addr.high = 0; + } +#endif + error = copyout(cm->cm_sense, sense_ptr.user_space, ioc->mfi_sense_len); if (error != 0) { device_printf(sc->mfi_dev, @@ -2203,7 +2236,7 @@ mfi_linux_ioctl_int(struct cdev *dev, u_ struct mfi_linux_ioc_aen l_aen; struct mfi_command *cm = NULL; struct mfi_aen *mfi_aen_entry; - uint8_t *sense_ptr; + union mfi_sense_ptr sense_ptr; uint32_t context; uint8_t *data = NULL, *temp; int i; @@ -2237,7 +2270,8 @@ mfi_linux_ioctl_int(struct cdev *dev, u_ bcopy(l_ioc.lioc_frame.raw, cm->cm_frame, 2 * MFI_DCMD_FRAME_SIZE); /* this isn't quite right */ - cm->cm_total_frame_size = (sizeof(union mfi_sgl) * l_ioc.lioc_sge_count) + l_ioc.lioc_sgl_off; + cm->cm_total_frame_size = (sizeof(union mfi_sgl) + * l_ioc.lioc_sge_count) + l_ioc.lioc_sgl_off; if (l_ioc.lioc_sge_count) cm->cm_sg = (union mfi_sgl *)&cm->cm_frame->bytes[l_ioc.lioc_sgl_off]; @@ -2247,7 +2281,8 @@ mfi_linux_ioctl_int(struct cdev *dev, u_ if (cm->cm_frame->header.flags & MFI_FRAME_DATAOUT) cm->cm_flags |= MFI_CMD_DATAOUT; cm->cm_len = cm->cm_frame->header.data_len; - if (cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT)) { + if (cm->cm_len && + (cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT))) { cm->cm_data = data = malloc(cm->cm_len, M_MFIBUF, M_WAITOK | M_ZERO); if (cm->cm_data == NULL) { @@ -2279,6 +2314,11 @@ mfi_linux_ioctl_int(struct cdev *dev, u_ if (cm->cm_frame->header.cmd == MFI_CMD_DCMD) locked = mfi_config_lock(sc, cm->cm_frame->dcmd.opcode); + if (cm->cm_frame->header.cmd == MFI_CMD_PD_SCSI_IO) { + cm->cm_frame->pass.sense_addr_lo = cm->cm_sense_busaddr; + cm->cm_frame->pass.sense_addr_hi = 0; + } + mtx_lock(&sc->mfi_io_lock); error = mfi_check_command_pre(sc, cm); if (error) { @@ -2312,10 +2352,19 @@ mfi_linux_ioctl_int(struct cdev *dev, u_ } if (l_ioc.lioc_sense_len) { - /* copy out sense */ - sense_ptr = &((struct mfi_linux_ioc_packet*)arg) - ->lioc_frame.raw[0]; - error = copyout(cm->cm_sense, sense_ptr, + /* get user-space sense ptr then copy out sense */ + bcopy(&((struct mfi_linux_ioc_packet*)arg) + ->lioc_frame.raw[l_ioc.lioc_sense_off], + &sense_ptr.sense_ptr_data[0], + sizeof(sense_ptr.sense_ptr_data)); +#ifdef __amd64__ + /* + * only 32bit Linux support so zero out any + * address over 32bit + */ + sense_ptr.addr.high = 0; +#endif + error = copyout(cm->cm_sense, sense_ptr.user_space, l_ioc.lioc_sense_len); if (error != 0) { device_printf(sc->mfi_dev, Modified: stable/6/sys/dev/mfi/mfi_ioctl.h ============================================================================== --- stable/6/sys/dev/mfi/mfi_ioctl.h Wed Mar 18 20:22:21 2009 (r189985) +++ stable/6/sys/dev/mfi/mfi_ioctl.h Wed Mar 18 20:42:00 2009 (r189986) @@ -50,6 +50,16 @@ union mfi_statrequest { struct mfi_qstat ms_qstat; }; +#define MAX_SPACE_FOR_SENSE_PTR 32 +union mfi_sense_ptr { + uint8_t sense_ptr_data[MAX_SPACE_FOR_SENSE_PTR]; + void *user_space; + struct { + uint32_t low; + uint32_t high; + } addr; +} __packed; + #define MAX_IOCTL_SGE 16 struct mfi_ioc_packet { Modified: stable/6/sys/dev/mfi/mfi_pci.c ============================================================================== --- stable/6/sys/dev/mfi/mfi_pci.c Wed Mar 18 20:22:21 2009 (r189985) +++ stable/6/sys/dev/mfi/mfi_pci.c Wed Mar 18 20:42:00 2009 (r189986) @@ -118,7 +118,14 @@ struct mfi_ident { {0x1000, 0x0413, 0xffff, 0xffff, MFI_FLAGS_1064R, "LSI MegaSAS 1064R"}, /* Verde ZCR */ {0x1028, 0x0015, 0xffff, 0xffff, MFI_FLAGS_1064R, "Dell PERC 5/i"}, {0x1000, 0x0060, 0x1028, 0xffff, MFI_FLAGS_1078, "Dell PERC 6"}, - {0x1000, 0x0060, 0xffff, 0xffff, MFI_FLAGS_1078, "LSI MegaSAS 1078"}, + {0x1000, 0x0060, 0xffff, 0xffff, MFI_FLAGS_1078, "LSI MegaSAS 1078"}, + {0x1000, 0x0079, 0x1028, 0x1f15, MFI_FLAGS_GEN2, "Dell PERC 607E Adapter"}, + {0x1000, 0x0079, 0x1028, 0x1f16, MFI_FLAGS_GEN2, "Dell PERC 607I Adapter"}, + {0x1000, 0x0079, 0x1028, 0x1f17, MFI_FLAGS_GEN2, "Dell PERC 607I Integrated"}, + {0x1000, 0x0079, 0x1028, 0x1f18, MFI_FLAGS_GEN2, "Dell PERC 607I Modular"}, + {0x1000, 0x0078, 0xffff, 0xffff, MFI_FLAGS_GEN2, "LSI MegaSAS Gen2"}, + {0x1000, 0x0079, 0xffff, 0xffff, MFI_FLAGS_GEN2, "LSI MegaSAS Gen2"}, + {0x1000, 0x007c, 0xffff, 0xffff, MFI_FLAGS_1078, "LSI MegaSAS 1078"}, {0, 0, 0, 0, 0, NULL} }; @@ -163,6 +170,8 @@ mfi_pci_attach(device_t dev) sc = device_get_softc(dev); bzero(sc, sizeof(*sc)); sc->mfi_dev = dev; + m = mfi_find_ident(dev); + sc->mfi_flags = m->flags; /* Verify that the adapter can be set up in PCI space */ command = pci_read_config(dev, PCIR_COMMAND, 2); @@ -179,7 +188,14 @@ mfi_pci_attach(device_t dev) } /* Allocate PCI registers */ - sc->mfi_regs_rid = PCIR_BAR(0); + if ((sc->mfi_flags & MFI_FLAGS_1064R) || + (sc->mfi_flags & MFI_FLAGS_1078)) { + /* 1068/1078: Memory mapped BAR is at offset 0x10 */ + sc->mfi_regs_rid = PCIR_BAR(0); + } else if (sc->mfi_flags & MFI_FLAGS_GEN2) { + /* GEN2: Memory mapped BAR is at offset 0x14 */ + sc->mfi_regs_rid = PCIR_BAR(1); + } if ((sc->mfi_regs_resource = bus_alloc_resource_any(sc->mfi_dev, SYS_RES_MEMORY, &sc->mfi_regs_rid, RF_ACTIVE)) == NULL) { device_printf(dev, "Cannot allocate PCI registers\n"); @@ -206,9 +222,6 @@ mfi_pci_attach(device_t dev) goto out; } - m = mfi_find_ident(dev); - sc->mfi_flags = m->flags; - error = mfi_attach(sc); out: if (error) { Modified: stable/6/sys/dev/mfi/mfireg.h ============================================================================== --- stable/6/sys/dev/mfi/mfireg.h Wed Mar 18 20:22:21 2009 (r189985) +++ stable/6/sys/dev/mfi/mfireg.h Wed Mar 18 20:42:00 2009 (r189986) @@ -89,10 +89,16 @@ __FBSDID("$FreeBSD$"); #define MFI_ODCR0 0xa0 /* outbound doorbell clear register0 */ #define MFI_OSP0 0xb0 /* outbound scratch pad0 */ #define MFI_1078_EIM 0x80000004 /* 1078 enable intrrupt mask */ -#define MFI_RMI 0x2 /* reply message interrupt */ +#define MFI_RMI 0x2 /* reply message interrupt */ #define MFI_1078_RM 0x80000000 /* reply 1078 message interrupt */ #define MFI_ODC 0x4 /* outbound doorbell change interrupt */ +/* + * GEN2 specific changes + */ +#define MFI_GEN2_EIM 0x00000005 /* GEN2 enable interrupt mask */ +#define MFI_GEN2_RM 0x00000001 /* reply GEN2 message interrupt */ + /* Bits for MFI_OSTS */ #define MFI_OSTS_INTR_VALID 0x00000002 @@ -153,6 +159,7 @@ typedef enum { MFI_DCMD_CFG_READ = 0x04010000, MFI_DCMD_CFG_ADD = 0x04020000, MFI_DCMD_CFG_CLEAR = 0x04030000, + MFI_DCMD_CFG_FOREIGN_IMPORT = 0x04060400, MFI_DCMD_CLUSTER = 0x08000000, MFI_DCMD_CLUSTER_RESET_ALL = 0x08010100, MFI_DCMD_CLUSTER_RESET_LD = 0x08010200 Modified: stable/6/sys/dev/mfi/mfivar.h ============================================================================== --- stable/6/sys/dev/mfi/mfivar.h Wed Mar 18 20:22:21 2009 (r189985) +++ stable/6/sys/dev/mfi/mfivar.h Wed Mar 18 20:42:00 2009 (r189986) @@ -133,6 +133,7 @@ struct mfi_softc { #define MFI_FLAGS_STOP (1<<3) #define MFI_FLAGS_1064R (1<<4) #define MFI_FLAGS_1078 (1<<5) +#define MFI_FLAGS_GEN2 (1<<6) struct mfi_hwcomms *mfi_comms; TAILQ_HEAD(,mfi_command) mfi_free;