diff options
author | Moore, Eric Dean <Eric.Moore@lsil.com> | 2005-11-16 20:54:25 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-12-13 20:41:15 -0500 |
commit | c7c82987b4844f555d309ccbd42abe95d46822ff (patch) | |
tree | 55eb2c02fa1ff25548b1cc673c47aaa19e380214 /drivers/message | |
parent | f2ea8671a8376e09cf759aa8cb3de8b8d3bced9e (diff) |
[SCSI] mptfusion - mapping fixs required support for transport layers.
This utilizes the hostdata area that is hung off of scsi_target and
scsi_device for saving unique firmware mapping. This will be required
for supporting new Fibre and SPI transport support.
This also fixs problems in error handling error code for SAS
controllers, in which the incorrect mapping was passed to the
firmware.
Signed-off-by: Eric Moore <Eric.Moore@lsil.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/message')
-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 | */ |