Commit c7c82987 authored by Moore, Eric Dean's avatar Moore, Eric Dean Committed by James Bottomley

[SCSI] mptfusion - mapping fixs required support for transport layers.

This utilizes the hostdata area that is hung off of scsi_target and
scsi_device for saving unique firmware mapping. This will be required
for supporting new Fibre and SPI transport support.

This also fixs problems in error handling error code for SAS
controllers, in which the incorrect mapping was passed to the
firmware.
Signed-off-by: default avatarEric Moore <Eric.Moore@lsil.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent f2ea8671
...@@ -321,7 +321,7 @@ typedef struct _SYSIF_REGS ...@@ -321,7 +321,7 @@ typedef struct _SYSIF_REGS
* Dynamic Multi-Pathing specific stuff... * Dynamic Multi-Pathing specific stuff...
*/ */
/* VirtDevice negoFlags field */ /* VirtTarget negoFlags field */
#define MPT_TARGET_NO_NEGO_WIDE 0x01 #define MPT_TARGET_NO_NEGO_WIDE 0x01
#define MPT_TARGET_NO_NEGO_SYNC 0x02 #define MPT_TARGET_NO_NEGO_SYNC 0x02
#define MPT_TARGET_NO_NEGO_QAS 0x04 #define MPT_TARGET_NO_NEGO_QAS 0x04
...@@ -330,8 +330,7 @@ typedef struct _SYSIF_REGS ...@@ -330,8 +330,7 @@ typedef struct _SYSIF_REGS
/* /*
* VirtDevice - FC LUN device or SCSI target device * VirtDevice - FC LUN device or SCSI target device
*/ */
typedef struct _VirtDevice { typedef struct _VirtTarget {
struct scsi_device *device;
u8 tflags; u8 tflags;
u8 ioc_id; u8 ioc_id;
u8 target_id; u8 target_id;
...@@ -342,21 +341,18 @@ typedef struct _VirtDevice { ...@@ -342,21 +341,18 @@ typedef struct _VirtDevice {
u8 negoFlags; /* bit field, see above */ u8 negoFlags; /* bit field, see above */
u8 raidVolume; /* set, if RAID Volume */ u8 raidVolume; /* set, if RAID Volume */
u8 type; /* byte 0 of Inquiry data */ u8 type; /* byte 0 of Inquiry data */
u8 cflags; /* controller flags */
u8 rsvd1raid;
u16 fc_phys_lun;
u16 fc_xlat_lun;
u32 num_luns; u32 num_luns;
u32 luns[8]; /* Max LUNs is 256 */ u32 luns[8]; /* Max LUNs is 256 */
u8 pad[4];
u8 inq_data[8]; u8 inq_data[8];
/* IEEE Registered Extended Identifier } VirtTarget;
obtained via INQUIRY VPD page 0x83 */
/* NOTE: Do not separate uniq_prepad and uniq_data typedef struct _VirtDevice {
as they are treateed as a single entity in the code */ VirtTarget *vtarget;
u8 uniq_prepad[8]; u8 ioc_id;
u8 uniq_data[20]; u8 bus_id;
u8 pad2[4]; u8 target_id;
u8 configured_lun;
u32 lun;
} VirtDevice; } VirtDevice;
/* /*
...@@ -912,7 +908,7 @@ typedef struct _MPT_SCSI_HOST { ...@@ -912,7 +908,7 @@ typedef struct _MPT_SCSI_HOST {
int port; int port;
u32 pad0; u32 pad0;
struct scsi_cmnd **ScsiLookup; struct scsi_cmnd **ScsiLookup;
VirtDevice **Targets; VirtTarget **Targets;
MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ MPT_LOCAL_REPLY *pLocal; /* used for internal commands */
struct timer_list timer; struct timer_list timer;
/* Pool of memory for holding SCpnts before doing /* Pool of memory for holding SCpnts before doing
......
...@@ -1245,7 +1245,7 @@ mptctl_gettargetinfo (unsigned long arg) ...@@ -1245,7 +1245,7 @@ mptctl_gettargetinfo (unsigned long arg)
MPT_ADAPTER *ioc; MPT_ADAPTER *ioc;
struct Scsi_Host *sh; struct Scsi_Host *sh;
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
VirtDevice *vdev; VirtTarget *vdev;
char *pmem; char *pmem;
int *pdata; int *pdata;
IOCPage2_t *pIoc2; IOCPage2_t *pIoc2;
...@@ -1822,7 +1822,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ...@@ -1822,7 +1822,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
case MPI_FUNCTION_SCSI_IO_REQUEST: case MPI_FUNCTION_SCSI_IO_REQUEST:
if (ioc->sh) { if (ioc->sh) {
SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
VirtDevice *pTarget = NULL; VirtTarget *pTarget = NULL;
MPT_SCSI_HOST *hd = NULL; MPT_SCSI_HOST *hd = NULL;
int qtag = MPI_SCSIIO_CONTROL_UNTAGGED; int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
int scsidir = 0; int scsidir = 0;
......
...@@ -90,8 +90,10 @@ static struct scsi_host_template mptfc_driver_template = { ...@@ -90,8 +90,10 @@ static struct scsi_host_template mptfc_driver_template = {
.name = "MPT FC Host", .name = "MPT FC Host",
.info = mptscsih_info, .info = mptscsih_info,
.queuecommand = mptscsih_qcmd, .queuecommand = mptscsih_qcmd,
.target_alloc = mptscsih_target_alloc,
.slave_alloc = mptscsih_slave_alloc, .slave_alloc = mptscsih_slave_alloc,
.slave_configure = mptscsih_slave_configure, .slave_configure = mptscsih_slave_configure,
.target_destroy = mptscsih_target_destroy,
.slave_destroy = mptscsih_slave_destroy, .slave_destroy = mptscsih_slave_destroy,
.change_queue_depth = mptscsih_change_queue_depth, .change_queue_depth = mptscsih_change_queue_depth,
.eh_abort_handler = mptscsih_abort, .eh_abort_handler = mptscsih_abort,
...@@ -292,10 +294,10 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -292,10 +294,10 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
} }
memset(mem, 0, sz); memset(mem, 0, sz);
hd->Targets = (VirtDevice **) mem; hd->Targets = (VirtTarget **) mem;
dprintk((KERN_INFO dprintk((KERN_INFO
" Targets @ %p, sz=%d\n", hd->Targets, sz)); " vdev @ %p, sz=%d\n", hd->Targets, sz));
/* Clear the TM flags /* Clear the TM flags
*/ */
......
...@@ -228,31 +228,35 @@ static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1) ...@@ -228,31 +228,35 @@ static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
* implement ->target_alloc. * implement ->target_alloc.
*/ */
static int static int
mptsas_slave_alloc(struct scsi_device *device) mptsas_slave_alloc(struct scsi_device *sdev)
{ {
struct Scsi_Host *host = device->host; struct Scsi_Host *host = sdev->host;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
struct sas_rphy *rphy; struct sas_rphy *rphy;
struct mptsas_portinfo *p; struct mptsas_portinfo *p;
VirtTarget *vtarget;
VirtDevice *vdev; VirtDevice *vdev;
uint target = device->id; struct scsi_target *starget;
int i; int i;
if ((vdev = hd->Targets[target]) != NULL)
goto out;
vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdev) { if (!vdev) {
printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
hd->ioc->name, sizeof(VirtDevice)); hd->ioc->name, sizeof(VirtDevice));
return -ENOMEM; return -ENOMEM;
} }
memset(vdev, 0, sizeof(VirtDevice)); memset(vdev, 0, sizeof(VirtDevice));
vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
vdev->ioc_id = hd->ioc->id; vdev->ioc_id = hd->ioc->id;
sdev->hostdata = vdev;
starget = scsi_target(sdev);
vtarget = starget->hostdata;
vdev->vtarget = vtarget;
if (vtarget->num_luns == 0) {
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
hd->Targets[sdev->id] = vtarget;
}
rphy = dev_to_rphy(device->sdev_target->dev.parent); rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
list_for_each_entry(p, &hd->ioc->sas_topology, list) { list_for_each_entry(p, &hd->ioc->sas_topology, list) {
for (i = 0; i < p->num_phys; i++) { for (i = 0; i < p->num_phys; i++) {
if (p->phy_info[i].attached.sas_address == if (p->phy_info[i].attached.sas_address ==
...@@ -260,7 +264,7 @@ mptsas_slave_alloc(struct scsi_device *device) ...@@ -260,7 +264,7 @@ mptsas_slave_alloc(struct scsi_device *device)
vdev->target_id = vdev->target_id =
p->phy_info[i].attached.target; p->phy_info[i].attached.target;
vdev->bus_id = p->phy_info[i].attached.bus; vdev->bus_id = p->phy_info[i].attached.bus;
hd->Targets[device->id] = vdev; vdev->lun = sdev->lun;
goto out; goto out;
} }
} }
...@@ -271,8 +275,10 @@ mptsas_slave_alloc(struct scsi_device *device) ...@@ -271,8 +275,10 @@ mptsas_slave_alloc(struct scsi_device *device)
return -ENODEV; return -ENODEV;
out: out:
vdev->num_luns++; vtarget->ioc_id = vdev->ioc_id;
device->hostdata = vdev; vtarget->target_id = vdev->target_id;
vtarget->bus_id = vdev->bus_id;
vtarget->num_luns++;
return 0; return 0;
} }
...@@ -283,8 +289,10 @@ static struct scsi_host_template mptsas_driver_template = { ...@@ -283,8 +289,10 @@ static struct scsi_host_template mptsas_driver_template = {
.name = "MPT SPI Host", .name = "MPT SPI Host",
.info = mptscsih_info, .info = mptscsih_info,
.queuecommand = mptscsih_qcmd, .queuecommand = mptscsih_qcmd,
.target_alloc = mptscsih_target_alloc,
.slave_alloc = mptsas_slave_alloc, .slave_alloc = mptsas_slave_alloc,
.slave_configure = mptscsih_slave_configure, .slave_configure = mptscsih_slave_configure,
.target_destroy = mptscsih_target_destroy,
.slave_destroy = mptscsih_slave_destroy, .slave_destroy = mptscsih_slave_destroy,
.change_queue_depth = mptscsih_change_queue_depth, .change_queue_depth = mptscsih_change_queue_depth,
.eh_abort_handler = mptscsih_abort, .eh_abort_handler = mptscsih_abort,
...@@ -987,7 +995,6 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index) ...@@ -987,7 +995,6 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
goto out_free_port_info; goto out_free_port_info;
list_add_tail(&port_info->list, &ioc->sas_topology); list_add_tail(&port_info->list, &ioc->sas_topology);
for (i = 0; i < port_info->num_phys; i++) { for (i = 0; i < port_info->num_phys; i++) {
mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER << (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
...@@ -1263,10 +1270,10 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1263,10 +1270,10 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
} }
memset(mem, 0, sz); memset(mem, 0, sz);
hd->Targets = (VirtDevice **) mem; hd->Targets = (VirtTarget **) mem;
dprintk((KERN_INFO dprintk((KERN_INFO
" Targets @ %p, sz=%d\n", hd->Targets, sz)); " vtarget @ %p, sz=%d\n", hd->Targets, sz));
/* Clear the TM flags /* Clear the TM flags
*/ */
......
...@@ -150,15 +150,16 @@ static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 tar ...@@ -150,15 +150,16 @@ static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 tar
int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen); static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen);
static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56); static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56);
static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags); static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id); static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags); static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 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 int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget);
static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
static struct work_struct mptscsih_persistTask; static struct work_struct mptscsih_persistTask;
...@@ -171,7 +172,7 @@ static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); ...@@ -171,7 +172,7 @@ static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
static void mptscsih_fillbuf(char *buffer, int size, int index, int width); static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id); static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq); static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
#endif #endif
void mptscsih_remove(struct pci_dev *); void mptscsih_remove(struct pci_dev *);
...@@ -627,7 +628,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -627,7 +628,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n" dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
"IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n" "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
"resid=%d bufflen=%d xfer_cnt=%d\n", "resid=%d bufflen=%d xfer_cnt=%d\n",
ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1], ioc->id, sc->device->id, sc->device->lun,
status, scsi_state, scsi_status, sc->resid, status, scsi_state, scsi_status, sc->resid,
sc->request_bufflen, xfer_cnt)); sc->request_bufflen, xfer_cnt));
...@@ -641,7 +642,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -641,7 +642,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
pScsiReply->ResponseInfo) { pScsiReply->ResponseInfo) {
printk(KERN_NOTICE "ha=%d id=%d lun=%d: " printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
"FCP_ResponseInfo=%08xh\n", "FCP_ResponseInfo=%08xh\n",
ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1], ioc->id, sc->device->id, sc->device->lun,
le32_to_cpu(pScsiReply->ResponseInfo)); le32_to_cpu(pScsiReply->ResponseInfo));
} }
...@@ -678,7 +679,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -678,7 +679,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
/* GEM Workaround. */ /* GEM Workaround. */
if (ioc->bus_type == SPI) if (ioc->bus_type == SPI)
mptscsih_no_negotiate(hd, sc->device->id); mptscsih_no_negotiate(hd, sc);
break; break;
case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
...@@ -893,15 +894,14 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) ...@@ -893,15 +894,14 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
* Do NOT access the referenced scsi_cmnd structure or * Do NOT access the referenced scsi_cmnd structure or
* members. Will cause either a paging or NULL ptr error. * members. Will cause either a paging or NULL ptr error.
* @hd: Pointer to a SCSI HOST structure * @hd: Pointer to a SCSI HOST structure
* @target: target id * @vdevice: per device private data
* @lun: lun
* *
* Returns: None. * Returns: None.
* *
* Called from slave_destroy. * Called from slave_destroy.
*/ */
static void static void
mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
{ {
SCSIIORequest_t *mf = NULL; SCSIIORequest_t *mf = NULL;
int ii; int ii;
...@@ -909,7 +909,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) ...@@ -909,7 +909,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
struct scsi_cmnd *sc; struct scsi_cmnd *sc;
dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
target, lun, max)); vdevice->target_id, vdevice->lun, max));
for (ii=0; ii < max; ii++) { for (ii=0; ii < max; ii++) {
if ((sc = hd->ScsiLookup[ii]) != NULL) { if ((sc = hd->ScsiLookup[ii]) != NULL) {
...@@ -919,7 +919,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) ...@@ -919,7 +919,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun))) if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
continue; continue;
/* Cleanup /* Cleanup
...@@ -1077,11 +1077,6 @@ mptscsih_shutdown(struct pci_dev *pdev) ...@@ -1077,11 +1077,6 @@ mptscsih_shutdown(struct pci_dev *pdev)
hd = (MPT_SCSI_HOST *)host->hostdata; hd = (MPT_SCSI_HOST *)host->hostdata;
/* Flush the cache of this adapter
*/
if(hd != NULL)
mptscsih_synchronize_cache(hd, 0);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -1288,7 +1283,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) ...@@ -1288,7 +1283,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
SCSIIORequest_t *pScsiReq; SCSIIORequest_t *pScsiReq;
VirtDevice *pTarget = SCpnt->device->hostdata; VirtDevice *vdev = SCpnt->device->hostdata;
int lun; int lun;
u32 datalen; u32 datalen;
u32 scsictl; u32 scsictl;
...@@ -1343,8 +1338,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) ...@@ -1343,8 +1338,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Default to untagged. Once a target structure has been allocated, /* Default to untagged. Once a target structure has been allocated,
* use the Inquiry data to determine if device supports tagged. * use the Inquiry data to determine if device supports tagged.
*/ */
if (pTarget if (vdev
&& (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES) && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
&& (SCpnt->device->tagged_supported)) { && (SCpnt->device->tagged_supported)) {
scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
} else { } else {
...@@ -1353,8 +1348,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) ...@@ -1353,8 +1348,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Use the above information to set up the message frame /* Use the above information to set up the message frame
*/ */
pScsiReq->TargetID = (u8) pTarget->target_id; pScsiReq->TargetID = (u8) vdev->target_id;
pScsiReq->Bus = pTarget->bus_id; pScsiReq->Bus = vdev->bus_id;
pScsiReq->ChainOffset = 0; pScsiReq->ChainOffset = 0;
pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
pScsiReq->CDBLength = SCpnt->cmd_len; pScsiReq->CDBLength = SCpnt->cmd_len;
...@@ -1406,7 +1401,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) ...@@ -1406,7 +1401,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
if (hd->ioc->bus_type == SPI) { if (hd->ioc->bus_type == SPI) {
int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id]; int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id];
int issueCmd = 1; int issueCmd = 1;
if (dvStatus || hd->ioc->spi_data.forceDv) { if (dvStatus || hd->ioc->spi_data.forceDv) {
...@@ -1439,7 +1434,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) ...@@ -1439,7 +1434,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Set the DV flags. /* Set the DV flags.
*/ */
if (dvStatus & MPT_SCSICFG_DV_NOT_DONE) if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
mptscsih_set_dvflags(hd, pScsiReq); mptscsih_set_dvflags(hd, SCpnt);
if (!issueCmd) if (!issueCmd)
goto fail; goto fail;
...@@ -1743,6 +1738,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) ...@@ -1743,6 +1738,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
u32 ctx2abort; u32 ctx2abort;
int scpnt_idx; int scpnt_idx;
int retval; int retval;
VirtDevice *vdev;
/* If we can't locate our host adapter structure, return FAILED status. /* If we can't locate our host adapter structure, return FAILED status.
*/ */
...@@ -1792,8 +1788,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) ...@@ -1792,8 +1788,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
hd->abortSCpnt = SCpnt; hd->abortSCpnt = SCpnt;
vdev = SCpnt->device->hostdata;
retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, vdev->bus_id, vdev->target_id, vdev->lun,
ctx2abort, 2 /* 2 second timeout */); ctx2abort, 2 /* 2 second timeout */);
printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
...@@ -1824,6 +1821,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) ...@@ -1824,6 +1821,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
int retval; int retval;
VirtDevice *vdev;
/* If we can't locate our host adapter structure, return FAILED status. /* If we can't locate our host adapter structure, return FAILED status.
*/ */
...@@ -1841,8 +1839,9 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) ...@@ -1841,8 +1839,9 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
hd->ioc->name, SCpnt); hd->ioc->name, SCpnt);
scsi_print_command(SCpnt); scsi_print_command(SCpnt);
vdev = SCpnt->device->hostdata;
retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
SCpnt->device->channel, SCpnt->device->id, vdev->bus_id, vdev->target_id,
0, 0, 5 /* 5 second timeout */); 0, 0, 5 /* 5 second timeout */);
printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
...@@ -1873,6 +1872,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) ...@@ -1873,6 +1872,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
int retval; int retval;
VirtDevice *vdev;
/* If we can't locate our host adapter structure, return FAILED status. /* If we can't locate our host adapter structure, return FAILED status.
*/ */
...@@ -1890,8 +1890,9 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) ...@@ -1890,8 +1890,9 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
if (hd->timeouts < -1) if (hd->timeouts < -1)
hd->timeouts++; hd->timeouts++;
vdev = SCpnt->device->hostdata;
retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */); vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */);
printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
hd->ioc->name, hd->ioc->name,
...@@ -2150,26 +2151,39 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, ...@@ -2150,26 +2151,39 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
return 0; return 0;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* OS entry point to allow host driver to alloc memory
* for each scsi target. Called once per device the bus scan.
* Return non-zero if allocation fails.
*/
int
mptscsih_target_alloc(struct scsi_target *starget)
{
VirtTarget *vtarget;
vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL);
if (!vtarget)
return -ENOMEM;
memset(vtarget, 0, sizeof(VirtTarget));
starget->hostdata = vtarget;
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* OS entry point to allow host driver to alloc memory * OS entry point to allow host driver to alloc memory
* for each scsi device. Called once per device the bus scan. * for each scsi device. Called once per device the bus scan.
* Return non-zero if allocation fails. * Return non-zero if allocation fails.
* Init memory once per id (not LUN).
*/ */
int int
mptscsih_slave_alloc(struct scsi_device *device) mptscsih_slave_alloc(struct scsi_device *sdev)
{ {
struct Scsi_Host *host = device->host; struct Scsi_Host *host = sdev->host;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
VirtTarget *vtarget;
VirtDevice *vdev; VirtDevice *vdev;
uint target = device->id; struct scsi_target *starget;
if (hd == NULL)
return -ENODEV;
if ((vdev = hd->Targets[target]) != NULL)
goto out;
vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdev) { if (!vdev) {
...@@ -2179,25 +2193,33 @@ mptscsih_slave_alloc(struct scsi_device *device) ...@@ -2179,25 +2193,33 @@ mptscsih_slave_alloc(struct scsi_device *device)
} }
memset(vdev, 0, sizeof(VirtDevice)); memset(vdev, 0, sizeof(VirtDevice));
vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
vdev->ioc_id = hd->ioc->id; vdev->ioc_id = hd->ioc->id;
vdev->target_id = device->id; vdev->target_id = sdev->id;
vdev->bus_id = device->channel; vdev->bus_id = sdev->channel;
vdev->raidVolume = 0; vdev->lun = sdev->lun;
hd->Targets[device->id] = vdev; sdev->hostdata = vdev;
starget = scsi_target(sdev);
vtarget = starget->hostdata;
vdev->vtarget = vtarget;
if (vtarget->num_luns == 0) {
hd->Targets[sdev->id] = vtarget;
vtarget->ioc_id = hd->ioc->id;
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
vtarget->target_id = sdev->id;
vtarget->bus_id = sdev->channel;
if (hd->ioc->bus_type == SPI) { if (hd->ioc->bus_type == SPI) {
if (hd->ioc->raid_data.isRaid & (1 << device->id)) { if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
vdev->raidVolume = 1; vtarget->raidVolume = 1;
ddvtprintk((KERN_INFO ddvtprintk((KERN_INFO
"RAID Volume @ id %d\n", device->id)); "RAID Volume @ id %d\n", sdev->id));
} }
} else { } else {
vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
} }
}
out: vtarget->num_luns++;
vdev->num_luns++;
device->hostdata = vdev;
return 0; return 0;
} }
...@@ -2206,40 +2228,52 @@ mptscsih_slave_alloc(struct scsi_device *device) ...@@ -2206,40 +2228,52 @@ mptscsih_slave_alloc(struct scsi_device *device)
* Called if no device present or device being unloaded * Called if no device present or device being unloaded
*/ */
void void
mptscsih_slave_destroy(struct scsi_device *device) mptscsih_target_destroy(struct scsi_target *starget)
{ {
struct Scsi_Host *host = device->host; if (starget->hostdata)
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; kfree(starget->hostdata);
VirtDevice *vdev; starget->hostdata = NULL;
uint target = device->id; }
uint lun = device->lun;
if (hd == NULL)
return;
mptscsih_search_running_cmds(hd, target, lun);
vdev = hd->Targets[target];
vdev->luns[0] &= ~(1 << lun);
if (--vdev->num_luns)
return;
kfree(hd->Targets[target]);
hd->Targets[target] = NULL;
/*
* OS entry point to allow for host driver to free allocated memory
* Called if no device present or device being unloaded
*/
void
mptscsih_slave_destroy(struct scsi_device *sdev)
{
struct Scsi_Host *host = sdev->host;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
VirtTarget *vtarget;
VirtDevice *vdevice;
struct scsi_target *starget;
starget = scsi_target(sdev);
vtarget = starget->hostdata;
vdevice = sdev->hostdata;
mptscsih_search_running_cmds(hd, vdevice);
vtarget->luns[0] &= ~(1 << vdevice->lun);
vtarget->num_luns--;
if (vtarget->num_luns == 0) {
mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
if (hd->ioc->bus_type == SPI) { if (hd->ioc->bus_type == SPI) {
if (mptscsih_is_phys_disk(hd->ioc, target)) { if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
} else { } else {
hd->ioc->spi_data.dvStatus[target] = hd->ioc->spi_data.dvStatus[vtarget->target_id] =
MPT_SCSICFG_NEGOTIATE; MPT_SCSICFG_NEGOTIATE;
if (!hd->negoNvram) { if (!hd->negoNvram) {
hd->ioc->spi_data.dvStatus[target] |= hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
MPT_SCSICFG_DV_NOT_DONE; MPT_SCSICFG_DV_NOT_DONE;
} }
} }
} }
hd->Targets[sdev->id] = NULL;
}
mptscsih_synchronize_cache(hd, vdevice);
kfree(vdevice);
sdev->hostdata = NULL;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -2254,21 +2288,20 @@ int ...@@ -2254,21 +2288,20 @@ int
mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
{ {
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
VirtDevice *pTarget; VirtTarget *vtarget;
struct scsi_target *starget;
int max_depth; int max_depth;
int tagged; int tagged;
if (hd == NULL) starget = scsi_target(sdev);
return 0; vtarget = starget->hostdata;
if (!(pTarget = hd->Targets[sdev->id]))
return 0;
if (hd->ioc->bus_type == SPI) { if (hd->ioc->bus_type == SPI) {
if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
max_depth = 1; max_depth = 1;
else if (((pTarget->inq_data[0] & 0x1f) == 0x00) && else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
(pTarget->minSyncFactor <= MPT_ULTRA160 )) (vtarget->minSyncFactor <= MPT_ULTRA160 ))
max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
else else
max_depth = MPT_SCSI_CMD_PER_DEV_LOW; max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
...@@ -2297,64 +2330,58 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) ...@@ -2297,64 +2330,58 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
* Return non-zero if fails. * Return non-zero if fails.
*/ */
int int
mptscsih_slave_configure(struct scsi_device *device) mptscsih_slave_configure(struct scsi_device *sdev)
{ {
struct Scsi_Host *sh = device->host; struct Scsi_Host *sh = sdev->host;
VirtDevice *pTarget; VirtTarget *vtarget;
VirtDevice *vdevice;
struct scsi_target *starget;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
int indexed_lun, lun_index;
if ((hd == NULL) || (hd->Targets == NULL)) { starget = scsi_target(sdev);
return 0; vtarget = starget->hostdata;
} vdevice = sdev->hostdata;
dsprintk((MYIOC_s_INFO_FMT dsprintk((MYIOC_s_INFO_FMT
"device @ %p, id=%d, LUN=%d, channel=%d\n", "device @ %p, id=%d, LUN=%d, channel=%d\n",
hd->ioc->name, device, device->id, device->lun, device->channel)); hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
if (hd->ioc->bus_type == SPI)
dsprintk((MYIOC_s_INFO_FMT dsprintk((MYIOC_s_INFO_FMT
"sdtr %d wdtr %d ppr %d inq length=%d\n", "sdtr %d wdtr %d ppr %d inq length=%d\n",
hd->ioc->name, device->sdtr, device->wdtr, hd->ioc->name, sdev->sdtr, sdev->wdtr,
device->ppr, device->inquiry_len)); sdev->ppr, sdev->inquiry_len));
if (device->id > sh->max_id) { if (sdev->id > sh->max_id) {
/* error case, should never happen */ /* error case, should never happen */
scsi_adjust_queue_depth(device, 0, 1); scsi_adjust_queue_depth(sdev, 0, 1);
goto slave_configure_exit; goto slave_configure_exit;
} }
pTarget = hd->Targets[device->id]; vdevice->configured_lun=1;
lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
if (pTarget == NULL) { indexed_lun = (vdevice->lun % 32);
/* Driver doesn't know about this device. vtarget->luns[lun_index] |= (1 << indexed_lun);
* Kernel may generate a "Dummy Lun 0" which mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry,
* may become a real Lun if a sdev->inquiry_len );
* "scsi add-single-device" command is executed mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
* while the driver is active (hot-plug a
* device). LSI Raid controllers need
* queue_depth set to DEV_HIGH for this reason.
*/
scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
MPT_SCSI_CMD_PER_DEV_HIGH);
goto slave_configure_exit;
}
mptscsih_initTarget(hd, device->channel, device->id, device->lun,
device->inquiry, device->inquiry_len );
mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH);
dsprintk((MYIOC_s_INFO_FMT dsprintk((MYIOC_s_INFO_FMT
"Queue depth=%d, tflags=%x\n", "Queue depth=%d, tflags=%x\n",
hd->ioc->name, device->queue_depth, pTarget->tflags)); hd->ioc->name, sdev->queue_depth, vtarget->tflags));
if (hd->ioc->bus_type == SPI)
dsprintk((MYIOC_s_INFO_FMT dsprintk((MYIOC_s_INFO_FMT
"negoFlags=%x, maxOffset=%x, SyncFactor=%x\n", "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor)); hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
vtarget->minSyncFactor));
slave_configure_exit: slave_configure_exit:
dsprintk((MYIOC_s_INFO_FMT dsprintk((MYIOC_s_INFO_FMT
"tagged %d, simple %d, ordered %d\n", "tagged %d, simple %d, ordered %d\n",
hd->ioc->name,device->tagged_supported, device->simple_tags, hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
device->ordered_tags)); sdev->ordered_tags));
return 0; return 0;
} }
...@@ -2372,16 +2399,14 @@ mptscsih_slave_configure(struct scsi_device *device) ...@@ -2372,16 +2399,14 @@ mptscsih_slave_configure(struct scsi_device *device)
static void static void
mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply) mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
{ {
VirtDevice *target; VirtDevice *vdev;
SCSIIORequest_t *pReq; SCSIIORequest_t *pReq;
u32 sense_count = le32_to_cpu(pScsiReply->SenseCount); u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
int index;
/* Get target structure /* Get target structure
*/ */
pReq = (SCSIIORequest_t *) mf; pReq = (SCSIIORequest_t *) mf;
index = (int) pReq->TargetID; vdev = sc->device->hostdata;
target = hd->Targets[index];
if (sense_count) { if (sense_count) {
u8 *sense_data; u8 *sense_data;
...@@ -2395,7 +2420,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR ...@@ -2395,7 +2420,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
/* Log SMART data (asc = 0x5D, non-IM case only) if required. /* Log SMART data (asc = 0x5D, non-IM case only) if required.
*/ */
if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) { if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) { if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
int idx; int idx;
MPT_ADAPTER *ioc = hd->ioc; MPT_ADAPTER *ioc = hd->ioc;
...@@ -2405,7 +2430,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR ...@@ -2405,7 +2430,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
ioc->events[idx].data[0] = (pReq->LUN[1] << 24) || ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) || (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
(pReq->Bus << 8) || pReq->TargetID; (sc->device->channel << 8) || sc->device->id;
ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12]; ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
...@@ -2634,8 +2659,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ...@@ -2634,8 +2659,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
/* /*
* mptscsih_initTarget - Target, LUN alloc/free functionality. * mptscsih_initTarget - Target, LUN alloc/free functionality.
* @hd: Pointer to MPT_SCSI_HOST structure * @hd: Pointer to MPT_SCSI_HOST structure
* @bus_id: Bus number (?) * @vtarget: per target private data
* @target_id: SCSI target id
* @lun: SCSI LUN id * @lun: SCSI LUN id
* @data: Pointer to data * @data: Pointer to data
* @dlen: Number of INQUIRY bytes * @dlen: Number of INQUIRY bytes
...@@ -2648,15 +2672,14 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ...@@ -2648,15 +2672,14 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
* *
*/ */
static void static void
mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen) mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen)
{ {
int indexed_lun, lun_index;
VirtDevice *vdev;
SpiCfgData *pSpi; SpiCfgData *pSpi;
char data_56; char data_56;
int inq_len;
dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
hd->ioc->name, bus_id, target_id, lun, hd)); hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
/* /*
* If the peripheral qualifier filter is enabled then if the target reports a 0x1 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
...@@ -2676,75 +2699,68 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char * ...@@ -2676,75 +2699,68 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
if (data[0] & 0xe0) if (data[0] & 0xe0)
return; return;
if ((vdev = hd->Targets[target_id]) == NULL) { if (vtarget == NULL)
return; return;
}
lun_index = (lun >> 5); /* 32 luns per lun_index */ if (data)
indexed_lun = (lun % 32); vtarget->type = data[0];
vdev->luns[lun_index] |= (1 << indexed_lun);
if (hd->ioc->bus_type != SPI)
return;
if (hd->ioc->bus_type == SPI) {
if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
/* Treat all Processors as SAF-TE if /* Treat all Processors as SAF-TE if
* command line option is set */ * command line option is set */
vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
mptscsih_writeIOCPage4(hd, target_id, bus_id); mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
}else if ((data[0] == TYPE_PROCESSOR) && }else if ((data[0] == TYPE_PROCESSOR) &&
!(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
if ( dlen > 49 ) { if ( dlen > 49 ) {
vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
if ( data[44] == 'S' && if ( data[44] == 'S' &&
data[45] == 'A' && data[45] == 'A' &&
data[46] == 'F' && data[46] == 'F' &&
data[47] == '-' && data[47] == '-' &&
data[48] == 'T' && data[48] == 'T' &&
data[49] == 'E' ) { data[49] == 'E' ) {
vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
mptscsih_writeIOCPage4(hd, target_id, bus_id); mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
} }
} }
} }
if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
if ( dlen > 8 ) { inq_len = dlen < 8 ? dlen : 8;
memcpy (vdev->inq_data, data, 8); memcpy (vtarget->inq_data, data, inq_len);
} else {
memcpy (vdev->inq_data, data, dlen);
}
/* If have not done DV, set the DV flag. /* If have not done DV, set the DV flag.
*/ */
pSpi = &hd->ioc->spi_data; pSpi = &hd->ioc->spi_data;
if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) { if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE) if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV; pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
} }
vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */ data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
if (dlen > 56) { if (dlen > 56) {
if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
/* Update the target capabilities /* Update the target capabilities
*/ */
data_56 = data[56]; data_56 = data[56];
vdev->tflags |= MPT_TARGET_FLAGS_VALID_56; vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
} }
} }
mptscsih_setTargetNegoParms(hd, vdev, data_56); mptscsih_setTargetNegoParms(hd, vtarget, data_56);
} else { } else {
/* Initial Inquiry may not request enough data bytes to /* Initial Inquiry may not request enough data bytes to
* obtain byte 57. DV will; if target doesn't return * obtain byte 57. DV will; if target doesn't return
* at least 57 bytes, data[56] will be zero. */ * at least 57 bytes, data[56] will be zero. */
if (dlen > 56) { if (dlen > 56) {
if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
/* Update the target capabilities /* Update the target capabilities
*/ */
data_56 = data[56]; data_56 = data[56];
vdev->tflags |= MPT_TARGET_FLAGS_VALID_56; vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
mptscsih_setTargetNegoParms(hd, vdev, data_56); mptscsih_setTargetNegoParms(hd, vtarget, data_56);
}
} }
} }
} }
...@@ -2757,12 +2773,12 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char * ...@@ -2757,12 +2773,12 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
* *
*/ */
static void static void
mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
{ {
SpiCfgData *pspi_data = &hd->ioc->spi_data; SpiCfgData *pspi_data = &hd->ioc->spi_data;
int id = (int) target->target_id; int id = (int) target->target_id;
int nvram; int nvram;
VirtDevice *vdev; VirtTarget *vtarget;
int ii; int ii;
u8 width = MPT_NARROW; u8 width = MPT_NARROW;
u8 factor = MPT_ASYNC; u8 factor = MPT_ASYNC;
...@@ -2907,9 +2923,9 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) ...@@ -2907,9 +2923,9 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
for (ii = 0; ii < id; ii++) { for (ii = 0; ii < id; ii++) {
if ( (vdev = hd->Targets[ii]) ) { if ( (vtarget = hd->Targets[ii]) ) {
vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS; vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags); mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
} }
} }
} }
...@@ -2933,12 +2949,12 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) ...@@ -2933,12 +2949,12 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
* prevent any future negotiations to this device. * prevent any future negotiations to this device.
*/ */
static void static void
mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id) mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
{ {
VirtDevice *vdev;
if ((hd->Targets) && (hd->Targets[target_id] == NULL)) if ((vdev = sc->device->hostdata) != NULL)
hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO; hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
return; return;
} }
...@@ -3014,7 +3030,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) ...@@ -3014,7 +3030,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
MPT_ADAPTER *ioc = hd->ioc; MPT_ADAPTER *ioc = hd->ioc;
Config_t *pReq; Config_t *pReq;
SCSIDevicePage1_t *pData; SCSIDevicePage1_t *pData;
VirtDevice *pTarget=NULL; VirtTarget *vtarget=NULL;
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
dma_addr_t dataDma; dma_addr_t dataDma;
u16 req_idx; u16 req_idx;
...@@ -3094,11 +3110,11 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) ...@@ -3094,11 +3110,11 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
/* If id is not a raid volume, get the updated /* If id is not a raid volume, get the updated
* transmission settings from the target structure. * transmission settings from the target structure.
*/ */
if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) { if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
width = pTarget->maxWidth; width = vtarget->maxWidth;
factor = pTarget->minSyncFactor; factor = vtarget->minSyncFactor;
offset = pTarget->maxOffset; offset = vtarget->maxOffset;
negoFlags = pTarget->negoFlags; negoFlags = vtarget->negoFlags;
} }
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
...@@ -3818,108 +3834,60 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) ...@@ -3818,108 +3834,60 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks. * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
* @hd: Pointer to MPT_SCSI_HOST structure * @hd: Pointer to a SCSI HOST structure
* @portnum: IOC port number * @vtarget: per device private data
* *
* Uses the ISR, but with special processing. * Uses the ISR, but with special processing.
* MUST be single-threaded. * MUST be single-threaded.
* *
* Return: 0 on completion
*/ */
static int static void
mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
{ {
MPT_ADAPTER *ioc= hd->ioc; MPT_ADAPTER *ioc= hd->ioc;
VirtDevice *pTarget; SCSIDevicePage1_t *pcfg1Data;
SCSIDevicePage1_t *pcfg1Data = NULL;
INTERNAL_CMD iocmd;
CONFIGPARMS cfg; CONFIGPARMS cfg;
dma_addr_t cfg1_dma_addr = -1; dma_addr_t cfg1_dma_addr;
ConfigPageHeader_t header1; ConfigPageHeader_t header;
int bus = 0; int id;
int id = 0; int requested, configuration, data,i;
int lun;
int indexed_lun, lun_index;
int hostId = ioc->pfacts[portnum].PortSCSIID;
int max_id;
int requested, configuration, data;
int doConfig = 0;
u8 flags, factor; u8 flags, factor;
max_id = ioc->sh->max_id - 1; if (ioc->bus_type != SPI)
return;
/* Following parameters will not change
* in this routine.
*/
iocmd.cmd = SYNCHRONIZE_CACHE;
iocmd.flags = 0;
iocmd.physDiskNum = -1;
iocmd.data = NULL;
iocmd.data_dma = -1;
iocmd.size = 0;
iocmd.rsvd = iocmd.rsvd2 = 0;
/* No SCSI hosts
*/
if (hd->Targets == NULL)
return 0;
/* Skip the host if (!ioc->spi_data.sdp1length)
*/ return;
if (id == hostId)
id++;
/* Write SDP1 for all SPI devices
* Alloc memory and set up config buffer
*/
if (ioc->bus_type == SPI) {
if (ioc->spi_data.sdp1length > 0) {
pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev, pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
ioc->spi_data.sdp1length * 4, &cfg1_dma_addr); ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
if (pcfg1Data != NULL) { if (pcfg1Data == NULL)
doConfig = 1; return;
header1.PageVersion = ioc->spi_data.sdp1version;
header1.PageLength = ioc->spi_data.sdp1length; header.PageVersion = ioc->spi_data.sdp1version;
header1.PageNumber = 1; header.PageLength = ioc->spi_data.sdp1length;
header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; header.PageNumber = 1;
cfg.cfghdr.hdr = &header1; header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
cfg.cfghdr.hdr = &header;
cfg.physAddr = cfg1_dma_addr; cfg.physAddr = cfg1_dma_addr;
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1; cfg.dir = 1;
cfg.timeout = 0; cfg.timeout = 0;
}
}
}
/* loop through all devices on this port if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
*/ for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
while (bus < MPT_MAX_BUS) { id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
iocmd.bus = bus;
iocmd.id = id;
pTarget = hd->Targets[(int)id];
if (doConfig) {
/* Set the negotiation flags */
if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
flags = pTarget->negoFlags;
} else {
flags = hd->ioc->spi_data.noQas; flags = hd->ioc->spi_data.noQas;
if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
data = hd->ioc->spi_data.nvram[id]; data = hd->ioc->spi_data.nvram[id];
if (data & MPT_NVRAM_WIDE_DISABLE) if (data & MPT_NVRAM_WIDE_DISABLE)
flags |= MPT_TARGET_NO_NEGO_WIDE; flags |= MPT_TARGET_NO_NEGO_WIDE;
factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
if ((factor == 0) || (factor == MPT_ASYNC)) if ((factor == 0) || (factor == MPT_ASYNC))
flags |= MPT_TARGET_NO_NEGO_SYNC; flags |= MPT_TARGET_NO_NEGO_SYNC;
} }
}
/* Force to async, narrow */
mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
&configuration, flags); &configuration, flags);
dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
...@@ -3928,42 +3896,60 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) ...@@ -3928,42 +3896,60 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
pcfg1Data->RequestedParameters = cpu_to_le32(requested); pcfg1Data->RequestedParameters = cpu_to_le32(requested);
pcfg1Data->Reserved = 0; pcfg1Data->Reserved = 0;
pcfg1Data->Configuration = cpu_to_le32(configuration); pcfg1Data->Configuration = cpu_to_le32(configuration);
cfg.pageAddr = (bus<<8) | id; cfg.pageAddr = (vtarget->bus_id<<8) | id;
mpt_config(hd->ioc, &cfg); mpt_config(hd->ioc, &cfg);
} }
} else {
/* If target Ptr NULL or if this target is NOT a disk, skip. flags = vtarget->negoFlags;
*/ mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){ &configuration, flags);
for (lun=0; lun <= MPT_LAST_LUN; lun++) { dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
/* If LUN present, issue the command "offset=0 negoFlags=%x request=%x config=%x\n",
*/ vtarget->target_id, flags, requested, configuration));
lun_index = (lun >> 5); /* 32 luns per lun_index */ pcfg1Data->RequestedParameters = cpu_to_le32(requested);
indexed_lun = (lun % 32); pcfg1Data->Reserved = 0;
if (pTarget->luns[lun_index] & (1<<indexed_lun)) { pcfg1Data->Configuration = cpu_to_le32(configuration);
iocmd.lun = lun; cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
(void) mptscsih_do_cmd(hd, &iocmd); mpt_config(hd->ioc, &cfg);
}
}
} }
/* get next relevant device */ if (pcfg1Data)
id++; pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
}
if (id == hostId)
id++;
if (id > max_id) { /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
id = 0; /**
bus++; * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
} * @hd: Pointer to a SCSI HOST structure
} * @vtarget: per device private data
* @lun: lun
*
* Uses the ISR, but with special processing.
* MUST be single-threaded.
*
*/
static void
mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
{
INTERNAL_CMD iocmd;
if (pcfg1Data) { /* Following parameters will not change
pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr); * in this routine.
} */
iocmd.cmd = SYNCHRONIZE_CACHE;
iocmd.flags = 0;
iocmd.physDiskNum = -1;
iocmd.data = NULL;
iocmd.data_dma = -1;
iocmd.size = 0;
iocmd.rsvd = iocmd.rsvd2 = 0;
iocmd.bus = vdevice->bus_id;
iocmd.id = vdevice->target_id;
iocmd.lun = (u8)vdevice->lun;
return 0; if ((vdevice->vtarget->type & TYPE_DISK) &&
(vdevice->configured_lun))
mptscsih_do_cmd(hd, &iocmd);
} }
/* Search IOC page 3 to determine if this is hidden physical disk /* Search IOC page 3 to determine if this is hidden physical disk
...@@ -4144,7 +4130,7 @@ mptscsih_domainValidation(void *arg) ...@@ -4144,7 +4130,7 @@ mptscsih_domainValidation(void *arg)
static void static void
mptscsih_qas_check(MPT_SCSI_HOST *hd, int id) mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
{ {
VirtDevice *pTarget; VirtTarget *vtarget;
int ii; int ii;
if (hd->Targets == NULL) if (hd->Targets == NULL)
...@@ -4157,11 +4143,11 @@ mptscsih_qas_check(MPT_SCSI_HOST *hd, int id) ...@@ -4157,11 +4143,11 @@ mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0) if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
continue; continue;
pTarget = hd->Targets[ii]; vtarget = hd->Targets[ii];
if ((pTarget != NULL) && (!pTarget->raidVolume)) { if ((vtarget != NULL) && (!vtarget->raidVolume)) {
if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) { if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
pTarget->negoFlags |= hd->ioc->spi_data.noQas; vtarget->negoFlags |= hd->ioc->spi_data.noQas;
dnegoprintk(("writeSDP1: id=%d flags=0\n", id)); dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
mptscsih_writeSDP1(hd, 0, ii, 0); mptscsih_writeSDP1(hd, 0, ii, 0);
} }
...@@ -4201,7 +4187,7 @@ static int ...@@ -4201,7 +4187,7 @@ static int
mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
{ {
MPT_ADAPTER *ioc = hd->ioc; MPT_ADAPTER *ioc = hd->ioc;
VirtDevice *pTarget; VirtTarget *vtarget;
SCSIDevicePage1_t *pcfg1Data; SCSIDevicePage1_t *pcfg1Data;
SCSIDevicePage0_t *pcfg0Data; SCSIDevicePage0_t *pcfg0Data;
u8 *pbuf1; u8 *pbuf1;
...@@ -4272,12 +4258,12 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -4272,12 +4258,12 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
iocmd.physDiskNum = -1; iocmd.physDiskNum = -1;
iocmd.rsvd = iocmd.rsvd2 = 0; iocmd.rsvd = iocmd.rsvd2 = 0;
pTarget = hd->Targets[id]; vtarget = hd->Targets[id];
/* Use tagged commands if possible. /* Use tagged commands if possible.
*/ */
if (pTarget) { if (vtarget) {
if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES) if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
iocmd.flags |= MPT_ICFLAG_TAGGED_CMD; iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
else { else {
if (hd->ioc->facts.FWVersion.Word < 0x01000600) if (hd->ioc->facts.FWVersion.Word < 0x01000600)
...@@ -4493,7 +4479,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -4493,7 +4479,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* Reset the size for disks /* Reset the size for disks
*/ */
inq0 = (*pbuf1) & 0x1F; inq0 = (*pbuf1) & 0x1F;
if ((inq0 == 0) && pTarget && !pTarget->raidVolume) { if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
sz = 0x40; sz = 0x40;
iocmd.size = sz; iocmd.size = sz;
} }
...@@ -4503,8 +4489,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -4503,8 +4489,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
*/ */
if (inq0 == TYPE_PROCESSOR) { if (inq0 == TYPE_PROCESSOR) {
mptscsih_initTarget(hd, mptscsih_initTarget(hd,
bus, vtarget,
id,
lun, lun,
pbuf1, pbuf1,
sz); sz);
...@@ -4518,22 +4503,22 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -4518,22 +4503,22 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
goto target_done; goto target_done;
if (sz == 0x40) { if (sz == 0x40) {
if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A) if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
&& (pTarget->minSyncFactor > 0x09)) { && (vtarget->minSyncFactor > 0x09)) {
if ((pbuf1[56] & 0x04) == 0) if ((pbuf1[56] & 0x04) == 0)
; ;
else if ((pbuf1[56] & 0x01) == 1) { else if ((pbuf1[56] & 0x01) == 1) {
pTarget->minSyncFactor = vtarget->minSyncFactor =
nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320; nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
} else { } else {
pTarget->minSyncFactor = vtarget->minSyncFactor =
nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160; nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
} }
dv.max.factor = pTarget->minSyncFactor; dv.max.factor = vtarget->minSyncFactor;
if ((pbuf1[56] & 0x02) == 0) { if ((pbuf1[56] & 0x02) == 0) {
pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
ddvprintk((MYIOC_s_NOTE_FMT ddvprintk((MYIOC_s_NOTE_FMT
"DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n", "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
...@@ -4616,8 +4601,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -4616,8 +4601,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
"DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id)); "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE; hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
mptscsih_initTarget(hd, mptscsih_initTarget(hd,
bus, vtarget,
id,
lun, lun,
pbuf1, pbuf1,
sz); sz);
...@@ -5118,7 +5102,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) ...@@ -5118,7 +5102,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
static void static void
mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
{ {
VirtDevice *pTarget; VirtTarget *vtarget;
SCSIDevicePage0_t *pPage0; SCSIDevicePage0_t *pPage0;
SCSIDevicePage1_t *pPage1; SCSIDevicePage1_t *pPage1;
int val = 0, data, configuration; int val = 0, data, configuration;
...@@ -5138,11 +5122,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) ...@@ -5138,11 +5122,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
* already throttled back. * already throttled back.
*/ */
negoFlags = hd->ioc->spi_data.noQas; negoFlags = hd->ioc->spi_data.noQas;
if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) { if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
width = pTarget->maxWidth; width = vtarget->maxWidth;
offset = pTarget->maxOffset; offset = vtarget->maxOffset;
factor = pTarget->minSyncFactor; factor = vtarget->minSyncFactor;
negoFlags |= pTarget->negoFlags; negoFlags |= vtarget->negoFlags;
} else { } else {
if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
data = hd->ioc->spi_data.nvram[id]; data = hd->ioc->spi_data.nvram[id];
...@@ -5344,11 +5328,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) ...@@ -5344,11 +5328,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
* or overwrite nvram (phys disks only). * or overwrite nvram (phys disks only).
*/ */
if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) { if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
pTarget->maxWidth = dv->now.width; vtarget->maxWidth = dv->now.width;
pTarget->maxOffset = dv->now.offset; vtarget->maxOffset = dv->now.offset;
pTarget->minSyncFactor = dv->now.factor; vtarget->minSyncFactor = dv->now.factor;
pTarget->negoFlags = dv->now.flags; vtarget->negoFlags = dv->now.flags;
} else { } else {
/* Preserv all flags, use /* Preserv all flags, use
* read-modify-write algorithm * read-modify-write algorithm
...@@ -5512,7 +5496,7 @@ mptscsih_fillbuf(char *buffer, int size, int index, int width) ...@@ -5512,7 +5496,7 @@ mptscsih_fillbuf(char *buffer, int size, int index, int width)
* Called only if DV_NOT_DONE flag is set * Called only if DV_NOT_DONE flag is set
*/ */
static void static void
mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
{ {
MPT_ADAPTER *ioc = hd->ioc; MPT_ADAPTER *ioc = hd->ioc;
u8 cmd; u8 cmd;
...@@ -5520,16 +5504,16 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) ...@@ -5520,16 +5504,16 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
ddvtprintk((MYIOC_s_NOTE_FMT ddvtprintk((MYIOC_s_NOTE_FMT
" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0])); hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0)) if ((sc->device->lun != 0) || (hd->negoNvram != 0))
return; return;
cmd = pReq->CDB[0]; cmd = sc->cmnd[0];
if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) { if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
pSpi = &ioc->spi_data; pSpi = &ioc->spi_data;
if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) { if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
/* Set NEED_DV for all hidden disks /* Set NEED_DV for all hidden disks
*/ */
Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk; Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
...@@ -5542,8 +5526,8 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) ...@@ -5542,8 +5526,8 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
numPDisk--; numPDisk--;
} }
} }
pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV; pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID)); ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
} }
} }
...@@ -5590,7 +5574,6 @@ mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id) ...@@ -5590,7 +5574,6 @@ mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
} }
} }
} }
#endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */ #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
EXPORT_SYMBOL(mptscsih_remove); EXPORT_SYMBOL(mptscsih_remove);
...@@ -5602,7 +5585,9 @@ EXPORT_SYMBOL(mptscsih_resume); ...@@ -5602,7 +5585,9 @@ EXPORT_SYMBOL(mptscsih_resume);
EXPORT_SYMBOL(mptscsih_proc_info); EXPORT_SYMBOL(mptscsih_proc_info);
EXPORT_SYMBOL(mptscsih_info); EXPORT_SYMBOL(mptscsih_info);
EXPORT_SYMBOL(mptscsih_qcmd); EXPORT_SYMBOL(mptscsih_qcmd);
EXPORT_SYMBOL(mptscsih_target_alloc);
EXPORT_SYMBOL(mptscsih_slave_alloc); EXPORT_SYMBOL(mptscsih_slave_alloc);
EXPORT_SYMBOL(mptscsih_target_destroy);
EXPORT_SYMBOL(mptscsih_slave_destroy); EXPORT_SYMBOL(mptscsih_slave_destroy);
EXPORT_SYMBOL(mptscsih_slave_configure); EXPORT_SYMBOL(mptscsih_slave_configure);
EXPORT_SYMBOL(mptscsih_abort); EXPORT_SYMBOL(mptscsih_abort);
......
...@@ -91,7 +91,9 @@ extern int mptscsih_resume(struct pci_dev *pdev); ...@@ -91,7 +91,9 @@ extern int mptscsih_resume(struct pci_dev *pdev);
extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func); extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
extern const char * mptscsih_info(struct Scsi_Host *SChost); extern const char * mptscsih_info(struct Scsi_Host *SChost);
extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
extern int mptscsih_target_alloc(struct scsi_target *starget);
extern int mptscsih_slave_alloc(struct scsi_device *device); extern int mptscsih_slave_alloc(struct scsi_device *device);
extern void mptscsih_target_destroy(struct scsi_target *starget);
extern void mptscsih_slave_destroy(struct scsi_device *device); extern void mptscsih_slave_destroy(struct scsi_device *device);
extern int mptscsih_slave_configure(struct scsi_device *device); extern int mptscsih_slave_configure(struct scsi_device *device);
extern int mptscsih_abort(struct scsi_cmnd * SCpnt); extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
......
...@@ -109,8 +109,10 @@ static struct scsi_host_template mptspi_driver_template = { ...@@ -109,8 +109,10 @@ static struct scsi_host_template mptspi_driver_template = {
.name = "MPT SPI Host", .name = "MPT SPI Host",
.info = mptscsih_info, .info = mptscsih_info,
.queuecommand = mptscsih_qcmd, .queuecommand = mptscsih_qcmd,
.target_alloc = mptscsih_target_alloc,
.slave_alloc = mptscsih_slave_alloc, .slave_alloc = mptscsih_slave_alloc,
.slave_configure = mptscsih_slave_configure, .slave_configure = mptscsih_slave_configure,
.target_destroy = mptscsih_target_destroy,
.slave_destroy = mptscsih_slave_destroy, .slave_destroy = mptscsih_slave_destroy,
.change_queue_depth = mptscsih_change_queue_depth, .change_queue_depth = mptscsih_change_queue_depth,
.eh_abort_handler = mptscsih_abort, .eh_abort_handler = mptscsih_abort,
...@@ -312,10 +314,10 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -312,10 +314,10 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
} }
memset(mem, 0, sz); memset(mem, 0, sz);
hd->Targets = (VirtDevice **) mem; hd->Targets = (VirtTarget **) mem;
dprintk((KERN_INFO dprintk((KERN_INFO
" Targets @ %p, sz=%d\n", hd->Targets, sz)); " vdev @ %p, sz=%d\n", hd->Targets, sz));
/* Clear the TM flags /* Clear the TM flags
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment