diff options
Diffstat (limited to 'drivers/scsi/aacraid/linit.c')
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 242 |
1 files changed, 165 insertions, 77 deletions
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 9dd331bc29b0..61be22774e99 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -159,27 +159,27 @@ static struct pci_device_id aac_pci_tbl[] = { | |||
159 | MODULE_DEVICE_TABLE(pci, aac_pci_tbl); | 159 | MODULE_DEVICE_TABLE(pci, aac_pci_tbl); |
160 | 160 | ||
161 | /* | 161 | /* |
162 | * dmb - For now we add the number of channels to this structure. | 162 | * dmb - For now we add the number of channels to this structure. |
163 | * In the future we should add a fib that reports the number of channels | 163 | * In the future we should add a fib that reports the number of channels |
164 | * for the card. At that time we can remove the channels from here | 164 | * for the card. At that time we can remove the channels from here |
165 | */ | 165 | */ |
166 | static struct aac_driver_ident aac_drivers[] = { | 166 | static struct aac_driver_ident aac_drivers[] = { |
167 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 2/Si (Iguana/PERC2Si) */ | 167 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 2/Si (Iguana/PERC2Si) */ |
168 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Opal/PERC3Di) */ | 168 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Opal/PERC3Di) */ |
169 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Si (SlimFast/PERC3Si */ | 169 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Si (SlimFast/PERC3Si */ |
170 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Iguana FlipChip/PERC3DiF */ | 170 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Iguana FlipChip/PERC3DiF */ |
171 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Viper/PERC3DiV) */ | 171 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Viper/PERC3DiV) */ |
172 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Lexus/PERC3DiL) */ | 172 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Lexus/PERC3DiL) */ |
173 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Jaguar/PERC3DiJ) */ | 173 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Jaguar/PERC3DiJ) */ |
174 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Dagger/PERC3DiD) */ | 174 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Dagger/PERC3DiD) */ |
175 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Boxster/PERC3DiB) */ | 175 | { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Boxster/PERC3DiB) */ |
176 | { aac_rx_init, "aacraid", "ADAPTEC ", "catapult ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* catapult */ | 176 | { aac_rx_init, "aacraid", "ADAPTEC ", "catapult ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* catapult */ |
177 | { aac_rx_init, "aacraid", "ADAPTEC ", "tomcat ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* tomcat */ | 177 | { aac_rx_init, "aacraid", "ADAPTEC ", "tomcat ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* tomcat */ |
178 | { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2120S ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec 2120S (Crusader) */ | 178 | { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2120S ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Adaptec 2120S (Crusader) */ |
179 | { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec 2200S (Vulcan) */ | 179 | { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Adaptec 2200S (Vulcan) */ |
180 | { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec 2200S (Vulcan-2m) */ | 180 | { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Adaptec 2200S (Vulcan-2m) */ |
181 | { aac_rx_init, "aacraid", "Legend ", "Legend S220 ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend S220 (Legend Crusader) */ | 181 | { aac_rx_init, "aacraid", "Legend ", "Legend S220 ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Legend S220 (Legend Crusader) */ |
182 | { aac_rx_init, "aacraid", "Legend ", "Legend S230 ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend S230 (Legend Vulcan) */ | 182 | { aac_rx_init, "aacraid", "Legend ", "Legend S230 ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Legend S230 (Legend Vulcan) */ |
183 | 183 | ||
184 | { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3230S ", 2 }, /* Adaptec 3230S (Harrier) */ | 184 | { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3230S ", 2 }, /* Adaptec 3230S (Harrier) */ |
185 | { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3240S ", 2 }, /* Adaptec 3240S (Tornado) */ | 185 | { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3240S ", 2 }, /* Adaptec 3240S (Tornado) */ |
@@ -224,8 +224,8 @@ static struct aac_driver_ident aac_drivers[] = { | |||
224 | { aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4, AAC_QUIRK_34SG }, /* Dell PERC2/QC */ | 224 | { aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4, AAC_QUIRK_34SG }, /* Dell PERC2/QC */ |
225 | { aac_sa_init, "hpnraid", "HP ", "NetRAID ", 4, AAC_QUIRK_34SG }, /* HP NetRAID-4M */ | 225 | { aac_sa_init, "hpnraid", "HP ", "NetRAID ", 4, AAC_QUIRK_34SG }, /* HP NetRAID-4M */ |
226 | 226 | ||
227 | { aac_rx_init, "aacraid", "DELL ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell Catchall */ | 227 | { aac_rx_init, "aacraid", "DELL ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Dell Catchall */ |
228 | { aac_rx_init, "aacraid", "Legend ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend Catchall */ | 228 | { aac_rx_init, "aacraid", "Legend ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Legend Catchall */ |
229 | { aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Catch All */ | 229 | { aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Catch All */ |
230 | { aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Rocket Catch All */ | 230 | { aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Rocket Catch All */ |
231 | { aac_nark_init, "aacraid", "ADAPTEC ", "RAID ", 2 } /* Adaptec NEMER/ARK Catch All */ | 231 | { aac_nark_init, "aacraid", "ADAPTEC ", "RAID ", 2 } /* Adaptec NEMER/ARK Catch All */ |
@@ -239,7 +239,7 @@ static struct aac_driver_ident aac_drivers[] = { | |||
239 | * Queues a command for execution by the associated Host Adapter. | 239 | * Queues a command for execution by the associated Host Adapter. |
240 | * | 240 | * |
241 | * TODO: unify with aac_scsi_cmd(). | 241 | * TODO: unify with aac_scsi_cmd(). |
242 | */ | 242 | */ |
243 | 243 | ||
244 | static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | 244 | static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) |
245 | { | 245 | { |
@@ -258,7 +258,7 @@ static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd | |||
258 | } | 258 | } |
259 | cmd->SCp.phase = AAC_OWNER_LOWLEVEL; | 259 | cmd->SCp.phase = AAC_OWNER_LOWLEVEL; |
260 | return (aac_scsi_cmd(cmd) ? FAILED : 0); | 260 | return (aac_scsi_cmd(cmd) ? FAILED : 0); |
261 | } | 261 | } |
262 | 262 | ||
263 | /** | 263 | /** |
264 | * aac_info - Returns the host adapter name | 264 | * aac_info - Returns the host adapter name |
@@ -292,21 +292,21 @@ struct aac_driver_ident* aac_get_driver_ident(int devtype) | |||
292 | * @capacity: the sector capacity of the disk | 292 | * @capacity: the sector capacity of the disk |
293 | * @geom: geometry block to fill in | 293 | * @geom: geometry block to fill in |
294 | * | 294 | * |
295 | * Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk. | 295 | * Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk. |
296 | * The default disk geometry is 64 heads, 32 sectors, and the appropriate | 296 | * The default disk geometry is 64 heads, 32 sectors, and the appropriate |
297 | * number of cylinders so as not to exceed drive capacity. In order for | 297 | * number of cylinders so as not to exceed drive capacity. In order for |
298 | * disks equal to or larger than 1 GB to be addressable by the BIOS | 298 | * disks equal to or larger than 1 GB to be addressable by the BIOS |
299 | * without exceeding the BIOS limitation of 1024 cylinders, Extended | 299 | * without exceeding the BIOS limitation of 1024 cylinders, Extended |
300 | * Translation should be enabled. With Extended Translation enabled, | 300 | * Translation should be enabled. With Extended Translation enabled, |
301 | * drives between 1 GB inclusive and 2 GB exclusive are given a disk | 301 | * drives between 1 GB inclusive and 2 GB exclusive are given a disk |
302 | * geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive | 302 | * geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive |
303 | * are given a disk geometry of 255 heads and 63 sectors. However, if | 303 | * are given a disk geometry of 255 heads and 63 sectors. However, if |
304 | * the BIOS detects that the Extended Translation setting does not match | 304 | * the BIOS detects that the Extended Translation setting does not match |
305 | * the geometry in the partition table, then the translation inferred | 305 | * the geometry in the partition table, then the translation inferred |
306 | * from the partition table will be used by the BIOS, and a warning may | 306 | * from the partition table will be used by the BIOS, and a warning may |
307 | * be displayed. | 307 | * be displayed. |
308 | */ | 308 | */ |
309 | 309 | ||
310 | static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, | 310 | static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, |
311 | sector_t capacity, int *geom) | 311 | sector_t capacity, int *geom) |
312 | { | 312 | { |
@@ -333,10 +333,10 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, | |||
333 | 333 | ||
334 | param->cylinders = cap_to_cyls(capacity, param->heads * param->sectors); | 334 | param->cylinders = cap_to_cyls(capacity, param->heads * param->sectors); |
335 | 335 | ||
336 | /* | 336 | /* |
337 | * Read the first 1024 bytes from the disk device, if the boot | 337 | * Read the first 1024 bytes from the disk device, if the boot |
338 | * sector partition table is valid, search for a partition table | 338 | * sector partition table is valid, search for a partition table |
339 | * entry whose end_head matches one of the standard geometry | 339 | * entry whose end_head matches one of the standard geometry |
340 | * translations ( 64/32, 128/32, 255/63 ). | 340 | * translations ( 64/32, 128/32, 255/63 ). |
341 | */ | 341 | */ |
342 | buf = scsi_bios_ptable(bdev); | 342 | buf = scsi_bios_ptable(bdev); |
@@ -401,30 +401,44 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, | |||
401 | 401 | ||
402 | static int aac_slave_configure(struct scsi_device *sdev) | 402 | static int aac_slave_configure(struct scsi_device *sdev) |
403 | { | 403 | { |
404 | struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; | ||
404 | if ((sdev->type == TYPE_DISK) && | 405 | if ((sdev->type == TYPE_DISK) && |
405 | (sdev_channel(sdev) != CONTAINER_CHANNEL)) { | 406 | (sdev_channel(sdev) != CONTAINER_CHANNEL) && |
407 | (!aac->jbod || sdev->inq_periph_qual) && | ||
408 | (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))) { | ||
406 | if (expose_physicals == 0) | 409 | if (expose_physicals == 0) |
407 | return -ENXIO; | 410 | return -ENXIO; |
408 | if (expose_physicals < 0) { | 411 | if (expose_physicals < 0) |
409 | struct aac_dev *aac = | 412 | sdev->no_uld_attach = 1; |
410 | (struct aac_dev *)sdev->host->hostdata; | ||
411 | if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) | ||
412 | sdev->no_uld_attach = 1; | ||
413 | } | ||
414 | } | 413 | } |
415 | if (sdev->tagged_supported && (sdev->type == TYPE_DISK) && | 414 | if (sdev->tagged_supported && (sdev->type == TYPE_DISK) && |
416 | (sdev_channel(sdev) == CONTAINER_CHANNEL)) { | 415 | (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) && |
416 | !sdev->no_uld_attach) { | ||
417 | struct scsi_device * dev; | 417 | struct scsi_device * dev; |
418 | struct Scsi_Host *host = sdev->host; | 418 | struct Scsi_Host *host = sdev->host; |
419 | unsigned num_lsu = 0; | 419 | unsigned num_lsu = 0; |
420 | unsigned num_one = 0; | 420 | unsigned num_one = 0; |
421 | unsigned depth; | 421 | unsigned depth; |
422 | unsigned cid; | ||
422 | 423 | ||
424 | /* | ||
425 | * Firmware has an individual device recovery time typically | ||
426 | * of 35 seconds, give us a margin. | ||
427 | */ | ||
428 | if (sdev->timeout < (45 * HZ)) | ||
429 | sdev->timeout = 45 * HZ; | ||
430 | for (cid = 0; cid < aac->maximum_num_containers; ++cid) | ||
431 | if (aac->fsa_dev[cid].valid) | ||
432 | ++num_lsu; | ||
423 | __shost_for_each_device(dev, host) { | 433 | __shost_for_each_device(dev, host) { |
424 | if (dev->tagged_supported && (dev->type == TYPE_DISK) && | 434 | if (dev->tagged_supported && (dev->type == TYPE_DISK) && |
425 | (sdev_channel(dev) == CONTAINER_CHANNEL)) | 435 | (!aac->raid_scsi_mode || |
426 | ++num_lsu; | 436 | (sdev_channel(sdev) != 2)) && |
427 | else | 437 | !dev->no_uld_attach) { |
438 | if ((sdev_channel(dev) != CONTAINER_CHANNEL) | ||
439 | || !aac->fsa_dev[sdev_id(dev)].valid) | ||
440 | ++num_lsu; | ||
441 | } else | ||
428 | ++num_one; | 442 | ++num_one; |
429 | } | 443 | } |
430 | if (num_lsu == 0) | 444 | if (num_lsu == 0) |
@@ -481,9 +495,35 @@ static int aac_change_queue_depth(struct scsi_device *sdev, int depth) | |||
481 | return sdev->queue_depth; | 495 | return sdev->queue_depth; |
482 | } | 496 | } |
483 | 497 | ||
498 | static ssize_t aac_show_raid_level(struct device *dev, struct device_attribute *attr, char *buf) | ||
499 | { | ||
500 | struct scsi_device * sdev = to_scsi_device(dev); | ||
501 | if (sdev_channel(sdev) != CONTAINER_CHANNEL) | ||
502 | return snprintf(buf, PAGE_SIZE, sdev->no_uld_attach | ||
503 | ? "Hidden\n" : "JBOD"); | ||
504 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
505 | get_container_type(((struct aac_dev *)(sdev->host->hostdata)) | ||
506 | ->fsa_dev[sdev_id(sdev)].type)); | ||
507 | } | ||
508 | |||
509 | static struct device_attribute aac_raid_level_attr = { | ||
510 | .attr = { | ||
511 | .name = "level", | ||
512 | .mode = S_IRUGO, | ||
513 | }, | ||
514 | .show = aac_show_raid_level | ||
515 | }; | ||
516 | |||
517 | static struct device_attribute *aac_dev_attrs[] = { | ||
518 | &aac_raid_level_attr, | ||
519 | NULL, | ||
520 | }; | ||
521 | |||
484 | static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg) | 522 | static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg) |
485 | { | 523 | { |
486 | struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata; | 524 | struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata; |
525 | if (!capable(CAP_SYS_RAWIO)) | ||
526 | return -EPERM; | ||
487 | return aac_do_ioctl(dev, cmd, arg); | 527 | return aac_do_ioctl(dev, cmd, arg); |
488 | } | 528 | } |
489 | 529 | ||
@@ -506,17 +546,33 @@ static int aac_eh_abort(struct scsi_cmnd* cmd) | |||
506 | break; | 546 | break; |
507 | case INQUIRY: | 547 | case INQUIRY: |
508 | case READ_CAPACITY: | 548 | case READ_CAPACITY: |
509 | case TEST_UNIT_READY: | ||
510 | /* Mark associated FIB to not complete, eh handler does this */ | 549 | /* Mark associated FIB to not complete, eh handler does this */ |
511 | for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { | 550 | for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { |
512 | struct fib * fib = &aac->fibs[count]; | 551 | struct fib * fib = &aac->fibs[count]; |
513 | if (fib->hw_fib_va->header.XferState && | 552 | if (fib->hw_fib_va->header.XferState && |
553 | (fib->flags & FIB_CONTEXT_FLAG) && | ||
514 | (fib->callback_data == cmd)) { | 554 | (fib->callback_data == cmd)) { |
515 | fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; | 555 | fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; |
516 | cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; | 556 | cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; |
517 | ret = SUCCESS; | 557 | ret = SUCCESS; |
518 | } | 558 | } |
519 | } | 559 | } |
560 | break; | ||
561 | case TEST_UNIT_READY: | ||
562 | /* Mark associated FIB to not complete, eh handler does this */ | ||
563 | for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { | ||
564 | struct scsi_cmnd * command; | ||
565 | struct fib * fib = &aac->fibs[count]; | ||
566 | if ((fib->hw_fib_va->header.XferState & cpu_to_le32(Async | NoResponseExpected)) && | ||
567 | (fib->flags & FIB_CONTEXT_FLAG) && | ||
568 | ((command = fib->callback_data)) && | ||
569 | (command->device == cmd->device)) { | ||
570 | fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; | ||
571 | command->SCp.phase = AAC_OWNER_ERROR_HANDLER; | ||
572 | if (command == cmd) | ||
573 | ret = SUCCESS; | ||
574 | } | ||
575 | } | ||
520 | } | 576 | } |
521 | return ret; | 577 | return ret; |
522 | } | 578 | } |
@@ -539,12 +595,13 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) | |||
539 | for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { | 595 | for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { |
540 | struct fib * fib = &aac->fibs[count]; | 596 | struct fib * fib = &aac->fibs[count]; |
541 | if (fib->hw_fib_va->header.XferState && | 597 | if (fib->hw_fib_va->header.XferState && |
598 | (fib->flags & FIB_CONTEXT_FLAG) && | ||
542 | (fib->callback_data == cmd)) { | 599 | (fib->callback_data == cmd)) { |
543 | fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; | 600 | fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; |
544 | cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; | 601 | cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; |
545 | } | 602 | } |
546 | } | 603 | } |
547 | printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", | 604 | printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", |
548 | AAC_DRIVERNAME); | 605 | AAC_DRIVERNAME); |
549 | 606 | ||
550 | if ((count = aac_check_health(aac))) | 607 | if ((count = aac_check_health(aac))) |
@@ -584,8 +641,11 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) | |||
584 | * support a register, instead of a commanded, reset. | 641 | * support a register, instead of a commanded, reset. |
585 | */ | 642 | */ |
586 | if ((aac->supplement_adapter_info.SupportedOptions2 & | 643 | if ((aac->supplement_adapter_info.SupportedOptions2 & |
587 | le32_to_cpu(AAC_OPTION_MU_RESET|AAC_OPTION_IGNORE_RESET)) == | 644 | AAC_OPTION_MU_RESET) && |
588 | le32_to_cpu(AAC_OPTION_MU_RESET)) | 645 | aac_check_reset && |
646 | ((aac_check_reset != 1) || | ||
647 | (aac->supplement_adapter_info.SupportedOptions2 & | ||
648 | AAC_OPTION_IGNORE_RESET))) | ||
589 | aac_reset_adapter(aac, 2); /* Bypass wait for command quiesce */ | 649 | aac_reset_adapter(aac, 2); /* Bypass wait for command quiesce */ |
590 | return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */ | 650 | return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */ |
591 | } | 651 | } |
@@ -632,8 +692,8 @@ static int aac_cfg_open(struct inode *inode, struct file *file) | |||
632 | * Bugs: Needs locking against parallel ioctls lower down | 692 | * Bugs: Needs locking against parallel ioctls lower down |
633 | * Bugs: Needs to handle hot plugging | 693 | * Bugs: Needs to handle hot plugging |
634 | */ | 694 | */ |
635 | 695 | ||
636 | static int aac_cfg_ioctl(struct inode *inode, struct file *file, | 696 | static int aac_cfg_ioctl(struct inode *inode, struct file *file, |
637 | unsigned int cmd, unsigned long arg) | 697 | unsigned int cmd, unsigned long arg) |
638 | { | 698 | { |
639 | if (!capable(CAP_SYS_RAWIO)) | 699 | if (!capable(CAP_SYS_RAWIO)) |
@@ -646,7 +706,7 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long | |||
646 | { | 706 | { |
647 | long ret; | 707 | long ret; |
648 | lock_kernel(); | 708 | lock_kernel(); |
649 | switch (cmd) { | 709 | switch (cmd) { |
650 | case FSACTL_MINIPORT_REV_CHECK: | 710 | case FSACTL_MINIPORT_REV_CHECK: |
651 | case FSACTL_SENDFIB: | 711 | case FSACTL_SENDFIB: |
652 | case FSACTL_OPEN_GET_ADAPTER_FIB: | 712 | case FSACTL_OPEN_GET_ADAPTER_FIB: |
@@ -656,14 +716,14 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long | |||
656 | case FSACTL_QUERY_DISK: | 716 | case FSACTL_QUERY_DISK: |
657 | case FSACTL_DELETE_DISK: | 717 | case FSACTL_DELETE_DISK: |
658 | case FSACTL_FORCE_DELETE_DISK: | 718 | case FSACTL_FORCE_DELETE_DISK: |
659 | case FSACTL_GET_CONTAINERS: | 719 | case FSACTL_GET_CONTAINERS: |
660 | case FSACTL_SEND_LARGE_FIB: | 720 | case FSACTL_SEND_LARGE_FIB: |
661 | ret = aac_do_ioctl(dev, cmd, (void __user *)arg); | 721 | ret = aac_do_ioctl(dev, cmd, (void __user *)arg); |
662 | break; | 722 | break; |
663 | 723 | ||
664 | case FSACTL_GET_NEXT_ADAPTER_FIB: { | 724 | case FSACTL_GET_NEXT_ADAPTER_FIB: { |
665 | struct fib_ioctl __user *f; | 725 | struct fib_ioctl __user *f; |
666 | 726 | ||
667 | f = compat_alloc_user_space(sizeof(*f)); | 727 | f = compat_alloc_user_space(sizeof(*f)); |
668 | ret = 0; | 728 | ret = 0; |
669 | if (clear_user(f, sizeof(*f))) | 729 | if (clear_user(f, sizeof(*f))) |
@@ -676,9 +736,9 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long | |||
676 | } | 736 | } |
677 | 737 | ||
678 | default: | 738 | default: |
679 | ret = -ENOIOCTLCMD; | 739 | ret = -ENOIOCTLCMD; |
680 | break; | 740 | break; |
681 | } | 741 | } |
682 | unlock_kernel(); | 742 | unlock_kernel(); |
683 | return ret; | 743 | return ret; |
684 | } | 744 | } |
@@ -735,6 +795,25 @@ static ssize_t aac_show_vendor(struct class_device *class_dev, | |||
735 | return len; | 795 | return len; |
736 | } | 796 | } |
737 | 797 | ||
798 | static ssize_t aac_show_flags(struct class_device *class_dev, char *buf) | ||
799 | { | ||
800 | int len = 0; | ||
801 | struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata; | ||
802 | |||
803 | if (nblank(dprintk(x))) | ||
804 | len = snprintf(buf, PAGE_SIZE, "dprintk\n"); | ||
805 | #ifdef AAC_DETAILED_STATUS_INFO | ||
806 | len += snprintf(buf + len, PAGE_SIZE - len, | ||
807 | "AAC_DETAILED_STATUS_INFO\n"); | ||
808 | #endif | ||
809 | if (dev->raw_io_interface && dev->raw_io_64) | ||
810 | len += snprintf(buf + len, PAGE_SIZE - len, | ||
811 | "SAI_READ_CAPACITY_16\n"); | ||
812 | if (dev->jbod) | ||
813 | len += snprintf(buf + len, PAGE_SIZE - len, "SUPPORTED_JBOD\n"); | ||
814 | return len; | ||
815 | } | ||
816 | |||
738 | static ssize_t aac_show_kernel_version(struct class_device *class_dev, | 817 | static ssize_t aac_show_kernel_version(struct class_device *class_dev, |
739 | char *buf) | 818 | char *buf) |
740 | { | 819 | { |
@@ -742,7 +821,7 @@ static ssize_t aac_show_kernel_version(struct class_device *class_dev, | |||
742 | int len, tmp; | 821 | int len, tmp; |
743 | 822 | ||
744 | tmp = le32_to_cpu(dev->adapter_info.kernelrev); | 823 | tmp = le32_to_cpu(dev->adapter_info.kernelrev); |
745 | len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", | 824 | len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", |
746 | tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff, | 825 | tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff, |
747 | le32_to_cpu(dev->adapter_info.kernelbuild)); | 826 | le32_to_cpu(dev->adapter_info.kernelbuild)); |
748 | return len; | 827 | return len; |
@@ -755,7 +834,7 @@ static ssize_t aac_show_monitor_version(struct class_device *class_dev, | |||
755 | int len, tmp; | 834 | int len, tmp; |
756 | 835 | ||
757 | tmp = le32_to_cpu(dev->adapter_info.monitorrev); | 836 | tmp = le32_to_cpu(dev->adapter_info.monitorrev); |
758 | len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", | 837 | len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", |
759 | tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff, | 838 | tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff, |
760 | le32_to_cpu(dev->adapter_info.monitorbuild)); | 839 | le32_to_cpu(dev->adapter_info.monitorbuild)); |
761 | return len; | 840 | return len; |
@@ -768,7 +847,7 @@ static ssize_t aac_show_bios_version(struct class_device *class_dev, | |||
768 | int len, tmp; | 847 | int len, tmp; |
769 | 848 | ||
770 | tmp = le32_to_cpu(dev->adapter_info.biosrev); | 849 | tmp = le32_to_cpu(dev->adapter_info.biosrev); |
771 | len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", | 850 | len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", |
772 | tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff, | 851 | tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff, |
773 | le32_to_cpu(dev->adapter_info.biosbuild)); | 852 | le32_to_cpu(dev->adapter_info.biosbuild)); |
774 | return len; | 853 | return len; |
@@ -844,6 +923,13 @@ static struct class_device_attribute aac_vendor = { | |||
844 | }, | 923 | }, |
845 | .show = aac_show_vendor, | 924 | .show = aac_show_vendor, |
846 | }; | 925 | }; |
926 | static struct class_device_attribute aac_flags = { | ||
927 | .attr = { | ||
928 | .name = "flags", | ||
929 | .mode = S_IRUGO, | ||
930 | }, | ||
931 | .show = aac_show_flags, | ||
932 | }; | ||
847 | static struct class_device_attribute aac_kernel_version = { | 933 | static struct class_device_attribute aac_kernel_version = { |
848 | .attr = { | 934 | .attr = { |
849 | .name = "hba_kernel_version", | 935 | .name = "hba_kernel_version", |
@@ -898,6 +984,7 @@ static struct class_device_attribute aac_reset = { | |||
898 | static struct class_device_attribute *aac_attrs[] = { | 984 | static struct class_device_attribute *aac_attrs[] = { |
899 | &aac_model, | 985 | &aac_model, |
900 | &aac_vendor, | 986 | &aac_vendor, |
987 | &aac_flags, | ||
901 | &aac_kernel_version, | 988 | &aac_kernel_version, |
902 | &aac_monitor_version, | 989 | &aac_monitor_version, |
903 | &aac_bios_version, | 990 | &aac_bios_version, |
@@ -928,21 +1015,22 @@ static struct scsi_host_template aac_driver_template = { | |||
928 | .compat_ioctl = aac_compat_ioctl, | 1015 | .compat_ioctl = aac_compat_ioctl, |
929 | #endif | 1016 | #endif |
930 | .queuecommand = aac_queuecommand, | 1017 | .queuecommand = aac_queuecommand, |
931 | .bios_param = aac_biosparm, | 1018 | .bios_param = aac_biosparm, |
932 | .shost_attrs = aac_attrs, | 1019 | .shost_attrs = aac_attrs, |
933 | .slave_configure = aac_slave_configure, | 1020 | .slave_configure = aac_slave_configure, |
934 | .change_queue_depth = aac_change_queue_depth, | 1021 | .change_queue_depth = aac_change_queue_depth, |
1022 | .sdev_attrs = aac_dev_attrs, | ||
935 | .eh_abort_handler = aac_eh_abort, | 1023 | .eh_abort_handler = aac_eh_abort, |
936 | .eh_host_reset_handler = aac_eh_reset, | 1024 | .eh_host_reset_handler = aac_eh_reset, |
937 | .can_queue = AAC_NUM_IO_FIB, | 1025 | .can_queue = AAC_NUM_IO_FIB, |
938 | .this_id = MAXIMUM_NUM_CONTAINERS, | 1026 | .this_id = MAXIMUM_NUM_CONTAINERS, |
939 | .sg_tablesize = 16, | 1027 | .sg_tablesize = 16, |
940 | .max_sectors = 128, | 1028 | .max_sectors = 128, |
941 | #if (AAC_NUM_IO_FIB > 256) | 1029 | #if (AAC_NUM_IO_FIB > 256) |
942 | .cmd_per_lun = 256, | 1030 | .cmd_per_lun = 256, |
943 | #else | 1031 | #else |
944 | .cmd_per_lun = AAC_NUM_IO_FIB, | 1032 | .cmd_per_lun = AAC_NUM_IO_FIB, |
945 | #endif | 1033 | #endif |
946 | .use_clustering = ENABLE_CLUSTERING, | 1034 | .use_clustering = ENABLE_CLUSTERING, |
947 | .use_sg_chaining = ENABLE_SG_CHAINING, | 1035 | .use_sg_chaining = ENABLE_SG_CHAINING, |
948 | .emulated = 1, | 1036 | .emulated = 1, |
@@ -979,18 +1067,18 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
979 | goto out; | 1067 | goto out; |
980 | error = -ENODEV; | 1068 | error = -ENODEV; |
981 | 1069 | ||
982 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) || | 1070 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) || |
983 | pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) | 1071 | pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) |
984 | goto out_disable_pdev; | 1072 | goto out_disable_pdev; |
985 | /* | 1073 | /* |
986 | * If the quirk31 bit is set, the adapter needs adapter | 1074 | * If the quirk31 bit is set, the adapter needs adapter |
987 | * to driver communication memory to be allocated below 2gig | 1075 | * to driver communication memory to be allocated below 2gig |
988 | */ | 1076 | */ |
989 | if (aac_drivers[index].quirks & AAC_QUIRK_31BIT) | 1077 | if (aac_drivers[index].quirks & AAC_QUIRK_31BIT) |
990 | if (pci_set_dma_mask(pdev, DMA_31BIT_MASK) || | 1078 | if (pci_set_dma_mask(pdev, DMA_31BIT_MASK) || |
991 | pci_set_consistent_dma_mask(pdev, DMA_31BIT_MASK)) | 1079 | pci_set_consistent_dma_mask(pdev, DMA_31BIT_MASK)) |
992 | goto out_disable_pdev; | 1080 | goto out_disable_pdev; |
993 | 1081 | ||
994 | pci_set_master(pdev); | 1082 | pci_set_master(pdev); |
995 | 1083 | ||
996 | shost = scsi_host_alloc(&aac_driver_template, sizeof(struct aac_dev)); | 1084 | shost = scsi_host_alloc(&aac_driver_template, sizeof(struct aac_dev)); |
@@ -1003,7 +1091,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
1003 | shost->max_cmd_len = 16; | 1091 | shost->max_cmd_len = 16; |
1004 | 1092 | ||
1005 | aac = (struct aac_dev *)shost->hostdata; | 1093 | aac = (struct aac_dev *)shost->hostdata; |
1006 | aac->scsi_host_ptr = shost; | 1094 | aac->scsi_host_ptr = shost; |
1007 | aac->pdev = pdev; | 1095 | aac->pdev = pdev; |
1008 | aac->name = aac_driver_template.name; | 1096 | aac->name = aac_driver_template.name; |
1009 | aac->id = shost->unique_id; | 1097 | aac->id = shost->unique_id; |
@@ -1040,7 +1128,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
1040 | if (aac_drivers[index].quirks & AAC_QUIRK_31BIT) | 1128 | if (aac_drivers[index].quirks & AAC_QUIRK_31BIT) |
1041 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) | 1129 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) |
1042 | goto out_deinit; | 1130 | goto out_deinit; |
1043 | 1131 | ||
1044 | aac->maximum_num_channels = aac_drivers[index].channels; | 1132 | aac->maximum_num_channels = aac_drivers[index].channels; |
1045 | error = aac_get_adapter_info(aac); | 1133 | error = aac_get_adapter_info(aac); |
1046 | if (error < 0) | 1134 | if (error < 0) |
@@ -1049,7 +1137,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
1049 | /* | 1137 | /* |
1050 | * Lets override negotiations and drop the maximum SG limit to 34 | 1138 | * Lets override negotiations and drop the maximum SG limit to 34 |
1051 | */ | 1139 | */ |
1052 | if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) && | 1140 | if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) && |
1053 | (aac->scsi_host_ptr->sg_tablesize > 34)) { | 1141 | (aac->scsi_host_ptr->sg_tablesize > 34)) { |
1054 | aac->scsi_host_ptr->sg_tablesize = 34; | 1142 | aac->scsi_host_ptr->sg_tablesize = 34; |
1055 | aac->scsi_host_ptr->max_sectors | 1143 | aac->scsi_host_ptr->max_sectors |
@@ -1066,17 +1154,17 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
1066 | /* | 1154 | /* |
1067 | * Firware printf works only with older firmware. | 1155 | * Firware printf works only with older firmware. |
1068 | */ | 1156 | */ |
1069 | if (aac_drivers[index].quirks & AAC_QUIRK_34SG) | 1157 | if (aac_drivers[index].quirks & AAC_QUIRK_34SG) |
1070 | aac->printf_enabled = 1; | 1158 | aac->printf_enabled = 1; |
1071 | else | 1159 | else |
1072 | aac->printf_enabled = 0; | 1160 | aac->printf_enabled = 0; |
1073 | 1161 | ||
1074 | /* | 1162 | /* |
1075 | * max channel will be the physical channels plus 1 virtual channel | 1163 | * max channel will be the physical channels plus 1 virtual channel |
1076 | * all containers are on the virtual channel 0 (CONTAINER_CHANNEL) | 1164 | * all containers are on the virtual channel 0 (CONTAINER_CHANNEL) |
1077 | * physical channels are address by their actual physical number+1 | 1165 | * physical channels are address by their actual physical number+1 |
1078 | */ | 1166 | */ |
1079 | if ((aac->nondasd_support == 1) || expose_physicals) | 1167 | if (aac->nondasd_support || expose_physicals || aac->jbod) |
1080 | shost->max_channel = aac->maximum_num_channels; | 1168 | shost->max_channel = aac->maximum_num_channels; |
1081 | else | 1169 | else |
1082 | shost->max_channel = 0; | 1170 | shost->max_channel = 0; |
@@ -1148,10 +1236,10 @@ static void __devexit aac_remove_one(struct pci_dev *pdev) | |||
1148 | kfree(aac->queues); | 1236 | kfree(aac->queues); |
1149 | 1237 | ||
1150 | aac_adapter_ioremap(aac, 0); | 1238 | aac_adapter_ioremap(aac, 0); |
1151 | 1239 | ||
1152 | kfree(aac->fibs); | 1240 | kfree(aac->fibs); |
1153 | kfree(aac->fsa_dev); | 1241 | kfree(aac->fsa_dev); |
1154 | 1242 | ||
1155 | list_del(&aac->entry); | 1243 | list_del(&aac->entry); |
1156 | scsi_host_put(shost); | 1244 | scsi_host_put(shost); |
1157 | pci_disable_device(pdev); | 1245 | pci_disable_device(pdev); |
@@ -1172,7 +1260,7 @@ static struct pci_driver aac_pci_driver = { | |||
1172 | static int __init aac_init(void) | 1260 | static int __init aac_init(void) |
1173 | { | 1261 | { |
1174 | int error; | 1262 | int error; |
1175 | 1263 | ||
1176 | printk(KERN_INFO "Adaptec %s driver %s\n", | 1264 | printk(KERN_INFO "Adaptec %s driver %s\n", |
1177 | AAC_DRIVERNAME, aac_driver_version); | 1265 | AAC_DRIVERNAME, aac_driver_version); |
1178 | 1266 | ||