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 | */ |