diff options
| -rw-r--r-- | drivers/message/fusion/mptbase.h | 28 | ||||
| -rw-r--r-- | drivers/message/fusion/mptctl.c | 4 | ||||
| -rw-r--r-- | drivers/message/fusion/mptfc.c | 6 | ||||
| -rw-r--r-- | drivers/message/fusion/mptsas.c | 37 | ||||
| -rw-r--r-- | drivers/message/fusion/mptscsih.c | 745 | ||||
| -rw-r--r-- | drivers/message/fusion/mptscsih.h | 2 | ||||
| -rw-r--r-- | drivers/message/fusion/mptspi.c | 6 |
7 files changed, 411 insertions, 417 deletions
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 7a6c11418452..2a46b33fa760 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
| @@ -321,7 +321,7 @@ typedef struct _SYSIF_REGS | |||
| 321 | * Dynamic Multi-Pathing specific stuff... | 321 | * Dynamic Multi-Pathing specific stuff... |
| 322 | */ | 322 | */ |
| 323 | 323 | ||
| 324 | /* VirtDevice negoFlags field */ | 324 | /* VirtTarget negoFlags field */ |
| 325 | #define MPT_TARGET_NO_NEGO_WIDE 0x01 | 325 | #define MPT_TARGET_NO_NEGO_WIDE 0x01 |
| 326 | #define MPT_TARGET_NO_NEGO_SYNC 0x02 | 326 | #define MPT_TARGET_NO_NEGO_SYNC 0x02 |
| 327 | #define MPT_TARGET_NO_NEGO_QAS 0x04 | 327 | #define MPT_TARGET_NO_NEGO_QAS 0x04 |
| @@ -330,8 +330,7 @@ typedef struct _SYSIF_REGS | |||
| 330 | /* | 330 | /* |
| 331 | * VirtDevice - FC LUN device or SCSI target device | 331 | * VirtDevice - FC LUN device or SCSI target device |
| 332 | */ | 332 | */ |
| 333 | typedef struct _VirtDevice { | 333 | typedef struct _VirtTarget { |
| 334 | struct scsi_device *device; | ||
| 335 | u8 tflags; | 334 | u8 tflags; |
| 336 | u8 ioc_id; | 335 | u8 ioc_id; |
| 337 | u8 target_id; | 336 | u8 target_id; |
| @@ -342,21 +341,18 @@ typedef struct _VirtDevice { | |||
| 342 | u8 negoFlags; /* bit field, see above */ | 341 | u8 negoFlags; /* bit field, see above */ |
| 343 | u8 raidVolume; /* set, if RAID Volume */ | 342 | u8 raidVolume; /* set, if RAID Volume */ |
| 344 | u8 type; /* byte 0 of Inquiry data */ | 343 | u8 type; /* byte 0 of Inquiry data */ |
| 345 | u8 cflags; /* controller flags */ | ||
| 346 | u8 rsvd1raid; | ||
| 347 | u16 fc_phys_lun; | ||
| 348 | u16 fc_xlat_lun; | ||
| 349 | u32 num_luns; | 344 | u32 num_luns; |
| 350 | u32 luns[8]; /* Max LUNs is 256 */ | 345 | u32 luns[8]; /* Max LUNs is 256 */ |
| 351 | u8 pad[4]; | ||
| 352 | u8 inq_data[8]; | 346 | u8 inq_data[8]; |
| 353 | /* IEEE Registered Extended Identifier | 347 | } VirtTarget; |
| 354 | obtained via INQUIRY VPD page 0x83 */ | 348 | |
| 355 | /* NOTE: Do not separate uniq_prepad and uniq_data | 349 | typedef struct _VirtDevice { |
| 356 | as they are treateed as a single entity in the code */ | 350 | VirtTarget *vtarget; |
| 357 | u8 uniq_prepad[8]; | 351 | u8 ioc_id; |
| 358 | u8 uniq_data[20]; | 352 | u8 bus_id; |
| 359 | u8 pad2[4]; | 353 | u8 target_id; |
| 354 | u8 configured_lun; | ||
| 355 | u32 lun; | ||
| 360 | } VirtDevice; | 356 | } VirtDevice; |
| 361 | 357 | ||
| 362 | /* | 358 | /* |
| @@ -912,7 +908,7 @@ typedef struct _MPT_SCSI_HOST { | |||
| 912 | int port; | 908 | int port; |
| 913 | u32 pad0; | 909 | u32 pad0; |
| 914 | struct scsi_cmnd **ScsiLookup; | 910 | struct scsi_cmnd **ScsiLookup; |
| 915 | VirtDevice **Targets; | 911 | VirtTarget **Targets; |
| 916 | MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ | 912 | MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ |
| 917 | struct timer_list timer; | 913 | struct timer_list timer; |
| 918 | /* Pool of memory for holding SCpnts before doing | 914 | /* Pool of memory for holding SCpnts before doing |
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 602138f8544d..959d2c5951b8 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
| @@ -1245,7 +1245,7 @@ mptctl_gettargetinfo (unsigned long arg) | |||
| 1245 | MPT_ADAPTER *ioc; | 1245 | MPT_ADAPTER *ioc; |
| 1246 | struct Scsi_Host *sh; | 1246 | struct Scsi_Host *sh; |
| 1247 | MPT_SCSI_HOST *hd; | 1247 | MPT_SCSI_HOST *hd; |
| 1248 | VirtDevice *vdev; | 1248 | VirtTarget *vdev; |
| 1249 | char *pmem; | 1249 | char *pmem; |
| 1250 | int *pdata; | 1250 | int *pdata; |
| 1251 | IOCPage2_t *pIoc2; | 1251 | IOCPage2_t *pIoc2; |
| @@ -1822,7 +1822,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
| 1822 | case MPI_FUNCTION_SCSI_IO_REQUEST: | 1822 | case MPI_FUNCTION_SCSI_IO_REQUEST: |
| 1823 | if (ioc->sh) { | 1823 | if (ioc->sh) { |
| 1824 | SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; | 1824 | SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; |
| 1825 | VirtDevice *pTarget = NULL; | 1825 | VirtTarget *pTarget = NULL; |
| 1826 | MPT_SCSI_HOST *hd = NULL; | 1826 | MPT_SCSI_HOST *hd = NULL; |
| 1827 | int qtag = MPI_SCSIIO_CONTROL_UNTAGGED; | 1827 | int qtag = MPI_SCSIIO_CONTROL_UNTAGGED; |
| 1828 | int scsidir = 0; | 1828 | int scsidir = 0; |
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 531664f9e339..ba61e1828858 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
| @@ -90,8 +90,10 @@ static struct scsi_host_template mptfc_driver_template = { | |||
| 90 | .name = "MPT FC Host", | 90 | .name = "MPT FC Host", |
| 91 | .info = mptscsih_info, | 91 | .info = mptscsih_info, |
| 92 | .queuecommand = mptscsih_qcmd, | 92 | .queuecommand = mptscsih_qcmd, |
| 93 | .target_alloc = mptscsih_target_alloc, | ||
| 93 | .slave_alloc = mptscsih_slave_alloc, | 94 | .slave_alloc = mptscsih_slave_alloc, |
| 94 | .slave_configure = mptscsih_slave_configure, | 95 | .slave_configure = mptscsih_slave_configure, |
| 96 | .target_destroy = mptscsih_target_destroy, | ||
| 95 | .slave_destroy = mptscsih_slave_destroy, | 97 | .slave_destroy = mptscsih_slave_destroy, |
| 96 | .change_queue_depth = mptscsih_change_queue_depth, | 98 | .change_queue_depth = mptscsih_change_queue_depth, |
| 97 | .eh_abort_handler = mptscsih_abort, | 99 | .eh_abort_handler = mptscsih_abort, |
| @@ -292,10 +294,10 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 292 | } | 294 | } |
| 293 | 295 | ||
| 294 | memset(mem, 0, sz); | 296 | memset(mem, 0, sz); |
| 295 | hd->Targets = (VirtDevice **) mem; | 297 | hd->Targets = (VirtTarget **) mem; |
| 296 | 298 | ||
| 297 | dprintk((KERN_INFO | 299 | dprintk((KERN_INFO |
| 298 | " Targets @ %p, sz=%d\n", hd->Targets, sz)); | 300 | " vdev @ %p, sz=%d\n", hd->Targets, sz)); |
| 299 | 301 | ||
| 300 | /* Clear the TM flags | 302 | /* Clear the TM flags |
| 301 | */ | 303 | */ |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 282fb5ebbadf..17e9757e728b 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
| @@ -228,31 +228,35 @@ static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1) | |||
| 228 | * implement ->target_alloc. | 228 | * implement ->target_alloc. |
| 229 | */ | 229 | */ |
| 230 | static int | 230 | static int |
| 231 | mptsas_slave_alloc(struct scsi_device *device) | 231 | mptsas_slave_alloc(struct scsi_device *sdev) |
| 232 | { | 232 | { |
| 233 | struct Scsi_Host *host = device->host; | 233 | struct Scsi_Host *host = sdev->host; |
| 234 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 234 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; |
| 235 | struct sas_rphy *rphy; | 235 | struct sas_rphy *rphy; |
| 236 | struct mptsas_portinfo *p; | 236 | struct mptsas_portinfo *p; |
| 237 | VirtTarget *vtarget; | ||
| 237 | VirtDevice *vdev; | 238 | VirtDevice *vdev; |
| 238 | uint target = device->id; | 239 | struct scsi_target *starget; |
| 239 | int i; | 240 | int i; |
| 240 | 241 | ||
| 241 | if ((vdev = hd->Targets[target]) != NULL) | ||
| 242 | goto out; | ||
| 243 | |||
| 244 | vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); | 242 | vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); |
| 245 | if (!vdev) { | 243 | if (!vdev) { |
| 246 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", | 244 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", |
| 247 | hd->ioc->name, sizeof(VirtDevice)); | 245 | hd->ioc->name, sizeof(VirtDevice)); |
| 248 | return -ENOMEM; | 246 | return -ENOMEM; |
| 249 | } | 247 | } |
| 250 | |||
| 251 | memset(vdev, 0, sizeof(VirtDevice)); | 248 | memset(vdev, 0, sizeof(VirtDevice)); |
| 252 | vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
| 253 | vdev->ioc_id = hd->ioc->id; | 249 | vdev->ioc_id = hd->ioc->id; |
| 250 | sdev->hostdata = vdev; | ||
| 251 | starget = scsi_target(sdev); | ||
| 252 | vtarget = starget->hostdata; | ||
| 253 | vdev->vtarget = vtarget; | ||
| 254 | if (vtarget->num_luns == 0) { | ||
| 255 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
| 256 | hd->Targets[sdev->id] = vtarget; | ||
| 257 | } | ||
| 254 | 258 | ||
| 255 | rphy = dev_to_rphy(device->sdev_target->dev.parent); | 259 | rphy = dev_to_rphy(sdev->sdev_target->dev.parent); |
| 256 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { | 260 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { |
| 257 | for (i = 0; i < p->num_phys; i++) { | 261 | for (i = 0; i < p->num_phys; i++) { |
| 258 | if (p->phy_info[i].attached.sas_address == | 262 | if (p->phy_info[i].attached.sas_address == |
| @@ -260,7 +264,7 @@ mptsas_slave_alloc(struct scsi_device *device) | |||
| 260 | vdev->target_id = | 264 | vdev->target_id = |
| 261 | p->phy_info[i].attached.target; | 265 | p->phy_info[i].attached.target; |
| 262 | vdev->bus_id = p->phy_info[i].attached.bus; | 266 | vdev->bus_id = p->phy_info[i].attached.bus; |
| 263 | hd->Targets[device->id] = vdev; | 267 | vdev->lun = sdev->lun; |
| 264 | goto out; | 268 | goto out; |
| 265 | } | 269 | } |
| 266 | } | 270 | } |
| @@ -271,8 +275,10 @@ mptsas_slave_alloc(struct scsi_device *device) | |||
| 271 | return -ENODEV; | 275 | return -ENODEV; |
| 272 | 276 | ||
| 273 | out: | 277 | out: |
| 274 | vdev->num_luns++; | 278 | vtarget->ioc_id = vdev->ioc_id; |
| 275 | device->hostdata = vdev; | 279 | vtarget->target_id = vdev->target_id; |
| 280 | vtarget->bus_id = vdev->bus_id; | ||
| 281 | vtarget->num_luns++; | ||
| 276 | return 0; | 282 | return 0; |
| 277 | } | 283 | } |
| 278 | 284 | ||
| @@ -283,8 +289,10 @@ static struct scsi_host_template mptsas_driver_template = { | |||
| 283 | .name = "MPT SPI Host", | 289 | .name = "MPT SPI Host", |
| 284 | .info = mptscsih_info, | 290 | .info = mptscsih_info, |
| 285 | .queuecommand = mptscsih_qcmd, | 291 | .queuecommand = mptscsih_qcmd, |
| 292 | .target_alloc = mptscsih_target_alloc, | ||
| 286 | .slave_alloc = mptsas_slave_alloc, | 293 | .slave_alloc = mptsas_slave_alloc, |
| 287 | .slave_configure = mptscsih_slave_configure, | 294 | .slave_configure = mptscsih_slave_configure, |
| 295 | .target_destroy = mptscsih_target_destroy, | ||
| 288 | .slave_destroy = mptscsih_slave_destroy, | 296 | .slave_destroy = mptscsih_slave_destroy, |
| 289 | .change_queue_depth = mptscsih_change_queue_depth, | 297 | .change_queue_depth = mptscsih_change_queue_depth, |
| 290 | .eh_abort_handler = mptscsih_abort, | 298 | .eh_abort_handler = mptscsih_abort, |
| @@ -987,7 +995,6 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index) | |||
| 987 | goto out_free_port_info; | 995 | goto out_free_port_info; |
| 988 | 996 | ||
| 989 | list_add_tail(&port_info->list, &ioc->sas_topology); | 997 | list_add_tail(&port_info->list, &ioc->sas_topology); |
| 990 | |||
| 991 | for (i = 0; i < port_info->num_phys; i++) { | 998 | for (i = 0; i < port_info->num_phys; i++) { |
| 992 | mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], | 999 | mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], |
| 993 | (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER << | 1000 | (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER << |
| @@ -1263,10 +1270,10 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 1263 | } | 1270 | } |
| 1264 | 1271 | ||
| 1265 | memset(mem, 0, sz); | 1272 | memset(mem, 0, sz); |
| 1266 | hd->Targets = (VirtDevice **) mem; | 1273 | hd->Targets = (VirtTarget **) mem; |
| 1267 | 1274 | ||
| 1268 | dprintk((KERN_INFO | 1275 | dprintk((KERN_INFO |
| 1269 | " Targets @ %p, sz=%d\n", hd->Targets, sz)); | 1276 | " vtarget @ %p, sz=%d\n", hd->Targets, sz)); |
| 1270 | 1277 | ||
| 1271 | /* Clear the TM flags | 1278 | /* Clear the TM flags |
| 1272 | */ | 1279 | */ |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index a5ca7494c8c1..93a16fa3c4ba 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
| @@ -150,15 +150,16 @@ static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 tar | |||
| 150 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); | 150 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); |
| 151 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); | 151 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); |
| 152 | 152 | ||
| 153 | static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen); | 153 | static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen); |
| 154 | static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56); | 154 | static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56); |
| 155 | static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags); | 155 | static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags); |
| 156 | static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id); | 156 | static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc); |
| 157 | static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags); | 157 | static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags); |
| 158 | static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); | 158 | static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); |
| 159 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); | 159 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); |
| 160 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); | 160 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); |
| 161 | static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); | 161 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); |
| 162 | static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget); | ||
| 162 | static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); | 163 | static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); |
| 163 | 164 | ||
| 164 | static struct work_struct mptscsih_persistTask; | 165 | static struct work_struct mptscsih_persistTask; |
| @@ -171,7 +172,7 @@ static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); | |||
| 171 | static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); | 172 | static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); |
| 172 | static void mptscsih_fillbuf(char *buffer, int size, int index, int width); | 173 | static void mptscsih_fillbuf(char *buffer, int size, int index, int width); |
| 173 | static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id); | 174 | static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id); |
| 174 | static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq); | 175 | static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc); |
| 175 | #endif | 176 | #endif |
| 176 | 177 | ||
| 177 | void mptscsih_remove(struct pci_dev *); | 178 | 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 | dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n" | 628 | dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n" |
| 628 | "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n" | 629 | "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n" |
| 629 | "resid=%d bufflen=%d xfer_cnt=%d\n", | 630 | "resid=%d bufflen=%d xfer_cnt=%d\n", |
| 630 | ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1], | 631 | ioc->id, sc->device->id, sc->device->lun, |
| 631 | status, scsi_state, scsi_status, sc->resid, | 632 | status, scsi_state, scsi_status, sc->resid, |
| 632 | sc->request_bufflen, xfer_cnt)); | 633 | sc->request_bufflen, xfer_cnt)); |
| 633 | 634 | ||
| @@ -641,7 +642,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
| 641 | pScsiReply->ResponseInfo) { | 642 | pScsiReply->ResponseInfo) { |
| 642 | printk(KERN_NOTICE "ha=%d id=%d lun=%d: " | 643 | printk(KERN_NOTICE "ha=%d id=%d lun=%d: " |
| 643 | "FCP_ResponseInfo=%08xh\n", | 644 | "FCP_ResponseInfo=%08xh\n", |
| 644 | ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1], | 645 | ioc->id, sc->device->id, sc->device->lun, |
| 645 | le32_to_cpu(pScsiReply->ResponseInfo)); | 646 | le32_to_cpu(pScsiReply->ResponseInfo)); |
| 646 | } | 647 | } |
| 647 | 648 | ||
| @@ -678,7 +679,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
| 678 | 679 | ||
| 679 | /* GEM Workaround. */ | 680 | /* GEM Workaround. */ |
| 680 | if (ioc->bus_type == SPI) | 681 | if (ioc->bus_type == SPI) |
| 681 | mptscsih_no_negotiate(hd, sc->device->id); | 682 | mptscsih_no_negotiate(hd, sc); |
| 682 | break; | 683 | break; |
| 683 | 684 | ||
| 684 | case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ | 685 | case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ |
| @@ -892,16 +893,15 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) | |||
| 892 | * when a lun is disable by mid-layer. | 893 | * when a lun is disable by mid-layer. |
| 893 | * Do NOT access the referenced scsi_cmnd structure or | 894 | * Do NOT access the referenced scsi_cmnd structure or |
| 894 | * members. Will cause either a paging or NULL ptr error. | 895 | * members. Will cause either a paging or NULL ptr error. |
| 895 | * @hd: Pointer to a SCSI HOST structure | 896 | * @hd: Pointer to a SCSI HOST structure |
| 896 | * @target: target id | 897 | * @vdevice: per device private data |
| 897 | * @lun: lun | ||
| 898 | * | 898 | * |
| 899 | * Returns: None. | 899 | * Returns: None. |
| 900 | * | 900 | * |
| 901 | * Called from slave_destroy. | 901 | * Called from slave_destroy. |
| 902 | */ | 902 | */ |
| 903 | static void | 903 | static void |
| 904 | mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) | 904 | mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) |
| 905 | { | 905 | { |
| 906 | SCSIIORequest_t *mf = NULL; | 906 | SCSIIORequest_t *mf = NULL; |
| 907 | int ii; | 907 | int ii; |
| @@ -909,7 +909,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) | |||
| 909 | struct scsi_cmnd *sc; | 909 | struct scsi_cmnd *sc; |
| 910 | 910 | ||
| 911 | dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", | 911 | dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", |
| 912 | target, lun, max)); | 912 | vdevice->target_id, vdevice->lun, max)); |
| 913 | 913 | ||
| 914 | for (ii=0; ii < max; ii++) { | 914 | for (ii=0; ii < max; ii++) { |
| 915 | if ((sc = hd->ScsiLookup[ii]) != NULL) { | 915 | if ((sc = hd->ScsiLookup[ii]) != NULL) { |
| @@ -919,7 +919,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) | |||
| 919 | dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", | 919 | dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", |
| 920 | hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); | 920 | hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); |
| 921 | 921 | ||
| 922 | if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun))) | 922 | if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) |
| 923 | continue; | 923 | continue; |
| 924 | 924 | ||
| 925 | /* Cleanup | 925 | /* Cleanup |
| @@ -996,7 +996,7 @@ mptscsih_remove(struct pci_dev *pdev) | |||
| 996 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION | 996 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION |
| 997 | int count; | 997 | int count; |
| 998 | unsigned long flags; | 998 | unsigned long flags; |
| 999 | #endif | 999 | #endif |
| 1000 | int sz1; | 1000 | int sz1; |
| 1001 | 1001 | ||
| 1002 | if(!host) { | 1002 | if(!host) { |
| @@ -1077,11 +1077,6 @@ mptscsih_shutdown(struct pci_dev *pdev) | |||
| 1077 | 1077 | ||
| 1078 | hd = (MPT_SCSI_HOST *)host->hostdata; | 1078 | hd = (MPT_SCSI_HOST *)host->hostdata; |
| 1079 | 1079 | ||
| 1080 | /* Flush the cache of this adapter | ||
| 1081 | */ | ||
| 1082 | if(hd != NULL) | ||
| 1083 | mptscsih_synchronize_cache(hd, 0); | ||
| 1084 | |||
| 1085 | } | 1080 | } |
| 1086 | 1081 | ||
| 1087 | #ifdef CONFIG_PM | 1082 | #ifdef CONFIG_PM |
| @@ -1288,7 +1283,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
| 1288 | MPT_SCSI_HOST *hd; | 1283 | MPT_SCSI_HOST *hd; |
| 1289 | MPT_FRAME_HDR *mf; | 1284 | MPT_FRAME_HDR *mf; |
| 1290 | SCSIIORequest_t *pScsiReq; | 1285 | SCSIIORequest_t *pScsiReq; |
| 1291 | VirtDevice *pTarget = SCpnt->device->hostdata; | 1286 | VirtDevice *vdev = SCpnt->device->hostdata; |
| 1292 | int lun; | 1287 | int lun; |
| 1293 | u32 datalen; | 1288 | u32 datalen; |
| 1294 | u32 scsictl; | 1289 | u32 scsictl; |
| @@ -1343,8 +1338,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
| 1343 | /* Default to untagged. Once a target structure has been allocated, | 1338 | /* Default to untagged. Once a target structure has been allocated, |
| 1344 | * use the Inquiry data to determine if device supports tagged. | 1339 | * use the Inquiry data to determine if device supports tagged. |
| 1345 | */ | 1340 | */ |
| 1346 | if (pTarget | 1341 | if (vdev |
| 1347 | && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES) | 1342 | && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) |
| 1348 | && (SCpnt->device->tagged_supported)) { | 1343 | && (SCpnt->device->tagged_supported)) { |
| 1349 | scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; | 1344 | scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; |
| 1350 | } else { | 1345 | } else { |
| @@ -1353,8 +1348,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
| 1353 | 1348 | ||
| 1354 | /* Use the above information to set up the message frame | 1349 | /* Use the above information to set up the message frame |
| 1355 | */ | 1350 | */ |
| 1356 | pScsiReq->TargetID = (u8) pTarget->target_id; | 1351 | pScsiReq->TargetID = (u8) vdev->target_id; |
| 1357 | pScsiReq->Bus = pTarget->bus_id; | 1352 | pScsiReq->Bus = vdev->bus_id; |
| 1358 | pScsiReq->ChainOffset = 0; | 1353 | pScsiReq->ChainOffset = 0; |
| 1359 | pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; | 1354 | pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; |
| 1360 | pScsiReq->CDBLength = SCpnt->cmd_len; | 1355 | pScsiReq->CDBLength = SCpnt->cmd_len; |
| @@ -1406,7 +1401,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
| 1406 | 1401 | ||
| 1407 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION | 1402 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION |
| 1408 | if (hd->ioc->bus_type == SPI) { | 1403 | if (hd->ioc->bus_type == SPI) { |
| 1409 | int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id]; | 1404 | int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id]; |
| 1410 | int issueCmd = 1; | 1405 | int issueCmd = 1; |
| 1411 | 1406 | ||
| 1412 | if (dvStatus || hd->ioc->spi_data.forceDv) { | 1407 | if (dvStatus || hd->ioc->spi_data.forceDv) { |
| @@ -1439,7 +1434,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
| 1439 | /* Set the DV flags. | 1434 | /* Set the DV flags. |
| 1440 | */ | 1435 | */ |
| 1441 | if (dvStatus & MPT_SCSICFG_DV_NOT_DONE) | 1436 | if (dvStatus & MPT_SCSICFG_DV_NOT_DONE) |
| 1442 | mptscsih_set_dvflags(hd, pScsiReq); | 1437 | mptscsih_set_dvflags(hd, SCpnt); |
| 1443 | 1438 | ||
| 1444 | if (!issueCmd) | 1439 | if (!issueCmd) |
| 1445 | goto fail; | 1440 | goto fail; |
| @@ -1743,6 +1738,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
| 1743 | u32 ctx2abort; | 1738 | u32 ctx2abort; |
| 1744 | int scpnt_idx; | 1739 | int scpnt_idx; |
| 1745 | int retval; | 1740 | int retval; |
| 1741 | VirtDevice *vdev; | ||
| 1746 | 1742 | ||
| 1747 | /* If we can't locate our host adapter structure, return FAILED status. | 1743 | /* If we can't locate our host adapter structure, return FAILED status. |
| 1748 | */ | 1744 | */ |
| @@ -1792,8 +1788,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
| 1792 | 1788 | ||
| 1793 | hd->abortSCpnt = SCpnt; | 1789 | hd->abortSCpnt = SCpnt; |
| 1794 | 1790 | ||
| 1791 | vdev = SCpnt->device->hostdata; | ||
| 1795 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, | 1792 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, |
| 1796 | SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, | 1793 | vdev->bus_id, vdev->target_id, vdev->lun, |
| 1797 | ctx2abort, 2 /* 2 second timeout */); | 1794 | ctx2abort, 2 /* 2 second timeout */); |
| 1798 | 1795 | ||
| 1799 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", | 1796 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", |
| @@ -1824,6 +1821,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
| 1824 | { | 1821 | { |
| 1825 | MPT_SCSI_HOST *hd; | 1822 | MPT_SCSI_HOST *hd; |
| 1826 | int retval; | 1823 | int retval; |
| 1824 | VirtDevice *vdev; | ||
| 1827 | 1825 | ||
| 1828 | /* If we can't locate our host adapter structure, return FAILED status. | 1826 | /* If we can't locate our host adapter structure, return FAILED status. |
| 1829 | */ | 1827 | */ |
| @@ -1841,8 +1839,9 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
| 1841 | hd->ioc->name, SCpnt); | 1839 | hd->ioc->name, SCpnt); |
| 1842 | scsi_print_command(SCpnt); | 1840 | scsi_print_command(SCpnt); |
| 1843 | 1841 | ||
| 1842 | vdev = SCpnt->device->hostdata; | ||
| 1844 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | 1843 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, |
| 1845 | SCpnt->device->channel, SCpnt->device->id, | 1844 | vdev->bus_id, vdev->target_id, |
| 1846 | 0, 0, 5 /* 5 second timeout */); | 1845 | 0, 0, 5 /* 5 second timeout */); |
| 1847 | 1846 | ||
| 1848 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", | 1847 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", |
| @@ -1873,6 +1872,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | |||
| 1873 | { | 1872 | { |
| 1874 | MPT_SCSI_HOST *hd; | 1873 | MPT_SCSI_HOST *hd; |
| 1875 | int retval; | 1874 | int retval; |
| 1875 | VirtDevice *vdev; | ||
| 1876 | 1876 | ||
| 1877 | /* If we can't locate our host adapter structure, return FAILED status. | 1877 | /* If we can't locate our host adapter structure, return FAILED status. |
| 1878 | */ | 1878 | */ |
| @@ -1890,8 +1890,9 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | |||
| 1890 | if (hd->timeouts < -1) | 1890 | if (hd->timeouts < -1) |
| 1891 | hd->timeouts++; | 1891 | hd->timeouts++; |
| 1892 | 1892 | ||
| 1893 | vdev = SCpnt->device->hostdata; | ||
| 1893 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, | 1894 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, |
| 1894 | SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */); | 1895 | vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */); |
| 1895 | 1896 | ||
| 1896 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", | 1897 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", |
| 1897 | hd->ioc->name, | 1898 | hd->ioc->name, |
| @@ -2153,23 +2154,36 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, | |||
| 2153 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2154 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
| 2154 | /* | 2155 | /* |
| 2155 | * OS entry point to allow host driver to alloc memory | 2156 | * OS entry point to allow host driver to alloc memory |
| 2157 | * for each scsi target. Called once per device the bus scan. | ||
| 2158 | * Return non-zero if allocation fails. | ||
| 2159 | */ | ||
| 2160 | int | ||
| 2161 | mptscsih_target_alloc(struct scsi_target *starget) | ||
| 2162 | { | ||
| 2163 | VirtTarget *vtarget; | ||
| 2164 | |||
| 2165 | vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL); | ||
| 2166 | if (!vtarget) | ||
| 2167 | return -ENOMEM; | ||
| 2168 | memset(vtarget, 0, sizeof(VirtTarget)); | ||
| 2169 | starget->hostdata = vtarget; | ||
| 2170 | return 0; | ||
| 2171 | } | ||
| 2172 | |||
| 2173 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
| 2174 | /* | ||
| 2175 | * OS entry point to allow host driver to alloc memory | ||
| 2156 | * for each scsi device. Called once per device the bus scan. | 2176 | * for each scsi device. Called once per device the bus scan. |
| 2157 | * Return non-zero if allocation fails. | 2177 | * Return non-zero if allocation fails. |
| 2158 | * Init memory once per id (not LUN). | ||
| 2159 | */ | 2178 | */ |
| 2160 | int | 2179 | int |
| 2161 | mptscsih_slave_alloc(struct scsi_device *device) | 2180 | mptscsih_slave_alloc(struct scsi_device *sdev) |
| 2162 | { | 2181 | { |
| 2163 | struct Scsi_Host *host = device->host; | 2182 | struct Scsi_Host *host = sdev->host; |
| 2164 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 2183 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; |
| 2184 | VirtTarget *vtarget; | ||
| 2165 | VirtDevice *vdev; | 2185 | VirtDevice *vdev; |
| 2166 | uint target = device->id; | 2186 | struct scsi_target *starget; |
| 2167 | |||
| 2168 | if (hd == NULL) | ||
| 2169 | return -ENODEV; | ||
| 2170 | |||
| 2171 | if ((vdev = hd->Targets[target]) != NULL) | ||
| 2172 | goto out; | ||
| 2173 | 2187 | ||
| 2174 | vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); | 2188 | vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); |
| 2175 | if (!vdev) { | 2189 | if (!vdev) { |
| @@ -2179,25 +2193,33 @@ mptscsih_slave_alloc(struct scsi_device *device) | |||
| 2179 | } | 2193 | } |
| 2180 | 2194 | ||
| 2181 | memset(vdev, 0, sizeof(VirtDevice)); | 2195 | memset(vdev, 0, sizeof(VirtDevice)); |
| 2182 | vdev->tflags = MPT_TARGET_FLAGS_Q_YES; | ||
| 2183 | vdev->ioc_id = hd->ioc->id; | 2196 | vdev->ioc_id = hd->ioc->id; |
| 2184 | vdev->target_id = device->id; | 2197 | vdev->target_id = sdev->id; |
| 2185 | vdev->bus_id = device->channel; | 2198 | vdev->bus_id = sdev->channel; |
| 2186 | vdev->raidVolume = 0; | 2199 | vdev->lun = sdev->lun; |
| 2187 | hd->Targets[device->id] = vdev; | 2200 | sdev->hostdata = vdev; |
| 2188 | if (hd->ioc->bus_type == SPI) { | 2201 | |
| 2189 | if (hd->ioc->raid_data.isRaid & (1 << device->id)) { | 2202 | starget = scsi_target(sdev); |
| 2190 | vdev->raidVolume = 1; | 2203 | vtarget = starget->hostdata; |
| 2191 | ddvtprintk((KERN_INFO | 2204 | vdev->vtarget = vtarget; |
| 2192 | "RAID Volume @ id %d\n", device->id)); | 2205 | |
| 2206 | if (vtarget->num_luns == 0) { | ||
| 2207 | hd->Targets[sdev->id] = vtarget; | ||
| 2208 | vtarget->ioc_id = hd->ioc->id; | ||
| 2209 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; | ||
| 2210 | vtarget->target_id = sdev->id; | ||
| 2211 | vtarget->bus_id = sdev->channel; | ||
| 2212 | if (hd->ioc->bus_type == SPI) { | ||
| 2213 | if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) { | ||
| 2214 | vtarget->raidVolume = 1; | ||
| 2215 | ddvtprintk((KERN_INFO | ||
| 2216 | "RAID Volume @ id %d\n", sdev->id)); | ||
| 2217 | } | ||
| 2218 | } else { | ||
| 2219 | vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
| 2193 | } | 2220 | } |
| 2194 | } else { | ||
| 2195 | vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
| 2196 | } | 2221 | } |
| 2197 | 2222 | vtarget->num_luns++; | |
| 2198 | out: | ||
| 2199 | vdev->num_luns++; | ||
| 2200 | device->hostdata = vdev; | ||
| 2201 | return 0; | 2223 | return 0; |
| 2202 | } | 2224 | } |
| 2203 | 2225 | ||
| @@ -2206,40 +2228,52 @@ mptscsih_slave_alloc(struct scsi_device *device) | |||
| 2206 | * Called if no device present or device being unloaded | 2228 | * Called if no device present or device being unloaded |
| 2207 | */ | 2229 | */ |
| 2208 | void | 2230 | void |
| 2209 | mptscsih_slave_destroy(struct scsi_device *device) | 2231 | mptscsih_target_destroy(struct scsi_target *starget) |
| 2210 | { | 2232 | { |
| 2211 | struct Scsi_Host *host = device->host; | 2233 | if (starget->hostdata) |
| 2212 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 2234 | kfree(starget->hostdata); |
| 2213 | VirtDevice *vdev; | 2235 | starget->hostdata = NULL; |
| 2214 | uint target = device->id; | 2236 | } |
| 2215 | uint lun = device->lun; | ||
| 2216 | |||
| 2217 | if (hd == NULL) | ||
| 2218 | return; | ||
| 2219 | |||
| 2220 | mptscsih_search_running_cmds(hd, target, lun); | ||
| 2221 | |||
| 2222 | vdev = hd->Targets[target]; | ||
| 2223 | vdev->luns[0] &= ~(1 << lun); | ||
| 2224 | if (--vdev->num_luns) | ||
| 2225 | return; | ||
| 2226 | |||
| 2227 | kfree(hd->Targets[target]); | ||
| 2228 | hd->Targets[target] = NULL; | ||
| 2229 | |||
| 2230 | if (hd->ioc->bus_type == SPI) { | ||
| 2231 | if (mptscsih_is_phys_disk(hd->ioc, target)) { | ||
| 2232 | hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; | ||
| 2233 | } else { | ||
| 2234 | hd->ioc->spi_data.dvStatus[target] = | ||
| 2235 | MPT_SCSICFG_NEGOTIATE; | ||
| 2236 | 2237 | ||
| 2237 | if (!hd->negoNvram) { | 2238 | /* |
| 2238 | hd->ioc->spi_data.dvStatus[target] |= | 2239 | * OS entry point to allow for host driver to free allocated memory |
| 2239 | MPT_SCSICFG_DV_NOT_DONE; | 2240 | * Called if no device present or device being unloaded |
| 2241 | */ | ||
| 2242 | void | ||
| 2243 | mptscsih_slave_destroy(struct scsi_device *sdev) | ||
| 2244 | { | ||
| 2245 | struct Scsi_Host *host = sdev->host; | ||
| 2246 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
| 2247 | VirtTarget *vtarget; | ||
| 2248 | VirtDevice *vdevice; | ||
| 2249 | struct scsi_target *starget; | ||
| 2250 | |||
| 2251 | starget = scsi_target(sdev); | ||
| 2252 | vtarget = starget->hostdata; | ||
| 2253 | vdevice = sdev->hostdata; | ||
| 2254 | |||
| 2255 | mptscsih_search_running_cmds(hd, vdevice); | ||
| 2256 | vtarget->luns[0] &= ~(1 << vdevice->lun); | ||
| 2257 | vtarget->num_luns--; | ||
| 2258 | if (vtarget->num_luns == 0) { | ||
| 2259 | mptscsih_negotiate_to_asyn_narrow(hd, vtarget); | ||
| 2260 | if (hd->ioc->bus_type == SPI) { | ||
| 2261 | if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) { | ||
| 2262 | hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; | ||
| 2263 | } else { | ||
| 2264 | hd->ioc->spi_data.dvStatus[vtarget->target_id] = | ||
| 2265 | MPT_SCSICFG_NEGOTIATE; | ||
| 2266 | if (!hd->negoNvram) { | ||
| 2267 | hd->ioc->spi_data.dvStatus[vtarget->target_id] |= | ||
| 2268 | MPT_SCSICFG_DV_NOT_DONE; | ||
| 2269 | } | ||
| 2240 | } | 2270 | } |
| 2241 | } | 2271 | } |
| 2272 | hd->Targets[sdev->id] = NULL; | ||
| 2242 | } | 2273 | } |
| 2274 | mptscsih_synchronize_cache(hd, vdevice); | ||
| 2275 | kfree(vdevice); | ||
| 2276 | sdev->hostdata = NULL; | ||
| 2243 | } | 2277 | } |
| 2244 | 2278 | ||
| 2245 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2279 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
| @@ -2253,22 +2287,21 @@ mptscsih_slave_destroy(struct scsi_device *device) | |||
| 2253 | int | 2287 | int |
| 2254 | mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | 2288 | mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) |
| 2255 | { | 2289 | { |
| 2256 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; | 2290 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; |
| 2257 | VirtDevice *pTarget; | 2291 | VirtTarget *vtarget; |
| 2258 | int max_depth; | 2292 | struct scsi_target *starget; |
| 2259 | int tagged; | 2293 | int max_depth; |
| 2294 | int tagged; | ||
| 2260 | 2295 | ||
| 2261 | if (hd == NULL) | 2296 | starget = scsi_target(sdev); |
| 2262 | return 0; | 2297 | vtarget = starget->hostdata; |
| 2263 | if (!(pTarget = hd->Targets[sdev->id])) | ||
| 2264 | return 0; | ||
| 2265 | 2298 | ||
| 2266 | if (hd->ioc->bus_type == SPI) { | 2299 | if (hd->ioc->bus_type == SPI) { |
| 2267 | if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { | 2300 | if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { |
| 2268 | if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) | 2301 | if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) |
| 2269 | max_depth = 1; | 2302 | max_depth = 1; |
| 2270 | else if (((pTarget->inq_data[0] & 0x1f) == 0x00) && | 2303 | else if (((vtarget->inq_data[0] & 0x1f) == 0x00) && |
| 2271 | (pTarget->minSyncFactor <= MPT_ULTRA160 )) | 2304 | (vtarget->minSyncFactor <= MPT_ULTRA160 )) |
| 2272 | max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; | 2305 | max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; |
| 2273 | else | 2306 | else |
| 2274 | max_depth = MPT_SCSI_CMD_PER_DEV_LOW; | 2307 | max_depth = MPT_SCSI_CMD_PER_DEV_LOW; |
| @@ -2297,64 +2330,58 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | |||
| 2297 | * Return non-zero if fails. | 2330 | * Return non-zero if fails. |
| 2298 | */ | 2331 | */ |
| 2299 | int | 2332 | int |
| 2300 | mptscsih_slave_configure(struct scsi_device *device) | 2333 | mptscsih_slave_configure(struct scsi_device *sdev) |
| 2301 | { | 2334 | { |
| 2302 | struct Scsi_Host *sh = device->host; | 2335 | struct Scsi_Host *sh = sdev->host; |
| 2303 | VirtDevice *pTarget; | 2336 | VirtTarget *vtarget; |
| 2337 | VirtDevice *vdevice; | ||
| 2338 | struct scsi_target *starget; | ||
| 2304 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; | 2339 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; |
| 2340 | int indexed_lun, lun_index; | ||
| 2305 | 2341 | ||
| 2306 | if ((hd == NULL) || (hd->Targets == NULL)) { | 2342 | starget = scsi_target(sdev); |
| 2307 | return 0; | 2343 | vtarget = starget->hostdata; |
| 2308 | } | 2344 | vdevice = sdev->hostdata; |
| 2309 | 2345 | ||
| 2310 | dsprintk((MYIOC_s_INFO_FMT | 2346 | dsprintk((MYIOC_s_INFO_FMT |
| 2311 | "device @ %p, id=%d, LUN=%d, channel=%d\n", | 2347 | "device @ %p, id=%d, LUN=%d, channel=%d\n", |
| 2312 | hd->ioc->name, device, device->id, device->lun, device->channel)); | 2348 | hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel)); |
| 2313 | dsprintk((MYIOC_s_INFO_FMT | 2349 | if (hd->ioc->bus_type == SPI) |
| 2314 | "sdtr %d wdtr %d ppr %d inq length=%d\n", | 2350 | dsprintk((MYIOC_s_INFO_FMT |
| 2315 | hd->ioc->name, device->sdtr, device->wdtr, | 2351 | "sdtr %d wdtr %d ppr %d inq length=%d\n", |
| 2316 | device->ppr, device->inquiry_len)); | 2352 | hd->ioc->name, sdev->sdtr, sdev->wdtr, |
| 2317 | 2353 | sdev->ppr, sdev->inquiry_len)); | |
| 2318 | if (device->id > sh->max_id) { | 2354 | |
| 2355 | if (sdev->id > sh->max_id) { | ||
| 2319 | /* error case, should never happen */ | 2356 | /* error case, should never happen */ |
| 2320 | scsi_adjust_queue_depth(device, 0, 1); | 2357 | scsi_adjust_queue_depth(sdev, 0, 1); |
| 2321 | goto slave_configure_exit; | ||
| 2322 | } | ||
| 2323 | |||
| 2324 | pTarget = hd->Targets[device->id]; | ||
| 2325 | |||
| 2326 | if (pTarget == NULL) { | ||
| 2327 | /* Driver doesn't know about this device. | ||
| 2328 | * Kernel may generate a "Dummy Lun 0" which | ||
| 2329 | * may become a real Lun if a | ||
| 2330 | * "scsi add-single-device" command is executed | ||
| 2331 | * while the driver is active (hot-plug a | ||
| 2332 | * device). LSI Raid controllers need | ||
| 2333 | * queue_depth set to DEV_HIGH for this reason. | ||
| 2334 | */ | ||
| 2335 | scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, | ||
| 2336 | MPT_SCSI_CMD_PER_DEV_HIGH); | ||
| 2337 | goto slave_configure_exit; | 2358 | goto slave_configure_exit; |
| 2338 | } | 2359 | } |
| 2339 | 2360 | ||
| 2340 | mptscsih_initTarget(hd, device->channel, device->id, device->lun, | 2361 | vdevice->configured_lun=1; |
| 2341 | device->inquiry, device->inquiry_len ); | 2362 | lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */ |
| 2342 | mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH); | 2363 | indexed_lun = (vdevice->lun % 32); |
| 2364 | vtarget->luns[lun_index] |= (1 << indexed_lun); | ||
| 2365 | mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry, | ||
| 2366 | sdev->inquiry_len ); | ||
| 2367 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); | ||
| 2343 | 2368 | ||
| 2344 | dsprintk((MYIOC_s_INFO_FMT | 2369 | dsprintk((MYIOC_s_INFO_FMT |
| 2345 | "Queue depth=%d, tflags=%x\n", | 2370 | "Queue depth=%d, tflags=%x\n", |
| 2346 | hd->ioc->name, device->queue_depth, pTarget->tflags)); | 2371 | hd->ioc->name, sdev->queue_depth, vtarget->tflags)); |
| 2347 | 2372 | ||
| 2348 | dsprintk((MYIOC_s_INFO_FMT | 2373 | if (hd->ioc->bus_type == SPI) |
| 2349 | "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n", | 2374 | dsprintk((MYIOC_s_INFO_FMT |
| 2350 | hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor)); | 2375 | "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n", |
| 2376 | hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset, | ||
| 2377 | vtarget->minSyncFactor)); | ||
| 2351 | 2378 | ||
| 2352 | slave_configure_exit: | 2379 | slave_configure_exit: |
| 2353 | 2380 | ||
| 2354 | dsprintk((MYIOC_s_INFO_FMT | 2381 | dsprintk((MYIOC_s_INFO_FMT |
| 2355 | "tagged %d, simple %d, ordered %d\n", | 2382 | "tagged %d, simple %d, ordered %d\n", |
| 2356 | hd->ioc->name,device->tagged_supported, device->simple_tags, | 2383 | hd->ioc->name,sdev->tagged_supported, sdev->simple_tags, |
| 2357 | device->ordered_tags)); | 2384 | sdev->ordered_tags)); |
| 2358 | 2385 | ||
| 2359 | return 0; | 2386 | return 0; |
| 2360 | } | 2387 | } |
| @@ -2372,16 +2399,14 @@ slave_configure_exit: | |||
| 2372 | static void | 2399 | static void |
| 2373 | mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply) | 2400 | mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply) |
| 2374 | { | 2401 | { |
| 2375 | VirtDevice *target; | 2402 | VirtDevice *vdev; |
| 2376 | SCSIIORequest_t *pReq; | 2403 | SCSIIORequest_t *pReq; |
| 2377 | u32 sense_count = le32_to_cpu(pScsiReply->SenseCount); | 2404 | u32 sense_count = le32_to_cpu(pScsiReply->SenseCount); |
| 2378 | int index; | ||
| 2379 | 2405 | ||
| 2380 | /* Get target structure | 2406 | /* Get target structure |
| 2381 | */ | 2407 | */ |
| 2382 | pReq = (SCSIIORequest_t *) mf; | 2408 | pReq = (SCSIIORequest_t *) mf; |
| 2383 | index = (int) pReq->TargetID; | 2409 | vdev = sc->device->hostdata; |
| 2384 | target = hd->Targets[index]; | ||
| 2385 | 2410 | ||
| 2386 | if (sense_count) { | 2411 | if (sense_count) { |
| 2387 | u8 *sense_data; | 2412 | u8 *sense_data; |
| @@ -2395,7 +2420,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR | |||
| 2395 | /* Log SMART data (asc = 0x5D, non-IM case only) if required. | 2420 | /* Log SMART data (asc = 0x5D, non-IM case only) if required. |
| 2396 | */ | 2421 | */ |
| 2397 | if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) { | 2422 | if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) { |
| 2398 | if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) { | 2423 | if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) { |
| 2399 | int idx; | 2424 | int idx; |
| 2400 | MPT_ADAPTER *ioc = hd->ioc; | 2425 | MPT_ADAPTER *ioc = hd->ioc; |
| 2401 | 2426 | ||
| @@ -2405,7 +2430,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR | |||
| 2405 | 2430 | ||
| 2406 | ioc->events[idx].data[0] = (pReq->LUN[1] << 24) || | 2431 | ioc->events[idx].data[0] = (pReq->LUN[1] << 24) || |
| 2407 | (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) || | 2432 | (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) || |
| 2408 | (pReq->Bus << 8) || pReq->TargetID; | 2433 | (sc->device->channel << 8) || sc->device->id; |
| 2409 | 2434 | ||
| 2410 | ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12]; | 2435 | ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12]; |
| 2411 | 2436 | ||
| @@ -2634,8 +2659,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
| 2634 | /* | 2659 | /* |
| 2635 | * mptscsih_initTarget - Target, LUN alloc/free functionality. | 2660 | * mptscsih_initTarget - Target, LUN alloc/free functionality. |
| 2636 | * @hd: Pointer to MPT_SCSI_HOST structure | 2661 | * @hd: Pointer to MPT_SCSI_HOST structure |
| 2637 | * @bus_id: Bus number (?) | 2662 | * @vtarget: per target private data |
| 2638 | * @target_id: SCSI target id | ||
| 2639 | * @lun: SCSI LUN id | 2663 | * @lun: SCSI LUN id |
| 2640 | * @data: Pointer to data | 2664 | * @data: Pointer to data |
| 2641 | * @dlen: Number of INQUIRY bytes | 2665 | * @dlen: Number of INQUIRY bytes |
| @@ -2648,15 +2672,14 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
| 2648 | * | 2672 | * |
| 2649 | */ | 2673 | */ |
| 2650 | static void | 2674 | static void |
| 2651 | mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen) | 2675 | mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen) |
| 2652 | { | 2676 | { |
| 2653 | int indexed_lun, lun_index; | ||
| 2654 | VirtDevice *vdev; | ||
| 2655 | SpiCfgData *pSpi; | 2677 | SpiCfgData *pSpi; |
| 2656 | char data_56; | 2678 | char data_56; |
| 2679 | int inq_len; | ||
| 2657 | 2680 | ||
| 2658 | dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", | 2681 | dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", |
| 2659 | hd->ioc->name, bus_id, target_id, lun, hd)); | 2682 | hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd)); |
| 2660 | 2683 | ||
| 2661 | /* | 2684 | /* |
| 2662 | * If the peripheral qualifier filter is enabled then if the target reports a 0x1 | 2685 | * 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 | if (data[0] & 0xe0) | 2699 | if (data[0] & 0xe0) |
| 2677 | return; | 2700 | return; |
| 2678 | 2701 | ||
| 2679 | if ((vdev = hd->Targets[target_id]) == NULL) { | 2702 | if (vtarget == NULL) |
| 2680 | return; | 2703 | return; |
| 2681 | } | ||
| 2682 | 2704 | ||
| 2683 | lun_index = (lun >> 5); /* 32 luns per lun_index */ | 2705 | if (data) |
| 2684 | indexed_lun = (lun % 32); | 2706 | vtarget->type = data[0]; |
| 2685 | vdev->luns[lun_index] |= (1 << indexed_lun); | ||
| 2686 | 2707 | ||
| 2687 | if (hd->ioc->bus_type == SPI) { | 2708 | if (hd->ioc->bus_type != SPI) |
| 2688 | if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { | 2709 | return; |
| 2689 | /* Treat all Processors as SAF-TE if | 2710 | |
| 2690 | * command line option is set */ | 2711 | if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { |
| 2691 | vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | 2712 | /* Treat all Processors as SAF-TE if |
| 2692 | mptscsih_writeIOCPage4(hd, target_id, bus_id); | 2713 | * command line option is set */ |
| 2693 | }else if ((data[0] == TYPE_PROCESSOR) && | 2714 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; |
| 2694 | !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { | 2715 | mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); |
| 2695 | if ( dlen > 49 ) { | 2716 | }else if ((data[0] == TYPE_PROCESSOR) && |
| 2696 | vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; | 2717 | !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { |
| 2697 | if ( data[44] == 'S' && | 2718 | if ( dlen > 49 ) { |
| 2698 | data[45] == 'A' && | 2719 | vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; |
| 2699 | data[46] == 'F' && | 2720 | if ( data[44] == 'S' && |
| 2700 | data[47] == '-' && | 2721 | data[45] == 'A' && |
| 2701 | data[48] == 'T' && | 2722 | data[46] == 'F' && |
| 2702 | data[49] == 'E' ) { | 2723 | data[47] == '-' && |
| 2703 | vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | 2724 | data[48] == 'T' && |
| 2704 | mptscsih_writeIOCPage4(hd, target_id, bus_id); | 2725 | data[49] == 'E' ) { |
| 2705 | } | 2726 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; |
| 2727 | mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); | ||
| 2706 | } | 2728 | } |
| 2707 | } | 2729 | } |
| 2708 | if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { | 2730 | } |
| 2709 | if ( dlen > 8 ) { | 2731 | if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { |
| 2710 | memcpy (vdev->inq_data, data, 8); | 2732 | inq_len = dlen < 8 ? dlen : 8; |
| 2711 | } else { | 2733 | memcpy (vtarget->inq_data, data, inq_len); |
| 2712 | memcpy (vdev->inq_data, data, dlen); | 2734 | /* If have not done DV, set the DV flag. |
| 2713 | } | 2735 | */ |
| 2736 | pSpi = &hd->ioc->spi_data; | ||
| 2737 | if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) { | ||
| 2738 | if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE) | ||
| 2739 | pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV; | ||
| 2740 | } | ||
| 2741 | vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
| 2714 | 2742 | ||
| 2715 | /* If have not done DV, set the DV flag. | 2743 | data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */ |
| 2744 | if (dlen > 56) { | ||
| 2745 | if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) { | ||
| 2746 | /* Update the target capabilities | ||
| 2716 | */ | 2747 | */ |
| 2717 | pSpi = &hd->ioc->spi_data; | 2748 | data_56 = data[56]; |
| 2718 | if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) { | 2749 | vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56; |
| 2719 | if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE) | ||
| 2720 | pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV; | ||
| 2721 | } | ||
| 2722 | |||
| 2723 | vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
| 2724 | |||
| 2725 | |||
| 2726 | data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */ | ||
| 2727 | if (dlen > 56) { | ||
| 2728 | if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { | ||
| 2729 | /* Update the target capabilities | ||
| 2730 | */ | ||
| 2731 | data_56 = data[56]; | ||
| 2732 | vdev->tflags |= MPT_TARGET_FLAGS_VALID_56; | ||
| 2733 | } | ||
| 2734 | } | 2750 | } |
| 2735 | mptscsih_setTargetNegoParms(hd, vdev, data_56); | 2751 | } |
| 2736 | } else { | 2752 | mptscsih_setTargetNegoParms(hd, vtarget, data_56); |
| 2737 | /* Initial Inquiry may not request enough data bytes to | 2753 | } else { |
| 2738 | * obtain byte 57. DV will; if target doesn't return | 2754 | /* Initial Inquiry may not request enough data bytes to |
| 2739 | * at least 57 bytes, data[56] will be zero. */ | 2755 | * obtain byte 57. DV will; if target doesn't return |
| 2740 | if (dlen > 56) { | 2756 | * at least 57 bytes, data[56] will be zero. */ |
| 2741 | if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { | 2757 | if (dlen > 56) { |
| 2742 | /* Update the target capabilities | 2758 | if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) { |
| 2743 | */ | 2759 | /* Update the target capabilities |
| 2744 | data_56 = data[56]; | 2760 | */ |
| 2745 | vdev->tflags |= MPT_TARGET_FLAGS_VALID_56; | 2761 | data_56 = data[56]; |
| 2746 | mptscsih_setTargetNegoParms(hd, vdev, data_56); | 2762 | vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56; |
| 2747 | } | 2763 | mptscsih_setTargetNegoParms(hd, vtarget, data_56); |
| 2748 | } | 2764 | } |
| 2749 | } | 2765 | } |
| 2750 | } | 2766 | } |
| @@ -2757,12 +2773,12 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char * | |||
| 2757 | * | 2773 | * |
| 2758 | */ | 2774 | */ |
| 2759 | static void | 2775 | static void |
| 2760 | mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) | 2776 | mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56) |
| 2761 | { | 2777 | { |
| 2762 | SpiCfgData *pspi_data = &hd->ioc->spi_data; | 2778 | SpiCfgData *pspi_data = &hd->ioc->spi_data; |
| 2763 | int id = (int) target->target_id; | 2779 | int id = (int) target->target_id; |
| 2764 | int nvram; | 2780 | int nvram; |
| 2765 | VirtDevice *vdev; | 2781 | VirtTarget *vtarget; |
| 2766 | int ii; | 2782 | int ii; |
| 2767 | u8 width = MPT_NARROW; | 2783 | u8 width = MPT_NARROW; |
| 2768 | u8 factor = MPT_ASYNC; | 2784 | u8 factor = MPT_ASYNC; |
| @@ -2907,9 +2923,9 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) | |||
| 2907 | 2923 | ||
| 2908 | ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); | 2924 | ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); |
| 2909 | for (ii = 0; ii < id; ii++) { | 2925 | for (ii = 0; ii < id; ii++) { |
| 2910 | if ( (vdev = hd->Targets[ii]) ) { | 2926 | if ( (vtarget = hd->Targets[ii]) ) { |
| 2911 | vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS; | 2927 | vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; |
| 2912 | mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags); | 2928 | mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags); |
| 2913 | } | 2929 | } |
| 2914 | } | 2930 | } |
| 2915 | } | 2931 | } |
| @@ -2933,12 +2949,12 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) | |||
| 2933 | * prevent any future negotiations to this device. | 2949 | * prevent any future negotiations to this device. |
| 2934 | */ | 2950 | */ |
| 2935 | static void | 2951 | static void |
| 2936 | mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id) | 2952 | mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc) |
| 2937 | { | 2953 | { |
| 2954 | VirtDevice *vdev; | ||
| 2938 | 2955 | ||
| 2939 | if ((hd->Targets) && (hd->Targets[target_id] == NULL)) | 2956 | if ((vdev = sc->device->hostdata) != NULL) |
| 2940 | hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO; | 2957 | hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO; |
| 2941 | |||
| 2942 | return; | 2958 | return; |
| 2943 | } | 2959 | } |
| 2944 | 2960 | ||
| @@ -3014,7 +3030,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) | |||
| 3014 | MPT_ADAPTER *ioc = hd->ioc; | 3030 | MPT_ADAPTER *ioc = hd->ioc; |
| 3015 | Config_t *pReq; | 3031 | Config_t *pReq; |
| 3016 | SCSIDevicePage1_t *pData; | 3032 | SCSIDevicePage1_t *pData; |
| 3017 | VirtDevice *pTarget=NULL; | 3033 | VirtTarget *vtarget=NULL; |
| 3018 | MPT_FRAME_HDR *mf; | 3034 | MPT_FRAME_HDR *mf; |
| 3019 | dma_addr_t dataDma; | 3035 | dma_addr_t dataDma; |
| 3020 | u16 req_idx; | 3036 | u16 req_idx; |
| @@ -3094,11 +3110,11 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) | |||
| 3094 | /* If id is not a raid volume, get the updated | 3110 | /* If id is not a raid volume, get the updated |
| 3095 | * transmission settings from the target structure. | 3111 | * transmission settings from the target structure. |
| 3096 | */ | 3112 | */ |
| 3097 | if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) { | 3113 | if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) { |
| 3098 | width = pTarget->maxWidth; | 3114 | width = vtarget->maxWidth; |
| 3099 | factor = pTarget->minSyncFactor; | 3115 | factor = vtarget->minSyncFactor; |
| 3100 | offset = pTarget->maxOffset; | 3116 | offset = vtarget->maxOffset; |
| 3101 | negoFlags = pTarget->negoFlags; | 3117 | negoFlags = vtarget->negoFlags; |
| 3102 | } | 3118 | } |
| 3103 | 3119 | ||
| 3104 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION | 3120 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION |
| @@ -3818,152 +3834,122 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
| 3818 | 3834 | ||
| 3819 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 3835 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
| 3820 | /** | 3836 | /** |
| 3821 | * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks. | 3837 | * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state |
| 3822 | * @hd: Pointer to MPT_SCSI_HOST structure | 3838 | * @hd: Pointer to a SCSI HOST structure |
| 3823 | * @portnum: IOC port number | 3839 | * @vtarget: per device private data |
| 3824 | * | 3840 | * |
| 3825 | * Uses the ISR, but with special processing. | 3841 | * Uses the ISR, but with special processing. |
| 3826 | * MUST be single-threaded. | 3842 | * MUST be single-threaded. |
| 3827 | * | 3843 | * |
| 3828 | * Return: 0 on completion | ||
| 3829 | */ | 3844 | */ |
| 3830 | static int | 3845 | static void |
| 3831 | mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) | 3846 | mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget) |
| 3832 | { | 3847 | { |
| 3833 | MPT_ADAPTER *ioc= hd->ioc; | 3848 | MPT_ADAPTER *ioc= hd->ioc; |
| 3834 | VirtDevice *pTarget; | 3849 | SCSIDevicePage1_t *pcfg1Data; |
| 3835 | SCSIDevicePage1_t *pcfg1Data = NULL; | ||
| 3836 | INTERNAL_CMD iocmd; | ||
| 3837 | CONFIGPARMS cfg; | 3850 | CONFIGPARMS cfg; |
| 3838 | dma_addr_t cfg1_dma_addr = -1; | 3851 | dma_addr_t cfg1_dma_addr; |
| 3839 | ConfigPageHeader_t header1; | 3852 | ConfigPageHeader_t header; |
| 3840 | int bus = 0; | 3853 | int id; |
| 3841 | int id = 0; | 3854 | int requested, configuration, data,i; |
| 3842 | int lun; | ||
| 3843 | int indexed_lun, lun_index; | ||
| 3844 | int hostId = ioc->pfacts[portnum].PortSCSIID; | ||
| 3845 | int max_id; | ||
| 3846 | int requested, configuration, data; | ||
| 3847 | int doConfig = 0; | ||
| 3848 | u8 flags, factor; | 3855 | u8 flags, factor; |
| 3849 | 3856 | ||
| 3850 | max_id = ioc->sh->max_id - 1; | 3857 | if (ioc->bus_type != SPI) |
| 3851 | 3858 | return; | |
| 3852 | /* Following parameters will not change | ||
| 3853 | * in this routine. | ||
| 3854 | */ | ||
| 3855 | iocmd.cmd = SYNCHRONIZE_CACHE; | ||
| 3856 | iocmd.flags = 0; | ||
| 3857 | iocmd.physDiskNum = -1; | ||
| 3858 | iocmd.data = NULL; | ||
| 3859 | iocmd.data_dma = -1; | ||
| 3860 | iocmd.size = 0; | ||
| 3861 | iocmd.rsvd = iocmd.rsvd2 = 0; | ||
| 3862 | |||
| 3863 | /* No SCSI hosts | ||
| 3864 | */ | ||
| 3865 | if (hd->Targets == NULL) | ||
| 3866 | return 0; | ||
| 3867 | |||
| 3868 | /* Skip the host | ||
| 3869 | */ | ||
| 3870 | if (id == hostId) | ||
| 3871 | id++; | ||
| 3872 | |||
| 3873 | /* Write SDP1 for all SPI devices | ||
| 3874 | * Alloc memory and set up config buffer | ||
| 3875 | */ | ||
| 3876 | if (ioc->bus_type == SPI) { | ||
| 3877 | if (ioc->spi_data.sdp1length > 0) { | ||
| 3878 | pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev, | ||
| 3879 | ioc->spi_data.sdp1length * 4, &cfg1_dma_addr); | ||
| 3880 | |||
| 3881 | if (pcfg1Data != NULL) { | ||
| 3882 | doConfig = 1; | ||
| 3883 | header1.PageVersion = ioc->spi_data.sdp1version; | ||
| 3884 | header1.PageLength = ioc->spi_data.sdp1length; | ||
| 3885 | header1.PageNumber = 1; | ||
| 3886 | header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; | ||
| 3887 | cfg.cfghdr.hdr = &header1; | ||
| 3888 | cfg.physAddr = cfg1_dma_addr; | ||
| 3889 | cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
| 3890 | cfg.dir = 1; | ||
| 3891 | cfg.timeout = 0; | ||
| 3892 | } | ||
| 3893 | } | ||
| 3894 | } | ||
| 3895 | 3859 | ||
| 3896 | /* loop through all devices on this port | 3860 | if (!ioc->spi_data.sdp1length) |
| 3897 | */ | 3861 | return; |
| 3898 | while (bus < MPT_MAX_BUS) { | ||
| 3899 | iocmd.bus = bus; | ||
| 3900 | iocmd.id = id; | ||
| 3901 | pTarget = hd->Targets[(int)id]; | ||
| 3902 | 3862 | ||
| 3903 | if (doConfig) { | 3863 | pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev, |
| 3864 | ioc->spi_data.sdp1length * 4, &cfg1_dma_addr); | ||
| 3904 | 3865 | ||
| 3905 | /* Set the negotiation flags */ | 3866 | if (pcfg1Data == NULL) |
| 3906 | if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) { | 3867 | return; |
| 3907 | flags = pTarget->negoFlags; | ||
| 3908 | } else { | ||
| 3909 | flags = hd->ioc->spi_data.noQas; | ||
| 3910 | if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { | ||
| 3911 | data = hd->ioc->spi_data.nvram[id]; | ||
| 3912 | 3868 | ||
| 3913 | if (data & MPT_NVRAM_WIDE_DISABLE) | 3869 | header.PageVersion = ioc->spi_data.sdp1version; |
| 3914 | flags |= MPT_TARGET_NO_NEGO_WIDE; | 3870 | header.PageLength = ioc->spi_data.sdp1length; |
| 3871 | header.PageNumber = 1; | ||
| 3872 | header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; | ||
| 3873 | cfg.cfghdr.hdr = &header; | ||
| 3874 | cfg.physAddr = cfg1_dma_addr; | ||
| 3875 | cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
| 3876 | cfg.dir = 1; | ||
| 3877 | cfg.timeout = 0; | ||
| 3915 | 3878 | ||
| 3916 | factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; | 3879 | if (vtarget->raidVolume && ioc->raid_data.pIocPg3) { |
| 3917 | if ((factor == 0) || (factor == MPT_ASYNC)) | 3880 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { |
| 3918 | flags |= MPT_TARGET_NO_NEGO_SYNC; | 3881 | id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID; |
| 3919 | } | 3882 | flags = hd->ioc->spi_data.noQas; |
| 3883 | if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { | ||
| 3884 | data = hd->ioc->spi_data.nvram[id]; | ||
| 3885 | if (data & MPT_NVRAM_WIDE_DISABLE) | ||
| 3886 | flags |= MPT_TARGET_NO_NEGO_WIDE; | ||
| 3887 | factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; | ||
| 3888 | if ((factor == 0) || (factor == MPT_ASYNC)) | ||
| 3889 | flags |= MPT_TARGET_NO_NEGO_SYNC; | ||
| 3920 | } | 3890 | } |
| 3921 | |||
| 3922 | /* Force to async, narrow */ | ||
| 3923 | mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, | 3891 | mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, |
| 3924 | &configuration, flags); | 3892 | &configuration, flags); |
| 3925 | dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " | 3893 | dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " |
| 3926 | "offset=0 negoFlags=%x request=%x config=%x\n", | 3894 | "offset=0 negoFlags=%x request=%x config=%x\n", |
| 3927 | id, flags, requested, configuration)); | 3895 | id, flags, requested, configuration)); |
| 3928 | pcfg1Data->RequestedParameters = cpu_to_le32(requested); | 3896 | pcfg1Data->RequestedParameters = cpu_to_le32(requested); |
| 3929 | pcfg1Data->Reserved = 0; | 3897 | pcfg1Data->Reserved = 0; |
| 3930 | pcfg1Data->Configuration = cpu_to_le32(configuration); | 3898 | pcfg1Data->Configuration = cpu_to_le32(configuration); |
| 3931 | cfg.pageAddr = (bus<<8) | id; | 3899 | cfg.pageAddr = (vtarget->bus_id<<8) | id; |
| 3932 | mpt_config(hd->ioc, &cfg); | 3900 | mpt_config(hd->ioc, &cfg); |
| 3933 | } | 3901 | } |
| 3902 | } else { | ||
| 3903 | flags = vtarget->negoFlags; | ||
| 3904 | mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, | ||
| 3905 | &configuration, flags); | ||
| 3906 | dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " | ||
| 3907 | "offset=0 negoFlags=%x request=%x config=%x\n", | ||
| 3908 | vtarget->target_id, flags, requested, configuration)); | ||
| 3909 | pcfg1Data->RequestedParameters = cpu_to_le32(requested); | ||
| 3910 | pcfg1Data->Reserved = 0; | ||
| 3911 | pcfg1Data->Configuration = cpu_to_le32(configuration); | ||
| 3912 | cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id; | ||
| 3913 | mpt_config(hd->ioc, &cfg); | ||
| 3914 | } | ||
| 3934 | 3915 | ||
| 3935 | /* If target Ptr NULL or if this target is NOT a disk, skip. | 3916 | if (pcfg1Data) |
| 3936 | */ | 3917 | pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr); |
| 3937 | if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){ | 3918 | } |
| 3938 | for (lun=0; lun <= MPT_LAST_LUN; lun++) { | ||
| 3939 | /* If LUN present, issue the command | ||
| 3940 | */ | ||
| 3941 | lun_index = (lun >> 5); /* 32 luns per lun_index */ | ||
| 3942 | indexed_lun = (lun % 32); | ||
| 3943 | if (pTarget->luns[lun_index] & (1<<indexed_lun)) { | ||
| 3944 | iocmd.lun = lun; | ||
| 3945 | (void) mptscsih_do_cmd(hd, &iocmd); | ||
| 3946 | } | ||
| 3947 | } | ||
| 3948 | } | ||
| 3949 | |||
| 3950 | /* get next relevant device */ | ||
| 3951 | id++; | ||
| 3952 | |||
| 3953 | if (id == hostId) | ||
| 3954 | id++; | ||
| 3955 | 3919 | ||
| 3956 | if (id > max_id) { | 3920 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
| 3957 | id = 0; | 3921 | /** |
| 3958 | bus++; | 3922 | * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks. |
| 3959 | } | 3923 | * @hd: Pointer to a SCSI HOST structure |
| 3960 | } | 3924 | * @vtarget: per device private data |
| 3925 | * @lun: lun | ||
| 3926 | * | ||
| 3927 | * Uses the ISR, but with special processing. | ||
| 3928 | * MUST be single-threaded. | ||
| 3929 | * | ||
| 3930 | */ | ||
| 3931 | static void | ||
| 3932 | mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | ||
| 3933 | { | ||
| 3934 | INTERNAL_CMD iocmd; | ||
| 3961 | 3935 | ||
| 3962 | if (pcfg1Data) { | 3936 | /* Following parameters will not change |
| 3963 | pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr); | 3937 | * in this routine. |
| 3964 | } | 3938 | */ |
| 3939 | iocmd.cmd = SYNCHRONIZE_CACHE; | ||
| 3940 | iocmd.flags = 0; | ||
| 3941 | iocmd.physDiskNum = -1; | ||
| 3942 | iocmd.data = NULL; | ||
| 3943 | iocmd.data_dma = -1; | ||
| 3944 | iocmd.size = 0; | ||
| 3945 | iocmd.rsvd = iocmd.rsvd2 = 0; | ||
| 3946 | iocmd.bus = vdevice->bus_id; | ||
| 3947 | iocmd.id = vdevice->target_id; | ||
| 3948 | iocmd.lun = (u8)vdevice->lun; | ||
| 3965 | 3949 | ||
| 3966 | return 0; | 3950 | if ((vdevice->vtarget->type & TYPE_DISK) && |
| 3951 | (vdevice->configured_lun)) | ||
| 3952 | mptscsih_do_cmd(hd, &iocmd); | ||
| 3967 | } | 3953 | } |
| 3968 | 3954 | ||
| 3969 | /* Search IOC page 3 to determine if this is hidden physical disk | 3955 | /* Search IOC page 3 to determine if this is hidden physical disk |
| @@ -4144,7 +4130,7 @@ mptscsih_domainValidation(void *arg) | |||
| 4144 | static void | 4130 | static void |
| 4145 | mptscsih_qas_check(MPT_SCSI_HOST *hd, int id) | 4131 | mptscsih_qas_check(MPT_SCSI_HOST *hd, int id) |
| 4146 | { | 4132 | { |
| 4147 | VirtDevice *pTarget; | 4133 | VirtTarget *vtarget; |
| 4148 | int ii; | 4134 | int ii; |
| 4149 | 4135 | ||
| 4150 | if (hd->Targets == NULL) | 4136 | if (hd->Targets == NULL) |
| @@ -4157,11 +4143,11 @@ mptscsih_qas_check(MPT_SCSI_HOST *hd, int id) | |||
| 4157 | if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0) | 4143 | if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0) |
| 4158 | continue; | 4144 | continue; |
| 4159 | 4145 | ||
| 4160 | pTarget = hd->Targets[ii]; | 4146 | vtarget = hd->Targets[ii]; |
| 4161 | 4147 | ||
| 4162 | if ((pTarget != NULL) && (!pTarget->raidVolume)) { | 4148 | if ((vtarget != NULL) && (!vtarget->raidVolume)) { |
| 4163 | if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) { | 4149 | if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) { |
| 4164 | pTarget->negoFlags |= hd->ioc->spi_data.noQas; | 4150 | vtarget->negoFlags |= hd->ioc->spi_data.noQas; |
| 4165 | dnegoprintk(("writeSDP1: id=%d flags=0\n", id)); | 4151 | dnegoprintk(("writeSDP1: id=%d flags=0\n", id)); |
| 4166 | mptscsih_writeSDP1(hd, 0, ii, 0); | 4152 | mptscsih_writeSDP1(hd, 0, ii, 0); |
| 4167 | } | 4153 | } |
| @@ -4201,7 +4187,7 @@ static int | |||
| 4201 | mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) | 4187 | mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) |
| 4202 | { | 4188 | { |
| 4203 | MPT_ADAPTER *ioc = hd->ioc; | 4189 | MPT_ADAPTER *ioc = hd->ioc; |
| 4204 | VirtDevice *pTarget; | 4190 | VirtTarget *vtarget; |
| 4205 | SCSIDevicePage1_t *pcfg1Data; | 4191 | SCSIDevicePage1_t *pcfg1Data; |
| 4206 | SCSIDevicePage0_t *pcfg0Data; | 4192 | SCSIDevicePage0_t *pcfg0Data; |
| 4207 | u8 *pbuf1; | 4193 | u8 *pbuf1; |
| @@ -4272,12 +4258,12 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) | |||
| 4272 | iocmd.physDiskNum = -1; | 4258 | iocmd.physDiskNum = -1; |
| 4273 | iocmd.rsvd = iocmd.rsvd2 = 0; | 4259 | iocmd.rsvd = iocmd.rsvd2 = 0; |
| 4274 | 4260 | ||
| 4275 | pTarget = hd->Targets[id]; | 4261 | vtarget = hd->Targets[id]; |
| 4276 | 4262 | ||
| 4277 | /* Use tagged commands if possible. | 4263 | /* Use tagged commands if possible. |
| 4278 | */ | 4264 | */ |
| 4279 | if (pTarget) { | 4265 | if (vtarget) { |
| 4280 | if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES) | 4266 | if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) |
| 4281 | iocmd.flags |= MPT_ICFLAG_TAGGED_CMD; | 4267 | iocmd.flags |= MPT_ICFLAG_TAGGED_CMD; |
| 4282 | else { | 4268 | else { |
| 4283 | if (hd->ioc->facts.FWVersion.Word < 0x01000600) | 4269 | if (hd->ioc->facts.FWVersion.Word < 0x01000600) |
| @@ -4493,7 +4479,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) | |||
| 4493 | /* Reset the size for disks | 4479 | /* Reset the size for disks |
| 4494 | */ | 4480 | */ |
| 4495 | inq0 = (*pbuf1) & 0x1F; | 4481 | inq0 = (*pbuf1) & 0x1F; |
| 4496 | if ((inq0 == 0) && pTarget && !pTarget->raidVolume) { | 4482 | if ((inq0 == 0) && vtarget && !vtarget->raidVolume) { |
| 4497 | sz = 0x40; | 4483 | sz = 0x40; |
| 4498 | iocmd.size = sz; | 4484 | iocmd.size = sz; |
| 4499 | } | 4485 | } |
| @@ -4503,8 +4489,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) | |||
| 4503 | */ | 4489 | */ |
| 4504 | if (inq0 == TYPE_PROCESSOR) { | 4490 | if (inq0 == TYPE_PROCESSOR) { |
| 4505 | mptscsih_initTarget(hd, | 4491 | mptscsih_initTarget(hd, |
| 4506 | bus, | 4492 | vtarget, |
| 4507 | id, | ||
| 4508 | lun, | 4493 | lun, |
| 4509 | pbuf1, | 4494 | pbuf1, |
| 4510 | sz); | 4495 | sz); |
| @@ -4518,22 +4503,22 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) | |||
| 4518 | goto target_done; | 4503 | goto target_done; |
| 4519 | 4504 | ||
| 4520 | if (sz == 0x40) { | 4505 | if (sz == 0x40) { |
| 4521 | if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A) | 4506 | if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A) |
| 4522 | && (pTarget->minSyncFactor > 0x09)) { | 4507 | && (vtarget->minSyncFactor > 0x09)) { |
| 4523 | if ((pbuf1[56] & 0x04) == 0) | 4508 | if ((pbuf1[56] & 0x04) == 0) |
| 4524 | ; | 4509 | ; |
| 4525 | else if ((pbuf1[56] & 0x01) == 1) { | 4510 | else if ((pbuf1[56] & 0x01) == 1) { |
| 4526 | pTarget->minSyncFactor = | 4511 | vtarget->minSyncFactor = |
| 4527 | nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320; | 4512 | nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320; |
| 4528 | } else { | 4513 | } else { |
| 4529 | pTarget->minSyncFactor = | 4514 | vtarget->minSyncFactor = |
| 4530 | nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160; | 4515 | nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160; |
| 4531 | } | 4516 | } |
| 4532 | 4517 | ||
| 4533 | dv.max.factor = pTarget->minSyncFactor; | 4518 | dv.max.factor = vtarget->minSyncFactor; |
| 4534 | 4519 | ||
| 4535 | if ((pbuf1[56] & 0x02) == 0) { | 4520 | if ((pbuf1[56] & 0x02) == 0) { |
| 4536 | pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; | 4521 | vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; |
| 4537 | hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; | 4522 | hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; |
| 4538 | ddvprintk((MYIOC_s_NOTE_FMT | 4523 | ddvprintk((MYIOC_s_NOTE_FMT |
| 4539 | "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n", | 4524 | "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 | "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id)); | 4601 | "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id)); |
| 4617 | hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE; | 4602 | hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE; |
| 4618 | mptscsih_initTarget(hd, | 4603 | mptscsih_initTarget(hd, |
| 4619 | bus, | 4604 | vtarget, |
| 4620 | id, | ||
| 4621 | lun, | 4605 | lun, |
| 4622 | pbuf1, | 4606 | pbuf1, |
| 4623 | sz); | 4607 | sz); |
| @@ -5118,7 +5102,7 @@ target_done: | |||
| 5118 | static void | 5102 | static void |
| 5119 | mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) | 5103 | mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) |
| 5120 | { | 5104 | { |
| 5121 | VirtDevice *pTarget; | 5105 | VirtTarget *vtarget; |
| 5122 | SCSIDevicePage0_t *pPage0; | 5106 | SCSIDevicePage0_t *pPage0; |
| 5123 | SCSIDevicePage1_t *pPage1; | 5107 | SCSIDevicePage1_t *pPage1; |
| 5124 | int val = 0, data, configuration; | 5108 | int val = 0, data, configuration; |
| @@ -5138,11 +5122,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) | |||
| 5138 | * already throttled back. | 5122 | * already throttled back. |
| 5139 | */ | 5123 | */ |
| 5140 | negoFlags = hd->ioc->spi_data.noQas; | 5124 | negoFlags = hd->ioc->spi_data.noQas; |
| 5141 | if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) { | 5125 | if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) { |
| 5142 | width = pTarget->maxWidth; | 5126 | width = vtarget->maxWidth; |
| 5143 | offset = pTarget->maxOffset; | 5127 | offset = vtarget->maxOffset; |
| 5144 | factor = pTarget->minSyncFactor; | 5128 | factor = vtarget->minSyncFactor; |
| 5145 | negoFlags |= pTarget->negoFlags; | 5129 | negoFlags |= vtarget->negoFlags; |
| 5146 | } else { | 5130 | } else { |
| 5147 | if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { | 5131 | if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { |
| 5148 | data = hd->ioc->spi_data.nvram[id]; | 5132 | data = hd->ioc->spi_data.nvram[id]; |
| @@ -5344,11 +5328,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) | |||
| 5344 | * or overwrite nvram (phys disks only). | 5328 | * or overwrite nvram (phys disks only). |
| 5345 | */ | 5329 | */ |
| 5346 | 5330 | ||
| 5347 | if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) { | 5331 | if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) { |
| 5348 | pTarget->maxWidth = dv->now.width; | 5332 | vtarget->maxWidth = dv->now.width; |
| 5349 | pTarget->maxOffset = dv->now.offset; | 5333 | vtarget->maxOffset = dv->now.offset; |
| 5350 | pTarget->minSyncFactor = dv->now.factor; | 5334 | vtarget->minSyncFactor = dv->now.factor; |
| 5351 | pTarget->negoFlags = dv->now.flags; | 5335 | vtarget->negoFlags = dv->now.flags; |
| 5352 | } else { | 5336 | } else { |
| 5353 | /* Preserv all flags, use | 5337 | /* Preserv all flags, use |
| 5354 | * read-modify-write algorithm | 5338 | * read-modify-write algorithm |
| @@ -5512,7 +5496,7 @@ mptscsih_fillbuf(char *buffer, int size, int index, int width) | |||
| 5512 | * Called only if DV_NOT_DONE flag is set | 5496 | * Called only if DV_NOT_DONE flag is set |
| 5513 | */ | 5497 | */ |
| 5514 | static void | 5498 | static void |
| 5515 | mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) | 5499 | mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc) |
| 5516 | { | 5500 | { |
| 5517 | MPT_ADAPTER *ioc = hd->ioc; | 5501 | MPT_ADAPTER *ioc = hd->ioc; |
| 5518 | u8 cmd; | 5502 | u8 cmd; |
| @@ -5520,16 +5504,16 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) | |||
| 5520 | 5504 | ||
| 5521 | ddvtprintk((MYIOC_s_NOTE_FMT | 5505 | ddvtprintk((MYIOC_s_NOTE_FMT |
| 5522 | " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", | 5506 | " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", |
| 5523 | hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0])); | 5507 | hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0])); |
| 5524 | 5508 | ||
| 5525 | if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0)) | 5509 | if ((sc->device->lun != 0) || (hd->negoNvram != 0)) |
| 5526 | return; | 5510 | return; |
| 5527 | 5511 | ||
| 5528 | cmd = pReq->CDB[0]; | 5512 | cmd = sc->cmnd[0]; |
| 5529 | 5513 | ||
| 5530 | if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) { | 5514 | if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) { |
| 5531 | pSpi = &ioc->spi_data; | 5515 | pSpi = &ioc->spi_data; |
| 5532 | if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) { | 5516 | if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) { |
| 5533 | /* Set NEED_DV for all hidden disks | 5517 | /* Set NEED_DV for all hidden disks |
| 5534 | */ | 5518 | */ |
| 5535 | Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk; | 5519 | Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk; |
| @@ -5542,8 +5526,8 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) | |||
| 5542 | numPDisk--; | 5526 | numPDisk--; |
| 5543 | } | 5527 | } |
| 5544 | } | 5528 | } |
| 5545 | pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV; | 5529 | pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV; |
| 5546 | ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID)); | 5530 | ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id)); |
| 5547 | } | 5531 | } |
| 5548 | } | 5532 | } |
| 5549 | 5533 | ||
| @@ -5590,7 +5574,6 @@ mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id) | |||
| 5590 | } | 5574 | } |
| 5591 | } | 5575 | } |
| 5592 | } | 5576 | } |
| 5593 | |||
| 5594 | #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */ | 5577 | #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */ |
| 5595 | 5578 | ||
| 5596 | EXPORT_SYMBOL(mptscsih_remove); | 5579 | EXPORT_SYMBOL(mptscsih_remove); |
| @@ -5602,7 +5585,9 @@ EXPORT_SYMBOL(mptscsih_resume); | |||
| 5602 | EXPORT_SYMBOL(mptscsih_proc_info); | 5585 | EXPORT_SYMBOL(mptscsih_proc_info); |
| 5603 | EXPORT_SYMBOL(mptscsih_info); | 5586 | EXPORT_SYMBOL(mptscsih_info); |
| 5604 | EXPORT_SYMBOL(mptscsih_qcmd); | 5587 | EXPORT_SYMBOL(mptscsih_qcmd); |
| 5588 | EXPORT_SYMBOL(mptscsih_target_alloc); | ||
| 5605 | EXPORT_SYMBOL(mptscsih_slave_alloc); | 5589 | EXPORT_SYMBOL(mptscsih_slave_alloc); |
| 5590 | EXPORT_SYMBOL(mptscsih_target_destroy); | ||
| 5606 | EXPORT_SYMBOL(mptscsih_slave_destroy); | 5591 | EXPORT_SYMBOL(mptscsih_slave_destroy); |
| 5607 | EXPORT_SYMBOL(mptscsih_slave_configure); | 5592 | EXPORT_SYMBOL(mptscsih_slave_configure); |
| 5608 | EXPORT_SYMBOL(mptscsih_abort); | 5593 | EXPORT_SYMBOL(mptscsih_abort); |
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index 971fda4b8b57..d3cba12f4bd9 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h | |||
| @@ -91,7 +91,9 @@ extern int mptscsih_resume(struct pci_dev *pdev); | |||
| 91 | extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func); | 91 | extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func); |
| 92 | extern const char * mptscsih_info(struct Scsi_Host *SChost); | 92 | extern const char * mptscsih_info(struct Scsi_Host *SChost); |
| 93 | extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); | 93 | extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); |
| 94 | extern int mptscsih_target_alloc(struct scsi_target *starget); | ||
| 94 | extern int mptscsih_slave_alloc(struct scsi_device *device); | 95 | extern int mptscsih_slave_alloc(struct scsi_device *device); |
| 96 | extern void mptscsih_target_destroy(struct scsi_target *starget); | ||
| 95 | extern void mptscsih_slave_destroy(struct scsi_device *device); | 97 | extern void mptscsih_slave_destroy(struct scsi_device *device); |
| 96 | extern int mptscsih_slave_configure(struct scsi_device *device); | 98 | extern int mptscsih_slave_configure(struct scsi_device *device); |
| 97 | extern int mptscsih_abort(struct scsi_cmnd * SCpnt); | 99 | extern int mptscsih_abort(struct scsi_cmnd * SCpnt); |
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 91bc467477ef..ce332a6085e5 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
| @@ -109,8 +109,10 @@ static struct scsi_host_template mptspi_driver_template = { | |||
| 109 | .name = "MPT SPI Host", | 109 | .name = "MPT SPI Host", |
| 110 | .info = mptscsih_info, | 110 | .info = mptscsih_info, |
| 111 | .queuecommand = mptscsih_qcmd, | 111 | .queuecommand = mptscsih_qcmd, |
| 112 | .target_alloc = mptscsih_target_alloc, | ||
| 112 | .slave_alloc = mptscsih_slave_alloc, | 113 | .slave_alloc = mptscsih_slave_alloc, |
| 113 | .slave_configure = mptscsih_slave_configure, | 114 | .slave_configure = mptscsih_slave_configure, |
| 115 | .target_destroy = mptscsih_target_destroy, | ||
| 114 | .slave_destroy = mptscsih_slave_destroy, | 116 | .slave_destroy = mptscsih_slave_destroy, |
| 115 | .change_queue_depth = mptscsih_change_queue_depth, | 117 | .change_queue_depth = mptscsih_change_queue_depth, |
| 116 | .eh_abort_handler = mptscsih_abort, | 118 | .eh_abort_handler = mptscsih_abort, |
| @@ -312,10 +314,10 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 312 | } | 314 | } |
| 313 | 315 | ||
| 314 | memset(mem, 0, sz); | 316 | memset(mem, 0, sz); |
| 315 | hd->Targets = (VirtDevice **) mem; | 317 | hd->Targets = (VirtTarget **) mem; |
| 316 | 318 | ||
| 317 | dprintk((KERN_INFO | 319 | dprintk((KERN_INFO |
| 318 | " Targets @ %p, sz=%d\n", hd->Targets, sz)); | 320 | " vdev @ %p, sz=%d\n", hd->Targets, sz)); |
| 319 | 321 | ||
| 320 | /* Clear the TM flags | 322 | /* Clear the TM flags |
| 321 | */ | 323 | */ |
