diff options
author | Eric Moore <eric.moore@lsi.com> | 2007-01-29 09:42:20 -0700 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-02-02 20:48:49 -0600 |
commit | 793955f549c710a1b0c18f823d5d710840747b15 (patch) | |
tree | ef85a09c1d90404a83f95b35d6fd717c421a4e5b | |
parent | 502c62f17aa7daa78d5da963305251b872885ff9 (diff) |
[SCSI] fusion - Greater than 255 target and lun support
Add support for greater than 255 target and luns.
Kill the hd->Target[] field, and change all references
of bus_id/target_id, to channel/id.
Signed-off-by: Eric Moore <Eric.Moore@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/message/fusion/Makefile | 2 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.c | 29 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 12 | ||||
-rw-r--r-- | drivers/message/fusion/mptctl.c | 159 | ||||
-rw-r--r-- | drivers/message/fusion/mptfc.c | 51 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.c | 73 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 301 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.h | 42 | ||||
-rw-r--r-- | drivers/message/fusion/mptspi.c | 188 |
9 files changed, 380 insertions, 477 deletions
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index 341691390e86..3217076b40f4 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile @@ -8,6 +8,7 @@ #EXTRA_CFLAGS += -DMPT_DEBUG_INIT #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL +#EXTRA_CFLAGS += -DMPT_DEBUG_TM # # driver/module specifics... @@ -22,7 +23,6 @@ # For mptscsih: #CFLAGS_mptscsih.o += -DMPT_DEBUG_DV #CFLAGS_mptscsih.o += -DMPT_DEBUG_NEGO -#CFLAGS_mptscsih.o += -DMPT_DEBUG_TM #CFLAGS_mptscsih.o += -DMPT_DEBUG_SCSI #CFLAGS_mptscsih.o += -DMPT_DEBUG_REPLY # diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index b3f28a03b6a9..a07f0f81f96b 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -82,6 +82,10 @@ static int mpt_msi_enable; module_param(mpt_msi_enable, int, 0); MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); +static int mpt_channel_mapping; +module_param(mpt_channel_mapping, int, 0); +MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)"); + #ifdef MFCNT static int mfcounter = 0; #define PRINT_MF_COUNT 20000 @@ -2505,6 +2509,7 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag) int ii; int req_sz; int reply_sz; + int max_id; /* IOC *must* NOT be in RESET state! */ if (ioc->last_state == MPI_IOC_STATE_RESET) { @@ -2552,6 +2557,21 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag) pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs); pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets); + max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID : + pfacts->MaxDevices; + ioc->devices_per_bus = (max_id > 255) ? 256 : max_id; + ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256; + + /* + * Place all the devices on channels + * + * (for debuging) + */ + if (mpt_channel_mapping) { + ioc->devices_per_bus = 1; + ioc->number_of_buses = (max_id > 255) ? 255 : max_id; + } + return 0; } @@ -2592,13 +2612,8 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n", ioc->name, ioc->upload_fw, ioc->facts.Flags)); - if(ioc->bus_type == SAS) - ioc_init.MaxDevices = ioc->facts.MaxDevices; - else if(ioc->bus_type == FC) - ioc_init.MaxDevices = MPT_MAX_FC_DEVICES; - else - ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES; - ioc_init.MaxBuses = MPT_MAX_BUS; + ioc_init.MaxDevices = (U8)ioc->devices_per_bus; + ioc_init.MaxBuses = (U8)ioc->number_of_buses; dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n", ioc->name, ioc->facts.MsgVersion)); if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) { diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index e316708f76bd..f82a817de81f 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -334,8 +334,8 @@ typedef struct _VirtTarget { struct scsi_target *starget; u8 tflags; u8 ioc_id; - u8 target_id; - u8 bus_id; + u8 id; + u8 channel; u8 minSyncFactor; /* 0xFF is async */ u8 maxOffset; /* 0 if async */ u8 maxWidth; /* 0 if narrow, 1 if wide */ @@ -344,13 +344,12 @@ typedef struct _VirtTarget { u8 type; /* byte 0 of Inquiry data */ u8 deleted; /* target in process of being removed */ u32 num_luns; - u32 luns[8]; /* Max LUNs is 256 */ } VirtTarget; typedef struct _VirtDevice { VirtTarget *vtarget; u8 configured_lun; - u32 lun; + int lun; } VirtDevice; /* @@ -412,7 +411,7 @@ typedef struct _MPT_IOCTL { u8 rsvd; u8 status; /* current command status */ u8 reset; /* 1 if bus reset allowed */ - u8 target; /* target for reset */ + u8 id; /* target for reset */ struct mutex ioctl_mutex; } MPT_IOCTL; @@ -528,6 +527,8 @@ typedef struct _MPT_ADAPTER u32 mem_phys; /* == f4020000 (mmap) */ u32 pio_mem_phys; /* Programmed IO (downloadboot) */ int mem_size; /* mmap memory size */ + int number_of_buses; + int devices_per_bus; int alloc_total; u32 last_state; int active; @@ -957,7 +958,6 @@ typedef struct _MPT_SCSI_HOST { int port; u32 pad0; struct scsi_cmnd **ScsiLookup; - VirtTarget **Targets; MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ struct timer_list timer; /* Pool of memory for holding SCpnts before doing diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 504632da4347..922d0c879f06 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -361,7 +361,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) ioctl->ioc->name, mf)); pScsiTm = (SCSITaskMgmt_t *) mf; - pScsiTm->TargetID = ioctl->target; + pScsiTm->TargetID = ioctl->id; pScsiTm->Bus = hd->port; /* 0 */ pScsiTm->ChainOffset = 0; pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; @@ -1159,15 +1159,12 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) struct mpt_ioctl_iocinfo *karg; MPT_ADAPTER *ioc; struct pci_dev *pdev; - struct Scsi_Host *sh; - MPT_SCSI_HOST *hd; int iocnum; - int numDevices = 0; - unsigned int max_id; - int ii; unsigned int port; int cim_rev; u8 revision; + struct scsi_device *sdev; + VirtDevice *vdev; dctlprintk((": mptctl_getiocinfo called.\n")); /* Add of PCI INFO results in unaligned access for @@ -1257,23 +1254,16 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) /* Get number of devices */ - if ((sh = ioc->sh) != NULL) { - /* sh->max_id = maximum target ID + 1 - */ - max_id = sh->max_id - 1; - hd = (MPT_SCSI_HOST *) sh->hostdata; - - /* Check all of the target structures and - * keep a counter. - */ - if (hd && hd->Targets) { - for (ii = 0; ii <= max_id; ii++) { - if (hd->Targets[ii]) - numDevices++; - } + karg->numDevices = 0; + if (ioc->sh) { + shost_for_each_device(sdev, ioc->sh) { + vdev = sdev->hostdata; + if (vdev->vtarget->tflags & + MPT_TARGET_FLAGS_RAID_COMPONENT) + continue; + karg->numDevices++; } } - karg->numDevices = numDevices; /* Set the BIOS and FW Version */ @@ -1319,21 +1309,16 @@ mptctl_gettargetinfo (unsigned long arg) struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg; struct mpt_ioctl_targetinfo karg; MPT_ADAPTER *ioc; - struct Scsi_Host *sh; - MPT_SCSI_HOST *hd; - VirtTarget *vdev; + VirtDevice *vdev; char *pmem; int *pdata; - IOCPage2_t *pIoc2; - IOCPage3_t *pIoc3; int iocnum; int numDevices = 0; - unsigned int max_id; - int id, jj, indexed_lun, lun_index; - u32 lun; + int lun; int maxWordsLeft; int numBytes; - u8 port, devType, bus_id; + u8 port; + struct scsi_device *sdev; dctlprintk(("mptctl_gettargetinfo called.\n")); if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) { @@ -1389,74 +1374,22 @@ mptctl_gettargetinfo (unsigned long arg) /* Get number of devices */ - if ((sh = ioc->sh) != NULL) { - - max_id = sh->max_id - 1; - hd = (MPT_SCSI_HOST *) sh->hostdata; - - /* Check all of the target structures. - * Save the Id and increment the counter, - * if ptr non-null. - * sh->max_id = maximum target ID + 1 - */ - if (hd && hd->Targets) { - mpt_findImVolumes(ioc); - pIoc2 = ioc->raid_data.pIocPg2; - for ( id = 0; id <= max_id; ) { - if ( pIoc2 && pIoc2->NumActiveVolumes ) { - if ( id == pIoc2->RaidVolume[0].VolumeID ) { - if (maxWordsLeft <= 0) { - printk(KERN_ERR "mptctl_gettargetinfo - " - "buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices); - goto data_space_full; - } - if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 ) - devType = 0x80; - else - devType = 0xC0; - bus_id = pIoc2->RaidVolume[0].VolumeBus; - numDevices++; - *pdata = ( (devType << 24) | (bus_id << 8) | id ); - dctlprintk((KERN_ERR "mptctl_gettargetinfo - " - "volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata)); - pdata++; - --maxWordsLeft; - goto next_id; - } else { - pIoc3 = ioc->raid_data.pIocPg3; - for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) { - if ( pIoc3->PhysDisk[jj].PhysDiskID == id ) - goto next_id; - } - } - } - if ( (vdev = hd->Targets[id]) ) { - for (jj = 0; jj <= MPT_LAST_LUN; jj++) { - lun_index = (jj >> 5); - indexed_lun = (jj % 32); - lun = (1 << indexed_lun); - if (vdev->luns[lun_index] & lun) { - if (maxWordsLeft <= 0) { - printk(KERN_ERR "mptctl_gettargetinfo - " - "buffer is full but more targets are available on ioc %d numDevices=%d\n", iocnum, numDevices); - goto data_space_full; - } - bus_id = vdev->bus_id; - numDevices++; - *pdata = ( (jj << 16) | (bus_id << 8) | id ); - dctlprintk((KERN_ERR "mptctl_gettargetinfo - " - "target ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata)); - pdata++; - --maxWordsLeft; - } - } - } -next_id: - id++; - } + if (ioc->sh){ + shost_for_each_device(sdev, ioc->sh) { + if (!maxWordsLeft) + continue; + vdev = sdev->hostdata; + if (vdev->vtarget->tflags & + MPT_TARGET_FLAGS_RAID_COMPONENT) + continue; + lun = (vdev->vtarget->raidVolume) ? 0x80 : vdev->lun; + *pdata = (((u8)lun << 16) + (vdev->vtarget->channel << 8) + + (vdev->vtarget->id )); + pdata++; + numDevices++; + --maxWordsLeft; } } -data_space_full: karg.numDevices = numDevices; /* Copy part of the data from kernel memory to user memory @@ -1821,6 +1754,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) int msgContext; u16 req_idx; ulong timeout; + struct scsi_device *sdev; dctlprintk(("mptctl_do_mpt_command called.\n")); bufIn.kptr = bufOut.kptr = NULL; @@ -1902,14 +1836,13 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) case MPI_FUNCTION_SCSI_IO_REQUEST: if (ioc->sh) { SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; - VirtTarget *pTarget = NULL; - MPT_SCSI_HOST *hd = NULL; int qtag = MPI_SCSIIO_CONTROL_UNTAGGED; int scsidir = 0; - int target = (int) pScsiReq->TargetID; int dataSize; + u32 id; - if ((target < 0) || (target >= ioc->sh->max_id)) { + id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus; + if (pScsiReq->TargetID > id) { printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " "Target ID out of bounds. \n", __FILE__, __LINE__); @@ -1917,6 +1850,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) goto done_free_mem; } + if (pScsiReq->Bus >= ioc->number_of_buses) { + printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + "Target Bus out of bounds. \n", + __FILE__, __LINE__); + rc = -ENODEV; + goto done_free_mem; + } + pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; pScsiReq->MsgFlags |= mpt_msg_flags(); @@ -1936,13 +1877,15 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) cpu_to_le32(ioc->sense_buf_low_dma + (req_idx * MPT_SENSE_BUFFER_ALLOC)); - if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) { - if (hd->Targets) - pTarget = hd->Targets[target]; - } + shost_for_each_device(sdev, ioc->sh) { + struct scsi_target *starget = scsi_target(sdev); + VirtTarget *vtarget = starget->hostdata; - if (pTarget &&(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) - qtag = MPI_SCSIIO_CONTROL_SIMPLEQ; + if ((pScsiReq->TargetID == vtarget->id) && + (pScsiReq->Bus == vtarget->channel) && + (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) + qtag = MPI_SCSIIO_CONTROL_SIMPLEQ; + } /* Have the IOCTL driver set the direction based * on the dataOutSize (ordering issue with Sparc). @@ -1959,7 +1902,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) pScsiReq->DataLength = cpu_to_le32(dataSize); ioc->ioctl->reset = MPTCTL_RESET_OK; - ioc->ioctl->target = target; + ioc->ioctl->id = pScsiReq->TargetID; } else { printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " @@ -2038,7 +1981,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) pScsiReq->DataLength = cpu_to_le32(dataSize); ioc->ioctl->reset = MPTCTL_RESET_OK; - ioc->ioctl->target = pScsiReq->TargetID; + ioc->ioctl->id = pScsiReq->TargetID; } else { printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " "SCSI driver is not loaded. \n", diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index c819c23b55b1..cd8fa39ec270 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -86,6 +86,12 @@ MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the " " return following a device loss event." " Default=60."); +/* scsi-mid layer global parmeter is max_report_luns, which is 511 */ +#define MPTFC_MAX_LUN (16895) +static int max_lun = MPTFC_MAX_LUN; +module_param(max_lun, int, 0); +MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); + static int mptfcDoneCtx = -1; static int mptfcTaskCtx = -1; static int mptfcInternalCtx = -1; /* Used only for internal commands */ @@ -292,10 +298,9 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port, U32 port_id = 0xffffff; int num_targ = 0; int max_bus = ioc->facts.MaxBuses; - int max_targ = ioc->facts.MaxDevices; + int max_targ; - if (max_bus == 0 || max_targ == 0) - goto out; + max_targ = (ioc->facts.MaxDevices == 0) ? 256 : ioc->facts.MaxDevices; data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ; p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL); @@ -467,8 +472,8 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) if (ri->starget) { vtarget = ri->starget->hostdata; if (vtarget) { - vtarget->target_id = pg0->CurrentTargetID; - vtarget->bus_id = pg0->CurrentBus; + vtarget->id = pg0->CurrentTargetID; + vtarget->channel = pg0->CurrentBus; } } *((struct mptfc_rport_info **)rport->dd_data) = ri; @@ -540,8 +545,8 @@ mptfc_target_alloc(struct scsi_target *starget) if (rport) { ri = *((struct mptfc_rport_info **)rport->dd_data); if (ri) { /* better be! */ - vtarget->target_id = ri->pg0.CurrentTargetID; - vtarget->bus_id = ri->pg0.CurrentBus; + vtarget->id = ri->pg0.CurrentTargetID; + vtarget->channel = ri->pg0.CurrentBus; ri->starget = starget; rc = 0; } @@ -592,7 +597,6 @@ 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; - hd->Targets[sdev->id] = vtarget; } vdev->vtarget = vtarget; @@ -630,16 +634,17 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) struct mptfc_rport_info *ri; struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); int err; + VirtDevice *vdev = SCpnt->device->hostdata; - err = fc_remote_port_chkready(rport); - if (unlikely(err)) { - SCpnt->result = err; + if (!vdev || !vdev->vtarget) { + SCpnt->result = DID_NO_CONNECT << 16; done(SCpnt); return 0; } - if (!SCpnt->device->hostdata) { /* vdev */ - SCpnt->result = DID_NO_CONNECT << 16; + err = fc_remote_port_chkready(rport); + if (unlikely(err)) { + SCpnt->result = err; done(SCpnt); return 0; } @@ -1143,7 +1148,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) printk(MYIOC_s_WARN_FMT "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", ioc->name, ioc); - return -ENODEV; + return 0; } sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); @@ -1173,10 +1178,9 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* set 16 byte cdb's */ sh->max_cmd_len = 16; - sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; + sh->max_id = ioc->pfacts->MaxDevices; + sh->max_lun = max_lun; - sh->max_lun = MPT_LAST_LUN + 1; - sh->max_channel = 0; sh->this_id = ioc->pfacts[0].PortSCSIID; /* Required entry. @@ -1230,19 +1234,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", ioc->name, hd->ScsiLookup)); - /* Allocate memory for the device structures. - * A non-Null pointer at an offset - * indicates a device exists. - * max_id = 1 + maximum id (hosts.h) - */ - hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC); - if (!hd->Targets) { - error = -ENOMEM; - goto out_mptfc_probe; - } - - dprintk((KERN_INFO " vdev @ %p\n", hd->Targets)); - /* Clear the TM flags */ hd->tmPending = 0; diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 09e9a9d96410..f7c5e0d97890 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -83,6 +83,12 @@ MODULE_PARM_DESC(mpt_pt_clear, " Clear persistency table: enable=1 " "(default=MPTSCSIH_PT_CLEAR=0)"); +/* scsi-mid layer global parmeter is max_report_luns, which is 511 */ +#define MPTSAS_MAX_LUN (16895) +static int max_lun = MPTSAS_MAX_LUN; +module_param(max_lun, int, 0); +MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); + static int mptsasDoneCtx = -1; static int mptsasTaskCtx = -1; static int mptsasInternalCtx = -1; /* Used only for internal commands */ @@ -568,12 +574,12 @@ mptsas_target_reset(MPT_ADAPTER *ioc, VirtTarget * vtarget) if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, - vtarget->bus_id, vtarget->target_id, 0, 0, 5) < 0) { + vtarget->channel, vtarget->id, 0, 0, 5) < 0) { hd->tmPending = 0; hd->tmState = TM_STATE_NONE; printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt id=%d TARGET_RESET\n", - ioc->name, vtarget->target_id); + ioc->name, vtarget->id); } } @@ -661,8 +667,7 @@ mptsas_target_alloc(struct scsi_target *starget) struct Scsi_Host *host = dev_to_shost(&starget->dev); MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; VirtTarget *vtarget; - u32 target_id; - u32 channel; + u8 id, channel; struct sas_rphy *rphy; struct mptsas_portinfo *p; int i; @@ -673,15 +678,19 @@ mptsas_target_alloc(struct scsi_target *starget) vtarget->starget = starget; vtarget->ioc_id = hd->ioc->id; - vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; - - target_id = starget->id; + vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; + id = starget->id; channel = 0; - hd->Targets[target_id] = vtarget; - - if (starget->channel == MPTSAS_RAID_CHANNEL) + /* + * RAID volumes placed beyond the last expected port. + */ + if (starget->channel == MPTSAS_RAID_CHANNEL) { + for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) + if (id == hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID) + channel = hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus; goto out; + } rphy = dev_to_rphy(starget->dev.parent); mutex_lock(&hd->ioc->sas_topology_mutex); @@ -690,16 +699,16 @@ mptsas_target_alloc(struct scsi_target *starget) if (p->phy_info[i].attached.sas_address != rphy->identify.sas_address) continue; - target_id = p->phy_info[i].attached.id; + id = p->phy_info[i].attached.id; channel = p->phy_info[i].attached.channel; mptsas_set_starget(&p->phy_info[i], starget); /* * Exposing hidden raid components */ - if (mptscsih_is_phys_disk(hd->ioc, target_id)) { - target_id = mptscsih_raid_id_to_num(hd, - target_id); + if (mptscsih_is_phys_disk(hd->ioc, channel, id)) { + id = mptscsih_raid_id_to_num(hd->ioc, + channel, id); vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; } @@ -713,8 +722,8 @@ mptsas_target_alloc(struct scsi_target *starget) return -ENXIO; out: - vtarget->target_id = target_id; - vtarget->bus_id = channel; + vtarget->id = id; + vtarget->channel = channel; starget->hostdata = vtarget; return 0; } @@ -786,7 +795,8 @@ mptsas_slave_alloc(struct scsi_device *sdev) * Exposing hidden raid components */ if (mptscsih_is_phys_disk(hd->ioc, - p->phy_info[i].attached.id)) + p->phy_info[i].attached.channel, + p->phy_info[i].attached.id)) sdev->no_uld_attach = 1; mutex_unlock(&hd->ioc->sas_topology_mutex); goto out; @@ -808,13 +818,14 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { VirtDevice *vdev = SCpnt->device->hostdata; -// scsi_print_command(SCpnt); - if (vdev->vtarget->deleted) { + if (!vdev || !vdev->vtarget || vdev->vtarget->deleted) { SCpnt->result = DID_NO_CONNECT << 16; done(SCpnt); return 0; } +// scsi_print_command(SCpnt); + return mptscsih_qcmd(SCpnt,done); } @@ -1976,7 +1987,7 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc) goto out; if (!ioc->raid_data.pIocPg2->NumActiveVolumes) goto out; - for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { + for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0); } @@ -2160,7 +2171,7 @@ mptsas_hotplug_work(struct work_struct *work) * Handling RAID components */ if (ev->phys_disk_num_valid) { - vtarget->target_id = ev->phys_disk_num; + vtarget->id = ev->phys_disk_num; vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; mptsas_reprobe_target(starget, 1); break; @@ -2233,7 +2244,7 @@ mptsas_hotplug_work(struct work_struct *work) */ if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; - vtarget->target_id = ev->id; + vtarget->id = ev->id; mptsas_reprobe_target(starget, 0); } break; @@ -2611,12 +2622,11 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* set 16 byte cdb's */ sh->max_cmd_len = 16; - sh->max_id = ioc->pfacts->MaxDevices + 1; + sh->max_id = ioc->pfacts[0].PortSCSIID; + sh->max_lun = max_lun; sh->transportt = mptsas_transport_template; - sh->max_lun = MPT_LAST_LUN + 1; - sh->max_channel = 0; sh->this_id = ioc->pfacts[0].PortSCSIID; /* Required entry. @@ -2676,19 +2686,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", ioc->name, hd->ScsiLookup)); - /* Allocate memory for the device structures. - * A non-Null pointer at an offset - * indicates a device exists. - * max_id = 1 + maximum id (hosts.h) - */ - hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC); - if (!hd->Targets) { - error = -ENOMEM; - goto out_mptsas_probe; - } - - dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets)); - /* Clear the TM flags */ hd->tmPending = 0; diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index f0cca3ea93b2..ce58431bee8e 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -79,43 +79,6 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(my_VERSION); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - -typedef struct _BIG_SENSE_BUF { - u8 data[MPT_SENSE_BUFFER_ALLOC]; -} BIG_SENSE_BUF; - -#define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */ -#define MPT_SCANDV_DID_RESET (0x00000001) -#define MPT_SCANDV_SENSE (0x00000002) -#define MPT_SCANDV_SOME_ERROR (0x00000004) -#define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008) -#define MPT_SCANDV_ISSUE_SENSE (0x00000010) -#define MPT_SCANDV_FALLBACK (0x00000020) - -#define MPT_SCANDV_MAX_RETRIES (10) - -#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */ -#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */ -#define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */ -#define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */ -#define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */ -#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */ -#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */ - -typedef struct _internal_cmd { - char *data; /* data pointer */ - dma_addr_t data_dma; /* data dma address */ - int size; /* transfer size */ - u8 cmd; /* SCSI Op Code */ - u8 bus; /* bus number */ - u8 id; /* SCSI ID (virtual) */ - u8 lun; - u8 flags; /* Bit Field - See above */ - u8 physDiskNum; /* Phys disk number, -1 else */ - u8 rsvd2; - u8 rsvd; -} INTERNAL_CMD; - /* * Other private/forward protos... */ @@ -131,14 +94,14 @@ static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); 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); +static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout); int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); -static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); +static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int channel, int id); int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); @@ -517,13 +480,13 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget, SEPMsg = (SEPRequest_t *)mf; SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; - SEPMsg->Bus = vtarget->bus_id; - SEPMsg->TargetID = vtarget->target_id; + SEPMsg->Bus = vtarget->channel; + SEPMsg->TargetID = vtarget->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)); + "Sending SEP cmd=%x channel=%d id=%d\n", + ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID)); mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); } @@ -955,9 +918,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) int ii; int max = hd->ioc->req_depth; struct scsi_cmnd *sc; + struct scsi_lun lun; - dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", - vdevice->vtarget->target_id, vdevice->lun, max)); + dsprintk((KERN_INFO MYNAM ": search_running channel %d id %d lun %d max %d\n", + vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max)); for (ii=0; ii < max; ii++) { if ((sc = hd->ScsiLookup[ii]) != NULL) { @@ -965,10 +929,14 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) 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))) + int_to_scsilun(vdevice->lun, &lun); + if ((mf->Bus != vdevice->vtarget->channel) || + (mf->TargetID != vdevice->vtarget->id) || + memcmp(lun.scsi_lun, mf->LUN, 8)) continue; + dsprintk(( "search_running: found (sc=%p, mf = %p) " + "channel %d id %d, lun %d \n", hd->ScsiLookup[ii], + mf, mf->Bus, mf->TargetID, vdevice->lun)); /* Cleanup */ @@ -1065,12 +1033,6 @@ mptscsih_remove(struct pci_dev *pdev) hd->ScsiLookup = NULL; } - /* - * Free pointer array. - */ - kfree(hd->Targets); - hd->Targets = NULL; - dprintk((MYIOC_s_INFO_FMT "Free'd ScsiLookup (%d) memory\n", hd->ioc->name, sz1)); @@ -1317,14 +1279,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) return SCSI_MLQUEUE_HOST_BUSY; } - if ((hd->ioc->bus_type == SPI) && - vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT && - mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) { - SCpnt->result = DID_NO_CONNECT << 16; - done(SCpnt); - return 0; - } - /* * Put together a MPT SCSI request... */ @@ -1368,8 +1322,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) /* Use the above information to set up the message frame */ - pScsiReq->TargetID = (u8) vdev->vtarget->target_id; - pScsiReq->Bus = vdev->vtarget->bus_id; + pScsiReq->TargetID = (u8) vdev->vtarget->id; + pScsiReq->Bus = vdev->vtarget->channel; pScsiReq->ChainOffset = 0; if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; @@ -1379,14 +1333,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; pScsiReq->Reserved = 0; pScsiReq->MsgFlags = mpt_msg_flags(); - pScsiReq->LUN[0] = 0; - pScsiReq->LUN[1] = lun; - pScsiReq->LUN[2] = 0; - pScsiReq->LUN[3] = 0; - pScsiReq->LUN[4] = 0; - pScsiReq->LUN[5] = 0; - pScsiReq->LUN[6] = 0; - pScsiReq->LUN[7] = 0; + int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN); pScsiReq->Control = cpu_to_le32(scsictl); /* @@ -1498,7 +1445,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) * * @ioc: Pointer to MPT_ADAPTER structure * @type: Task Management type - * @target: Logical Target ID for reset (if appropriate) + * @id: Logical Target ID for reset (if appropriate) * @lun: Logical Unit for reset (if appropriate) * @ctx2abort: Context for the task to be aborted (if appropriate) * @@ -1510,7 +1457,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) * Returns 0 for SUCCESS or -1 if FAILED. */ int -mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) +mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) { MPT_ADAPTER *ioc; int rc = -1; @@ -1590,7 +1537,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in */ if (hd->hard_resets < -1) hd->hard_resets++; - rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout); + rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun, ctx2abort, timeout); if (rc) { printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name); } else { @@ -1624,7 +1571,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in * mptscsih_IssueTaskMgmt - Generic send Task Management function. * @hd: Pointer to MPT_SCSI_HOST structure * @type: Task Management type - * @target: Logical Target ID for reset (if appropriate) + * @id: Logical Target ID for reset (if appropriate) * @lun: Logical Unit for reset (if appropriate) * @ctx2abort: Context for the task to be aborted (if appropriate) * @@ -1637,7 +1584,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in * else other non-zero value returned. */ static int -mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) +mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) { MPT_FRAME_HDR *mf; SCSITaskMgmt_t *pScsiTm; @@ -1657,7 +1604,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun /* Format the Request */ pScsiTm = (SCSITaskMgmt_t *) mf; - pScsiTm->TargetID = target; + pScsiTm->TargetID = id; pScsiTm->Bus = channel; pScsiTm->ChainOffset = 0; pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; @@ -1668,10 +1615,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0; - for (ii= 0; ii < 8; ii++) { - pScsiTm->LUN[ii] = 0; - } - pScsiTm->LUN[1] = lun; + int_to_scsilun(lun, |