Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Fri, 21 Jul 2006 19:04:53 +0000 (12:04 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 21 Jul 2006 19:04:53 +0000 (12:04 -0700)
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6: (38 commits)
  [SCSI] More buffer->request_buffer changes
  [SCSI] mptfusion: bump version to 3.04.01
  [SCSI] mptfusion: misc fix's
  [SCSI] mptfusion: firmware download boot fix's
  [SCSI] mptfusion: task abort fix's
  [SCSI] mptfusion: sas nexus loss support
  [SCSI] mptfusion: sas loginfo update
  [SCSI] mptfusion: mptctl panic when loading
  [SCSI] mptfusion: sas enclosures with smart drive
  [SCSI] NCR_D700: misc fixes (section and argument ordering)
  [SCSI] scsi_debug: must_check fixes
  [SCSI] scsi_transport_sas: kill the use of channel
  [SCSI] scsi_transport_sas: add expander backlink
  [SCSI] hide EH backup data outside the scsi_cmnd
  [SCSI] ibmvscsi: handle inactive SCSI target during probe
  [SCSI] ibmvscsi: allocate lpevents for ibmvscsi on iseries
  [SCSI] aic7[9x]xx: Remove last vestiges of reverse_scan
  [SCSI] aha152x: stop poking at saved scsi_cmnd members
  [SCSI] st.c: Improve sense output
  [SCSI] lpfc 8.1.7: Change version number to 8.1.7
  ...

55 files changed:
drivers/fc4/fc.c
drivers/message/fusion/Kconfig
drivers/message/fusion/Makefile
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptctl.c
drivers/message/fusion/mptctl.h
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptsas.c
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptspi.c
drivers/scsi/53c7xx.c
drivers/scsi/NCR53C9x.c
drivers/scsi/NCR_D700.c
drivers/scsi/aha152x.c
drivers/scsi/aic7xxx/aic79xx_core.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/atari_NCR5380.c
drivers/scsi/constants.c
drivers/scsi/esp.c
drivers/scsi/ibmvscsi/iseries_vscsi.c
drivers/scsi/ibmvscsi/rpa_vscsi.c
drivers/scsi/jazz_esp.c
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_mem.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli.h
drivers/scsi/lpfc/lpfc_version.h
drivers/scsi/mac53c94.c
drivers/scsi/mesh.c
drivers/scsi/pluto.c
drivers/scsi/qlogicpti.c
drivers/scsi/scsi.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_priv.h
drivers/scsi/scsi_transport_sas.c
drivers/scsi/sd.c
drivers/scsi/seagate.c
drivers/scsi/sr.c
drivers/scsi/st.c
drivers/scsi/sun3_NCR5380.c
drivers/scsi/sun3x_esp.c
drivers/scsi/wd33c93.c
include/scsi/scsi_cmnd.h
include/scsi/scsi_transport_sas.h

index 66d03f242d3ce7f1c741109a6b235494a90efca7..1a159e8843ca47dd27778937d350df400448c48f 100644 (file)
@@ -429,7 +429,7 @@ static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hd
                
                if (fcmd->data) {
                        if (SCpnt->use_sg)
-                               dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->buffer,
+                               dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->request_buffer,
                                                SCpnt->use_sg,
                                                SCpnt->sc_data_direction);
                        else
@@ -810,7 +810,7 @@ static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, i
                                                             SCpnt->request_bufflen,
                                                             SCpnt->sc_data_direction);
                        } else {
-                               struct scatterlist *sg = (struct scatterlist *)SCpnt->buffer;
+                               struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer;
                                int nents;
 
                                FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length))
index bbc229852881e133affea9a4984a6ce806f1f622..ea31d84705107ca361d7cc0d59992a0aca3e97a3 100644 (file)
@@ -48,10 +48,8 @@ config FUSION_SAS
          List of supported controllers:
 
          LSISAS1064
-         LSISAS1066
          LSISAS1068
          LSISAS1064E
-         LSISAS1066E
          LSISAS1068E
 
 config FUSION_MAX_SGE
index b114236f43953ef126a85a6365812cfe2536ec01..341691390e86370bec5ccfd37b73b8aa9266c92d 100644 (file)
@@ -9,7 +9,6 @@
 #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
 #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
 
-
 #
 # driver/module specifics...
 #
index 43308df64623ace8b1d261f9b28858643306fc8c..29d0635cce1d2d314a9f5f9d41277f178199299c 100644 (file)
@@ -436,8 +436,6 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
                 */
                if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
                        freereq = 0;
-                       devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
-                               ioc->name, pEvReply));
                } else {
                        devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
                                ioc->name, pEvReply));
@@ -678,19 +676,19 @@ int
 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
 {
        MPT_ADAPTER     *ioc;
+       const struct pci_device_id *id;
 
-       if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
+       if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
                return -EINVAL;
-       }
 
        MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
 
        /* call per pci device probe entry point */
        list_for_each_entry(ioc, &ioc_list, list) {
-               if(dd_cbfunc->probe) {
-                       dd_cbfunc->probe(ioc->pcidev,
-                         ioc->pcidev->driver->id_table);
-               }
+               id = ioc->pcidev->driver ?
+                   ioc->pcidev->driver->id_table : NULL;
+               if (dd_cbfunc->probe)
+                       dd_cbfunc->probe(ioc->pcidev, id);
         }
 
        return 0;
@@ -1056,9 +1054,8 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
 
                                dinitprintk((MYIOC_s_INFO_FMT
                                    "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
-                                   ioc->name,
-                                   ioc->HostPageBuffer,
-                                   ioc->HostPageBuffer_dma,
+                                   ioc->name, ioc->HostPageBuffer,
+                                   (u32)ioc->HostPageBuffer_dma,
                                    host_page_buffer_sz));
                                ioc->alloc_total += host_page_buffer_sz;
                                ioc->HostPageBuffer_sz = host_page_buffer_sz;
@@ -1380,6 +1377,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
                printk(KERN_WARNING MYNAM
                  ": WARNING - %s did not initialize properly! (%d)\n",
                  ioc->name, r);
+
                list_del(&ioc->list);
                if (ioc->alt_ioc)
                        ioc->alt_ioc->alt_ioc = NULL;
@@ -1762,9 +1760,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
                                                 * chips (mpt_adapter_disable,
                                                 * mpt_diag_reset)
                                                 */
-                                               ioc->cached_fw = NULL;
                                                ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload:  alt_%s has cached_fw=%p \n",
                                                        ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
+                                               ioc->alt_ioc->cached_fw = NULL;
                                        }
                                } else {
                                        printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
@@ -1885,7 +1883,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
                /* FIXME?  Examine results here? */
        }
 
-out:
+ out:
        if ((ret != 0) && irq_allocated) {
                free_irq(ioc->pci_irq, ioc);
                if (mpt_msi_enable)
@@ -2670,6 +2668,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
        dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
                        ioc->name, count));
 
+       ioc->aen_event_read_flag=0;
        return r;
 }
 
@@ -2737,6 +2736,8 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
        if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
                ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
                ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
+               ioc->alloc_total += size;
+               ioc->alt_ioc->alloc_total -= size;
        } else {
                if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
                        ioc->alloc_total += size;
@@ -3166,6 +3167,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
 static int
 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
 {
+       MPT_ADAPTER     *iocp=NULL;
        u32 diag0val;
        u32 doorbell;
        int hard_reset_done = 0;
@@ -3301,17 +3303,23 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
                        /* FIXME?  Examine results here? */
                }
 
-               if (ioc->cached_fw) {
+               if (ioc->cached_fw)
+                       iocp = ioc;
+               else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
+                       iocp = ioc->alt_ioc;
+               if (iocp) {
                        /* If the DownloadBoot operation fails, the
                         * IOC will be left unusable. This is a fatal error
                         * case.  _diag_reset will return < 0
                         */
                        for (count = 0; count < 30; count ++) {
-                               diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+                               diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
                                if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
                                        break;
                                }
 
+                               dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
+                                       iocp->name, diag0val, count));
                                /* wait 1 sec */
                                if (sleepFlag == CAN_SLEEP) {
                                        msleep (1000);
@@ -3320,7 +3328,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
                                }
                        }
                        if ((count = mpt_downloadboot(ioc,
-                               (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
+                               (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
                                printk(KERN_WARNING MYNAM
                                        ": firmware downloadboot failure (%d)!\n", count);
                        }
@@ -3907,18 +3915,18 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
 
        if (sleepFlag == CAN_SLEEP) {
                while (--cntdn) {
+                       msleep (1);
                        intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
                        if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
                                break;
-                       msleep (1);
                        count++;
                }
        } else {
                while (--cntdn) {
+                       mdelay (1);
                        intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
                        if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
                                break;
-                       mdelay (1);
                        count++;
                }
        }
@@ -4883,6 +4891,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
                pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
                if (!pIoc4)
                        return;
+               ioc->alloc_total += iocpage4sz;
        } else {
                ioc4_dma = ioc->spi_data.IocPg4_dma;
                iocpage4sz = ioc->spi_data.IocPg4Sz;
@@ -4899,6 +4908,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
        } else {
                pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
                ioc->spi_data.pIocPg4 = NULL;
+               ioc->alloc_total -= iocpage4sz;
        }
 }
 
@@ -5030,19 +5040,18 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
        EventAck_t      *pAck;
 
        if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
-               printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
-                       "request frame for Event=%x EventContext=%x EventData=%x!\n",
-                       ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
-                       le32_to_cpu(evnp->Data[0]));
+               dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
+                   ioc->name,__FUNCTION__));
                return -1;
        }
-       memset(pAck, 0, sizeof(*pAck));
 
-       dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
+       devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
 
        pAck->Function     = MPI_FUNCTION_EVENT_ACK;
        pAck->ChainOffset  = 0;
+       pAck->Reserved[0]  = pAck->Reserved[1] = 0;
        pAck->MsgFlags     = 0;
+       pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
        pAck->Event        = evnp->Event;
        pAck->EventContext = evnp->EventContext;
 
@@ -5704,9 +5713,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
                break;
        case MPI_EVENT_EVENT_CHANGE:
                if (evData0)
-                       ds = "Events(ON) Change";
+                       ds = "Events ON";
                else
-                       ds = "Events(OFF) Change";
+                       ds = "Events OFF";
                break;
        case MPI_EVENT_INTEGRATED_RAID:
        {
@@ -5777,8 +5786,27 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
                        break;
                case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
                        snprintf(evStr, EVENT_DESCR_STR_SZ,
-                           "SAS Device Status Change: No Persistancy "
-                           "Added: id=%d", id);
+                           "SAS Device Status Change: No Persistancy: id=%d", id);
+                       break;
+               case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Internal Device Reset : id=%d", id);
+                       break;
+               case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Internal Task Abort : id=%d", id);
+                       break;
+               case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Internal Abort Task Set : id=%d", id);
+                       break;
+               case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Internal Clear Task Set : id=%d", id);
+                       break;
+               case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Internal Query Task : id=%d", id);
                        break;
                default:
                        snprintf(evStr, EVENT_DESCR_STR_SZ,
@@ -6034,7 +6062,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
  *     @ioc: Pointer to MPT_ADAPTER structure
  *     @log_info: U32 LogInfo reply word from the IOC
  *
- *     Refer to lsi/fc_log.h.
+ *     Refer to lsi/mpi_log_fc.h.
  */
 static void
 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
@@ -6131,8 +6159,10 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
                "Invalid SAS Address",                          /* 01h */
                NULL,                                           /* 02h */
                "Invalid Page",                                 /* 03h */
-               NULL,                                           /* 04h */
-               "Task Terminated"                               /* 05h */
+               "Diag Message Error",                           /* 04h */
+               "Task Terminated",                              /* 05h */
+               "Enclosure Management",                         /* 06h */
+               "Target Mode"                                   /* 07h */
        };
        static char *pl_code_str[] = {
                NULL,                                           /* 00h */
@@ -6158,7 +6188,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
                "IO Executed",                                  /* 14h */
                "Persistant Reservation Out Not Affiliation Owner", /* 15h */
                "Open Transmit DMA Abort",                      /* 16h */
-               NULL,                                           /* 17h */
+               "IO Device Missing Delay Retry",                /* 17h */
                NULL,                                           /* 18h */
                NULL,                                           /* 19h */
                NULL,                                           /* 1Ah */
@@ -6238,7 +6268,7 @@ static void
 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
 {
        u32 status = ioc_status & MPI_IOCSTATUS_MASK;
-       char *desc = "";
+       char *desc = NULL;
 
        switch (status) {
        case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
@@ -6348,7 +6378,7 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
                desc = "Others";
                break;
        }
-       if (desc != "")
+       if (desc != NULL)
                printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
 }
 
@@ -6386,7 +6416,6 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory);
 EXPORT_SYMBOL(mpt_free_fw_memory);
 EXPORT_SYMBOL(mptbase_sas_persist_operation);
 
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *     fusion_init - Fusion MPT base driver initialization routine.
index a5ce10b67d02644640edae0d8930dc8037acb44b..d4cb144ab402ba97a56e9d8e96f78d23837aedda 100644 (file)
@@ -75,8 +75,8 @@
 #define COPYRIGHT      "Copyright (c) 1999-2005 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON       "3.04.00"
-#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.04.00"
+#define MPT_LINUX_VERSION_COMMON       "3.04.01"
+#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.04.01"
 #define WHAT_MAGIC_STRING              "@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -307,8 +307,8 @@ typedef struct _SYSIF_REGS
        u32     HostIndex;      /* 50     Host Index register        */
        u32     Reserved4[15];  /* 54-8F                             */
        u32     Fubar;          /* 90     For Fubar usage            */
-       u32     Reserved5[1050];/* 94-10F8                           */
-       u32     Reset_1078;     /* 10FC   Reset 1078                 */
+       u32     Reserved5[1050];/* 94-10F8                           */
+       u32     Reset_1078;     /* 10FC   Reset 1078                 */
 } SYSIF_REGS;
 
 /*
@@ -363,6 +363,7 @@ typedef struct _VirtDevice {
 #define MPT_TARGET_FLAGS_VALID_56      0x10
 #define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
 #define MPT_TARGET_FLAGS_RAID_COMPONENT        0x40
+#define MPT_TARGET_FLAGS_LED_ON                0x80
 
 /*
  *     /proc/mpt interface
@@ -634,7 +635,6 @@ typedef struct _MPT_ADAPTER
        u16                      handle;
        int                      sas_index; /* index refrencing */
        MPT_SAS_MGMT             sas_mgmt;
-       int                      num_ports;
        struct work_struct       sas_persist_task;
 
        struct work_struct       fc_setup_reset_work;
@@ -644,7 +644,6 @@ typedef struct _MPT_ADAPTER
        struct work_struct       fc_rescan_work;
        char                     fc_rescan_work_q_name[KOBJ_NAME_LEN];
        struct workqueue_struct *fc_rescan_work_q;
-       u8              port_serial_number;
 } MPT_ADAPTER;
 
 /*
@@ -982,7 +981,7 @@ typedef struct _MPT_SCSI_HOST {
        wait_queue_head_t         scandv_waitq;
        int                       scandv_wait_done;
        long                      last_queue_full;
-       u8                        mpt_pq_filter;
+       u16                       tm_iocstatus;
 } MPT_SCSI_HOST;
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
index b4967bb8a7d64521b23207520fa22702fbce034d..30975ccd9947622de211661134bc74e94ceea254 100644 (file)
@@ -2332,7 +2332,7 @@ done_free_mem:
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* Prototype Routine for the HP HOST INFO command.
+/* Prototype Routine for the HOST INFO command.
  *
  * Outputs:    None.
  * Return:     0 if successful
@@ -2568,7 +2568,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* Prototype Routine for the HP TARGET INFO command.
+/* Prototype Routine for the TARGET INFO command.
  *
  * Outputs:    None.
  * Return:     0 if successful
index a2f8a97992e68106b04514e1b4c404ebc0f24ef7..043941882c6e8b05c39f5b8341944abad9f3b10d 100644 (file)
@@ -354,9 +354,6 @@ struct mpt_ioctl_command32 {
 
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *     HP Specific IOCTL Defines and Structures
- */
 
 #define CPQFCTS_IOC_MAGIC 'Z'
 #define HP_IOC_MAGIC 'Z'
@@ -364,8 +361,6 @@ struct mpt_ioctl_command32 {
 #define HP_GETHOSTINFO1                _IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t)
 #define HP_GETTARGETINFO       _IOR(HP_IOC_MAGIC, 21, hp_target_info_t)
 
-/* All HP IOCTLs must include this header
- */
 typedef struct _hp_header {
        unsigned int iocnum;
        unsigned int host;
index a8f2fa985455b6bdf88af739f6d38efdee72299b..90da7d63b08e1070bdb13030e96780c688e8b79e 100644 (file)
@@ -77,10 +77,6 @@ MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
 
 /* Command line args */
-static int mpt_pq_filter = 0;
-module_param(mpt_pq_filter, int, 0);
-MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
-
 #define MPTFC_DEV_LOSS_TMO (60)
 static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;    /* reasonable default */
 module_param(mptfc_dev_loss_tmo, int, 0);
@@ -513,8 +509,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
 
        if (vtarget->num_luns == 0) {
                vtarget->ioc_id = hd->ioc->id;
-               vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
-                                 MPT_TARGET_FLAGS_VALID_INQUIRY;
+               vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
                hd->Targets[sdev->id] = vtarget;
        }
 
@@ -1129,13 +1124,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        hd->timer.data = (unsigned long) hd;
        hd->timer.function = mptscsih_timer_expired;
 
-       hd->mpt_pq_filter = mpt_pq_filter;
-
-       ddvprintk((MYIOC_s_INFO_FMT
-               "mpt_pq_filter %x\n",
-               ioc->name, 
-               mpt_pq_filter));
-
        init_waitqueue_head(&hd->scandv_waitq);
        hd->scandv_wait_done = 0;
        hd->last_queue_full = 0;
index f7bd8b11ed3be860feeffadc736aa6681e8d3724..f66f2203143a8435c8e84840a12204afefda76ba 100644 (file)
 #define my_VERSION     MPT_LINUX_VERSION_COMMON
 #define MYNAM          "mptsas"
 
+/*
+ * Reserved channel for integrated raid
+ */
+#define MPTSAS_RAID_CHANNEL    1
+
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
 
-static int mpt_pq_filter;
-module_param(mpt_pq_filter, int, 0);
-MODULE_PARM_DESC(mpt_pq_filter,
-               "Enable peripheral qualifier filter: enable=1  "
-               "(default=0)");
-
 static int mpt_pt_clear;
 module_param(mpt_pt_clear, int, 0);
 MODULE_PARM_DESC(mpt_pt_clear,
-               "Clear persistency table: enable=1  "
+               " Clear persistency table: enable=1  "
                "(default=MPTSCSIH_PT_CLEAR=0)");
 
 static int     mptsasDoneCtx = -1;
@@ -144,7 +143,6 @@ struct mptsas_devinfo {
  * Specific details on ports, wide/narrow
  */
 struct mptsas_portinfo_details{
-       u8      port_id;        /* port number provided to transport */
        u16     num_phys;       /* number of phys belong to this port */
        u64     phy_bitmask;    /* TODO, extend support for 255 phys */
        struct sas_rphy *rphy;  /* transport layer rphy object */
@@ -350,10 +348,10 @@ mptsas_port_delete(struct mptsas_portinfo_details * port_details)
        port_info = port_details->port_info;
        phy_info = port_info->phy_info;
 
-       dsaswideprintk((KERN_DEBUG "%s: [%p]: port=%02d num_phys=%02d "
+       dsaswideprintk((KERN_DEBUG "%s: [%p]: num_phys=%02d "
                "bitmask=0x%016llX\n",
-               __FUNCTION__, port_details, port_details->port_id,
-               port_details->num_phys, port_details->phy_bitmask));
+               __FUNCTION__, port_details, port_details->num_phys,
+                   port_details->phy_bitmask));
 
        for (i = 0; i < port_info->num_phys; i++, phy_info++) {
                if(phy_info->port_details != port_details)
@@ -462,9 +460,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
                 * phy be removed by firmware events.
                 */
                dsaswideprintk((KERN_DEBUG
-                       "%s: [%p]: port=%d deleting phy = %d\n",
-                       __FUNCTION__, port_details,
-                       port_details->port_id, i));
+                       "%s: [%p]: deleting phy = %d\n",
+                       __FUNCTION__, port_details, i));
                port_details->num_phys--;
                port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
                memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
@@ -493,7 +490,6 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
                                goto out;
                        port_details->num_phys = 1;
                        port_details->port_info = port_info;
-                       port_details->port_id = ioc->port_serial_number++;
                        if (phy_info->phy_id < 64 )
                                port_details->phy_bitmask |=
                                    (1 << phy_info->phy_id);
@@ -525,12 +521,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
                                    mptsas_get_port(phy_info_cmp);
                                port_details->starget =
                                    mptsas_get_starget(phy_info_cmp);
-                               port_details->port_id =
-                                       phy_info_cmp->port_details->port_id;
                                port_details->num_phys =
                                        phy_info_cmp->port_details->num_phys;
-//                             port_info->port_serial_number--;
-                               ioc->port_serial_number--;
                                if (!phy_info_cmp->port_details->num_phys)
                                        kfree(phy_info_cmp->port_details);
                        } else
@@ -554,11 +546,11 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
                if (!port_details)
                        continue;
                dsaswideprintk((KERN_DEBUG
-                       "%s: [%p]: phy_id=%02d port_id=%02d num_phys=%02d "
+                       "%s: [%p]: phy_id=%02d num_phys=%02d "
                        "bitmask=0x%016llX\n",
                        __FUNCTION__,
-                       port_details, i, port_details->port_id,
-                       port_details->num_phys, port_details->phy_bitmask));
+                       port_details, i, port_details->num_phys,
+                       port_details->phy_bitmask));
                dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n",
                        port_details->port, port_details->rphy));
        }
@@ -651,16 +643,13 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
 static int
 mptsas_slave_configure(struct scsi_device *sdev)
 {
-       struct Scsi_Host        *host = sdev->host;
-       MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
 
-       /*
-        * RAID volumes placed beyond the last expected port.
-        * Ignore sending sas mode pages in that case..
-        */
-       if (sdev->channel < hd->ioc->num_ports)
-               sas_read_port_mode_page(sdev);
+       if (sdev->channel == MPTSAS_RAID_CHANNEL)
+               goto out;
+
+       sas_read_port_mode_page(sdev);
 
+ out:
        return mptscsih_slave_configure(sdev);
 }
 
@@ -689,10 +678,7 @@ mptsas_target_alloc(struct scsi_target *starget)
 
        hd->Targets[target_id] = vtarget;
 
-       /*
-        * RAID volumes placed beyond the last expected port.
-        */
-       if (starget->channel == hd->ioc->num_ports)
+       if (starget->channel == MPTSAS_RAID_CHANNEL)
                goto out;
 
        rphy = dev_to_rphy(starget->dev.parent);
@@ -743,7 +729,7 @@ mptsas_target_destroy(struct scsi_target *starget)
        if (!starget->hostdata)
                return;
 
-       if (starget->channel == hd->ioc->num_ports)
+       if (starget->channel == MPTSAS_RAID_CHANNEL)
                goto out;
 
        rphy = dev_to_rphy(starget->dev.parent);
@@ -783,10 +769,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
        starget = scsi_target(sdev);
        vdev->vtarget = starget->hostdata;
 
-       /*
-        * RAID volumes placed beyond the last expected port.
-        */
-       if (sdev->channel == hd->ioc->num_ports)
+       if (sdev->channel == MPTSAS_RAID_CHANNEL)
                goto out;
 
        rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
@@ -1608,11 +1591,7 @@ static int mptsas_probe_one_phy(struct device *dev,
        if (phy_info->sas_port_add_phy) {
 
                if (!port) {
-                       port = sas_port_alloc(dev,
-                           phy_info->port_details->port_id);
-                       dsaswideprintk((KERN_DEBUG
-                           "sas_port_alloc: port=%p dev=%p port_id=%d\n",
-                           port, dev, phy_info->port_details->port_id));
+                       port = sas_port_alloc_num(dev);
                        if (!port) {
                                error = -ENOMEM;
                                goto out;
@@ -1625,6 +1604,9 @@ static int mptsas_probe_one_phy(struct device *dev,
                                goto out;
                        }
                        mptsas_set_port(phy_info, port);
+                       dsaswideprintk((KERN_DEBUG
+                           "sas_port_alloc: port=%p dev=%p port_id=%d\n",
+                           port, dev, port->port_identifier));
                }
                dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n",
                    phy_info->phy_id));
@@ -1736,7 +1718,6 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
                hba = NULL;
        }
        mutex_unlock(&ioc->sas_topology_mutex);
-       ioc->num_ports = port_info->num_phys;
 
        for (i = 0; i < port_info->num_phys; i++) {
                mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
@@ -1939,7 +1920,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
                                        expander_sas_address)
                                        continue;
 #ifdef MPT_DEBUG_SAS_WIDE
-                               dev_printk(KERN_DEBUG, &port->dev, "delete\n");
+                               dev_printk(KERN_DEBUG, &port->dev,
+                                   "delete port (%d)\n", port->port_identifier);
 #endif
                                sas_port_delete(port);
                                mptsas_port_delete(phy_info->port_details);
@@ -1984,7 +1966,7 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
        if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
                goto out;
        for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
-               scsi_add_device(ioc->sh, ioc->num_ports,
+               scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
                    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
        }
  out:
@@ -2185,7 +2167,8 @@ mptsas_hotplug_work(void *arg)
                       ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
 
 #ifdef MPT_DEBUG_SAS_WIDE
-               dev_printk(KERN_DEBUG, &port->dev, "delete\n");
+               dev_printk(KERN_DEBUG, &port->dev,
+                   "delete port (%d)\n", port->port_identifier);
 #endif
                sas_port_delete(port);
                mptsas_port_delete(phy_info->port_details);
@@ -2289,35 +2272,26 @@ mptsas_hotplug_work(void *arg)
                mptsas_set_rphy(phy_info, rphy);
                break;
        case MPTSAS_ADD_RAID:
-               sdev = scsi_device_lookup(
-                       ioc->sh,
-                       ioc->num_ports,
-                       ev->id,
-                       0);
+               sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
+                   ev->id, 0);
                if (sdev) {
                        scsi_device_put(sdev);
                        break;
                }
                printk(MYIOC_s_INFO_FMT
                       "attaching raid volume, channel %d, id %d\n",
-                      ioc->name, ioc->num_ports, ev->id);
-               scsi_add_device(ioc->sh,
-                       ioc->num_ports,
-                       ev->id,
-                       0);
+                      ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
+               scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
                mpt_findImVolumes(ioc);
                break;
        case MPTSAS_DEL_RAID:
-               sdev = scsi_device_lookup(
-                       ioc->sh,
-                       ioc->num_ports,
-                       ev->id,
-                       0);
+               sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
+                   ev->id, 0);
                if (!sdev)
                        break;
                printk(MYIOC_s_INFO_FMT
                       "removing raid volume, channel %d, id %d\n",
-                      ioc->name, ioc->num_ports, ev->id);
+                      ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
                vdevice = sdev->hostdata;
                vdevice->vtarget->deleted = 1;
                mptsas_target_reset(ioc, vdevice->vtarget);
@@ -2723,7 +2697,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        hd->timer.data = (unsigned long) hd;
        hd->timer.function = mptscsih_timer_expired;
 
-       hd->mpt_pq_filter = mpt_pq_filter;
        ioc->sas_data.ptClear = mpt_pt_clear;
 
        if (ioc->sas_data.ptClear==1) {
@@ -2731,12 +2704,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                    ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
        }
 
-       ddvprintk((MYIOC_s_INFO_FMT
-               "mpt_pq_filter %x mpt_pq_filter %x\n",
-               ioc->name,
-               mpt_pq_filter,
-               mpt_pq_filter));
-
        init_waitqueue_head(&hd->scandv_waitq);
        hd->scandv_wait_done = 0;
        hd->last_queue_full = 0;
index 8242b16e316841643e85db9d235ac314e2265bc8..30524dc54b16b720dea158f45c5f477ff446cf19 100644 (file)
@@ -66,6 +66,7 @@
 
 #include "mptbase.h"
 #include "mptscsih.h"
+#include "lsi/mpi_log_sas.h"
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #define my_NAME                "Fusion MPT SCSI Host driver"
@@ -127,7 +128,7 @@ static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
 static void    mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
 static int     mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
 static int     mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
-static u32     SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
+static int     SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
 
 static int     mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
 
@@ -497,6 +498,34 @@ nextSGEset:
        return SUCCESS;
 } /* mptscsih_AddSGE() */
 
+static void
+mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
+    U32 SlotStatus)
+{
+       MPT_FRAME_HDR *mf;
+       SEPRequest_t     *SEPMsg;
+
+       if (ioc->bus_type == FC)
+               return;
+
+       if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
+               dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
+                   ioc->name,__FUNCTION__));
+               return;
+       }
+
+       SEPMsg = (SEPRequest_t *)mf;
+       SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
+       SEPMsg->Bus = vtarget->bus_id;
+       SEPMsg->TargetID = vtarget->target_id;
+       SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
+       SEPMsg->SlotStatus = SlotStatus;
+       devtverboseprintk((MYIOC_s_WARN_FMT
+           "Sending SEP cmd=%x id=%d bus=%d\n",
+           ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus));
+       mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *     mptscsih_io_done - Main SCSI IO callback routine registered to
@@ -520,6 +549,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
        SCSIIORequest_t *pScsiReq;
        SCSIIOReply_t   *pScsiReply;
        u16              req_idx, req_idx_MR;
+       VirtDevice       *vdev;
+       VirtTarget       *vtarget;
 
        hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
 
@@ -538,6 +569,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
        }
 
        sc = hd->ScsiLookup[req_idx];
+       hd->ScsiLookup[req_idx] = NULL;
        if (sc == NULL) {
                MPIHeader_t *hdr = (MPIHeader_t *)mf;
 
@@ -553,6 +585,12 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                return 1;
        }
 
+       if ((unsigned char *)mf != sc->host_scribble) {
+               mptscsih_freeChainBuffers(ioc, req_idx);
+               return 1;
+       }
+
+       sc->host_scribble = NULL;
        sc->result = DID_OK << 16;              /* Set default reply as OK */
        pScsiReq = (SCSIIORequest_t *) mf;
        pScsiReply = (SCSIIOReply_t *) mr;
@@ -640,10 +678,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 
                        if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
                                hd->sel_timeout[pScsiReq->TargetID]++;
+
+                       vdev = sc->device->hostdata;
+                       if (!vdev)
+                               break;
+                       vtarget = vdev->vtarget;
+                       if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
+                               mptscsih_issue_sep_command(ioc, vtarget,
+                                   MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
+                               vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
+                       }
                        break;
 
-               case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:        /* 0x0048 */
                case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:         /* 0x004B */
+                       if ( ioc->bus_type == SAS ) {
+                               u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
+                               if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
+                                       u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
+                                       log_info &=SAS_LOGINFO_MASK;
+                                       if (log_info == SAS_LOGINFO_NEXUS_LOSS) {
+                                               sc->result = (DID_BUS_BUSY << 16);
+                                               break;
+                                       }
+                               }
+                       }
+
+                       /*
+                        * Allow non-SAS & non-NEXUS_LOSS to drop into below code
+                        */
+
+               case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:        /* 0x0048 */
                case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:         /* 0x004C */
                        /* Linux handles an unsolicited DID_RESET better
                         * than an unsolicited DID_ABORT.
@@ -658,7 +722,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                                sc->result=DID_SOFT_ERROR << 16;
                        else /* Sufficient data transfer occurred */
                                sc->result = (DID_OK << 16) | scsi_status;
-                       dreplyprintk((KERN_NOTICE 
+                       dreplyprintk((KERN_NOTICE
                            "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
                        break;
 
@@ -784,8 +848,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                                sc->request_bufflen, sc->sc_data_direction);
        }
 
-       hd->ScsiLookup[req_idx] = NULL;
-
        sc->scsi_done(sc);              /* Issue the command callback */
 
        /* Free Chain buffers */
@@ -827,9 +889,17 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
                        dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
                                        mf, SCpnt));
 
+                       /* Free Chain buffers */
+                       mptscsih_freeChainBuffers(ioc, ii);
+
+                       /* Free Message frames */
+                       mpt_free_msg_frame(ioc, mf);
+
+                       if ((unsigned char *)mf != SCpnt->host_scribble)
+                               continue;
+
                        /* Set status, free OS resources (SG DMA buffers)
                         * Do OS callback
-                        * Free driver resources (chain, msg buffers)
                         */
                        if (SCpnt->use_sg) {
                                pci_unmap_sg(ioc->pcidev,
@@ -845,12 +915,6 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
                        SCpnt->result = DID_RESET << 16;
                        SCpnt->host_scribble = NULL;
 
-                       /* Free Chain buffers */
-                       mptscsih_freeChainBuffers(ioc, ii);
-
-                       /* Free Message frames */
-                       mpt_free_msg_frame(ioc, mf);
-
                        SCpnt->scsi_done(SCpnt);        /* Issue the command callback */
                }
        }
@@ -887,10 +951,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
                if ((sc = hd->ScsiLookup[ii]) != NULL) {
 
                        mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
-
+                       if (mf == NULL)
+                               continue;
                        dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
                                        hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
-
                        if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
                                continue;
 
@@ -899,6 +963,8 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
                        hd->ScsiLookup[ii] = NULL;
                        mptscsih_freeChainBuffers(hd->ioc, ii);
                        mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
+                       if ((unsigned char *)mf != sc->host_scribble)
+                               continue;
                        if (sc->use_sg) {
                                pci_unmap_sg(hd->ioc->pcidev,
                                (struct scatterlist *) sc->request_buffer,
@@ -1341,8 +1407,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
                        goto fail;
        }
 
+       SCpnt->host_scribble = (unsigned char *)mf;
        hd->ScsiLookup[my_idx] = SCpnt;
-       SCpnt->host_scribble = NULL;
 
        mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
        dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
@@ -1529,6 +1595,12 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
                rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
        }
 
+       /*
+        * Check IOCStatus from TM reply message
+        */
+        if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS)
+               rc = FAILED;
+
        dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
 
        return rc;
@@ -1654,6 +1726,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
        int              scpnt_idx;
        int              retval;
        VirtDevice       *vdev;
+       ulong            sn = SCpnt->serial_number;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
@@ -1707,6 +1780,11 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
                vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
                ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
 
+       if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
+           SCpnt->serial_number == sn) {
+               retval = FAILED;
+       }
+
        printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
                hd->ioc->name,
                ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
@@ -2023,6 +2101,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
                DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
 
                iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
+               hd->tm_iocstatus = iocstatus;
                dtmprintk((MYIOC_s_WARN_FMT "  SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
                        ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
                /* Error?  (anything non-zero?) */
@@ -2401,6 +2480,13 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
                                ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
 
                                ioc->eventContext++;
+                               if (hd->ioc->pcidev->vendor ==
+                                   PCI_VENDOR_ID_IBM) {
+                                       mptscsih_issue_sep_command(hd->ioc,
+                                           vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
+                                       vdev->vtarget->tflags |=
+                                           MPT_TARGET_FLAGS_LED_ON;
+                               }
                        }
                }
        } else {
@@ -2409,7 +2495,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
        }
 }
 
-static u32
+static int
 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
 {
        MPT_SCSI_HOST *hd;
index 0a1ff762205f0eec3d3f1cb6306527cc3adf6eaf..e4cc3dd5fc9fbeb17f2154ed544bd6e39306b074 100644 (file)
@@ -83,10 +83,6 @@ static int mpt_saf_te = MPTSCSIH_SAF_TE;
 module_param(mpt_saf_te, int, 0);
 MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1  (default=MPTSCSIH_SAF_TE=0)");
 
-static int mpt_pq_filter = 0;
-module_param(mpt_pq_filter, int, 0);
-MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
-
 static void mptspi_write_offset(struct scsi_target *, int);
 static void mptspi_write_width(struct scsi_target *, int);
 static int mptspi_write_spi_device_pg1(struct scsi_target *,
@@ -1047,14 +1043,12 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        hd->timer.function = mptscsih_timer_expired;
 
        ioc->spi_data.Saf_Te = mpt_saf_te;
-       hd->mpt_pq_filter = mpt_pq_filter;
 
        hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
        ddvprintk((MYIOC_s_INFO_FMT
-               "saf_te %x mpt_pq_filter %x\n",
+               "saf_te %x\n",
                ioc->name,
-               mpt_saf_te,
-               mpt_pq_filter));
+               mpt_saf_te));
        ioc->spi_data.noQas = 0;
 
        init_waitqueue_head(&hd->scandv_waitq);
index c690c2b89e41ddf59abb611a3a7c2f43448bbed8..acf292736b4e18403a59daef06da6171c1dd4282 100644 (file)
@@ -3451,12 +3451,12 @@ create_cmd (Scsi_Cmnd *cmd) {
     for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4, 
        cmd_dataout += 4, ++i) {
        u32 vbuf = cmd->use_sg
-           ? (u32)page_address(((struct scatterlist *)cmd->buffer)[i].page)+
-             ((struct scatterlist *)cmd->buffer)[i].offset
+           ? (u32)page_address(((struct scatterlist *)cmd->request_buffer)[i].page)+
+             ((struct scatterlist *)cmd->request_buffer)[i].offset
            : (u32)(cmd->request_buffer);
        u32 bbuf = virt_to_bus((void *)vbuf);
        u32 count = cmd->use_sg ?
-           ((struct scatterlist *)cmd->buffer)[i].length :
+           ((struct scatterlist *)cmd->request_buffer)[i].length :
            cmd->request_bufflen;
 
        /*
@@ -5417,7 +5417,7 @@ insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
 
            if ((buffers = cmd->use_sg)) {
                for (offset = 0, 
-                       segment = (struct scatterlist *) cmd->buffer;
+                       segment = (struct scatterlist *) cmd->request_buffer;
                     buffers && !((found = ((ptr >= (char *)page_address(segment->page)+segment->offset) && 
                            (ptr < ((char *)page_address(segment->page)+segment->offset+segment->length)))));
                     --buffers, offset += segment->length, ++segment)
index 8a4659e94105c58c81327db2cbc876bf46c93611..085db4826e0ed16f9fb3f371825fb59c604e214c 100644 (file)
@@ -911,7 +911,7 @@ static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp)
                        sp->SCp.ptr =
                                (char *) virt_to_phys(sp->request_buffer);
        } else {
-               sp->SCp.buffer = (struct scatterlist *) sp->buffer;
+               sp->SCp.buffer = (struct scatterlist *) sp->request_buffer;
                sp->SCp.buffers_residual = sp->use_sg - 1;
                sp->SCp.this_residual = sp->SCp.buffer->length;
                if (esp->dma_mmu_get_scsi_sgl)
index a06f547e87f715c7211a0b0bab17f77d20e32e10..d05681f9d81a81e55385fb2e8b621ae1d8a0a7e1 100644 (file)
@@ -114,7 +114,7 @@ MODULE_DESCRIPTION("NCR Dual700 SCSI Driver");
 MODULE_LICENSE("GPL");
 module_param(NCR_D700, charp, 0);
 
-static __u8 __initdata id_array[2*(MCA_MAX_SLOT_NR + 1)] =
+static __u8 __devinitdata id_array[2*(MCA_MAX_SLOT_NR + 1)] =
        { [0 ... 2*(MCA_MAX_SLOT_NR + 1)-1] = 7 };
 
 #ifdef MODULE
@@ -173,7 +173,7 @@ struct NCR_D700_private {
        char                    pad;
 };
 
-static int 
+static int __devinit
 NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq,
                   int slot, u32 region, int differential)
 {
@@ -243,7 +243,7 @@ NCR_D700_intr(int irq, void *data, struct pt_regs *regs)
  * essentially connectecd to the MCA bus independently, it is easier
  * to set them up as two separate host adapters, rather than one
  * adapter with two channels */
-static int
+static int __devinit
 NCR_D700_probe(struct device *dev)
 {
        struct NCR_D700_private *p;
@@ -329,7 +329,7 @@ NCR_D700_probe(struct device *dev)
        for (i = 0; i < 2; i++) {
                int err;
 
-               if ((err = NCR_D700_probe_one(p, i, slot, irq,
+               if ((err = NCR_D700_probe_one(p, i, irq, slot,
                                              offset_addr + (0x80 * i),
                                              differential)) != 0)
                        printk("D700: SIOP%d: probe failed, error = %d\n",
@@ -349,7 +349,7 @@ NCR_D700_probe(struct device *dev)
        return 0;
 }
 
-static void
+static void __devexit
 NCR_D700_remove_one(struct Scsi_Host *host)
 {
        scsi_remove_host(host);
@@ -359,7 +359,7 @@ NCR_D700_remove_one(struct Scsi_Host *host)
        release_region(host->base, 64);
 }
 
-static int
+static int __devexit
 NCR_D700_remove(struct device *dev)
 {
        struct NCR_D700_private *p = dev_get_drvdata(dev);
@@ -380,7 +380,7 @@ static struct mca_driver NCR_D700_driver = {
                .name           = "NCR_D700",
                .bus            = &mca_bus_type,
                .probe          = NCR_D700_probe,
-               .remove         = NCR_D700_remove,
+               .remove         = __devexit_p(NCR_D700_remove),
        },
 };
 
index 36e63f82d9f8c3e57dc2d51f4878e8d119b08546..f974869ea3236a1ff958846c60b1c8e4d2a90b8b 100644 (file)
@@ -551,6 +551,11 @@ struct aha152x_hostdata {
 struct aha152x_scdata {
        Scsi_Cmnd *next;        /* next sc in queue */
        struct semaphore *sem;  /* semaphore to block on */
+       unsigned char cmd_len;
+       unsigned char cmnd[MAX_COMMAND_SIZE];
+       unsigned short use_sg;
+       unsigned request_bufflen;
+       void *request_buffer;
 };
 
 
@@ -1006,11 +1011,20 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int p
                        return FAILED;
                }
        } else {
+               struct aha152x_scdata *sc;
+
                SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC);
                if(SCpnt->host_scribble==0) {
                        printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt));
                        return FAILED;
                }
+
+               sc = SCDATA(SCpnt);
+               memcpy(sc->cmnd, SCpnt->cmnd, sizeof(sc->cmnd));
+               sc->request_buffer  = SCpnt->request_buffer;
+               sc->request_bufflen = SCpnt->request_bufflen;
+               sc->use_sg          = SCpnt->use_sg;
+               sc->cmd_len         = SCpnt->cmd_len;
        }
 
        SCNEXT(SCpnt)           = NULL;
@@ -1165,6 +1179,10 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
        DECLARE_MUTEX_LOCKED(sem);
        struct timer_list timer;
        int ret, issued, disconnected;
+       unsigned char old_cmd_len = SCpnt->cmd_len;
+       unsigned short old_use_sg = SCpnt->use_sg;
+       void *old_buffer = SCpnt->request_buffer;
+       unsigned old_bufflen = SCpnt->request_bufflen;
        unsigned long flags;
 
 #if defined(AHA152X_DEBUG)
@@ -1198,11 +1216,11 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
        add_timer(&timer);
        down(&sem);
        del_timer(&timer);
-       
-       SCpnt->cmd_len         = SCpnt->old_cmd_len;
-       SCpnt->use_sg          = SCpnt->old_use_sg;
-       SCpnt->request_buffer  = SCpnt->buffer;
-               SCpnt->request_bufflen = SCpnt->bufflen;
+
+       SCpnt->cmd_len         = old_cmd_len;
+       SCpnt->use_sg          = old_use_sg;
+       SCpnt->request_buffer  = old_buffer;
+               SCpnt->request_bufflen = old_bufflen;
 
        DO_LOCK(flags);
 
@@ -1565,6 +1583,9 @@ static void busfree_run(struct Scsi_Host *shpnt)
 #endif
 
                if(DONE_SC->SCp.phase & check_condition) {
+                       struct scsi_cmnd *cmd = HOSTDATA(shpnt)->done_SC;
+                       struct aha152x_scdata *sc = SCDATA(cmd);
+
 #if 0
                        if(HOSTDATA(shpnt)->debug & debug_eh) {
                                printk(ERR_LEAD "received sense: ", CMDINFO(DONE_SC));
@@ -1573,13 +1594,13 @@ static void busfree_run(struct Scsi_Host *shpnt)
 #endif
 
                        /* restore old command */
-                       memcpy((void *) DONE_SC->cmnd, (void *) DONE_SC->data_cmnd, sizeof(DONE_SC->data_cmnd));
-                       DONE_SC->request_buffer  = DONE_SC->buffer;
-                       DONE_SC->request_bufflen = DONE_SC->bufflen;
-                       DONE_SC->use_sg          = DONE_SC->old_use_sg;
-                       DONE_SC->cmd_len         = DONE_SC->old_cmd_len;
+                       memcpy(cmd->cmnd, sc->cmnd, sizeof(sc->cmnd));
+                       cmd->request_buffer  = sc->request_buffer;
+                       cmd->request_bufflen = sc->request_bufflen;
+                       cmd->use_sg          = sc->use_sg;
+                       cmd->cmd_len         = sc->cmd_len;
 
-                       DONE_SC->SCp.Status = 0x02;
+                       cmd->SCp.Status = 0x02;
 
                        HOSTDATA(shpnt)->commands--;
                        if (!HOSTDATA(shpnt)->commands)
index a1e8ca758594ab43936efd73f0aa1b43ae46c292..653818d2f80255d824fd3deb79b029af6c54931f 100644 (file)
@@ -7289,7 +7289,7 @@ ahd_reset_cmds_pending(struct ahd_softc *ahd)
        ahd->flags &= ~AHD_UPDATE_PEND_CMDS;
 }
 
-void
+static void
 ahd_done_with_status(struct ahd_softc *ahd, struct scb *scb, uint32_t status)
 {
        cam_status ostat;
index b244c712417923ac088c06f5665e2741b5017e6d..998999c0a972154efb9d191367a450efac768de9 100644 (file)
@@ -242,25 +242,6 @@ ahd_print_path(struct ahd_softc *ahd, struct scb *scb)
  */
 static uint32_t aic79xx_no_reset;
 
-/*
- * Certain PCI motherboards will scan PCI devices from highest to lowest,
- * others scan from lowest to highest, and they tend to do all kinds of
- * strange things when they come into contact with PCI bridge chips.  The
- * net result of all this is that the PCI card that is actually used to boot
- * the machine is very hard to detect.  Most motherboards go from lowest
- * PCI slot number to highest, and the first SCSI controller found is the
- * one you boot from.  The only exceptions to this are when a controller
- * has its BIOS disabled.  So, we by default sort all of our SCSI controllers
- * from lowest PCI slot number to highest PCI slot number.  We also force
- * all controllers with their BIOS disabled to the end of the list.  This
- * works on *almost* all computers.  Where it doesn't work, we have this
- * option.  Setting this option to non-0 will reverse the order of the sort
- * to highest first, then lowest, but will still leave cards with their BIOS
- * disabled at the very end.  That should fix everyone up unless there are
- * really strange cirumstances.
- */
-static uint32_t aic79xx_reverse_scan;
-
 /*
  * Should we force EXTENDED translation on a controller.
  *     0 == Use whatever is in the SEEPROM or default to off
@@ -350,7 +331,6 @@ MODULE_PARM_DESC(aic79xx,
 "                              periodically to prevent tag starvation.\n"
 "                              This may be required by some older disk\n"
 "                              or drives/RAID arrays.\n"
-"      reverse_scan            Sort PCI devices highest Bus/Slot to lowest\n"
 "      tag_info:<tag_str>      Set per-target tag depth\n"
 "      global_tag_depth:<int>  Global tag depth for all targets on all buses\n"
 "      slewrate:<slewrate_list>Set the signal slew rate (0-15).\n"
@@ -1031,7 +1011,6 @@ aic79xx_setup(char *s)
 #ifdef AHD_DEBUG
                { "debug", &ahd_debug },
 #endif
-               { "reverse_scan", &aic79xx_reverse_scan },
                { "periodic_otag", &aic79xx_periodic_otag },
                { "pci_parity", &aic79xx_pci_parity },
                { "seltime", &aic79xx_seltime },
index debf3e2a079808454beb1fcf67f2670b0ed5862c..aa4be8a31415e1b7006ad1f22df8ce42e89cda73 100644 (file)
@@ -353,7 +353,6 @@ MODULE_PARM_DESC(aic7xxx,
 "                              periodically to prevent tag starvation.\n"
 "                              This may be required by some older disk\n"
 "                              drives or RAID arrays.\n"
-"      reverse_scan            Sort PCI devices highest Bus/Slot to lowest\n"
 "      tag_info:<tag_str>      Set per-target tag depth\n"
 "      global_tag_depth:<int>  Global tag depth for every target\n"
 "                              on every bus\n"
index 007a14e5c3fddac952adcdd467c72bd744329007..e397129c90d188e689ac260a34fe90f49c01daea 100644 (file)
@@ -507,7 +507,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd)
      */
 
     if (cmd->use_sg) {
-       cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
+       cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
        cmd->SCp.buffers_residual = cmd->use_sg - 1;
        cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+
                       cmd->SCp.buffer->offset;
index dddd2acce76f0cd11a4151cfd4752834432b1914..61f6024b61bac33c0252f5011480553d429d3c3a 100644 (file)
@@ -5,6 +5,7 @@
  * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002)
  *   by D. Gilbert and aeb (20020609)
  * Additions for SPC-3 T10/1416-D Rev 21 22 Sept 2004, D. Gilbert 20041025
+ * Update to SPC-4 T10/1713-D Rev 5a, 14 June 2006, D. Gilbert 20060702
  */
 
 #include <linux/blkdev.h>
@@ -36,55 +37,56 @@ static const char * cdb_byte0_names[] = {
 /* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense",
 /* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL,
            "Reasssign Blocks",
-/* 08-0d */ "Read (6)", NULL, "Write (6)", "Seek (6)", NULL, NULL,
+/* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL,
 /* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
-/* 13-16 */ "Verify (6)", "Recover Buffered Data", "Mode Select (6)",
-           "Reserve (6)",
-/* 17-1a */ "Release (6)", "Copy", "Erase", "Mode Sense (6)", 
+/* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)",
+           "Reserve(6)",
+/* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)",
 /* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", 
 /* 1e-1f */ "Prevent/Allow Medium Removal", NULL,
 /* 20-22 */  NULL, NULL, NULL,
 /* 23-28 */ "Read Format Capacities", "Set Window",
-           "Read Capacity (10)", NULL, NULL, "Read (10)", 
-/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase (10)", 
-            "Read updated block", 
-/* 2e-31 */ "Write Verify (10)", "Verify (10)", "Search High", "Search Equal", 
+           "Read Capacity(10)", NULL, NULL, "Read(10)",
+/* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)",
+            "Read updated block",
+/* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal",
 /* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", 
-/* 35-37 */ "Synchronize Cache (10)", "Lock/Unlock Cache (10)",
+/* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)",
            "Read Defect Data(10)", 
 /* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", 
             "Read Buffer", 
-/* 3d-3f */ "Update Block", "Read Long (10)",  "Write Long (10)",
-/* 40-41 */ "Change Definition", "Write Same (10)",
+/* 3d-3f */ "Update Block", "Read Long(10)",  "Write Long(10)",
+/* 40-41 */ "Change Definition", "Write Same(10)",
 /* 42-48 */ "Read sub-channel", "Read TOC/PMA/ATIP", "Read density support",
-            "Play audio (10)", "Get configuration", "Play audio msf",
+            "Play audio(10)", "Get configuration", "Play audio msf",
             "Play audio track/index",
-/* 49-4f */ "Play track relative (10)", "Get event status notification",
+/* 49-4f */ "Play track relative(10)", "Get event status notification",
             "Pause/resume", "Log Select", "Log Sense", "Stop play/scan",
             NULL,
 /* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info",
-            "Reserve track", "Send OPC info", "Mode Select (10)",
-/* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", "Read master cue",
-            "Mode Sense (10)", "Close track/session",
+            "Reserve track", "Send OPC info", "Mode Select(10)",
+/* 56-5b */ "Reserve(10)", "Release(10)", "Repair track", "Read master cue",
+            "Mode Sense(10)", "Close track/session",
 /* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in",
             "Persistent reserve out",
 /* 60-67 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 /* 68-6f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 /* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 /* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Variable length",
-/* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", "Extended copy",
+/* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)", "Extended copy",
             "Receive copy results",
-/* 85-89 */ "Memory Export In (16)", "Access control in", "Access control out",
-            "Read (16)", "Memory Export Out (16)",
-/* 8a-8f */ "Write (16)", NULL, "Read attributes", "Write attributes",
-            "Write and verify (16)", "Verify (16)",
-/* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)",
-            "Lock/unlock cache (16)", "Write same (16)", NULL,
+/* 85-89 */ "ATA command pass through(16)", "Access control in",
+           "Access control out", "Read(16)", "Memory Export Out(16)",
+/* 8a-8f */ "Write(16)", NULL, "Read attributes", "Write attributes",
+            "Write and verify(16)", "Verify(16)",
+/* 90-94 */ "Pre-fetch(16)", "Synchronize cache(16)",
+            "Lock/unlock cache(16)", "Write same(16)", NULL,
 /* 95-99 */ NULL, NULL, NULL, NULL, NULL,
-/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in (16)",
-            "Service action out (16)",
-/* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance in",
-            "Maintenance out", "Move medium/play audio(12)",
+/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in(16)",
+            "Service action out(16)",
+/* a0-a5 */ "Report luns", "ATA command pass through(12)/Blank",
+            "Security protocol in", "Maintenance in", "Maintenance out",
+           "Move medium/play audio(12)",
 /* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)",
             "Play track relative(12)",
 /* aa-ae */ "Write(12)", NULL, "Erase(12), Get Performance",
@@ -92,12 +94,12 @@ static const char * cdb_byte0_names[] = {
 /* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)",
 /* b2-b4 */ "Search data low(12)", "Set limits(12)",
             "Read element status attached",
-/* b5-b6 */ "Request volume element address", "Send volume tag, set streaming",
+/* b5-b6 */ "Security protocol out", "Send volume tag, set streaming",
 /* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf",
 /* ba-bc */ "Redundancy group (in), Scan",
-            "Redundancy group (out), Set cd-rom speed", "Spare in, Play cd",
-/* bd-bf */ "Spare out, Mechanism status", "Volume set in, Read cd",
-            "Volume set out, Send DVD structure",
+            "Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd",
+/* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd",
+            "Volume set (out), Send DVD structure",
 };
 
 struct value_name_pair {
@@ -112,6 +114,7 @@ static const struct value_name_pair maint_in_arr[] = {
        {0xc, "Report supported operation codes"},
        {0xd, "Report supported task management functions"},
        {0xe, "Report priority"},
+       {0xf, "Report timestamp"},
 };
 #define MAINT_IN_SZ ARRAY_SIZE(maint_in_arr)
 
@@ -120,6 +123,7 @@ static const struct value_name_pair maint_out_arr[] = {
        {0xa, "Set target port groups"},
        {0xb, "Change aliases"},
        {0xe, "Set priority"},
+       {0xe, "Set timestamp"},
 };
 #define MAINT_OUT_SZ ARRAY_SIZE(maint_out_arr)
 
@@ -427,6 +431,7 @@ static struct error_info additional[] =
        {0x001A, "Rewind operation in progress"},
        {0x001B, "Set capacity operation in progress"},
        {0x001C, "Verify operation in progress"},
+       {0x001D, "ATA pass through information available"},
 
        {0x0100, "No index/sector signal"},
 
@@ -438,7 +443,7 @@ static struct error_info additional[] =
 
        {0x0400, "Logical unit not ready, cause not reportable"},
        {0x0401, "Logical unit is in process of becoming ready"},
-       {0x0402, "Logical unit not ready, initializing cmd. required"},
+       {0x0402, "Logical unit not ready, initializing command required"},
        {0x0403, "Logical unit not ready, manual intervention required"},
        {0x0404, "Logical unit not ready, format in progress"},
        {0x0405, "Logical unit not ready, rebuild in progress"},
@@ -478,6 +483,9 @@ static struct error_info additional[] =
        {0x0B00, "Warning"},
        {0x0B01, "Warning - specified temperature exceeded"},
        {0x0B02, "Warning - enclosure degraded"},
+       {0x0B03, "Warning - background self-test failed"},
+       {0x0B04, "Warning - background pre-scan detected medium error"},
+       {0x0B05, "Warning - background medium scan detected medium error"},
 
        {0x0C00, "Write error"},
        {0x0C01, "Write error - recovered with auto reallocation"},
@@ -493,6 +501,7 @@ static struct error_info additional[] =
        {0x0C0B, "Auxiliary memory write error"},
        {0x0C0C, "Write error - unexpected unsolicited data"},
        {0x0C0D, "Write error - not enough unsolicited data"},
+       {0x0C0F, "Defects in error window"},
 
        {0x0D00, "Error detected by third party temporary initiator"},
        {0x0D01, "Third party device failure"},
@@ -504,11 +513,12 @@ static struct error_info additional[] =
        {0x0E00, "Invalid information unit"},
        {0x0E01, "Information unit too short"},
        {0x0E02, "Information unit too long"},
+       {0x0E03, "Invalid field in command information unit"},
 
        {0x1000, "Id CRC or ECC error"},
-       {0x1001, "Data block guard check failed"},
-       {0x1002, "Data block application tag check failed"},
-       {0x1003, "Data block reference tag check failed"},
+       {0x1001, "Logical block guard check failed"},
+       {0x1002, "Logical block application tag check failed"},
+       {0x1003, "Logical block reference tag check failed"},
 
        {0x1100, "Unrecovered read error"},
        {0x1101, "Read retries exhausted"},
@@ -530,6 +540,7 @@ static struct error_info additional[] =
        {0x1111, "Read error - loss of streaming"},
        {0x1112, "Auxiliary memory read error"},
        {0x1113, "Read error - failed retransmission request"},
+       {0x1114, "Read error - lba marked bad by application client"},
 
        {0x1200, "Address mark not found for id field"},
 
@@ -610,11 +621,14 @@ static struct error_info additional[] =
        {0x2100, "Logical block address out of range"},
        {0x2101, "Invalid element address"},
        {0x2102, "Invalid address for write"},
+       {0x2103, "Invalid write crossing layer jump"},
 
        {0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"},
 
        {0x2400, "Invalid field in cdb"},
        {0x2401, "CDB decryption error"},
+       {0x2402, "Obsolete"},
+       {0x2403, "Obsolete"},
        {0x2404, "Security audit value frozen"},
        {0x2405, "Security working key frozen"},
        {0x2406, "Nonce not unique"},
@@ -637,7 +651,10 @@ static struct error_info additional[] =
        {0x260C, "Invalid operation for copy source or destination"},
        {0x260D, "Copy segment granularity violation"},
        {0x260E, "Invalid parameter while port is enabled"},
-       {0x260F, "Invalid data-out buffer integrity"},
+       {0x260F, "Invalid data-out buffer integrity check value"},
+       {0x2610, "Data decryption key fail limit reached"},
+       {0x2611, "Incomplete key-associated data set"},
+       {0x2612, "Vendor specific key reference not found"},
 
        {0x2700, "Write protected"},
        {0x2701, "Hardware write protected"},
@@ -649,6 +666,7 @@ static struct error_info additional[] =
 
        {0x2800, "Not ready to ready change, medium may have changed"},
        {0x2801, "Import or export element accessed"},
+       {0x2802, "Format-layer may have changed"},
 
        {0x2900, "Power on, reset, or bus device reset occurred"},
        {0x2901, "Power on occurred"},
@@ -669,6 +687,11 @@ static struct error_info additional[] =
        {0x2A07, "Implicit asymmetric access state transition failed"},
        {0x2A08, "Priority changed"},
        {0x2A09, "Capacity data has changed"},
+       {0x2A10, "Timestamp changed"},
+       {0x2A11, "Data encryption parameters changed by another i_t nexus"},
+       {0x2A12, "Data encryption parameters changed by vendor specific "
+                "event"},
+       {0x2A13, "Data encryption key instance counter has changed"},
 
        {0x2B00, "Copy cannot execute since host cannot disconnect"},
 
@@ -690,6 +713,7 @@ static struct error_info additional[] =
        {0x2E00, "Insufficient time for operation"},
 
        {0x2F00, "Commands cleared by another initiator"},
+       {0x2F01, "Commands cleared by power loss notification"},
 
        {0x3000, "Incompatible medium installed"},
        {0x3001, "Cannot read medium - unknown format"},
@@ -702,7 +726,8 @@ static struct error_info additional[] =
        {0x3008, "Cannot write - application code mismatch"},
        {0x3009, "Current session not fixated for append"},
        {0x300A, "Cleaning request rejected"},
-       {0x300C, "WORM medium, overwrite attempted"},
+       {0x300C, "WORM medium - overwrite attempted"},
+       {0x300D, "WORM medium - integrity check"},
        {0x3010, "Medium not formatted"},
 
        {0x3100, "Medium format corrupted"},
@@ -790,6 +815,9 @@ static struct error_info additional[] =
        {0x3F0F, "Echo buffer overwritten"},
        {0x3F10, "Medium loadable"},
        {0x3F11, "Medium auxiliary memory accessible"},
+       {0x3F12, "iSCSI IP address added"},
+       {0x3F13, "iSCSI IP address removed"},
+       {0x3F14, "iSCSI IP address changed"},
 /*
  *     {0x40NN, "Ram failure"},
  *     {0x40NN, "Diagnostic failure on component nn"},
@@ -799,6 +827,7 @@ static struct error_info additional[] =
        {0x4300, "Message error"},
 
        {0x4400, "Internal target failure"},
+       {0x4471, "ATA device failed set features"},
 
        {0x4500, "Select or reselect failure"},
 
@@ -807,9 +836,10 @@ static struct error_info additional[] =
        {0x4700, "Scsi parity error"},
        {0x4701, "Data phase CRC error detected"},
        {0x4702, "Scsi parity error detected during st data phase"},
-       {0x4703, "Information unit CRC error detected"},
+       {0x4703, "Information unit iuCRC error detected"},
        {0x4704, "Asynchronous information protection error detected"},
        {0x4705, "Protocol service CRC error"},
+       {0x4706, "Phy test function in progress"},
        {0x477f, "Some commands cleared by iSCSI Protocol event"},
 
        {0x4800, "Initiator detected error message received"},
@@ -844,6 +874,8 @@ static struct error_info additional[] =
        {0x5300, "Media load or eject failed"},
        {0x5301, "Unload tape failure"},
        {0x5302, "Medium removal prevented"},
+       {0x5303, "Medium removal prevented by data transfer element"},
+       {0x5304, "Medium thread or unthread failure"},
 
        {0x5400, "Scsi to host system interface failure"},
 
@@ -855,6 +887,7 @@ static struct error_info additional[] =
        {0x5505, "Insufficient access control resources"},
        {0x5506, "Auxiliary memory out of space"},
        {0x5507, "Quota error"},
+       {0x5508, "Maximum number of supplemental decryption keys exceeded"},
 
        {0x5700, "Unable to recover table-of-contents"},
 
@@ -1004,6 +1037,7 @@ static struct error_info additional[] =
        {0x6708, "Assign failure occurred"},
        {0x6709, "Multiply assigned logical unit"},
        {0x670A, "Set target port groups command failed"},
+       {0x670B, "ATA device feature not enabled"},
 
        {0x6800, "Logical unit not configured"},
 
@@ -1030,6 +1064,8 @@ static struct error_info additional[] =
        {0x6F03, "Read of scrambled sector without authentication"},
        {0x6F04, "Media region code is mismatched to logical unit region"},
        {0x6F05, "Drive region must be permanent/region reset count error"},
+       {0x6F06, "Insufficient block count for binding nonce recording"},
+       {0x6F07, "Conflict in binding nonce recording"},
 /*
  *     {0x70NN, "Decompression exception short algorithm id of nn"},
  */
@@ -1041,6 +1077,8 @@ static struct error_info additional[] =
        {0x7203, "Session fixation error - incomplete track in session"},
        {0x7204, "Empty or partially written reserved track"},
        {0x7205, "No more track reservations allowed"},
+       {0x7206, "RMZ extension is not allowed"},
+       {0x7207, "No more test zone extensions are allowed"},
 
        {0x7300, "Cd control error"},
        {0x7301, "Power calibration area almost full"},
@@ -1049,6 +1087,18 @@ static struct error_info additional[] =
        {0x7304, "Program memory area update failure"},
        {0x7305, "Program memory area is full"},
        {0x7306, "RMA/PMA is almost full"},
+       {0x7310, "Current power calibration area almost full"},
+       {0x7311, "Current power calibration area is full"},
+       {0x7317, "RDZ is full"},
+
+       {0x7400, "Security error"},
+       {0x7401, "Unable to decrypt data"},
+       {0x7402, "Unencrypted data encountered while decrypting"},
+       {0x7403, "Incorrect data encryption key"},
+       {0x7404, "Cryptographic integrity validation failed"},
+       {0x7405, "Error decrypting data"},
+       {0x7471, "Logical unit access not authorized"},
+
        {0, NULL}
 };
 
index 10573c24a50bc02a514770d6b09272efdd73e30a..eaf64c7e54e7014821b5145536edeb28090dfe03 100644 (file)
@@ -1397,7 +1397,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
                        sp->SCp.ptr = NULL;
                }
        } else {
-               sp->SCp.buffer = (struct scatterlist *) sp->buffer;
+               sp->SCp.buffer = (struct scatterlist *) sp->request_buffer;
                sp->SCp.buffers_residual = sbus_map_sg(esp->sdev,
                                                       sp->SCp.buffer,
                                                       sp->use_sg,
@@ -1410,7 +1410,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
 static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
 {
        if (sp->use_sg) {
-               sbus_unmap_sg(esp->sdev, sp->buffer, sp->use_sg,
+               sbus_unmap_sg(esp->sdev, sp->request_buffer, sp->use_sg,
                              sp->sc_data_direction);
        } else if (sp->request_bufflen) {
                sbus_unmap_single(esp->sdev,
index 7eed0b098171f6b37670ebe3db4b24689cfa68ad..6aeb5f003c3c912a0e53099d7d86c126f2ed505e 100644 (file)
@@ -81,7 +81,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
        int rc;
 
        single_host_data = hostdata;
-       rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, 0);
+       rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, max_requests);
        if (rc < 0) {
                printk("viopath_open failed with rc %d in open_event_path\n",
                       rc);
index 242b8873b33363c26692db97cc36218d5aed378e..ed22b96580c6622debcacf3b51978c9acc5a2d77 100644 (file)
@@ -238,6 +238,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
        if (rc == 2) {
                /* Adapter is good, but other end is not ready */
                printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n");
+               retrc = 0;
        } else if (rc != 0) {
                printk(KERN_WARNING "ibmvscsi: Error %d opening adapter\n", rc);
                goto reg_crq_failed;
index 3fd8a96f2af397989c80788e65423ad02ed50de3..bfac4441d89fdcad18132a6e9e8720774697d364 100644 (file)
@@ -257,7 +257,7 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 {
     int sz = sp->use_sg - 1;
-    struct scatterlist *sg = (struct scatterlist *)sp->buffer;
+    struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
                        
     while(sz >= 0) {
        vdma_free(sg[sz].dma_address);
index f81691fcf177f5ddd1bd56da746730fd9beeeda4..d44f9aac6b8fe3c954710a070d8e136a0bebe82b 100644 (file)
 
 struct lpfc_sli2_slim;
 
-#define LPFC_MAX_TARGET         256    /* max targets supported */
-#define LPFC_MAX_DISC_THREADS  64      /* max outstanding discovery els req */
-#define LPFC_MAX_NS_RETRY       3      /* max NameServer retries */
 
+#define LPFC_MAX_TARGET                256     /* max number of targets supported */
+#define LPFC_MAX_DISC_THREADS  64      /* max outstanding discovery els
+                                          requests */
+#define LPFC_MAX_NS_RETRY      3       /* Number of retry attempts to contact
+                                          the NameServer  before giving up. */
 #define LPFC_DFT_HBA_Q_DEPTH   2048    /* max cmds per hba */
 #define LPFC_LC_HBA_Q_DEPTH    1024    /* max cmds per low cost hba */
 #define LPFC_LP101_HBA_Q_DEPTH 128     /* max cmds per low cost hba */
@@ -41,7 +43,6 @@ struct lpfc_sli2_slim;
                             (( (u64)(high)<<16 ) << 16)|( (u64)(low))))
 /* Provide maximum configuration definitions. */
 #define LPFC_DRVR_TIMEOUT      16      /* driver iocb timeout value in sec */
-#define MAX_FCP_TARGET         256     /* max num of FCP targets supported */
 #define FC_MAX_ADPTMSG         64
 
 #define MAX_HBAEVT     32
index b62a72dfab296f46991abe51a9a3105f7358e597..5c68cdd8736f72d12e06e458d4945e8e5f15e85a 100644 (file)
@@ -219,9 +219,19 @@ lpfc_issue_lip(struct Scsi_Host *host)
                return -ENOMEM;
 
        memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
-       lpfc_init_link(phba, pmboxq, phba->cfg_topology, phba->cfg_link_speed);
+       pmboxq->mb.mbxCommand = MBX_DOWN_LINK;
+       pmboxq->mb.mbxOwner = OWN_HOST;
+
        mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
 
+       if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) {
+               memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
+               lpfc_init_link(phba, pmboxq, phba->cfg_topology,
+                              phba->cfg_link_speed);
+               mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq,
+                                                    phba->fc_ratov * 2);
+       }
+
        if (mbxstatus == MBX_TIMEOUT)
                pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
        else
@@ -233,51 +243,53 @@ lpfc_issue_lip(struct Scsi_Host *host)
        return 0;
 }
 
-static ssize_t
-lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
+static int
+lpfc_selective_reset(struct lpfc_hba *phba)
 {
-       struct Scsi_Host *host = class_to_shost(cdev);
-       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
-       return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
+       struct completion online_compl;
+       int status = 0;
+
+       init_completion(&online_compl);
+       lpfc_workq_post_event(phba, &status, &online_compl,
+                             LPFC_EVT_OFFLINE);
+       wait_for_completion(&online_compl);
+
+       if (status != 0)
+               return -EIO;
+
+       init_completion(&online_compl);
+       lpfc_workq_post_event(phba, &status, &online_compl,
+                             LPFC_EVT_ONLINE);
+       wait_for_completion(&online_compl);
+
+       if (status != 0)
+               return -EIO;
+
+       return 0;
 }
 
 static ssize_t
-lpfc_board_online_show(struct class_device *cdev, char *buf)
+lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count)
 {
        struct Scsi_Host *host = class_to_shost(cdev);
        struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+       int status = -EINVAL;
 
-       if (phba->fc_flag & FC_OFFLINE_MODE)
-               return snprintf(buf, PAGE_SIZE, "0\n");
+       if (strncmp(buf, "selective", sizeof("selective") - 1) == 0)
+               status = lpfc_selective_reset(phba);
+
+       if (status == 0)
+               return strlen(buf);
        else
-               return snprintf(buf, PAGE_SIZE, "1\n");
+               return status;
 }
 
 static ssize_t
-lpfc_board_online_store(struct class_device *cdev, const char *buf,
-                                                               size_t count)
+lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
 {
        struct Scsi_Host *host = class_to_shost(cdev);
        struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
-       struct completion online_compl;
-       int val=0, status=0;
-
-       if (sscanf(buf, "%d", &val) != 1)
-               return -EINVAL;
-
-       init_completion(&online_compl);
-
-       if (val)
-               lpfc_workq_post_event(phba, &status, &online_compl,
-                                                       LPFC_EVT_ONLINE);
-       else
-               lpfc_workq_post_event(phba, &status, &online_compl,
-                                                       LPFC_EVT_OFFLINE);
-       wait_for_completion(&online_compl);
-       if (!status)
-               return strlen(buf);
-       else
-               return -EIO;
+       return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
 }
 
 static ssize_t
@@ -532,10 +544,9 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
                         NULL);
 static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
                         NULL);
-static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
-                        lpfc_board_online_show, lpfc_board_online_store);
 static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
                         lpfc_board_mode_show, lpfc_board_mode_store);
+static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
 
 static int lpfc_poll = 0;
 module_param(lpfc_poll, int, 0);
@@ -695,12 +706,12 @@ LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
                 "during discovery");
 
 /*
-# lpfc_max_luns: maximum number of LUNs per target driver will support
-# Value range is [1,32768]. Default value is 256.
-# NOTE: The SCSI layer will scan each target for this many luns
+# lpfc_max_luns: maximum allowed LUN.
+# Value range is [0,65535]. Default value is 255.
+# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
 */
-LPFC_ATTR_R(max_luns, 256, 1, 32768,
-            "Maximum number of LUNs per target driver will support");
+LPFC_ATTR_R(max_luns, 255, 0, 65535,
+            "Maximum allowed LUN");
 
 /*
 # lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
@@ -739,8 +750,8 @@ struct class_device_attribute *lpfc_host_attrs[] = {
        &class_device_attr_lpfc_max_luns,
        &class_device_attr_nport_evt_cnt,
        &class_device_attr_management_version,
-       &class_device_attr_board_online,
        &class_device_attr_board_mode,
+       &class_device_attr_issue_reset,
        &class_device_attr_lpfc_poll,
        &class_device_attr_lpfc_poll_tmo,
        NULL,
index ee22173fce43c664cc2a352b580d8984bf60f718..517e9e4dd461aa15f200ea7858315dbfa6d87ce0 100644 (file)
@@ -147,6 +147,7 @@ int lpfc_sli_hba_setup(struct lpfc_hba *);
 int lpfc_sli_hba_down(struct lpfc_hba *);
 int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
 int lpfc_sli_handle_mb_event(struct lpfc_hba *);
+int lpfc_sli_flush_mbox_queue(struct lpfc_hba *);
 int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *,
                                    struct lpfc_sli_ring *, uint32_t);
 void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
index 4126fd87956f76d7f947322a2ed6d7ef26c6f30b..b89f6cb641e64d759223f3cbb21d246e18518648 100644 (file)
@@ -648,33 +648,32 @@ lpfc_more_plogi(struct lpfc_hba * phba)
 }
 
 static struct lpfc_nodelist *
-lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
+lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp,
                         struct lpfc_nodelist *ndlp)
 {
        struct lpfc_nodelist *new_ndlp;
-       struct lpfc_dmabuf *pcmd, *prsp;
        uint32_t *lp;
        struct serv_parm *sp;
        uint8_t name[sizeof (struct lpfc_name)];
        uint32_t rc;
 
-       pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
-       prsp = (struct lpfc_dmabuf *) pcmd->list.next;
        lp = (uint32_t *) prsp->virt;
        sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
+       memset(name, 0, sizeof (struct lpfc_name));
 
        /* Now we to find out if the NPort we are logging into, matches the WWPN
         * we have for that ndlp. If not, we have some work to do.
         */
        new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName);
 
-       memset(name, 0, sizeof (struct lpfc_name));
-       rc =  memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name));
-       if (!rc || (new_ndlp == ndlp)) {
+       if (new_ndlp == ndlp)
                return ndlp;
-       }
 
        if (!new_ndlp) {
+               rc =
+                  memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name));
+               if (!rc)
+                       return ndlp;
                new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
                if (!new_ndlp)
                        return ndlp;
@@ -683,17 +682,21 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
        }
 
        lpfc_unreg_rpi(phba, new_ndlp);
-       new_ndlp->nlp_prev_state = ndlp->nlp_state;
        new_ndlp->nlp_DID = ndlp->nlp_DID;
-       new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
-       lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST);
+       new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
+       new_ndlp->nlp_state = ndlp->nlp_state;
+       lpfc_nlp_list(phba, new_ndlp, ndlp->nlp_flag & NLP_LIST_MASK);
 
        /* Move this back to NPR list */
-       lpfc_unreg_rpi(phba, ndlp);
-       ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
-       ndlp->nlp_state = NLP_STE_NPR_NODE;
-       lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
-
+       if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) {
+               lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+       }
+       else {
+               lpfc_unreg_rpi(phba, ndlp);
+               ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
+               ndlp->nlp_state = NLP_STE_NPR_NODE;
+               lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
+       }
        return new_ndlp;
 }
 
@@ -703,6 +706,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 {
        IOCB_t *irsp;
        struct lpfc_nodelist *ndlp;
+       struct lpfc_dmabuf *prsp;
        int disc, rc, did, type;
 
 
@@ -769,7 +773,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                }
        } else {
                /* Good status, call state machine */
-               ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp);
+               prsp = list_entry(((struct lpfc_dmabuf *)
+                       cmdiocb->context2)->list.next,
+                       struct lpfc_dmabuf, list);
+               ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp);
                rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb,
                                        NLP_EVT_CMPL_PLOGI);
        }
@@ -3282,10 +3289,9 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
                } else
                        lpfc_sli_release_iocbq(phba, piocb);
        }
-       if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) {
-               phba->els_tmofunc.expires = jiffies + HZ * timeout;
-               add_timer(&phba->els_tmofunc);
-       }
+       if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt)
+               mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout);
+
        spin_unlock_irq(phba->host->host_lock);
 }
 
@@ -3442,6 +3448,8 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) {
                        ndlp->nlp_type |= NLP_FABRIC;
                }
+               ndlp->nlp_state = NLP_STE_UNUSED_NODE;
+               lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
        }
 
        phba->fc_stat.elsRcvFrame++;
@@ -3463,13 +3471,14 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                        rjt_err = 1;
                        break;
                }
+               ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp);
                lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI);
                break;
        case ELS_CMD_FLOGI:
                phba->fc_stat.elsRcvFLOGI++;
                lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        case ELS_CMD_LOGO:
@@ -3492,7 +3501,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                phba->fc_stat.elsRcvRSCN++;
                lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        case ELS_CMD_ADISC:
@@ -3535,28 +3544,28 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                phba->fc_stat.elsRcvLIRR++;
                lpfc_els_rcv_lirr(phba, elsiocb, ndlp);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        case ELS_CMD_RPS:
                phba->fc_stat.elsRcvRPS++;
                lpfc_els_rcv_rps(phba, elsiocb, ndlp);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        case ELS_CMD_RPL:
                phba->fc_stat.elsRcvRPL++;
                lpfc_els_rcv_rpl(phba, elsiocb, ndlp);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        case ELS_CMD_RNID:
                phba->fc_stat.elsRcvRNID++;
                lpfc_els_rcv_rnid(phba, elsiocb, ndlp);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        default:
@@ -3568,7 +3577,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                                "%d:0115 Unknown ELS command x%x received from "
                                "NPORT x%x\n", phba->brd_no, cmd, did);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        }
index adb086009ae09fb0221c5ec06deeb2d772914609..4d6cf990c4fcde66190cc06383420c306d98e8f6 100644 (file)
@@ -1084,7 +1084,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
                fc_remote_port_rolechg(rport, rport_ids.roles);
 
        if ((rport->scsi_target_id != -1) &&
-               (rport->scsi_target_id < MAX_FCP_TARGET)) {
+               (rport->scsi_target_id < LPFC_MAX_TARGET)) {
                ndlp->nlp_sid = rport->scsi_target_id;
        }
 
@@ -1313,7 +1313,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
                        if ((rport_add == mapped) &&
                            ((!nlp->rport) ||
                             (nlp->rport->scsi_target_id == -1) ||
-                            (nlp->rport->scsi_target_id >= MAX_FCP_TARGET))) {
+                            (nlp->rport->scsi_target_id >= LPFC_MAX_TARGET))) {
                                nlp->nlp_state = NLP_STE_UNMAPPED_NODE;
                                spin_lock_irq(phba->host->host_lock);
                                nlp->nlp_flag |= NLP_TGT_NO_SCSIID;
index 81755a3f7c6868ebf2e7a7cc60d457db8cb4f9b2..ef47b824cbed46f2c6667fa42316e3544bf05a95 100644 (file)
@@ -71,6 +71,7 @@ lpfc_config_port_prep(struct lpfc_hba * phba)
        uint16_t offset = 0;
        static char licensed[56] =
                    "key unlock for use with gnu public licensed code only\0";
+       static int init_key = 1;
 
        pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (!pmb) {
@@ -82,10 +83,13 @@ lpfc_config_port_prep(struct lpfc_hba * phba)
        phba->hba_state = LPFC_INIT_MBX_CMDS;
 
        if (lpfc_is_LC_HBA(phba->pcidev->device)) {
-               uint32_t *ptext = (uint32_t *) licensed;
+               if (init_key) {
+                       uint32_t *ptext = (uint32_t *) licensed;
 
-               for (i = 0; i < 56; i += sizeof (uint32_t), ptext++)
-                       *ptext = cpu_to_be32(*ptext);
+                       for (i = 0; i < 56; i += sizeof (uint32_t), ptext++)
+                               *ptext = cpu_to_be32(*ptext);
+                       init_key = 0;
+               }
 
                lpfc_read_nv(phba, pmb);
                memset((char*)mb->un.varRDnvp.rsvd3, 0,
@@ -405,19 +409,26 @@ lpfc_config_port_post(struct lpfc_hba * phba)
        }
        /* MBOX buffer will be freed in mbox compl */
 
-       i = 0;
+       return (0);
+}
+
+static int
+lpfc_discovery_wait(struct lpfc_hba *phba)
+{
+       int i = 0;
+
        while ((phba->hba_state != LPFC_HBA_READY) ||
               (phba->num_disc_nodes) || (phba->fc_prli_sent) ||
               ((phba->fc_map_cnt == 0) && (i<2)) ||
-              (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE)) {
+              (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)) {
                /* Check every second for 30 retries. */
                i++;
                if (i > 30) {
-                       break;
+                       return -ETIMEDOUT;
                }
                if ((i >= 15) && (phba->hba_state <= LPFC_LINK_DOWN)) {
                        /* The link is down.  Set linkdown timeout */
-                       break;
+                       return -ETIMEDOUT;
                }
 
                /* Delay for 1 second to give discovery time to complete. */
@@ -425,12 +436,7 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 
        }
 
-       /* Since num_disc_nodes keys off of PLOGI, delay a bit to let
-        * any potential PRLIs to flush thru the SLI sub-system.
-        */
-       msleep(50);
-
-       return (0);
+       return 0;
 }
 
 /************************************************************************/
@@ -1339,7 +1345,8 @@ lpfc_offline(struct lpfc_hba * phba)
        struct lpfc_sli_ring *pring;
        struct lpfc_sli *psli;
        unsigned long iflag;
-       int i = 0;
+       int i;
+       int cnt = 0;
 
        if (!phba)
                return 0;
@@ -1348,17 +1355,27 @@ lpfc_offline(struct lpfc_hba * phba)
                return 0;
 
        psli = &phba->sli;
-       pring = &psli->ring[psli->fcp_ring];
 
        lpfc_linkdown(phba);
+       lpfc_sli_flush_mbox_queue(phba);
 
-       /* The linkdown event takes 30 seconds to timeout. */
-       while (pring->txcmplq_cnt) {
-               mdelay(10);
-               if (i++ > 3000)
-                       break;
+       for (i = 0; i < psli->num_rings; i++) {
+               pring = &psli->ring[i];
+               /* The linkdown event takes 30 seconds to timeout. */
+               while (pring->txcmplq_cnt) {
+                       mdelay(10);
+                       if (cnt++ > 3000) {
+                               lpfc_printf_log(phba,
+                                       KERN_WARNING, LOG_INIT,
+                                       "%d:0466 Outstanding IO when "
+                                       "bringing Adapter offline\n",
+                                       phba->brd_no);
+                               break;
+                       }
+               }
        }
 
+
        /* stop all timers associated with this hba */
        lpfc_stop_timer(phba);
        phba->work_hba_events = 0;
@@ -1639,6 +1656,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
                goto out_free_irq;
        }
 
+       lpfc_discovery_wait(phba);
+
        if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
                spin_lock_irq(phba->host->host_lock);
                lpfc_poll_start_timer(phba);
index 07017658ac56770e601659727b641957d9c0a6c4..066292d3995a5b33eba898a34f76a1eab206c8c7 100644 (file)
@@ -133,6 +133,11 @@ lpfc_mem_free(struct lpfc_hba * phba)
 
        pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
        pci_pool_destroy(phba->lpfc_mbuf_pool);
+
+       /* Free the iocb lookup array */
+       kfree(psli->iocbq_lookup);
+       psli->iocbq_lookup = NULL;
+
 }
 
 void *
index 27d60ad897cdc81de79fde9dd2fab98a568a3211..bd0b0e293d637be80e7888edaa9dd0212a4c9cad 100644 (file)
@@ -1110,6 +1110,17 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
                                phba->brd_no,
                                did, mb->mbxStatus, phba->hba_state);
 
+               /*
+                * If RegLogin failed due to lack of HBA resources do not
+                * retry discovery.
+                */
+               if (mb->mbxStatus == MBXERR_RPI_FULL) {
+                       ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
+                       ndlp->nlp_state = NLP_STE_UNUSED_NODE;
+                       lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
+                       return ndlp->nlp_state;
+               }
+
                /* Put ndlp in npr list set plogi timer for 1 sec */
                mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
                spin_lock_irq(phba->host->host_lock);
index aea1ee472f3d503d263684669bd4dd1374406883..a760a44173df6e8a8092f4963fcf3f2a235d6b02 100644 (file)
@@ -153,22 +153,6 @@ static void
 lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
 {
        unsigned long iflag = 0;
-       /*
-        * There are only two special cases to consider.  (1) the scsi command
-        * requested scatter-gather usage or (2) the scsi command allocated
-        * a request buffer, but did not request use_sg.  There is a third
-        * case, but it does not require resource deallocation.
-        */
-       if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) {
-               dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer,
-                               psb->seg_cnt, psb->pCmd->sc_data_direction);
-       } else {
-                if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) {
-                       dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys,
-                                               psb->pCmd->request_bufflen,
-                                               psb->pCmd->sc_data_direction);
-                }
-       }
 
        spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
        psb->pCmd = NULL;
@@ -281,6 +265,27 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd)
        return 0;
 }
 
+static void
+lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
+{
+       /*
+        * There are only two special cases to consider.  (1) the scsi command
+        * requested scatter-gather usage or (2) the scsi command allocated
+        * a request buffer, but did not request use_sg.  There is a third
+        * case, but it does not require resource deallocation.
+        */
+       if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) {
+               dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer,
+                               psb->seg_cnt, psb->pCmd->sc_data_direction);
+       } else {
+                if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) {
+                       dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys,
+                                               psb->pCmd->request_bufflen,
+                                               psb->pCmd->sc_data_direction);
+                }
+       }
+}
+
 static void
 lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
 {
@@ -454,6 +459,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
        cmd->scsi_done(cmd);
 
        if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+               lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
                lpfc_release_scsi_buf(phba, lpfc_cmd);
                return;
        }
@@ -511,6 +517,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
                }
        }
 
+       lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
        lpfc_release_scsi_buf(phba, lpfc_cmd);
 }
 
@@ -609,6 +616,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd,
 static int
 lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
                             struct lpfc_scsi_buf *lpfc_cmd,
+                            unsigned int lun,
                             uint8_t task_mgmt_cmd)
 {
        struct lpfc_sli *psli;
@@ -627,8 +635,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
        piocb = &piocbq->iocb;
 
        fcp_cmnd = lpfc_cmd->fcp_cmnd;
-       int_to_scsilun(lpfc_cmd->pCmd->device->lun,
-                       &lpfc_cmd->fcp_cmnd->fcp_lun);
+       int_to_scsilun(lun, &lpfc_cmd->fcp_cmnd->fcp_lun);
        fcp_cmnd->fcpCntl2 = task_mgmt_cmd;
 
        piocb->ulpCommand = CMD_FCP_ICMND64_CR;
@@ -655,14 +662,16 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
 
 static int
 lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba,
-                   unsigned  tgt_id, struct lpfc_rport_data *rdata)
+                   unsigned  tgt_id, unsigned int lun,
+                   struct lpfc_rport_data *rdata)
 {
        struct lpfc_iocbq *iocbq;
        struct lpfc_iocbq *iocbqrsp;
        int ret;
 
        lpfc_cmd->rdata = rdata;
-       ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET);
+       ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun,
+                                          FCP_TARGET_RESET);
        if (!ret)
                return FAILED;
 
@@ -822,6 +831,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
        return 0;
 
  out_host_busy_free_buf:
+       lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
        lpfc_release_scsi_buf(phba, lpfc_cmd);
  out_host_busy:
        return SCSI_MLQUEUE_HOST_BUSY;
@@ -969,12 +979,12 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
        if (lpfc_cmd == NULL)
                goto out;
 
-       lpfc_cmd->pCmd = cmnd;
        lpfc_cmd->timeout = 60;
        lpfc_cmd->scsi_hba = phba;
        lpfc_cmd->rdata = rdata;
 
-       ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET);
+       ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun,
+                                          FCP_LUN_RESET);
        if (!ret)
                goto out_free_scsi_buf;
 
@@ -1001,7 +1011,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
        cmd_status = iocbqrsp->iocb.ulpStatus;
 
        lpfc_sli_release_iocbq(phba, iocbqrsp);
-       lpfc_release_scsi_buf(phba, lpfc_cmd);
 
        /*
         * All outstanding txcmplq I/Os should have been aborted by the device.
@@ -1040,6 +1049,8 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
        }
 
 out_free_scsi_buf:
+       lpfc_release_scsi_buf(phba, lpfc_cmd);
+
        lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
                        "%d:0713 SCSI layer issued LUN reset (%d, %d) "
                        "Data: x%x x%x x%x\n",
@@ -1070,7 +1081,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
 
        /* The lpfc_cmd storage is reused.  Set all loop invariants. */
        lpfc_cmd->timeout = 60;
-       lpfc_cmd->pCmd = cmnd;
        lpfc_cmd->scsi_hba = phba;
 
        /*
@@ -1078,7 +1088,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
         * targets known to the driver.  Should any target reset
         * fail, this routine returns failure to the midlayer.
         */
-       for (i = 0; i < MAX_FCP_TARGET; i++) {
+       for (i = 0; i < LPFC_MAX_TARGET; i++) {
                /* Search the mapped list for this target ID */
                match = 0;
                list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
@@ -1090,8 +1100,8 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
                if (!match)
                        continue;
 
-               ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba,
-                                         i, ndlp->rport->dd_data);
+               ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, i, cmnd->device->lun,
+                                         ndlp->rport->dd_data);
                if (ret != SUCCESS) {
                        lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
                                "%d:0713 Bus Reset on target %d failed\n",
index bb69a7a1ec598d78a03663627930f791d9dbd9d8..350a625fa2244601f003e1cea4080bcf7bc73845 100644 (file)
@@ -191,35 +191,12 @@ static int
 lpfc_sli_ringtxcmpl_put(struct lpfc_hba * phba,
                        struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocb)
 {
-       uint16_t iotag;
-
        list_add_tail(&piocb->list, &pring->txcmplq);
        pring->txcmplq_cnt++;
        if (unlikely(pring->ringno == LPFC_ELS_RING))
                mod_timer(&phba->els_tmofunc,
                                        jiffies + HZ * (phba->fc_ratov << 1));
 
-       if (pring->fast_lookup) {
-               /* Setup fast lookup based on iotag for completion */
-               iotag = piocb->iocb.ulpIoTag;
-               if (iotag && (iotag < pring->fast_iotag))
-                       *(pring->fast_lookup + iotag) = piocb;
-               else {
-
-                       /* Cmd ring <ringno> put: iotag <iotag> greater then
-                          configured max <fast_iotag> wd0 <icmd> */
-                       lpfc_printf_log(phba,
-                                       KERN_ERR,
-                                       LOG_SLI,
-                                       "%d:0316 Cmd ring %d put: iotag x%x "
-                                       "greater then configured max x%x "
-                                       "wd0 x%x\n",
-                                       phba->brd_no,
-                                       pring->ringno, iotag,
-                                       pring->fast_iotag,
-                                       *(((uint32_t *)(&piocb->iocb)) + 7));
-               }
-       }
        return (0);
 }
 
@@ -601,7 +578,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba)
                        /* Stray Mailbox Interrupt, mbxCommand <cmd> mbxStatus
                           <status> */
                        lpfc_printf_log(phba,
-                                       KERN_ERR,
+                                       KERN_WARNING,
                                        LOG_MBOX | LOG_SLI,
                                        "%d:0304 Stray Mailbox Interrupt "
                                        "mbxCommand x%x mbxStatus x%x\n",
@@ -1570,8 +1547,8 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask)
 
 void lpfc_reset_barrier(struct lpfc_hba * phba)
 {
-       uint32_t resp_buf;
-       uint32_t mbox_buf;
+       uint32_t __iomem *resp_buf;
+       uint32_t __iomem *mbox_buf;
        volatile uint32_t mbox;
        uint32_t hc_copy;
        int  i;
@@ -1587,7 +1564,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba)
         * Tell the other part of the chip to suspend temporarily all
         * its DMA activity.
         */
-       resp_buf =  (uint32_t *)phba->MBslimaddr;
+       resp_buf = phba->MBslimaddr;
 
        /* Disable the error attention */
        hc_copy = readl(phba->HCregaddr);
@@ -1605,7 +1582,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba)
        ((MAILBOX_t *)&mbox)->mbxOwner = OWN_CHIP;
 
        writel(BARRIER_TEST_PATTERN, (resp_buf + 1));
-       mbox_buf = (uint32_t *)phba->MBslimaddr;
+       mbox_buf = phba->MBslimaddr;
        writel(mbox, mbox_buf);
 
        for (i = 0;
@@ -1805,7 +1782,7 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba)
                skip_post = 0;
                word0 = 0;      /* This is really setting up word1 */
        }
-       to_slim = (uint8_t *) phba->MBslimaddr + sizeof (uint32_t);
+       to_slim = phba->MBslimaddr + sizeof (uint32_t);
        writel(*(uint32_t *) mb, to_slim);
        readl(to_slim); /* flush */
 
@@ -2659,8 +2636,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
 
                INIT_LIST_HEAD(&(pring->txq));
 
-               kfree(pring->fast_lookup);
-               pring->fast_lookup = NULL;
        }
 
        spin_unlock_irqrestore(phba->host->host_lock, flags);
@@ -3110,6 +3085,24 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
        return retval;
 }
 
+int
+lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba)
+{
+       int i = 0;
+
+       while (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE && !phba->stopped) {
+               if (i++ > LPFC_MBOX_TMO * 1000)
+                       return 1;
+
+               if (lpfc_sli_handle_mb_event(phba) == 0)
+                       i = 0;
+
+               msleep(1);
+       }
+
+       return (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) ? 1 : 0;
+}
+
 irqreturn_t
 lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs)
 {
index a52d6c6cf0838563ff74eb04665af10fc9e089b4..d8ef0d2894d46bc13d7c954bdfb09fcb43f52baf 100644 (file)
@@ -135,8 +135,6 @@ struct lpfc_sli_ring {
        uint32_t fast_iotag;    /* max fastlookup based iotag           */
        uint32_t iotag_ctr;     /* keeps track of the next iotag to use */
        uint32_t iotag_max;     /* max iotag value to use               */
-       struct lpfc_iocbq ** fast_lookup; /* array of IOCB ptrs indexed by
-                                          iotag */
        struct list_head txq;
        uint16_t txq_cnt;       /* current length of queue */
        uint16_t txq_max;       /* max length */
index 6b737568b8310cb29bdf717ac00d18d5371de10e..10e89c6ae82313d4e28e4ddfd2a50190aee0418a 100644 (file)
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.1.6"
+#define LPFC_DRIVER_VERSION "8.1.7"
 
 #define LPFC_DRIVER_NAME "lpfc"
 
index 93edaa8696cf35e0b54a72dc3cfd266931e2c18b..89ef34df5a1db443eb15b28727b5f9b91df413f1 100644 (file)
@@ -378,7 +378,7 @@ static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd)
                int nseg;
 
                total = 0;
-               scl = (struct scatterlist *) cmd->buffer;
+               scl = (struct scatterlist *) cmd->request_buffer;
                nseg = pci_map_sg(state->pdev, scl, cmd->use_sg,
                                cmd->sc_data_direction);
                for (i = 0; i < nseg; ++i) {
index c88717727be8ed58e9cbf23a2b1c376a2819ac09..5572981a9f925648f5fd44c841499d93ab63c70e 100644 (file)
@@ -1268,7 +1268,7 @@ static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd)
                if (cmd->use_sg > 0) {
                        int nseg;
                        total = 0;
-                       scl = (struct scatterlist *) cmd->buffer;
+                       scl = (struct scatterlist *) cmd->request_buffer;
                        off = ms->data_ptr;
                        nseg = pci_map_sg(ms->pdev, scl, cmd->use_sg,
                                          cmd->sc_data_direction);
index 7abf64d1bfc9960c051b827b6d3c0377e51041be..0bd9c60e6455b879b831c4b7a64854422213ee8c 100644 (file)
@@ -169,8 +169,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
                SCpnt->request->rq_status = RQ_SCSI_BUSY;
                
                SCpnt->done = pluto_detect_done;
-               SCpnt->bufflen = 256;
-               SCpnt->buffer = fcs[i].inquiry;
                SCpnt->request_bufflen = 256;
                SCpnt->request_buffer = fcs[i].inquiry;
                PLD(("set up %d %08lx\n", i, (long)SCpnt))
index 69e0551a81d26abf80e5a4a53dda1ed9f8c6459e..5b2f0741a55b841f06ad6dc93e9eba81dd809e27 100644 (file)
@@ -874,7 +874,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
        if (Cmnd->use_sg) {
                int sg_count;
 
-               sg = (struct scatterlist *) Cmnd->buffer;
+               sg = (struct scatterlist *) Cmnd->request_buffer;
                sg_count = sbus_map_sg(qpti->sdev, sg, Cmnd->use_sg, Cmnd->sc_data_direction);
 
                ds = cmd->dataseg;
@@ -1278,7 +1278,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti)
 
                if (Cmnd->use_sg) {
                        sbus_unmap_sg(qpti->sdev,
-                                     (struct scatterlist *)Cmnd->buffer,
+                                     (struct scatterlist *)Cmnd->request_buffer,
                                      Cmnd->use_sg,
                                      Cmnd->sc_data_direction);
                } else {
index 2ab7df0dcfe8df2901cd9aaf68e735ee1f521d01..b332caddd5b379f849764922fd78a69164253bef 100644 (file)
@@ -346,7 +346,7 @@ void scsi_log_send(struct scsi_cmnd *cmd)
                        if (level > 3) {
                                printk(KERN_INFO "buffer = 0x%p, bufflen = %d,"
                                       " done = 0x%p, queuecommand 0x%p\n",
-                                       cmd->buffer, cmd->bufflen,
+                                       cmd->request_buffer, cmd->request_bufflen,
                                        cmd->done,
                                        sdev->host->hostt->queuecommand);
 
@@ -661,11 +661,6 @@ void __scsi_done(struct scsi_cmnd *cmd)
  */
 int scsi_retry_command(struct scsi_cmnd *cmd)
 {
-       /*
-        * Restore the SCSI command state.
-        */
-       scsi_setup_cmd_retry(cmd);
-
         /*
          * Zero the sense information from the last time we tried
          * this command.
@@ -711,10 +706,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
                                "Notifying upper driver of completion "
                                "(result %x)\n", cmd->result));
 
-       /*
-        * We can get here with use_sg=0, causing a panic in the upper level
-        */
-       cmd->use_sg = cmd->old_use_sg;
        cmd->done(cmd);
 }
 EXPORT_SYMBOL(scsi_finish_command);
index 9c63b00773c43c9be0a4df3b9fc0c055954ae5d3..a80303c6b3fdade137dfccaf9c36b22bb2fd432d 100644 (file)
@@ -286,7 +286,7 @@ static int inquiry_evpd_83(unsigned char * arr, int target_dev_id,
                           int dev_id_num, const char * dev_id_str,
                           int dev_id_str_len);
 static int inquiry_evpd_88(unsigned char * arr, int target_dev_id);
-static void do_create_driverfs_files(void);
+static int do_create_driverfs_files(void);
 static void do_remove_driverfs_files(void);
 
 static int sdebug_add_adapter(void);
@@ -2487,19 +2487,22 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp,
 DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, 
            sdebug_add_host_store);
 
-static void do_create_driverfs_files(void)
+static int do_create_driverfs_files(void)
 {
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
+       int ret;
+
+       ret = driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
+       return ret;
 }
 
 static void do_remove_driverfs_files(void)
@@ -2522,6 +2525,7 @@ static int __init scsi_debug_init(void)
        unsigned int sz;
        int host_to_add;
        int k;
+       int ret;
 
        if (scsi_debug_dev_size_mb < 1)
                scsi_debug_dev_size_mb = 1;  /* force minimum 1 MB ramdisk */
@@ -2560,12 +2564,32 @@ static int __init scsi_debug_init(void)
        if (scsi_debug_num_parts > 0)
                sdebug_build_parts(fake_storep);
 
-       init_all_queued();
+       ret = device_register(&pseudo_primary);
+       if (ret < 0) {
+               printk(KERN_WARNING "scsi_debug: device_register error: %d\n",
+                       ret);
+               goto free_vm;
+       }
+       ret = bus_register(&pseudo_lld_bus);
+       if (ret < 0) {
+               printk(KERN_WARNING "scsi_debug: bus_register error: %d\n",
+                       ret);
+               goto dev_unreg;
+       }
+       ret = driver_register(&sdebug_driverfs_driver);
+       if (ret < 0) {
+               printk(KERN_WARNING "scsi_debug: driver_register error: %d\n",
+                       ret);
+               goto bus_unreg;
+       }
+       ret = do_create_driverfs_files();
+       if (ret < 0) {
+               printk(KERN_WARNING "scsi_debug: driver_create_file error: %d\n",
+                       ret);
+               goto del_files;
+       }
 
-       device_register(&pseudo_primary);
-       bus_register(&pseudo_lld_bus);
-       driver_register(&sdebug_driverfs_driver);
-       do_create_driverfs_files();
+       init_all_queued();
 
        sdebug_driver_template.proc_name = (char *)sdebug_proc_name;
 
@@ -2585,6 +2609,18 @@ static int __init scsi_debug_init(void)
                       scsi_debug_add_host);
        }
        return 0;
+
+del_files:
+       do_remove_driverfs_files();
+       driver_unregister(&sdebug_driverfs_driver);
+bus_unreg:
+       bus_unregister(&pseudo_lld_bus);
+dev_unreg:
+       device_unregister(&pseudo_primary);
+free_vm:
+       vfree(fake_storep);
+
+       return ret;
 }
 
 static void __exit scsi_debug_exit(void)
index 6683d596234a7acab897066d96cad4f25af49608..6a5b731bd5ba45e11329c24dc88caf9aae892a36 100644 (file)
@@ -460,19 +460,67 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
  * Return value:
  *    SUCCESS or FAILED or NEEDS_RETRY
  **/
-static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
+static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout, int copy_sense)
 {
        struct scsi_device *sdev = scmd->device;
        struct Scsi_Host *shost = sdev->host;
+       int old_result = scmd->result;
        DECLARE_COMPLETION(done);
        unsigned long timeleft;
        unsigned long flags;
+       unsigned char old_cmnd[MAX_COMMAND_SIZE];
+       enum dma_data_direction old_data_direction;
+       unsigned short old_use_sg;
+       unsigned char old_cmd_len;
+       unsigned old_bufflen;
+       void *old_buffer;
        int rtn;
 
+       /*
+        * We need saved copies of a number of fields - this is because
+        * error handling may need to overwrite these with different values
+        * to run different commands, and once error handling is complete,
+        * we will need to restore these values prior to running the actual
+        * command.
+        */
+       old_buffer = scmd->request_buffer;
+       old_bufflen = scmd->request_bufflen;
+       memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd));
+       old_data_direction = scmd->sc_data_direction;
+       old_cmd_len = scmd->cmd_len;
+       old_use_sg = scmd->use_sg;
+
+       if (copy_sense) {
+               int gfp_mask = GFP_ATOMIC;
+
+               if (shost->hostt->unchecked_isa_dma)
+                       gfp_mask |= __GFP_DMA;
+
+               scmd->sc_data_direction = DMA_FROM_DEVICE;
+               scmd->request_bufflen = 252;
+               scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask);
+               if (!scmd->request_buffer)
+                       return FAILED;
+       } else {
+               scmd->request_buffer = NULL;
+               scmd->request_bufflen = 0;
+               scmd->sc_data_direction = DMA_NONE;
+       }
+
+       scmd->underflow = 0;
+       scmd->use_sg = 0;
+       scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
+
        if (sdev->scsi_level <= SCSI_2)
                scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
                        (sdev->lun << 5 & 0xe0);
 
+       /*
+        * Zero the sense buffer.  The scsi spec mandates that any
+        * untransferred sense data should be interpreted as being zero.
+        */
+       memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
+
        shost->eh_action = &done;
 
        spin_lock_irqsave(shost->host_lock, flags);
@@ -522,6 +570,29 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
                rtn = FAILED;
        }
 
+
+       /*
+        * Last chance to have valid sense data.
+        */
+       if (copy_sense) {
+               if (!SCSI_SENSE_VALID(scmd)) {
+                       memcpy(scmd->sense_buffer, scmd->request_buffer,
+                              sizeof(scmd->sense_buffer));
+               }
+               kfree(scmd->request_buffer);
+       }
+
+
+       /*
+        * Restore original data
+        */
+       scmd->request_buffer = old_buffer;
+       scmd->request_bufflen = old_bufflen;
+       memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd));
+       scmd->sc_data_direction = old_data_direction;
+       scmd->cmd_len = old_cmd_len;
+       scmd->use_sg = old_use_sg;
+       scmd->result = old_result;
        return rtn;
 }
 
@@ -537,56 +608,10 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
 static int scsi_request_sense(struct scsi_cmnd *scmd)
 {
        static unsigned char generic_sense[6] =
-       {REQUEST_SENSE, 0, 0, 0, 252, 0};
-       unsigned char *scsi_result;
-       int saved_result;
-       int rtn;
+               {REQUEST_SENSE, 0, 0, 0, 252, 0};
 
        memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense));
-
-       scsi_result = kmalloc(252, GFP_ATOMIC | ((scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0));
-
-
-       if (unlikely(!scsi_result)) {
-               printk(KERN_ERR "%s: cannot allocate scsi_result.\n",
-                      __FUNCTION__);
-               return FAILED;
-       }
-
-       /*
-        * zero the sense buffer.  some host adapters automatically always
-        * request sense, so it is not a good idea that
-        * scmd->request_buffer and scmd->sense_buffer point to the same
-        * address (db).  0 is not a valid sense code. 
-        */
-       memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
-       memset(scsi_result, 0, 252);
-
-       saved_result = scmd->result;
-       scmd->request_buffer = scsi_result;
-       scmd->request_bufflen = 252;
-       scmd->use_sg = 0;
-       scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
-       scmd->sc_data_direction = DMA_FROM_DEVICE;
-       scmd->underflow = 0;
-
-       rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
-
-       /* last chance to have valid sense data */
-       if(!SCSI_SENSE_VALID(scmd)) {
-               memcpy(scmd->sense_buffer, scmd->request_buffer,
-                      sizeof(scmd->sense_buffer));
-       }
-
-       kfree(scsi_result);
-
-       /*
-        * when we eventually call scsi_finish, we really wish to complete
-        * the original request, so let's restore the original data. (db)
-        */
-       scsi_setup_cmd_retry(scmd);
-       scmd->result = saved_result;
-       return rtn;
+       return scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 1);
 }
 
 /**
@@ -605,12 +630,6 @@ void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
 {
        scmd->device->host->host_failed--;
        scmd->eh_eflags = 0;
-
-       /*
-        * set this back so that the upper level can correctly free up
-        * things.
-        */
-       scsi_setup_cmd_retry(scmd);
        list_move_tail(&scmd->eh_entry, done_q);
 }
 EXPORT_SYMBOL(scsi_eh_finish_cmd);
@@ -715,47 +734,26 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd)
 {
        static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
        int retry_cnt = 1, rtn;
-       int saved_result;
 
 retry_tur:
        memcpy(scmd->cmnd, tur_command, sizeof(tur_command));
 
-       /*
-        * zero the sense buffer.  the scsi spec mandates that any
-        * untransferred sense data should be interpreted as being zero.
-        */
-       memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
-
-       saved_result = scmd->result;
-       scmd->request_buffer = NULL;
-       scmd->request_bufflen = 0;
-       scmd->use_sg = 0;
-       scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
-       scmd->underflow = 0;
-       scmd->sc_data_direction = DMA_NONE;
 
-       rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
+       rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 0);
 
-       /*
-        * when we eventually call scsi_finish, we really wish to complete
-        * the original request, so let's restore the original data. (db)
-        */
-       scsi_setup_cmd_retry(scmd);
-       scmd->result = saved_result;
-
-       /*
-        * hey, we are done.  let's look to see what happened.
-        */
        SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
                __FUNCTION__, scmd, rtn));
-       if (rtn == SUCCESS)
-               return 0;
-       else if (rtn == NEEDS_RETRY) {
+
+       switch (rtn) {
+       case NEEDS_RETRY:
                if (retry_cnt--)
                        goto retry_tur;
+               /*FALLTHRU*/
+       case SUCCESS:
                return 0;
+       default:
+               return 1;
        }
-       return 1;
 }
 
 /**
@@ -837,44 +835,16 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
 static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
 {
        static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};
-       int rtn;
-       int saved_result;
 
-       if (!scmd->device->allow_restart)
-               return 1;
-
-       memcpy(scmd->cmnd, stu_command, sizeof(stu_command));
-
-       /*
-        * zero the sense buffer.  the scsi spec mandates that any
-        * untransferred sense data should be interpreted as being zero.
-        */
-       memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
-
-       saved_result = scmd->result;
-       scmd->request_buffer = NULL;
-       scmd->request_bufflen = 0;
-       scmd->use_sg = 0;
-       scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
-       scmd->underflow = 0;
-       scmd->sc_data_direction = DMA_NONE;
+       if (scmd->device->allow_restart) {
+               int rtn;
 
-       rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT);
-
-       /*
-        * when we eventually call scsi_finish, we really wish to complete
-        * the original request, so let's restore the original data. (db)
-        */
-       scsi_setup_cmd_retry(scmd);
-       scmd->result = saved_result;
+               memcpy(scmd->cmnd, stu_command, sizeof(stu_command));
+               rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT, 0);
+               if (rtn == SUCCESS)
+                       return 0;
+       }
 
-       /*
-        * hey, we are done.  let's look to see what happened.
-        */
-       SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
-               __FUNCTION__, scmd, rtn));
-       if (rtn == SUCCESS)
-               return 0;
        return 1;
 }
 
@@ -1684,8 +1654,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
     
        scmd->scsi_done         = scsi_reset_provider_done_command;
        scmd->done                      = NULL;
-       scmd->buffer                    = NULL;
-       scmd->bufflen                   = 0;
        scmd->request_buffer            = NULL;
        scmd->request_bufflen           = 0;
 
index 08af9aae7df38e22f86c6d17da7dc4fc491edb72..077c1c691210284428d416fb73392c89f1cdc92b 100644 (file)
@@ -436,60 +436,16 @@ EXPORT_SYMBOL_GPL(scsi_execute_async);
  *
  * Arguments:   cmd    - command that is ready to be queued.
  *
- * Returns:     Nothing
- *
  * Notes:       This function has the job of initializing a number of
  *              fields related to error handling.   Typically this will
  *              be called once for each command, as required.
  */
-static int scsi_init_cmd_errh(struct scsi_cmnd *cmd)
+static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
 {
        cmd->serial_number = 0;
-
        memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer);
-
        if (cmd->cmd_len == 0)
                cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
-
-       /*
-        * We need saved copies of a number of fields - this is because
-        * error handling may need to overwrite these with different values
-        * to run different commands, and once error handling is complete,
-        * we will need to restore these values prior to running the actual
-        * command.
-        */
-       cmd->old_use_sg = cmd->use_sg;
-       cmd->old_cmd_len = cmd->cmd_len;
-       cmd->sc_old_data_direction = cmd->sc_data_direction;
-       cmd->old_underflow = cmd->underflow;
-       memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd));
-       cmd->buffer = cmd->request_buffer;
-       cmd->bufflen = cmd->request_bufflen;
-
-       return 1;
-}
-
-/*
- * Function:   scsi_setup_cmd_retry()
- *
- * Purpose:    Restore the command state for a retry
- *
- * Arguments:  cmd     - command to be restored
- *
- * Returns:    Nothing
- *
- * Notes:      Immediately prior to retrying a command, we need
- *             to restore certain fields that we saved above.
- */
-void scsi_setup_cmd_retry(struct scsi_cmnd *cmd)
-{
-       memcpy(cmd->cmnd, cmd->data_cmnd, sizeof(cmd->data_cmnd));
-       cmd->request_buffer = cmd->buffer;
-       cmd->request_bufflen = cmd->bufflen;
-       cmd->use_sg = cmd->old_use_sg;
-       cmd->cmd_len = cmd->old_cmd_len;
-       cmd->sc_data_direction = cmd->sc_old_data_direction;
-       cmd->underflow = cmd->old_underflow;
 }
 
 void scsi_device_unbusy(struct scsi_device *sdev)
@@ -807,22 +763,13 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index)
  */
 static void scsi_release_buffers(struct scsi_cmnd *cmd)
 {
-       struct request *req = cmd->request;
-
-       /*
-        * Free up any indirection buffers we allocated for DMA purposes. 
-        */
        if (cmd->use_sg)
                scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
-       else if (cmd->request_buffer != req->buffer)
-               kfree(cmd->request_buffer);
 
        /*
         * Zero these out.  They now point to freed memory, and it is
         * dangerous to hang onto the pointers.
         */
-       cmd->buffer  = NULL;
-       cmd->bufflen = 0;
        cmd->request_buffer = NULL;
        cmd->request_bufflen = 0;
 }
@@ -858,7 +805,7 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd)
 void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 {
        int result = cmd->result;
-       int this_count = cmd->bufflen;
+       int this_count = cmd->request_bufflen;
        request_queue_t *q = cmd->device->request_queue;
        struct request *req = cmd->request;
        int clear_errors = 1;
@@ -866,28 +813,14 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
        int sense_valid = 0;
        int sense_deferred = 0;
 
-       /*
-        * Free up any indirection buffers we allocated for DMA purposes. 
-        * For the case of a READ, we need to copy the data out of the
-        * bounce buffer and into the real buffer.
-        */
-       if (cmd->use_sg)
-               scsi_free_sgtable(cmd->buffer, cmd->sglist_len);
-       else if (cmd->buffer != req->buffer) {
-               if (rq_data_dir(req) == READ) {
-                       unsigned long flags;
-                       char *to = bio_kmap_irq(req->bio, &flags);
-                       memcpy(to, cmd->buffer, cmd->bufflen);
-                       bio_kunmap_irq(to, &flags);
-               }
-               kfree(cmd->buffer);
-       }
+       scsi_release_buffers(cmd);
 
        if (result) {
                sense_valid = scsi_command_normalize_sense(cmd, &sshdr);
                if (sense_valid)
                        sense_deferred = scsi_sense_is_deferred(&sshdr);
        }
+
        if (blk_pc_request(req)) { /* SG_IO ioctl from block level */
                req->errors = result;
                if (result) {
@@ -907,15 +840,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                        req->data_len = cmd->resid;
        }
 
-       /*
-        * Zero these out.  They now point to freed memory, and it is
-        * dangerous to hang onto the pointers.
-        */
-       cmd->buffer  = NULL;
-       cmd->bufflen = 0;
-       cmd->request_buffer = NULL;
-       cmd->request_bufflen = 0;
-
        /*
         * Next deal with any sectors which we were able to correctly
         * handle.
@@ -1012,7 +936,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                        if (!(req->flags & REQ_QUIET)) {
                                scmd_printk(KERN_INFO, cmd,
                                            "Volume overflow, CDB: ");
-                               __scsi_print_command(cmd->data_cmnd);
+                               __scsi_print_command(cmd->cmnd);
                                scsi_print_sense("", cmd);
                        }
                        /* See SSC3rXX or current. */
@@ -1143,7 +1067,7 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
         * successfully. Since this is a REQ_BLOCK_PC command the
         * caller should check the request's errors value
         */
-       scsi_io_completion(cmd, cmd->bufflen);
+       scsi_io_completion(cmd, cmd->request_bufflen);
 }
 
 static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
index e2fbe9a9d5a98945a9641d86f4adb9cc72ab86f9..ae24c85aaeea2432e229972f3f134413420860bd 100644 (file)
@@ -57,7 +57,6 @@ extern int scsi_eh_scmd_add(struct scsi_cmnd *, int);
 
 /* scsi_lib.c */
 extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
-extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd);
 extern void scsi_device_unbusy(struct scsi_device *sdev);
 extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason);
 extern void scsi_next_command(struct scsi_cmnd *cmd);
index dd075627e605f073f72677985ad13b25db66054c..5a625c3fddaed7cc4f4a68105ed415f1c6c198d7 100644 (file)
@@ -41,6 +41,7 @@ struct sas_host_attrs {
        struct mutex lock;
        u32 next_target_id;
        u32 next_expander_id;
+       int next_port_id;
 };
 #define to_sas_host_attrs(host)        ((struct sas_host_attrs *)(host)->shost_data)
 
@@ -146,6 +147,7 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev,
        mutex_init(&sas_host->lock);
        sas_host->next_target_id = 0;
        sas_host->next_expander_id = 0;
+       sas_host->next_port_id = 0;
        return 0;
 }
 
@@ -327,7 +329,7 @@ sas_phy_protocol_attr(identify.target_port_protocols,
 sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
                unsigned long long);
 sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);
-//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8);
+//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", int);
 sas_phy_linkspeed_attr(negotiated_linkrate);
 sas_phy_linkspeed_attr(minimum_linkrate_hw);
 sas_phy_linkspeed_attr(minimum_linkrate);
@@ -590,6 +592,38 @@ struct sas_port *sas_port_alloc(struct device *parent, int port_id)
 }
 EXPORT_SYMBOL(sas_port_alloc);
 
+/** sas_port_alloc_num - allocate and initialize a SAS port structure
+ *
+ * @parent:    parent device
+ *
+ * Allocates a SAS port structure and a number to go with it.  This
+ * interface is really for adapters where the port number has no
+ * meansing, so the sas class should manage them.  It will be added to
+ * the device tree below the device specified by @parent which must be
+ * either a Scsi_Host or a sas_expander_device.
+ *
+ * Returns %NULL on error
+ */
+struct sas_port *sas_port_alloc_num(struct device *parent)
+{
+       int index;
+       struct Scsi_Host *shost = dev_to_shost(parent);
+       struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
+
+       /* FIXME: use idr for this eventually */
+       mutex_lock(&sas_host->lock);
+       if (scsi_is_sas_expander_device(parent)) {
+               struct sas_rphy *rphy = dev_to_rphy(parent);
+               struct sas_expander_device *exp = rphy_to_expander_device(rphy);
+
+               index = exp->next_port_id++;
+       } else
+               index = sas_host->next_port_id++;
+       mutex_unlock(&sas_host->lock);
+       return sas_port_alloc(parent, index);
+}
+EXPORT_SYMBOL(sas_port_alloc_num);
+
 /**
  * sas_port_add - add a SAS port to the device hierarchy
  *
@@ -658,6 +692,13 @@ void sas_port_delete(struct sas_port *port)
        }
        mutex_unlock(&port->phy_list_mutex);
 
+       if (port->is_backlink) {
+               struct device *parent = port->dev.parent;
+
+               sysfs_remove_link(&port->dev.kobj, parent->bus_id);
+               port->is_backlink = 0;
+       }
+
        transport_remove_device(dev);
        device_del(dev);
        transport_destroy_device(dev);
@@ -733,6 +774,19 @@ void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy)
 }
 EXPORT_SYMBOL(sas_port_delete_phy);
 
+void sas_port_mark_backlink(struct sas_port *port)
+{
+       struct device *parent = port->dev.parent->parent->parent;
+
+       if (port->is_backlink)
+               return;
+       port->is_backlink = 1;
+       sysfs_create_link(&port->dev.kobj, &parent->kobj,
+                         parent->bus_id);
+
+}
+EXPORT_SYMBOL(sas_port_mark_backlink);
+
 /*
  * SAS remote PHY attributes.
  */
@@ -1140,7 +1194,7 @@ int sas_rphy_add(struct sas_rphy *rphy)
 
        if (identify->device_type == SAS_END_DEVICE &&
            rphy->scsi_target_id != -1) {
-               scsi_scan_target(&rphy->dev, parent->port_identifier,
+               scsi_scan_target(&rphy->dev, 0,
                                rphy->scsi_target_id, ~0, 0);
        }
 
@@ -1242,15 +1296,13 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel,
 
        mutex_lock(&sas_host->lock);
        list_for_each_entry(rphy, &sas_host->rphy_list, list) {
-               struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
-
                if (rphy->identify.device_type != SAS_END_DEVICE ||
                    rphy->scsi_target_id == -1)
                        continue;
 
-               if ((channel == SCAN_WILD_CARD || channel == parent->port_identifier) &&
+               if ((channel == SCAN_WILD_CARD || channel == 0) &&
                    (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) {
-                       scsi_scan_target(&rphy->dev, parent->port_identifier,
+                       scsi_scan_target(&rphy->dev, 0,
                                         rphy->scsi_target_id, lun, 1);
                }
        }
index 3225d31449e1167e818e879f9e9a7cf3fddc9f7e..98bd3aab9739114f6b4dd1a538928856929fe7a5 100644 (file)
@@ -502,8 +502,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
                SCpnt->cmnd[4] = (unsigned char) this_count;
                SCpnt->cmnd[5] = 0;
        }
-       SCpnt->request_bufflen = SCpnt->bufflen =
-                       this_count * sdp->sector_size;
+       SCpnt->request_bufflen = this_count * sdp->sector_size;
 
        /*
         * We shouldn't disconnect in the middle of a sector, so with a dumb
index 3f312a84c6a7d585dc7d9f08859b35bc6daff9a8..2679ea8bff1a98365225ff22662c7a3990239321 100644 (file)
@@ -1002,7 +1002,7 @@ connect_loop:
                        }
 #endif
 
-                       buffer = (struct scatterlist *) SCint->buffer;
+                       buffer = (struct scatterlist *) SCint->request_buffer;
                        len = buffer->length;
                        data = page_address(buffer->page) + buffer->offset;
                } else {
index fd94408577e5ae3aec19b5e7fa3657d14e641e22..fae6e95a629884cdcffdb50058b522419115e722 100644 (file)
@@ -360,7 +360,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
                                "mismatch count %d, bytes %d\n",
                                size, SCpnt->request_bufflen);
                        if (SCpnt->request_bufflen > size)
-                               SCpnt->request_bufflen = SCpnt->bufflen = size;
+                               SCpnt->request_bufflen = size;
                }
        }
 
@@ -387,8 +387,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
 
        if (this_count > 0xffff) {
                this_count = 0xffff;
-               SCpnt->request_bufflen = SCpnt->bufflen =
-                               this_count * s_size;
+               SCpnt->request_bufflen = this_count * s_size;
        }
 
        SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
index 756ceb93ddc801f5249ca5f20f67f0ccea78f88d..7f669b6006777a05ee8e5509c25df824332887eb 100644 (file)
@@ -368,7 +368,7 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
                       SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
                       SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
                if (cmdstatp->have_sense)
-                        __scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
+                        __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
        } ) /* end DEB */
        if (!debugging) { /* Abnormal conditions for tape */
                if (!cmdstatp->have_sense)
@@ -384,9 +384,8 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
                         scode != VOLUME_OVERFLOW &&
                         SRpnt->cmd[0] != MODE_SENSE &&
                         SRpnt->cmd[0] != TEST_UNIT_READY) {
-                               printk(KERN_WARNING "%s: Error with sense data: ", name);
-                               __scsi_print_sense("st", SRpnt->sense,
-                                                  SCSI_SENSE_BUFFERSIZE);
+
+                       __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
                }
        }
 
index 2ebe0d66389969b3cc6504ee7deed2515e4e1fc0..2f8073b73bf30d1d5924498ec899c8984c0549ff 100644 (file)
@@ -517,7 +517,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd)
      */
 
     if (cmd->use_sg) {
-       cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
+       cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
        cmd->SCp.buffers_residual = cmd->use_sg - 1;
        cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer);
        cmd->SCp.this_residual = cmd->SCp.buffer->length;
index 1f328cae5c05c2faf303204f7acd16329e4ba23b..6b60536ac92b4bb11278eb2f8b9ae37519f649e4 100644 (file)
@@ -347,7 +347,7 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp)
 static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
 {
     int sz = sp->use_sg - 1;
-    struct scatterlist *sg = (struct scatterlist *)sp->buffer;
+    struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
                         
     while(sz >= 0) {
         dvma_unmap((char *)sg[sz].dma_address);
index 680f38ab60d8800c4458738b337a75156bba5d17..2083454db511d7daf260eb8ceace3f2580cc47bc 100644 (file)
@@ -373,7 +373,7 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd,
  */
 
        if (cmd->use_sg) {
-               cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
+               cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
                cmd->SCp.buffers_residual = cmd->use_sg - 1;
                cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
                    cmd->SCp.buffer->offset;
index 371f70d9aa92e993438a29a2981f182772f7478b..58e6444eebee7c67bd7916e41d9b712a70eb079a 100644 (file)
@@ -58,9 +58,7 @@ struct scsi_cmnd {
        int timeout_per_command;
 
        unsigned char cmd_len;
-       unsigned char old_cmd_len;
        enum dma_data_direction sc_data_direction;
-       enum dma_data_direction sc_old_data_direction;
 
        /* These elements define the operation we are about to perform */
 #define MAX_COMMAND_SIZE       16
@@ -71,18 +69,11 @@ struct scsi_cmnd {
        void *request_buffer;           /* Actual requested buffer */
 
        /* These elements define the operation we ultimately want to perform */
-       unsigned char data_cmnd[MAX_COMMAND_SIZE];
-       unsigned short old_use_sg;      /* We save  use_sg here when requesting
-                                        * sense info */
        unsigned short use_sg;  /* Number of pieces of scatter-gather */
        unsigned short sglist_len;      /* size of malloc'd scatter-gather list */
-       unsigned bufflen;       /* Size of data buffer */
-       void *buffer;           /* Data buffer */
 
        unsigned underflow;     /* Return error if less than
                                   this amount is transferred */
-       unsigned old_underflow; /* save underflow here when reusing the
-                                * command for error handling */
 
        unsigned transfersize;  /* How much we are guaranteed to
                                   transfer with each SCSI transfer
index e3c503cd175ea5b9e5b00bbbf7ab3e42c3a18429..6cc2314098cf72fa1823eae546c34f999a5aa91b 100644 (file)
@@ -106,6 +106,7 @@ struct sas_end_device {
 
 struct sas_expander_device {
        int    level;
+       int    next_port_id;
 
        #define SAS_EXPANDER_VENDOR_ID_LEN      8
        char   vendor_id[SAS_EXPANDER_VENDOR_ID_LEN+1];
@@ -127,8 +128,10 @@ struct sas_expander_device {
 struct sas_port {
        struct device           dev;
 
-       u8                      port_identifier;
+       int                     port_identifier;
        int                     num_phys;
+       /* port flags */
+       unsigned int            is_backlink:1;
 
        /* the other end of the link */
        struct sas_rphy         *rphy;
@@ -168,11 +171,13 @@ extern void sas_rphy_delete(struct sas_rphy *);
 extern int scsi_is_sas_rphy(const struct device *);
 
 struct sas_port *sas_port_alloc(struct device *, int);
+struct sas_port *sas_port_alloc_num(struct device *);
 int sas_port_add(struct sas_port *);
 void sas_port_free(struct sas_port *);
 void sas_port_delete(struct sas_port *);
 void sas_port_add_phy(struct sas_port *, struct sas_phy *);
 void sas_port_delete_phy(struct sas_port *, struct sas_phy *);
+void sas_port_mark_backlink(struct sas_port *);
 int scsi_is_sas_port(const struct device *);
 
 extern struct scsi_transport_template *