Skip to content

Commit

Permalink
[SCSI] fusion - Greater than 255 target and lun support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Eric Moore authored and James Bottomley committed Feb 3, 2007
1 parent 502c62f commit 793955f
Show file tree
Hide file tree
Showing 9 changed files with 380 additions and 477 deletions.
2 changes: 1 addition & 1 deletion drivers/message/fusion/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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...
Expand All @@ -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
#
Expand Down
29 changes: 22 additions & 7 deletions drivers/message/fusion/mptbase.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand Down
12 changes: 6 additions & 6 deletions drivers/message/fusion/mptbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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;

/*
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
159 changes: 51 additions & 108 deletions drivers/message/fusion/mptctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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))) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1902,21 +1836,28 @@ 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__);
rc = -ENODEV;
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();

Expand All @@ -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).
Expand All @@ -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 - "
Expand Down Expand Up @@ -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",
Expand Down
Loading

0 comments on commit 793955f

Please sign in to comment.