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;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to