diff options
Diffstat (limited to 'drivers/scsi/aacraid/linit.c')
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 179 |
1 files changed, 164 insertions, 15 deletions
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 242fa77513f5..f7e9c89c4915 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -215,7 +215,7 @@ static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd | |||
215 | * Returns a static string describing the device in question | 215 | * Returns a static string describing the device in question |
216 | */ | 216 | */ |
217 | 217 | ||
218 | const char *aac_info(struct Scsi_Host *shost) | 218 | static const char *aac_info(struct Scsi_Host *shost) |
219 | { | 219 | { |
220 | struct aac_dev *dev = (struct aac_dev *)shost->hostdata; | 220 | struct aac_dev *dev = (struct aac_dev *)shost->hostdata; |
221 | return aac_drivers[dev->cardtype].name; | 221 | return aac_drivers[dev->cardtype].name; |
@@ -288,7 +288,7 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, | |||
288 | * translations ( 64/32, 128/32, 255/63 ). | 288 | * translations ( 64/32, 128/32, 255/63 ). |
289 | */ | 289 | */ |
290 | buf = scsi_bios_ptable(bdev); | 290 | buf = scsi_bios_ptable(bdev); |
291 | if(*(unsigned short *)(buf + 0x40) == cpu_to_le16(0xaa55)) { | 291 | if(*(__le16 *)(buf + 0x40) == cpu_to_le16(0xaa55)) { |
292 | struct partition *first = (struct partition * )buf; | 292 | struct partition *first = (struct partition * )buf; |
293 | struct partition *entry = first; | 293 | struct partition *entry = first; |
294 | int saved_cylinders = param->cylinders; | 294 | int saved_cylinders = param->cylinders; |
@@ -347,10 +347,16 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, | |||
347 | 347 | ||
348 | static int aac_slave_configure(struct scsi_device *sdev) | 348 | static int aac_slave_configure(struct scsi_device *sdev) |
349 | { | 349 | { |
350 | struct Scsi_Host *host = sdev->host; | ||
351 | |||
350 | if (sdev->tagged_supported) | 352 | if (sdev->tagged_supported) |
351 | scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128); | 353 | scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128); |
352 | else | 354 | else |
353 | scsi_adjust_queue_depth(sdev, 0, 1); | 355 | scsi_adjust_queue_depth(sdev, 0, 1); |
356 | |||
357 | if (host->max_sectors < AAC_MAX_32BIT_SGBCOUNT) | ||
358 | blk_queue_max_segment_size(sdev->request_queue, 65536); | ||
359 | |||
354 | return 0; | 360 | return 0; |
355 | } | 361 | } |
356 | 362 | ||
@@ -361,14 +367,6 @@ static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg) | |||
361 | } | 367 | } |
362 | 368 | ||
363 | /* | 369 | /* |
364 | * XXX: does aac really need no error handling?? | ||
365 | */ | ||
366 | static int aac_eh_abort(struct scsi_cmnd *cmd) | ||
367 | { | ||
368 | return FAILED; | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * aac_eh_reset - Reset command handling | 370 | * aac_eh_reset - Reset command handling |
373 | * @scsi_cmd: SCSI command block causing the reset | 371 | * @scsi_cmd: SCSI command block causing the reset |
374 | * | 372 | * |
@@ -386,10 +384,13 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) | |||
386 | AAC_DRIVERNAME); | 384 | AAC_DRIVERNAME); |
387 | 385 | ||
388 | 386 | ||
387 | spin_lock_irq(host->host_lock); | ||
388 | |||
389 | aac = (struct aac_dev *)host->hostdata; | 389 | aac = (struct aac_dev *)host->hostdata; |
390 | if (aac_adapter_check_health(aac)) { | 390 | if (aac_adapter_check_health(aac)) { |
391 | printk(KERN_ERR "%s: Host adapter appears dead\n", | 391 | printk(KERN_ERR "%s: Host adapter appears dead\n", |
392 | AAC_DRIVERNAME); | 392 | AAC_DRIVERNAME); |
393 | spin_unlock_irq(host->host_lock); | ||
393 | return -ENODEV; | 394 | return -ENODEV; |
394 | } | 395 | } |
395 | /* | 396 | /* |
@@ -420,6 +421,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) | |||
420 | ssleep(1); | 421 | ssleep(1); |
421 | spin_lock_irq(host->host_lock); | 422 | spin_lock_irq(host->host_lock); |
422 | } | 423 | } |
424 | spin_unlock_irq(host->host_lock); | ||
423 | printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME); | 425 | printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME); |
424 | return -ETIMEDOUT; | 426 | return -ETIMEDOUT; |
425 | } | 427 | } |
@@ -439,11 +441,11 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) | |||
439 | static int aac_cfg_open(struct inode *inode, struct file *file) | 441 | static int aac_cfg_open(struct inode *inode, struct file *file) |
440 | { | 442 | { |
441 | struct aac_dev *aac; | 443 | struct aac_dev *aac; |
442 | unsigned minor = iminor(inode); | 444 | unsigned minor_number = iminor(inode); |
443 | int err = -ENODEV; | 445 | int err = -ENODEV; |
444 | 446 | ||
445 | list_for_each_entry(aac, &aac_devices, entry) { | 447 | list_for_each_entry(aac, &aac_devices, entry) { |
446 | if (aac->id == minor) { | 448 | if (aac->id == minor_number) { |
447 | file->private_data = aac; | 449 | file->private_data = aac; |
448 | err = 0; | 450 | err = 0; |
449 | break; | 451 | break; |
@@ -489,6 +491,7 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long | |||
489 | case FSACTL_DELETE_DISK: | 491 | case FSACTL_DELETE_DISK: |
490 | case FSACTL_FORCE_DELETE_DISK: | 492 | case FSACTL_FORCE_DELETE_DISK: |
491 | case FSACTL_GET_CONTAINERS: | 493 | case FSACTL_GET_CONTAINERS: |
494 | case FSACTL_SEND_LARGE_FIB: | ||
492 | ret = aac_do_ioctl(dev, cmd, (void __user *)arg); | 495 | ret = aac_do_ioctl(dev, cmd, (void __user *)arg); |
493 | break; | 496 | break; |
494 | 497 | ||
@@ -526,6 +529,134 @@ static long aac_compat_cfg_ioctl(struct file *file, unsigned cmd, unsigned long | |||
526 | } | 529 | } |
527 | #endif | 530 | #endif |
528 | 531 | ||
532 | static ssize_t aac_show_model(struct class_device *class_dev, | ||
533 | char *buf) | ||
534 | { | ||
535 | struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata; | ||
536 | int len; | ||
537 | |||
538 | len = snprintf(buf, PAGE_SIZE, "%s\n", | ||
539 | aac_drivers[dev->cardtype].model); | ||
540 | return len; | ||
541 | } | ||
542 | |||
543 | static ssize_t aac_show_vendor(struct class_device *class_dev, | ||
544 | char *buf) | ||
545 | { | ||
546 | struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata; | ||
547 | int len; | ||
548 | |||
549 | len = snprintf(buf, PAGE_SIZE, "%s\n", | ||
550 | aac_drivers[dev->cardtype].vname); | ||
551 | return len; | ||
552 | } | ||
553 | |||
554 | static ssize_t aac_show_kernel_version(struct class_device *class_dev, | ||
555 | char *buf) | ||
556 | { | ||
557 | struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata; | ||
558 | int len, tmp; | ||
559 | |||
560 | tmp = le32_to_cpu(dev->adapter_info.kernelrev); | ||
561 | len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", | ||
562 | tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff, | ||
563 | le32_to_cpu(dev->adapter_info.kernelbuild)); | ||
564 | return len; | ||
565 | } | ||
566 | |||
567 | static ssize_t aac_show_monitor_version(struct class_device *class_dev, | ||
568 | char *buf) | ||
569 | { | ||
570 | struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata; | ||
571 | int len, tmp; | ||
572 | |||
573 | tmp = le32_to_cpu(dev->adapter_info.monitorrev); | ||
574 | len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", | ||
575 | tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff, | ||
576 | le32_to_cpu(dev->adapter_info.monitorbuild)); | ||
577 | return len; | ||
578 | } | ||
579 | |||
580 | static ssize_t aac_show_bios_version(struct class_device *class_dev, | ||
581 | char *buf) | ||
582 | { | ||
583 | struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata; | ||
584 | int len, tmp; | ||
585 | |||
586 | tmp = le32_to_cpu(dev->adapter_info.biosrev); | ||
587 | len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", | ||
588 | tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff, | ||
589 | le32_to_cpu(dev->adapter_info.biosbuild)); | ||
590 | return len; | ||
591 | } | ||
592 | |||
593 | static ssize_t aac_show_serial_number(struct class_device *class_dev, | ||
594 | char *buf) | ||
595 | { | ||
596 | struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata; | ||
597 | int len = 0; | ||
598 | |||
599 | if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0) | ||
600 | len = snprintf(buf, PAGE_SIZE, "%x\n", | ||
601 | le32_to_cpu(dev->adapter_info.serial[0])); | ||
602 | return len; | ||
603 | } | ||
604 | |||
605 | |||
606 | static struct class_device_attribute aac_model = { | ||
607 | .attr = { | ||
608 | .name = "model", | ||
609 | .mode = S_IRUGO, | ||
610 | }, | ||
611 | .show = aac_show_model, | ||
612 | }; | ||
613 | static struct class_device_attribute aac_vendor = { | ||
614 | .attr = { | ||
615 | .name = "vendor", | ||
616 | .mode = S_IRUGO, | ||
617 | }, | ||
618 | .show = aac_show_vendor, | ||
619 | }; | ||
620 | static struct class_device_attribute aac_kernel_version = { | ||
621 | .attr = { | ||
622 | .name = "hba_kernel_version", | ||
623 | .mode = S_IRUGO, | ||
624 | }, | ||
625 | .show = aac_show_kernel_version, | ||
626 | }; | ||
627 | static struct class_device_attribute aac_monitor_version = { | ||
628 | .attr = { | ||
629 | .name = "hba_monitor_version", | ||
630 | .mode = S_IRUGO, | ||
631 | }, | ||
632 | .show = aac_show_monitor_version, | ||
633 | }; | ||
634 | static struct class_device_attribute aac_bios_version = { | ||
635 | .attr = { | ||
636 | .name = "hba_bios_version", | ||
637 | .mode = S_IRUGO, | ||
638 | }, | ||
639 | .show = aac_show_bios_version, | ||
640 | }; | ||
641 | static struct class_device_attribute aac_serial_number = { | ||
642 | .attr = { | ||
643 | .name = "serial_number", | ||
644 | .mode = S_IRUGO, | ||
645 | }, | ||
646 | .show = aac_show_serial_number, | ||
647 | }; | ||
648 | |||
649 | static struct class_device_attribute *aac_attrs[] = { | ||
650 | &aac_model, | ||
651 | &aac_vendor, | ||
652 | &aac_kernel_version, | ||
653 | &aac_monitor_version, | ||
654 | &aac_bios_version, | ||
655 | &aac_serial_number, | ||
656 | NULL | ||
657 | }; | ||
658 | |||
659 | |||
529 | static struct file_operations aac_cfg_fops = { | 660 | static struct file_operations aac_cfg_fops = { |
530 | .owner = THIS_MODULE, | 661 | .owner = THIS_MODULE, |
531 | .ioctl = aac_cfg_ioctl, | 662 | .ioctl = aac_cfg_ioctl, |
@@ -538,7 +669,7 @@ static struct file_operations aac_cfg_fops = { | |||
538 | static struct scsi_host_template aac_driver_template = { | 669 | static struct scsi_host_template aac_driver_template = { |
539 | .module = THIS_MODULE, | 670 | .module = THIS_MODULE, |
540 | .name = "AAC", | 671 | .name = "AAC", |
541 | .proc_name = "aacraid", | 672 | .proc_name = AAC_DRIVERNAME, |
542 | .info = aac_info, | 673 | .info = aac_info, |
543 | .ioctl = aac_ioctl, | 674 | .ioctl = aac_ioctl, |
544 | #ifdef CONFIG_COMPAT | 675 | #ifdef CONFIG_COMPAT |
@@ -546,8 +677,8 @@ static struct scsi_host_template aac_driver_template = { | |||
546 | #endif | 677 | #endif |
547 | .queuecommand = aac_queuecommand, | 678 | .queuecommand = aac_queuecommand, |
548 | .bios_param = aac_biosparm, | 679 | .bios_param = aac_biosparm, |
680 | .shost_attrs = aac_attrs, | ||
549 | .slave_configure = aac_slave_configure, | 681 | .slave_configure = aac_slave_configure, |
550 | .eh_abort_handler = aac_eh_abort, | ||
551 | .eh_host_reset_handler = aac_eh_reset, | 682 | .eh_host_reset_handler = aac_eh_reset, |
552 | .can_queue = AAC_NUM_IO_FIB, | 683 | .can_queue = AAC_NUM_IO_FIB, |
553 | .this_id = 16, | 684 | .this_id = 16, |
@@ -612,7 +743,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
612 | aac->cardtype = index; | 743 | aac->cardtype = index; |
613 | INIT_LIST_HEAD(&aac->entry); | 744 | INIT_LIST_HEAD(&aac->entry); |
614 | 745 | ||
615 | aac->fibs = kmalloc(sizeof(struct fib) * AAC_NUM_FIB, GFP_KERNEL); | 746 | aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL); |
616 | if (!aac->fibs) | 747 | if (!aac->fibs) |
617 | goto out_free_host; | 748 | goto out_free_host; |
618 | spin_lock_init(&aac->fib_lock); | 749 | spin_lock_init(&aac->fib_lock); |
@@ -632,6 +763,24 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
632 | aac_get_adapter_info(aac); | 763 | aac_get_adapter_info(aac); |
633 | 764 | ||
634 | /* | 765 | /* |
766 | * Lets override negotiations and drop the maximum SG limit to 34 | ||
767 | */ | ||
768 | if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) && | ||
769 | (aac->scsi_host_ptr->sg_tablesize > 34)) { | ||
770 | aac->scsi_host_ptr->sg_tablesize = 34; | ||
771 | aac->scsi_host_ptr->max_sectors | ||
772 | = (aac->scsi_host_ptr->sg_tablesize * 8) + 112; | ||
773 | } | ||
774 | |||
775 | /* | ||
776 | * Firware printf works only with older firmware. | ||
777 | */ | ||
778 | if (aac_drivers[index].quirks & AAC_QUIRK_34SG) | ||
779 | aac->printf_enabled = 1; | ||
780 | else | ||
781 | aac->printf_enabled = 0; | ||
782 | |||
783 | /* | ||
635 | * max channel will be the physical channels plus 1 virtual channel | 784 | * max channel will be the physical channels plus 1 virtual channel |
636 | * all containers are on the virtual channel 0 | 785 | * all containers are on the virtual channel 0 |
637 | * physical channels are address by their actual physical number+1 | 786 | * physical channels are address by their actual physical number+1 |