From owner-svn-src-head@FreeBSD.ORG Wed Nov 12 22:44:51 2008 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4ABF11065673; Wed, 12 Nov 2008 22:44:51 +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 352828FC12; Wed, 12 Nov 2008 22:44:51 +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 mACMipf2042204; Wed, 12 Nov 2008 22:44:51 GMT (envelope-from ambrisko@svn.freebsd.org) Received: (from ambrisko@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mACMioux042199; Wed, 12 Nov 2008 22:44:50 GMT (envelope-from ambrisko@svn.freebsd.org) Message-Id: <200811122244.mACMioux042199@svn.freebsd.org> From: Doug Ambrisko Date: Wed, 12 Nov 2008 22:44:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r184897 - head/sys/dev/mfi X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Nov 2008 22:44:51 -0000 Author: ambrisko Date: Wed Nov 12 22:44:50 2008 New Revision: 184897 URL: http://svn.freebsd.org/changeset/base/184897 Log: - Fix from jhb for failing I/O request when bus_dmamap_load fails. - Fix to ioctl path in which the length could be 0 which means no data in/out from LSI. - Fix to ioctl path in which the data in the sense data space of the ioctl packet is a really a pointer to some location in user-space. From LSI re-worked a bit by me. - Add HW support for next gen cards from LSI. Thanks to LSI for their support! Submitted by: jhb, LSI MFC after: 3 days Modified: head/sys/dev/mfi/mfi.c head/sys/dev/mfi/mfi_ioctl.h head/sys/dev/mfi/mfi_pci.c head/sys/dev/mfi/mfireg.h head/sys/dev/mfi/mfivar.h Modified: head/sys/dev/mfi/mfi.c ============================================================================== --- head/sys/dev/mfi/mfi.c Wed Nov 12 22:14:05 2008 (r184896) +++ head/sys/dev/mfi/mfi.c Wed Nov 12 22:44:50 2008 (r184897) @@ -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; @@ -191,26 +195,33 @@ mfi_check_clear_intr_xscale(struct mfi_s 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) { @@ -2102,10 +2120,12 @@ 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)); + error = copyout(cm->cm_sense, sense_ptr.user_space, ioc->mfi_sense_len); if (error != 0) { device_printf(sc->mfi_dev, @@ -2207,7 +2227,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; @@ -2241,7 +2261,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]; @@ -2251,7 +2272,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) { @@ -2316,10 +2338,12 @@ 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)); + error = copyout(cm->cm_sense, sense_ptr.user_space, l_ioc.lioc_sense_len); if (error != 0) { device_printf(sc->mfi_dev, Modified: head/sys/dev/mfi/mfi_ioctl.h ============================================================================== --- head/sys/dev/mfi/mfi_ioctl.h Wed Nov 12 22:14:05 2008 (r184896) +++ head/sys/dev/mfi/mfi_ioctl.h Wed Nov 12 22:44:50 2008 (r184897) @@ -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: head/sys/dev/mfi/mfi_pci.c ============================================================================== --- head/sys/dev/mfi/mfi_pci.c Wed Nov 12 22:14:05 2008 (r184896) +++ head/sys/dev/mfi/mfi_pci.c Wed Nov 12 22:44:50 2008 (r184897) @@ -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: head/sys/dev/mfi/mfireg.h ============================================================================== --- head/sys/dev/mfi/mfireg.h Wed Nov 12 22:14:05 2008 (r184896) +++ head/sys/dev/mfi/mfireg.h Wed Nov 12 22:44:50 2008 (r184897) @@ -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: head/sys/dev/mfi/mfivar.h ============================================================================== --- head/sys/dev/mfi/mfivar.h Wed Nov 12 22:14:05 2008 (r184896) +++ head/sys/dev/mfi/mfivar.h Wed Nov 12 22:44:50 2008 (r184897) @@ -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;