diff options
author | Hannes Reinecke <hare@suse.de> | 2005-07-22 10:42:28 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-08-03 12:25:36 -0400 |
commit | 60a13213840296b1e32d6781653a0eaa83d04382 (patch) | |
tree | f1fe8ccfa5336a820796077c546de61145d29905 /drivers/scsi/aic7xxx | |
parent | 8d6810d33e5e43b11675190318a81303c601a568 (diff) |
[SCSI] aic79xx: Remove busyq
From: Jeff Garzik <jgarzik@pobox.com>
This patch removes the busyq in aic79xx and uses the command-queue from
the midlayer instead. Additionally some dead code is removed.
Signed-off-by: Hannes Reinecke <hare@suse.de>
Fixed rejections
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aic7xxx')
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_core.c | 1 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_osm.c | 824 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_osm.h | 26 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_proc.c | 12 |
4 files changed, 139 insertions, 724 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 137fb1a37dd1..d69bbffb34a0 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -9039,7 +9039,6 @@ ahd_dump_card_state(struct ahd_softc *ahd) | |||
9039 | ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF); | 9039 | ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF); |
9040 | } | 9040 | } |
9041 | printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n"); | 9041 | printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n"); |
9042 | ahd_platform_dump_card_state(ahd); | ||
9043 | ahd_restore_modes(ahd, saved_modes); | 9042 | ahd_restore_modes(ahd, saved_modes); |
9044 | if (paused == 0) | 9043 | if (paused == 0) |
9045 | ahd_unpause(ahd); | 9044 | ahd_unpause(ahd); |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 329cb2331339..7463dd515d11 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -53,11 +53,6 @@ | |||
53 | #include "aiclib.c" | 53 | #include "aiclib.c" |
54 | 54 | ||
55 | #include <linux/init.h> /* __setup */ | 55 | #include <linux/init.h> /* __setup */ |
56 | |||
57 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
58 | #include "sd.h" /* For geometry detection */ | ||
59 | #endif | ||
60 | |||
61 | #include <linux/mm.h> /* For fetching system memory size */ | 56 | #include <linux/mm.h> /* For fetching system memory size */ |
62 | #include <linux/delay.h> /* For ssleep/msleep */ | 57 | #include <linux/delay.h> /* For ssleep/msleep */ |
63 | 58 | ||
@@ -66,11 +61,6 @@ | |||
66 | */ | 61 | */ |
67 | spinlock_t ahd_list_spinlock; | 62 | spinlock_t ahd_list_spinlock; |
68 | 63 | ||
69 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
70 | /* For dynamic sglist size calculation. */ | ||
71 | u_int ahd_linux_nseg; | ||
72 | #endif | ||
73 | |||
74 | /* | 64 | /* |
75 | * Bucket size for counting good commands in between bad ones. | 65 | * Bucket size for counting good commands in between bad ones. |
76 | */ | 66 | */ |
@@ -457,7 +447,6 @@ static void ahd_linux_filter_inquiry(struct ahd_softc *ahd, | |||
457 | static void ahd_linux_dev_timed_unfreeze(u_long arg); | 447 | static void ahd_linux_dev_timed_unfreeze(u_long arg); |
458 | static void ahd_linux_sem_timeout(u_long arg); | 448 | static void ahd_linux_sem_timeout(u_long arg); |
459 | static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd); | 449 | static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd); |
460 | static void ahd_linux_size_nseg(void); | ||
461 | static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd); | 450 | static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd); |
462 | static void ahd_linux_start_dv(struct ahd_softc *ahd); | 451 | static void ahd_linux_start_dv(struct ahd_softc *ahd); |
463 | static void ahd_linux_dv_timeout(struct scsi_cmnd *cmd); | 452 | static void ahd_linux_dv_timeout(struct scsi_cmnd *cmd); |
@@ -516,31 +505,23 @@ static struct ahd_linux_device* ahd_linux_alloc_device(struct ahd_softc*, | |||
516 | u_int); | 505 | u_int); |
517 | static void ahd_linux_free_device(struct ahd_softc*, | 506 | static void ahd_linux_free_device(struct ahd_softc*, |
518 | struct ahd_linux_device*); | 507 | struct ahd_linux_device*); |
519 | static void ahd_linux_run_device_queue(struct ahd_softc*, | 508 | static int ahd_linux_run_command(struct ahd_softc*, |
520 | struct ahd_linux_device*); | 509 | struct ahd_linux_device*, |
510 | struct scsi_cmnd *); | ||
521 | static void ahd_linux_setup_tag_info_global(char *p); | 511 | static void ahd_linux_setup_tag_info_global(char *p); |
522 | static aic_option_callback_t ahd_linux_setup_tag_info; | 512 | static aic_option_callback_t ahd_linux_setup_tag_info; |
523 | static aic_option_callback_t ahd_linux_setup_rd_strm_info; | 513 | static aic_option_callback_t ahd_linux_setup_rd_strm_info; |
524 | static aic_option_callback_t ahd_linux_setup_dv; | 514 | static aic_option_callback_t ahd_linux_setup_dv; |
525 | static aic_option_callback_t ahd_linux_setup_iocell_info; | 515 | static aic_option_callback_t ahd_linux_setup_iocell_info; |
526 | static int ahd_linux_next_unit(void); | 516 | static int ahd_linux_next_unit(void); |
527 | static void ahd_runq_tasklet(unsigned long data); | ||
528 | static int aic79xx_setup(char *c); | 517 | static int aic79xx_setup(char *c); |
529 | 518 | ||
530 | /****************************** Inlines ***************************************/ | 519 | /****************************** Inlines ***************************************/ |
531 | static __inline void ahd_schedule_completeq(struct ahd_softc *ahd); | 520 | static __inline void ahd_schedule_completeq(struct ahd_softc *ahd); |
532 | static __inline void ahd_schedule_runq(struct ahd_softc *ahd); | ||
533 | static __inline void ahd_setup_runq_tasklet(struct ahd_softc *ahd); | ||
534 | static __inline void ahd_teardown_runq_tasklet(struct ahd_softc *ahd); | ||
535 | static __inline struct ahd_linux_device* | 521 | static __inline struct ahd_linux_device* |
536 | ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, | 522 | ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, |
537 | u_int target, u_int lun, int alloc); | 523 | u_int target, u_int lun, int alloc); |
538 | static struct ahd_cmd *ahd_linux_run_complete_queue(struct ahd_softc *ahd); | 524 | static struct ahd_cmd *ahd_linux_run_complete_queue(struct ahd_softc *ahd); |
539 | static __inline void ahd_linux_check_device_queue(struct ahd_softc *ahd, | ||
540 | struct ahd_linux_device *dev); | ||
541 | static __inline struct ahd_linux_device * | ||
542 | ahd_linux_next_device_to_run(struct ahd_softc *ahd); | ||
543 | static __inline void ahd_linux_run_device_queues(struct ahd_softc *ahd); | ||
544 | static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*); | 525 | static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*); |
545 | 526 | ||
546 | static __inline void | 527 | static __inline void |
@@ -553,28 +534,6 @@ ahd_schedule_completeq(struct ahd_softc *ahd) | |||
553 | } | 534 | } |
554 | } | 535 | } |
555 | 536 | ||
556 | /* | ||
557 | * Must be called with our lock held. | ||
558 | */ | ||
559 | static __inline void | ||
560 | ahd_schedule_runq(struct ahd_softc *ahd) | ||
561 | { | ||
562 | tasklet_schedule(&ahd->platform_data->runq_tasklet); | ||
563 | } | ||
564 | |||
565 | static __inline | ||
566 | void ahd_setup_runq_tasklet(struct ahd_softc *ahd) | ||
567 | { | ||
568 | tasklet_init(&ahd->platform_data->runq_tasklet, ahd_runq_tasklet, | ||
569 | (unsigned long)ahd); | ||
570 | } | ||
571 | |||
572 | static __inline void | ||
573 | ahd_teardown_runq_tasklet(struct ahd_softc *ahd) | ||
574 | { | ||
575 | tasklet_kill(&ahd->platform_data->runq_tasklet); | ||
576 | } | ||
577 | |||
578 | static __inline struct ahd_linux_device* | 537 | static __inline struct ahd_linux_device* |
579 | ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, u_int target, | 538 | ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, u_int target, |
580 | u_int lun, int alloc) | 539 | u_int lun, int alloc) |
@@ -641,46 +600,6 @@ ahd_linux_run_complete_queue(struct ahd_softc *ahd) | |||
641 | } | 600 | } |
642 | 601 | ||
643 | static __inline void | 602 | static __inline void |
644 | ahd_linux_check_device_queue(struct ahd_softc *ahd, | ||
645 | struct ahd_linux_device *dev) | ||
646 | { | ||
647 | if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) != 0 | ||
648 | && dev->active == 0) { | ||
649 | dev->flags &= ~AHD_DEV_FREEZE_TIL_EMPTY; | ||
650 | dev->qfrozen--; | ||
651 | } | ||
652 | |||
653 | if (TAILQ_FIRST(&dev->busyq) == NULL | ||
654 | || dev->openings == 0 || dev->qfrozen != 0) | ||
655 | return; | ||
656 | |||
657 | ahd_linux_run_device_queue(ahd, dev); | ||
658 | } | ||
659 | |||
660 | static __inline struct ahd_linux_device * | ||
661 | ahd_linux_next_device_to_run(struct ahd_softc *ahd) | ||
662 | { | ||
663 | |||
664 | if ((ahd->flags & AHD_RESOURCE_SHORTAGE) != 0 | ||
665 | || (ahd->platform_data->qfrozen != 0 | ||
666 | && AHD_DV_SIMQ_FROZEN(ahd) == 0)) | ||
667 | return (NULL); | ||
668 | return (TAILQ_FIRST(&ahd->platform_data->device_runq)); | ||
669 | } | ||
670 | |||
671 | static __inline void | ||
672 | ahd_linux_run_device_queues(struct ahd_softc *ahd) | ||
673 | { | ||
674 | struct ahd_linux_device *dev; | ||
675 | |||
676 | while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) { | ||
677 | TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links); | ||
678 | dev->flags &= ~AHD_DEV_ON_RUN_LIST; | ||
679 | ahd_linux_check_device_queue(ahd, dev); | ||
680 | } | ||
681 | } | ||
682 | |||
683 | static __inline void | ||
684 | ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb) | 603 | ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb) |
685 | { | 604 | { |
686 | Scsi_Cmnd *cmd; | 605 | Scsi_Cmnd *cmd; |
@@ -709,7 +628,6 @@ ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb) | |||
709 | static int ahd_linux_detect(Scsi_Host_Template *); | 628 | static int ahd_linux_detect(Scsi_Host_Template *); |
710 | static const char *ahd_linux_info(struct Scsi_Host *); | 629 | static const char *ahd_linux_info(struct Scsi_Host *); |
711 | static int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); | 630 | static int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); |
712 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
713 | static int ahd_linux_slave_alloc(Scsi_Device *); | 631 | static int ahd_linux_slave_alloc(Scsi_Device *); |
714 | static int ahd_linux_slave_configure(Scsi_Device *); | 632 | static int ahd_linux_slave_configure(Scsi_Device *); |
715 | static void ahd_linux_slave_destroy(Scsi_Device *); | 633 | static void ahd_linux_slave_destroy(Scsi_Device *); |
@@ -717,78 +635,10 @@ static void ahd_linux_slave_destroy(Scsi_Device *); | |||
717 | static int ahd_linux_biosparam(struct scsi_device*, | 635 | static int ahd_linux_biosparam(struct scsi_device*, |
718 | struct block_device*, sector_t, int[]); | 636 | struct block_device*, sector_t, int[]); |
719 | #endif | 637 | #endif |
720 | #else | ||
721 | static int ahd_linux_release(struct Scsi_Host *); | ||
722 | static void ahd_linux_select_queue_depth(struct Scsi_Host *host, | ||
723 | Scsi_Device *scsi_devs); | ||
724 | #if defined(__i386__) | ||
725 | static int ahd_linux_biosparam(Disk *, kdev_t, int[]); | ||
726 | #endif | ||
727 | #endif | ||
728 | static int ahd_linux_bus_reset(Scsi_Cmnd *); | 638 | static int ahd_linux_bus_reset(Scsi_Cmnd *); |
729 | static int ahd_linux_dev_reset(Scsi_Cmnd *); | 639 | static int ahd_linux_dev_reset(Scsi_Cmnd *); |
730 | static int ahd_linux_abort(Scsi_Cmnd *); | 640 | static int ahd_linux_abort(Scsi_Cmnd *); |
731 | 641 | ||
732 | /* | ||
733 | * Calculate a safe value for AHD_NSEG (as expressed through ahd_linux_nseg). | ||
734 | * | ||
735 | * In pre-2.5.X... | ||
736 | * The midlayer allocates an S/G array dynamically when a command is issued | ||
737 | * using SCSI malloc. This array, which is in an OS dependent format that | ||
738 | * must later be copied to our private S/G list, is sized to house just the | ||
739 | * number of segments needed for the current transfer. Since the code that | ||
740 | * sizes the SCSI malloc pool does not take into consideration fragmentation | ||
741 | * of the pool, executing transactions numbering just a fraction of our | ||
742 | * concurrent transaction limit with SG list lengths aproaching AHC_NSEG will | ||
743 | * quickly depleat the SCSI malloc pool of usable space. Unfortunately, the | ||
744 | * mid-layer does not properly handle this scsi malloc failures for the S/G | ||
745 | * array and the result can be a lockup of the I/O subsystem. We try to size | ||
746 | * our S/G list so that it satisfies our drivers allocation requirements in | ||
747 | * addition to avoiding fragmentation of the SCSI malloc pool. | ||
748 | */ | ||
749 | static void | ||
750 | ahd_linux_size_nseg(void) | ||
751 | { | ||
752 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
753 | u_int cur_size; | ||
754 | u_int best_size; | ||
755 | |||
756 | /* | ||
757 | * The SCSI allocator rounds to the nearest 512 bytes | ||
758 | * an cannot allocate across a page boundary. Our algorithm | ||
759 | * is to start at 1K of scsi malloc space per-command and | ||
760 | * loop through all factors of the PAGE_SIZE and pick the best. | ||
761 | */ | ||
762 | best_size = 0; | ||
763 | for (cur_size = 1024; cur_size <= PAGE_SIZE; cur_size *= 2) { | ||
764 | u_int nseg; | ||
765 | |||
766 | nseg = cur_size / sizeof(struct scatterlist); | ||
767 | if (nseg < AHD_LINUX_MIN_NSEG) | ||
768 | continue; | ||
769 | |||
770 | if (best_size == 0) { | ||
771 | best_size = cur_size; | ||
772 | ahd_linux_nseg = nseg; | ||
773 | } else { | ||
774 | u_int best_rem; | ||
775 | u_int cur_rem; | ||
776 | |||
777 | /* | ||
778 | * Compare the traits of the current "best_size" | ||
779 | * with the current size to determine if the | ||
780 | * current size is a better size. | ||
781 | */ | ||
782 | best_rem = best_size % sizeof(struct scatterlist); | ||
783 | cur_rem = cur_size % sizeof(struct scatterlist); | ||
784 | if (cur_rem < best_rem) { | ||
785 | best_size = cur_size; | ||
786 | ahd_linux_nseg = nseg; | ||
787 | } | ||
788 | } | ||
789 | } | ||
790 | #endif | ||
791 | } | ||
792 | 642 | ||
793 | /* | 643 | /* |
794 | * Try to detect an Adaptec 79XX controller. | 644 | * Try to detect an Adaptec 79XX controller. |
@@ -800,14 +650,6 @@ ahd_linux_detect(Scsi_Host_Template *template) | |||
800 | int found; | 650 | int found; |
801 | int error = 0; | 651 | int error = 0; |
802 | 652 | ||
803 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
804 | /* | ||
805 | * It is a bug that the upper layer takes | ||
806 | * this lock just prior to calling us. | ||
807 | */ | ||
808 | spin_unlock_irq(&io_request_lock); | ||
809 | #endif | ||
810 | |||
811 | /* | 653 | /* |
812 | * Sanity checking of Linux SCSI data structures so | 654 | * Sanity checking of Linux SCSI data structures so |
813 | * that some of our hacks^H^H^H^H^Hassumptions aren't | 655 | * that some of our hacks^H^H^H^H^Hassumptions aren't |
@@ -819,10 +661,7 @@ ahd_linux_detect(Scsi_Host_Template *template) | |||
819 | printf("ahd_linux_detect: Unable to attach\n"); | 661 | printf("ahd_linux_detect: Unable to attach\n"); |
820 | return (0); | 662 | return (0); |
821 | } | 663 | } |
822 | /* | 664 | |
823 | * Determine an appropriate size for our Scatter Gatther lists. | ||
824 | */ | ||
825 | ahd_linux_size_nseg(); | ||
826 | #ifdef MODULE | 665 | #ifdef MODULE |
827 | /* | 666 | /* |
828 | * If we've been passed any parameters, process them now. | 667 | * If we've been passed any parameters, process them now. |
@@ -855,47 +694,10 @@ ahd_linux_detect(Scsi_Host_Template *template) | |||
855 | if (ahd_linux_register_host(ahd, template) == 0) | 694 | if (ahd_linux_register_host(ahd, template) == 0) |
856 | found++; | 695 | found++; |
857 | } | 696 | } |
858 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
859 | spin_lock_irq(&io_request_lock); | ||
860 | #endif | ||
861 | aic79xx_detect_complete++; | 697 | aic79xx_detect_complete++; |
862 | return 0; | 698 | return 0; |
863 | } | 699 | } |
864 | 700 | ||
865 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
866 | /* | ||
867 | * Free the passed in Scsi_Host memory structures prior to unloading the | ||
868 | * module. | ||
869 | */ | ||
870 | static int | ||
871 | ahd_linux_release(struct Scsi_Host * host) | ||
872 | { | ||
873 | struct ahd_softc *ahd; | ||
874 | u_long l; | ||
875 | |||
876 | ahd_list_lock(&l); | ||
877 | if (host != NULL) { | ||
878 | |||
879 | /* | ||
880 | * We should be able to just perform | ||
881 | * the free directly, but check our | ||
882 | * list for extra sanity. | ||
883 | */ | ||
884 | ahd = ahd_find_softc(*(struct ahd_softc **)host->hostdata); | ||
885 | if (ahd != NULL) { | ||
886 | u_long s; | ||
887 | |||
888 | ahd_lock(ahd, &s); | ||
889 | ahd_intr_enable(ahd, FALSE); | ||
890 | ahd_unlock(ahd, &s); | ||
891 | ahd_free(ahd); | ||
892 | } | ||
893 | } | ||
894 | ahd_list_unlock(&l); | ||
895 | return (0); | ||
896 | } | ||
897 | #endif | ||
898 | |||
899 | /* | 701 | /* |
900 | * Return a string describing the driver. | 702 | * Return a string describing the driver. |
901 | */ | 703 | */ |
@@ -932,18 +734,10 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) | |||
932 | { | 734 | { |
933 | struct ahd_softc *ahd; | 735 | struct ahd_softc *ahd; |
934 | struct ahd_linux_device *dev; | 736 | struct ahd_linux_device *dev; |
935 | u_long flags; | ||
936 | 737 | ||
937 | ahd = *(struct ahd_softc **)cmd->device->host->hostdata; | 738 | ahd = *(struct ahd_softc **)cmd->device->host->hostdata; |
938 | 739 | ||
939 | /* | 740 | /* |
940 | * Save the callback on completion function. | ||
941 | */ | ||
942 | cmd->scsi_done = scsi_done; | ||
943 | |||
944 | ahd_midlayer_entrypoint_lock(ahd, &flags); | ||
945 | |||
946 | /* | ||
947 | * Close the race of a command that was in the process of | 741 | * Close the race of a command that was in the process of |
948 | * being queued to us just as our simq was frozen. Let | 742 | * being queued to us just as our simq was frozen. Let |
949 | * DV commands through so long as we are only frozen to | 743 | * DV commands through so long as we are only frozen to |
@@ -951,39 +745,26 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) | |||
951 | */ | 745 | */ |
952 | if (ahd->platform_data->qfrozen != 0 | 746 | if (ahd->platform_data->qfrozen != 0 |
953 | && AHD_DV_CMD(cmd) == 0) { | 747 | && AHD_DV_CMD(cmd) == 0) { |
748 | printf("%s: queue frozen\n", ahd_name(ahd)); | ||
954 | 749 | ||
955 | ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); | 750 | return SCSI_MLQUEUE_HOST_BUSY; |
956 | ahd_linux_queue_cmd_complete(ahd, cmd); | ||
957 | ahd_schedule_completeq(ahd); | ||
958 | ahd_midlayer_entrypoint_unlock(ahd, &flags); | ||
959 | return (0); | ||
960 | } | 751 | } |
752 | |||
753 | /* | ||
754 | * Save the callback on completion function. | ||
755 | */ | ||
756 | cmd->scsi_done = scsi_done; | ||
757 | |||
961 | dev = ahd_linux_get_device(ahd, cmd->device->channel, | 758 | dev = ahd_linux_get_device(ahd, cmd->device->channel, |
962 | cmd->device->id, cmd->device->lun, | 759 | cmd->device->id, cmd->device->lun, |
963 | /*alloc*/TRUE); | 760 | /*alloc*/TRUE); |
964 | if (dev == NULL) { | 761 | BUG_ON(dev == NULL); |
965 | ahd_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL); | 762 | |
966 | ahd_linux_queue_cmd_complete(ahd, cmd); | ||
967 | ahd_schedule_completeq(ahd); | ||
968 | ahd_midlayer_entrypoint_unlock(ahd, &flags); | ||
969 | printf("%s: aic79xx_linux_queue - Unable to allocate device!\n", | ||
970 | ahd_name(ahd)); | ||
971 | return (0); | ||
972 | } | ||
973 | if (cmd->cmd_len > MAX_CDB_LEN) | ||
974 | return (-EINVAL); | ||
975 | cmd->result = CAM_REQ_INPROG << 16; | 763 | cmd->result = CAM_REQ_INPROG << 16; |
976 | TAILQ_INSERT_TAIL(&dev->busyq, (struct ahd_cmd *)cmd, acmd_links.tqe); | 764 | |
977 | if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) { | 765 | return ahd_linux_run_command(ahd, dev, cmd); |
978 | TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links); | ||
979 | dev->flags |= AHD_DEV_ON_RUN_LIST; | ||
980 | ahd_linux_run_device_queues(ahd); | ||
981 | } | ||
982 | ahd_midlayer_entrypoint_unlock(ahd, &flags); | ||
983 | return (0); | ||
984 | } | 766 | } |
985 | 767 | ||
986 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
987 | static int | 768 | static int |
988 | ahd_linux_slave_alloc(Scsi_Device *device) | 769 | ahd_linux_slave_alloc(Scsi_Device *device) |
989 | { | 770 | { |
@@ -1049,99 +830,22 @@ ahd_linux_slave_destroy(Scsi_Device *device) | |||
1049 | if (dev != NULL | 830 | if (dev != NULL |
1050 | && (dev->flags & AHD_DEV_SLAVE_CONFIGURED) != 0) { | 831 | && (dev->flags & AHD_DEV_SLAVE_CONFIGURED) != 0) { |
1051 | dev->flags |= AHD_DEV_UNCONFIGURED; | 832 | dev->flags |= AHD_DEV_UNCONFIGURED; |
1052 | if (TAILQ_EMPTY(&dev->busyq) | 833 | if (dev->active == 0 |
1053 | && dev->active == 0 | ||
1054 | && (dev->flags & AHD_DEV_TIMER_ACTIVE) == 0) | 834 | && (dev->flags & AHD_DEV_TIMER_ACTIVE) == 0) |
1055 | ahd_linux_free_device(ahd, dev); | 835 | ahd_linux_free_device(ahd, dev); |
1056 | } | 836 | } |
1057 | ahd_midlayer_entrypoint_unlock(ahd, &flags); | 837 | ahd_midlayer_entrypoint_unlock(ahd, &flags); |
1058 | } | 838 | } |
1059 | #else | ||
1060 | /* | ||
1061 | * Sets the queue depth for each SCSI device hanging | ||
1062 | * off the input host adapter. | ||
1063 | */ | ||
1064 | static void | ||
1065 | ahd_linux_select_queue_depth(struct Scsi_Host * host, | ||
1066 | Scsi_Device * scsi_devs) | ||
1067 | { | ||
1068 | Scsi_Device *device; | ||
1069 | Scsi_Device *ldev; | ||
1070 | struct ahd_softc *ahd; | ||
1071 | u_long flags; | ||
1072 | |||
1073 | ahd = *((struct ahd_softc **)host->hostdata); | ||
1074 | ahd_lock(ahd, &flags); | ||
1075 | for (device = scsi_devs; device != NULL; device = device->next) { | ||
1076 | |||
1077 | /* | ||
1078 | * Watch out for duplicate devices. This works around | ||
1079 | * some quirks in how the SCSI scanning code does its | ||
1080 | * device management. | ||
1081 | */ | ||
1082 | for (ldev = scsi_devs; ldev != device; ldev = ldev->next) { | ||
1083 | if (ldev->host == device->host | ||
1084 | && ldev->channel == device->channel | ||
1085 | && ldev->id == device->id | ||
1086 | && ldev->lun == device->lun) | ||
1087 | break; | ||
1088 | } | ||
1089 | /* Skip duplicate. */ | ||
1090 | if (ldev != device) | ||
1091 | continue; | ||
1092 | |||
1093 | if (device->host == host) { | ||
1094 | struct ahd_linux_device *dev; | ||
1095 | |||
1096 | /* | ||
1097 | * Since Linux has attached to the device, configure | ||
1098 | * it so we don't free and allocate the device | ||
1099 | * structure on every command. | ||
1100 | */ | ||
1101 | dev = ahd_linux_get_device(ahd, device->channel, | ||
1102 | device->id, device->lun, | ||
1103 | /*alloc*/TRUE); | ||
1104 | if (dev != NULL) { | ||
1105 | dev->flags &= ~AHD_DEV_UNCONFIGURED; | ||
1106 | dev->scsi_device = device; | ||
1107 | ahd_linux_device_queue_depth(ahd, dev); | ||
1108 | device->queue_depth = dev->openings | ||
1109 | + dev->active; | ||
1110 | if ((dev->flags & (AHD_DEV_Q_BASIC | ||
1111 | | AHD_DEV_Q_TAGGED)) == 0) { | ||
1112 | /* | ||
1113 | * We allow the OS to queue 2 untagged | ||
1114 | * transactions to us at any time even | ||
1115 | * though we can only execute them | ||
1116 | * serially on the controller/device. | ||
1117 | * This should remove some latency. | ||
1118 | */ | ||
1119 | device->queue_depth = 2; | ||
1120 | } | ||
1121 | } | ||
1122 | } | ||
1123 | } | ||
1124 | ahd_unlock(ahd, &flags); | ||
1125 | } | ||
1126 | #endif | ||
1127 | 839 | ||
1128 | #if defined(__i386__) | 840 | #if defined(__i386__) |
1129 | /* | 841 | /* |
1130 | * Return the disk geometry for the given SCSI device. | 842 | * Return the disk geometry for the given SCSI device. |
1131 | */ | 843 | */ |
1132 | static int | 844 | static int |
1133 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1134 | ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, | 845 | ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, |
1135 | sector_t capacity, int geom[]) | 846 | sector_t capacity, int geom[]) |
1136 | { | 847 | { |
1137 | uint8_t *bh; | 848 | uint8_t *bh; |
1138 | #else | ||
1139 | ahd_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) | ||
1140 | { | ||
1141 | struct scsi_device *sdev = disk->device; | ||
1142 | u_long capacity = disk->capacity; | ||
1143 | struct buffer_head *bh; | ||
1144 | #endif | ||
1145 | int heads; | 849 | int heads; |
1146 | int sectors; | 850 | int sectors; |
1147 | int cylinders; | 851 | int cylinders; |
@@ -1151,22 +855,11 @@ ahd_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) | |||
1151 | 855 | ||
1152 | ahd = *((struct ahd_softc **)sdev->host->hostdata); | 856 | ahd = *((struct ahd_softc **)sdev->host->hostdata); |
1153 | 857 | ||
1154 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1155 | bh = scsi_bios_ptable(bdev); | 858 | bh = scsi_bios_ptable(bdev); |
1156 | #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) | ||
1157 | bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); | ||
1158 | #else | ||
1159 | bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); | ||
1160 | #endif | ||
1161 | |||
1162 | if (bh) { | 859 | if (bh) { |
1163 | ret = scsi_partsize(bh, capacity, | 860 | ret = scsi_partsize(bh, capacity, |
1164 | &geom[2], &geom[0], &geom[1]); | 861 | &geom[2], &geom[0], &geom[1]); |
1165 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1166 | kfree(bh); | 862 | kfree(bh); |
1167 | #else | ||
1168 | brelse(bh); | ||
1169 | #endif | ||
1170 | if (ret != -1) | 863 | if (ret != -1) |
1171 | return (ret); | 864 | return (ret); |
1172 | } | 865 | } |
@@ -1198,7 +891,6 @@ ahd_linux_abort(Scsi_Cmnd *cmd) | |||
1198 | { | 891 | { |
1199 | struct ahd_softc *ahd; | 892 | struct ahd_softc *ahd; |
1200 | struct ahd_cmd *acmd; | 893 | struct ahd_cmd *acmd; |
1201 | struct ahd_cmd *list_acmd; | ||
1202 | struct ahd_linux_device *dev; | 894 | struct ahd_linux_device *dev; |
1203 | struct scb *pending_scb; | 895 | struct scb *pending_scb; |
1204 | u_long s; | 896 | u_long s; |
@@ -1265,22 +957,6 @@ ahd_linux_abort(Scsi_Cmnd *cmd) | |||
1265 | goto no_cmd; | 957 | goto no_cmd; |
1266 | } | 958 | } |
1267 | 959 | ||
1268 | TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) { | ||
1269 | if (list_acmd == acmd) | ||
1270 | break; | ||
1271 | } | ||
1272 | |||
1273 | if (list_acmd != NULL) { | ||
1274 | printf("%s:%d:%d:%d: Command found on device queue\n", | ||
1275 | ahd_name(ahd), cmd->device->channel, cmd->device->id, | ||
1276 | cmd->device->lun); | ||
1277 | TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); | ||
1278 | cmd->result = DID_ABORT << 16; | ||
1279 | ahd_linux_queue_cmd_complete(ahd, cmd); | ||
1280 | retval = SUCCESS; | ||
1281 | goto done; | ||
1282 | } | ||
1283 | |||
1284 | /* | 960 | /* |
1285 | * See if we can find a matching cmd in the pending list. | 961 | * See if we can find a matching cmd in the pending list. |
1286 | */ | 962 | */ |
@@ -1468,7 +1144,6 @@ done: | |||
1468 | } | 1144 | } |
1469 | spin_lock_irq(&ahd->platform_data->spin_lock); | 1145 | spin_lock_irq(&ahd->platform_data->spin_lock); |
1470 | } | 1146 | } |
1471 | ahd_schedule_runq(ahd); | ||
1472 | ahd_linux_run_complete_queue(ahd); | 1147 | ahd_linux_run_complete_queue(ahd); |
1473 | ahd_midlayer_entrypoint_unlock(ahd, &s); | 1148 | ahd_midlayer_entrypoint_unlock(ahd, &s); |
1474 | return (retval); | 1149 | return (retval); |
@@ -1568,7 +1243,6 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd) | |||
1568 | retval = FAILED; | 1243 | retval = FAILED; |
1569 | } | 1244 | } |
1570 | ahd_lock(ahd, &s); | 1245 | ahd_lock(ahd, &s); |
1571 | ahd_schedule_runq(ahd); | ||
1572 | ahd_linux_run_complete_queue(ahd); | 1246 | ahd_linux_run_complete_queue(ahd); |
1573 | ahd_unlock(ahd, &s); | 1247 | ahd_unlock(ahd, &s); |
1574 | printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval); | 1248 | printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval); |
@@ -1625,35 +1299,6 @@ Scsi_Host_Template aic79xx_driver_template = { | |||
1625 | .slave_destroy = ahd_linux_slave_destroy, | 1299 | .slave_destroy = ahd_linux_slave_destroy, |
1626 | }; | 1300 | }; |
1627 | 1301 | ||
1628 | /**************************** Tasklet Handler *********************************/ | ||
1629 | |||
1630 | /* | ||
1631 | * In 2.4.X and above, this routine is called from a tasklet, | ||
1632 | * so we must re-acquire our lock prior to executing this code. | ||
1633 | * In all prior kernels, ahd_schedule_runq() calls this routine | ||
1634 | * directly and ahd_schedule_runq() is called with our lock held. | ||
1635 | */ | ||
1636 | static void | ||
1637 | ahd_runq_tasklet(unsigned long data) | ||
1638 | { | ||
1639 | struct ahd_softc* ahd; | ||
1640 | struct ahd_linux_device *dev; | ||
1641 | u_long flags; | ||
1642 | |||
1643 | ahd = (struct ahd_softc *)data; | ||
1644 | ahd_lock(ahd, &flags); | ||
1645 | while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) { | ||
1646 | |||
1647 | TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links); | ||
1648 | dev->flags &= ~AHD_DEV_ON_RUN_LIST; | ||
1649 | ahd_linux_check_device_queue(ahd, dev); | ||
1650 | /* Yeild to our interrupt handler */ | ||
1651 | ahd_unlock(ahd, &flags); | ||
1652 | ahd_lock(ahd, &flags); | ||
1653 | } | ||
1654 | ahd_unlock(ahd, &flags); | ||
1655 | } | ||
1656 | |||
1657 | /******************************** Bus DMA *************************************/ | 1302 | /******************************** Bus DMA *************************************/ |
1658 | int | 1303 | int |
1659 | ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent, | 1304 | ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent, |
@@ -1997,11 +1642,7 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template) | |||
1997 | 1642 | ||
1998 | *((struct ahd_softc **)host->hostdata) = ahd; | 1643 | *((struct ahd_softc **)host->hostdata) = ahd; |
1999 | ahd_lock(ahd, &s); | 1644 | ahd_lock(ahd, &s); |
2000 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
2001 | scsi_assign_lock(host, &ahd->platform_data->spin_lock); | 1645 | scsi_assign_lock(host, &ahd->platform_data->spin_lock); |
2002 | #elif AHD_SCSI_HAS_HOST_LOCK != 0 | ||
2003 | host->lock = &ahd->platform_data->spin_lock; | ||
2004 | #endif | ||
2005 | ahd->platform_data->host = host; | 1646 | ahd->platform_data->host = host; |
2006 | host->can_queue = AHD_MAX_QUEUE; | 1647 | host->can_queue = AHD_MAX_QUEUE; |
2007 | host->cmd_per_lun = 2; | 1648 | host->cmd_per_lun = 2; |
@@ -2020,9 +1661,6 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template) | |||
2020 | ahd_set_name(ahd, new_name); | 1661 | ahd_set_name(ahd, new_name); |
2021 | } | 1662 | } |
2022 | host->unique_id = ahd->unit; | 1663 | host->unique_id = ahd->unit; |
2023 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
2024 | scsi_set_pci_device(host, ahd->dev_softc); | ||
2025 | #endif | ||
2026 | ahd_linux_setup_user_rd_strm_settings(ahd); | 1664 | ahd_linux_setup_user_rd_strm_settings(ahd); |
2027 | ahd_linux_initialize_scsi_bus(ahd); | 1665 | ahd_linux_initialize_scsi_bus(ahd); |
2028 | ahd_unlock(ahd, &s); | 1666 | ahd_unlock(ahd, &s); |
@@ -2064,10 +1702,8 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template) | |||
2064 | ahd_linux_start_dv(ahd); | 1702 | ahd_linux_start_dv(ahd); |
2065 | ahd_unlock(ahd, &s); | 1703 | ahd_unlock(ahd, &s); |
2066 | 1704 | ||
2067 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
2068 | scsi_add_host(host, &ahd->dev_softc->dev); /* XXX handle failure */ | 1705 | scsi_add_host(host, &ahd->dev_softc->dev); /* XXX handle failure */ |
2069 | scsi_scan_host(host); | 1706 | scsi_scan_host(host); |
2070 | #endif | ||
2071 | return (0); | 1707 | return (0); |
2072 | } | 1708 | } |
2073 | 1709 | ||
@@ -2163,7 +1799,6 @@ ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg) | |||
2163 | return (ENOMEM); | 1799 | return (ENOMEM); |
2164 | memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data)); | 1800 | memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data)); |
2165 | TAILQ_INIT(&ahd->platform_data->completeq); | 1801 | TAILQ_INIT(&ahd->platform_data->completeq); |
2166 | TAILQ_INIT(&ahd->platform_data->device_runq); | ||
2167 | ahd->platform_data->irq = AHD_LINUX_NOIRQ; | 1802 | ahd->platform_data->irq = AHD_LINUX_NOIRQ; |
2168 | ahd->platform_data->hw_dma_mask = 0xFFFFFFFF; | 1803 | ahd->platform_data->hw_dma_mask = 0xFFFFFFFF; |
2169 | ahd_lockinit(ahd); | 1804 | ahd_lockinit(ahd); |
@@ -2175,7 +1810,6 @@ ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg) | |||
2175 | init_MUTEX_LOCKED(&ahd->platform_data->eh_sem); | 1810 | init_MUTEX_LOCKED(&ahd->platform_data->eh_sem); |
2176 | init_MUTEX_LOCKED(&ahd->platform_data->dv_sem); | 1811 | init_MUTEX_LOCKED(&ahd->platform_data->dv_sem); |
2177 | init_MUTEX_LOCKED(&ahd->platform_data->dv_cmd_sem); | 1812 | init_MUTEX_LOCKED(&ahd->platform_data->dv_cmd_sem); |
2178 | ahd_setup_runq_tasklet(ahd); | ||
2179 | ahd->seltime = (aic79xx_seltime & 0x3) << 4; | 1813 | ahd->seltime = (aic79xx_seltime & 0x3) << 4; |
2180 | return (0); | 1814 | return (0); |
2181 | } | 1815 | } |
@@ -2190,11 +1824,8 @@ ahd_platform_free(struct ahd_softc *ahd) | |||
2190 | if (ahd->platform_data != NULL) { | 1824 | if (ahd->platform_data != NULL) { |
2191 | del_timer_sync(&ahd->platform_data->completeq_timer); | 1825 | del_timer_sync(&ahd->platform_data->completeq_timer); |
2192 | ahd_linux_kill_dv_thread(ahd); | 1826 | ahd_linux_kill_dv_thread(ahd); |
2193 | ahd_teardown_runq_tasklet(ahd); | ||
2194 | if (ahd->platform_data->host != NULL) { | 1827 | if (ahd->platform_data->host != NULL) { |
2195 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
2196 | scsi_remove_host(ahd->platform_data->host); | 1828 | scsi_remove_host(ahd->platform_data->host); |
2197 | #endif | ||
2198 | scsi_host_put(ahd->platform_data->host); | 1829 | scsi_host_put(ahd->platform_data->host); |
2199 | } | 1830 | } |
2200 | 1831 | ||
@@ -2233,16 +1864,6 @@ ahd_platform_free(struct ahd_softc *ahd) | |||
2233 | release_mem_region(ahd->platform_data->mem_busaddr, | 1864 | release_mem_region(ahd->platform_data->mem_busaddr, |
2234 | 0x1000); | 1865 | 0x1000); |
2235 | } | 1866 | } |
2236 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
2237 | /* | ||
2238 | * In 2.4 we detach from the scsi midlayer before the PCI | ||
2239 | * layer invokes our remove callback. No per-instance | ||
2240 | * detach is provided, so we must reach inside the PCI | ||
2241 | * subsystem's internals and detach our driver manually. | ||
2242 | */ | ||
2243 | if (ahd->dev_softc != NULL) | ||
2244 | ahd->dev_softc->driver = NULL; | ||
2245 | #endif | ||
2246 | free(ahd->platform_data, M_DEVBUF); | 1867 | free(ahd->platform_data, M_DEVBUF); |
2247 | } | 1868 | } |
2248 | } | 1869 | } |
@@ -2339,7 +1960,7 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
2339 | dev->maxtags = 0; | 1960 | dev->maxtags = 0; |
2340 | dev->openings = 1 - dev->active; | 1961 | dev->openings = 1 - dev->active; |
2341 | } | 1962 | } |
2342 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | 1963 | |
2343 | if (dev->scsi_device != NULL) { | 1964 | if (dev->scsi_device != NULL) { |
2344 | switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) { | 1965 | switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) { |
2345 | case AHD_DEV_Q_BASIC: | 1966 | case AHD_DEV_Q_BASIC: |
@@ -2365,65 +1986,13 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
2365 | break; | 1986 | break; |
2366 | } | 1987 | } |
2367 | } | 1988 | } |
2368 | #endif | ||
2369 | } | 1989 | } |
2370 | 1990 | ||
2371 | int | 1991 | int |
2372 | ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel, | 1992 | ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel, |
2373 | int lun, u_int tag, role_t role, uint32_t status) | 1993 | int lun, u_int tag, role_t role, uint32_t status) |
2374 | { | 1994 | { |
2375 | int targ; | 1995 | return 0; |
2376 | int maxtarg; | ||
2377 | int maxlun; | ||
2378 | int clun; | ||
2379 | int count; | ||
2380 | |||
2381 | if (tag != SCB_LIST_NULL) | ||
2382 | return (0); | ||
2383 | |||
2384 | targ = 0; | ||
2385 | if (target != CAM_TARGET_WILDCARD) { | ||
2386 | targ = target; | ||
2387 | maxtarg = targ + 1; | ||
2388 | } else { | ||
2389 | maxtarg = (ahd->features & AHD_WIDE) ? 16 : 8; | ||
2390 | } | ||
2391 | clun = 0; | ||
2392 | if (lun != CAM_LUN_WILDCARD) { | ||
2393 | clun = lun; | ||
2394 | maxlun = clun + 1; | ||
2395 | } else { | ||
2396 | maxlun = AHD_NUM_LUNS; | ||
2397 | } | ||
2398 | |||
2399 | count = 0; | ||
2400 | for (; targ < maxtarg; targ++) { | ||
2401 | |||
2402 | for (; clun < maxlun; clun++) { | ||
2403 | struct ahd_linux_device *dev; | ||
2404 | struct ahd_busyq *busyq; | ||
2405 | struct ahd_cmd *acmd; | ||
2406 | |||
2407 | dev = ahd_linux_get_device(ahd, /*chan*/0, targ, | ||
2408 | clun, /*alloc*/FALSE); | ||
2409 | if (dev == NULL) | ||
2410 | continue; | ||
2411 | |||
2412 | busyq = &dev->busyq; | ||
2413 | while ((acmd = TAILQ_FIRST(busyq)) != NULL) { | ||
2414 | Scsi_Cmnd *cmd; | ||
2415 | |||
2416 | cmd = &acmd_scsi_cmd(acmd); | ||
2417 | TAILQ_REMOVE(busyq, acmd, | ||
2418 | acmd_links.tqe); | ||
2419 | count++; | ||
2420 | cmd->result = status << 16; | ||
2421 | ahd_linux_queue_cmd_complete(ahd, cmd); | ||
2422 | } | ||
2423 | } | ||
2424 | } | ||
2425 | |||
2426 | return (count); | ||
2427 | } | 1996 | } |
2428 | 1997 | ||
2429 | static void | 1998 | static void |
@@ -2478,18 +2047,10 @@ ahd_linux_dv_thread(void *data) | |||
2478 | * Complete thread creation. | 2047 | * Complete thread creation. |
2479 | */ | 2048 | */ |
2480 | lock_kernel(); | 2049 | lock_kernel(); |
2481 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60) | ||
2482 | /* | ||
2483 | * Don't care about any signals. | ||
2484 | */ | ||
2485 | siginitsetinv(¤t->blocked, 0); | ||
2486 | 2050 | ||
2487 | daemonize(); | ||
2488 | sprintf(current->comm, "ahd_dv_%d", ahd->unit); | ||
2489 | #else | ||
2490 | daemonize("ahd_dv_%d", ahd->unit); | 2051 | daemonize("ahd_dv_%d", ahd->unit); |
2491 | current->flags |= PF_NOFREEZE; | 2052 | current->flags |= PF_FREEZE; |
2492 | #endif | 2053 | |
2493 | unlock_kernel(); | 2054 | unlock_kernel(); |
2494 | 2055 | ||
2495 | while (1) { | 2056 | while (1) { |
@@ -3685,8 +3246,6 @@ ahd_linux_dv_timeout(struct scsi_cmnd *cmd) | |||
3685 | ahd->platform_data->reset_timer.function = | 3246 | ahd->platform_data->reset_timer.function = |
3686 | (ahd_linux_callback_t *)ahd_release_simq; | 3247 | (ahd_linux_callback_t *)ahd_release_simq; |
3687 | add_timer(&ahd->platform_data->reset_timer); | 3248 | add_timer(&ahd->platform_data->reset_timer); |
3688 | if (ahd_linux_next_device_to_run(ahd) != NULL) | ||
3689 | ahd_schedule_runq(ahd); | ||
3690 | ahd_linux_run_complete_queue(ahd); | 3249 | ahd_linux_run_complete_queue(ahd); |
3691 | ahd_unlock(ahd, &flags); | 3250 | ahd_unlock(ahd, &flags); |
3692 | } | 3251 | } |
@@ -3903,11 +3462,10 @@ ahd_linux_device_queue_depth(struct ahd_softc *ahd, | |||
3903 | } | 3462 | } |
3904 | } | 3463 | } |
3905 | 3464 | ||
3906 | static void | 3465 | static int |
3907 | ahd_linux_run_device_queue(struct ahd_softc *ahd, struct ahd_linux_device *dev) | 3466 | ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, |
3467 | struct scsi_cmnd *cmd) | ||
3908 | { | 3468 | { |
3909 | struct ahd_cmd *acmd; | ||
3910 | struct scsi_cmnd *cmd; | ||
3911 | struct scb *scb; | 3469 | struct scb *scb; |
3912 | struct hardware_scb *hscb; | 3470 | struct hardware_scb *hscb; |
3913 | struct ahd_initiator_tinfo *tinfo; | 3471 | struct ahd_initiator_tinfo *tinfo; |
@@ -3915,157 +3473,132 @@ ahd_linux_run_device_queue(struct ahd_softc *ahd, struct ahd_linux_device *dev) | |||
3915 | u_int col_idx; | 3473 | u_int col_idx; |
3916 | uint16_t mask; | 3474 | uint16_t mask; |
3917 | 3475 | ||
3918 | if ((dev->flags & AHD_DEV_ON_RUN_LIST) != 0) | 3476 | /* |
3919 | panic("running device on run list"); | 3477 | * Get an scb to use. |
3920 | 3478 | */ | |
3921 | while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL | 3479 | tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, |
3922 | && dev->openings > 0 && dev->qfrozen == 0) { | 3480 | cmd->device->id, &tstate); |
3923 | 3481 | if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0 | |
3924 | /* | 3482 | || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { |
3925 | * Schedule us to run later. The only reason we are not | 3483 | col_idx = AHD_NEVER_COL_IDX; |
3926 | * running is because the whole controller Q is frozen. | 3484 | } else { |
3927 | */ | 3485 | col_idx = AHD_BUILD_COL_IDX(cmd->device->id, |
3928 | if (ahd->platform_data->qfrozen != 0 | 3486 | cmd->device->lun); |
3929 | && AHD_DV_SIMQ_FROZEN(ahd) == 0) { | 3487 | } |
3930 | 3488 | if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { | |
3931 | TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, | 3489 | ahd->flags |= AHD_RESOURCE_SHORTAGE; |
3932 | dev, links); | 3490 | return SCSI_MLQUEUE_HOST_BUSY; |
3933 | dev->flags |= AHD_DEV_ON_RUN_LIST; | 3491 | } |
3934 | return; | ||
3935 | } | ||
3936 | 3492 | ||
3937 | cmd = &acmd_scsi_cmd(acmd); | 3493 | scb->io_ctx = cmd; |
3494 | scb->platform_data->dev = dev; | ||
3495 | hscb = scb->hscb; | ||
3496 | cmd->host_scribble = (char *)scb; | ||
3938 | 3497 | ||
3939 | /* | 3498 | /* |
3940 | * Get an scb to use. | 3499 | * Fill out basics of the HSCB. |
3941 | */ | 3500 | */ |
3942 | tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, | 3501 | hscb->control = 0; |
3943 | cmd->device->id, &tstate); | 3502 | hscb->scsiid = BUILD_SCSIID(ahd, cmd); |
3944 | if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0 | 3503 | hscb->lun = cmd->device->lun; |
3945 | || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { | 3504 | scb->hscb->task_management = 0; |
3946 | col_idx = AHD_NEVER_COL_IDX; | 3505 | mask = SCB_GET_TARGET_MASK(ahd, scb); |
3947 | } else { | ||
3948 | col_idx = AHD_BUILD_COL_IDX(cmd->device->id, | ||
3949 | cmd->device->lun); | ||
3950 | } | ||
3951 | if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { | ||
3952 | TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, | ||
3953 | dev, links); | ||
3954 | dev->flags |= AHD_DEV_ON_RUN_LIST; | ||
3955 | ahd->flags |= AHD_RESOURCE_SHORTAGE; | ||
3956 | return; | ||
3957 | } | ||
3958 | TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe); | ||
3959 | scb->io_ctx = cmd; | ||
3960 | scb->platform_data->dev = dev; | ||
3961 | hscb = scb->hscb; | ||
3962 | cmd->host_scribble = (char *)scb; | ||
3963 | 3506 | ||
3964 | /* | 3507 | if ((ahd->user_discenable & mask) != 0) |
3965 | * Fill out basics of the HSCB. | 3508 | hscb->control |= DISCENB; |
3966 | */ | ||
3967 | hscb->control = 0; | ||
3968 | hscb->scsiid = BUILD_SCSIID(ahd, cmd); | ||
3969 | hscb->lun = cmd->device->lun; | ||
3970 | scb->hscb->task_management = 0; | ||
3971 | mask = SCB_GET_TARGET_MASK(ahd, scb); | ||
3972 | 3509 | ||
3973 | if ((ahd->user_discenable & mask) != 0) | 3510 | if (AHD_DV_CMD(cmd) != 0) |
3974 | hscb->control |= DISCENB; | 3511 | scb->flags |= SCB_SILENT; |
3975 | 3512 | ||
3976 | if (AHD_DV_CMD(cmd) != 0) | 3513 | if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) |
3977 | scb->flags |= SCB_SILENT; | 3514 | scb->flags |= SCB_PACKETIZED; |
3978 | 3515 | ||
3979 | if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) | 3516 | if ((tstate->auto_negotiate & mask) != 0) { |
3980 | scb->flags |= SCB_PACKETIZED; | 3517 | scb->flags |= SCB_AUTO_NEGOTIATE; |
3518 | scb->hscb->control |= MK_MESSAGE; | ||
3519 | } | ||
3981 | 3520 | ||
3982 | if ((tstate->auto_negotiate & mask) != 0) { | 3521 | if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) { |
3983 | scb->flags |= SCB_AUTO_NEGOTIATE; | 3522 | int msg_bytes; |
3984 | scb->hscb->control |= MK_MESSAGE; | 3523 | uint8_t tag_msgs[2]; |
3985 | } | ||
3986 | 3524 | ||
3987 | if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) { | 3525 | msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); |
3988 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | 3526 | if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { |
3989 | int msg_bytes; | 3527 | hscb->control |= tag_msgs[0]; |
3990 | uint8_t tag_msgs[2]; | 3528 | if (tag_msgs[0] == MSG_ORDERED_TASK) |
3991 | |||
3992 | msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); | ||
3993 | if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { | ||
3994 | hscb->control |= tag_msgs[0]; | ||
3995 | if (tag_msgs[0] == MSG_ORDERED_TASK) | ||
3996 | dev->commands_since_idle_or_otag = 0; | ||
3997 | } else | ||
3998 | #endif | ||
3999 | if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH | ||
4000 | && (dev->flags & AHD_DEV_Q_TAGGED) != 0) { | ||
4001 | hscb->control |= MSG_ORDERED_TASK; | ||
4002 | dev->commands_since_idle_or_otag = 0; | 3529 | dev->commands_since_idle_or_otag = 0; |
4003 | } else { | 3530 | } else |
4004 | hscb->control |= MSG_SIMPLE_TASK; | 3531 | if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH |
4005 | } | 3532 | && (dev->flags & AHD_DEV_Q_TAGGED) != 0) { |
3533 | hscb->control |= MSG_ORDERED_TASK; | ||
3534 | dev->commands_since_idle_or_otag = 0; | ||
3535 | } else { | ||
3536 | hscb->control |= MSG_SIMPLE_TASK; | ||
4006 | } | 3537 | } |
3538 | } | ||
4007 | 3539 | ||
4008 | hscb->cdb_len = cmd->cmd_len; | 3540 | hscb->cdb_len = cmd->cmd_len; |
4009 | memcpy(hscb->shared_data.idata.cdb, cmd->cmnd, hscb->cdb_len); | 3541 | memcpy(hscb->shared_data.idata.cdb, cmd->cmnd, hscb->cdb_len); |
4010 | 3542 | ||
4011 | scb->sg_count = 0; | 3543 | scb->sg_count = 0; |
4012 | ahd_set_residual(scb, 0); | 3544 | ahd_set_residual(scb, 0); |
4013 | ahd_set_sense_residual(scb, 0); | 3545 | ahd_set_sense_residual(scb, 0); |
4014 | if (cmd->use_sg != 0) { | 3546 | if (cmd->use_sg != 0) { |
4015 | void *sg; | 3547 | void *sg; |
4016 | struct scatterlist *cur_seg; | 3548 | struct scatterlist *cur_seg; |
4017 | u_int nseg; | 3549 | u_int nseg; |
4018 | int dir; | 3550 | int dir; |
4019 | 3551 | ||
4020 | cur_seg = (struct scatterlist *)cmd->request_buffer; | 3552 | cur_seg = (struct scatterlist *)cmd->request_buffer; |
4021 | dir = cmd->sc_data_direction; | 3553 | dir = cmd->sc_data_direction; |
4022 | nseg = pci_map_sg(ahd->dev_softc, cur_seg, | 3554 | nseg = pci_map_sg(ahd->dev_softc, cur_seg, |
4023 | cmd->use_sg, dir); | 3555 | cmd->use_sg, dir); |
4024 | scb->platform_data->xfer_len = 0; | 3556 | scb->platform_data->xfer_len = 0; |
4025 | for (sg = scb->sg_list; nseg > 0; nseg--, cur_seg++) { | 3557 | for (sg = scb->sg_list; nseg > 0; nseg--, cur_seg++) { |
4026 | dma_addr_t addr; | ||
4027 | bus_size_t len; | ||
4028 | |||
4029 | addr = sg_dma_address(cur_seg); | ||
4030 | len = sg_dma_len(cur_seg); | ||
4031 | scb->platform_data->xfer_len += len; | ||
4032 | sg = ahd_sg_setup(ahd, scb, sg, addr, len, | ||
4033 | /*last*/nseg == 1); | ||
4034 | } | ||
4035 | } else if (cmd->request_bufflen != 0) { | ||
4036 | void *sg; | ||
4037 | dma_addr_t addr; | 3558 | dma_addr_t addr; |
4038 | int dir; | 3559 | bus_size_t len; |
4039 | |||
4040 | sg = scb->sg_list; | ||
4041 | dir = cmd->sc_data_direction; | ||
4042 | addr = pci_map_single(ahd->dev_softc, | ||
4043 | cmd->request_buffer, | ||
4044 | cmd->request_bufflen, dir); | ||
4045 | scb->platform_data->xfer_len = cmd->request_bufflen; | ||
4046 | scb->platform_data->buf_busaddr = addr; | ||
4047 | sg = ahd_sg_setup(ahd, scb, sg, addr, | ||
4048 | cmd->request_bufflen, /*last*/TRUE); | ||
4049 | } | ||
4050 | 3560 | ||
4051 | LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); | 3561 | addr = sg_dma_address(cur_seg); |
4052 | dev->openings--; | 3562 | len = sg_dma_len(cur_seg); |
4053 | dev->active++; | 3563 | scb->platform_data->xfer_len += len; |
4054 | dev->commands_issued++; | 3564 | sg = ahd_sg_setup(ahd, scb, sg, addr, len, |
4055 | 3565 | /*last*/nseg == 1); | |
4056 | /* Update the error counting bucket and dump if needed */ | ||
4057 | if (dev->target->cmds_since_error) { | ||
4058 | dev->target->cmds_since_error++; | ||
4059 | if (dev->target->cmds_since_error > | ||
4060 | AHD_LINUX_ERR_THRESH) | ||
4061 | dev->target->cmds_since_error = 0; | ||
4062 | } | 3566 | } |
3567 | } else if (cmd->request_bufflen != 0) { | ||
3568 | void *sg; | ||
3569 | dma_addr_t addr; | ||
3570 | int dir; | ||
3571 | |||
3572 | sg = scb->sg_list; | ||
3573 | dir = cmd->sc_data_direction; | ||
3574 | addr = pci_map_single(ahd->dev_softc, | ||
3575 | cmd->request_buffer, | ||
3576 | cmd->request_bufflen, dir); | ||
3577 | scb->platform_data->xfer_len = cmd->request_bufflen; | ||
3578 | scb->platform_data->buf_busaddr = addr; | ||
3579 | sg = ahd_sg_setup(ahd, scb, sg, addr, | ||
3580 | cmd->request_bufflen, /*last*/TRUE); | ||
3581 | } | ||
4063 | 3582 | ||
4064 | if ((dev->flags & AHD_DEV_PERIODIC_OTAG) != 0) | 3583 | LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); |
4065 | dev->commands_since_idle_or_otag++; | 3584 | dev->openings--; |
4066 | scb->flags |= SCB_ACTIVE; | 3585 | dev->active++; |
4067 | ahd_queue_scb(ahd, scb); | 3586 | dev->commands_issued++; |
3587 | |||
3588 | /* Update the error counting bucket and dump if needed */ | ||
3589 | if (dev->target->cmds_since_error) { | ||
3590 | dev->target->cmds_since_error++; | ||
3591 | if (dev->target->cmds_since_error > | ||
3592 | AHD_LINUX_ERR_THRESH) | ||
3593 | dev->target->cmds_since_error = 0; | ||
4068 | } | 3594 | } |
3595 | |||
3596 | if ((dev->flags & AHD_DEV_PERIODIC_OTAG) != 0) | ||
3597 | dev->commands_since_idle_or_otag++; | ||
3598 | scb->flags |= SCB_ACTIVE; | ||
3599 | ahd_queue_scb(ahd, scb); | ||
3600 | |||
3601 | return 0; | ||
4069 | } | 3602 | } |
4070 | 3603 | ||
4071 | /* | 3604 | /* |
@@ -4081,8 +3614,6 @@ ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs) | |||
4081 | ahd = (struct ahd_softc *) dev_id; | 3614 | ahd = (struct ahd_softc *) dev_id; |
4082 | ahd_lock(ahd, &flags); | 3615 | ahd_lock(ahd, &flags); |
4083 | ours = ahd_intr(ahd); | 3616 | ours = ahd_intr(ahd); |
4084 | if (ahd_linux_next_device_to_run(ahd) != NULL) | ||
4085 | ahd_schedule_runq(ahd); | ||
4086 | ahd_linux_run_complete_queue(ahd); | 3617 | ahd_linux_run_complete_queue(ahd); |
4087 | ahd_unlock(ahd, &flags); | 3618 | ahd_unlock(ahd, &flags); |
4088 | return IRQ_RETVAL(ours); | 3619 | return IRQ_RETVAL(ours); |
@@ -4161,7 +3692,6 @@ ahd_linux_alloc_device(struct ahd_softc *ahd, | |||
4161 | return (NULL); | 3692 | return (NULL); |
4162 | memset(dev, 0, sizeof(*dev)); | 3693 | memset(dev, 0, sizeof(*dev)); |
4163 | init_timer(&dev->timer); | 3694 | init_timer(&dev->timer); |
4164 | TAILQ_INIT(&dev->busyq); | ||
4165 | dev->flags = AHD_DEV_UNCONFIGURED; | 3695 | dev->flags = AHD_DEV_UNCONFIGURED; |
4166 | dev->lun = lun; | 3696 | dev->lun = lun; |
4167 | dev->target = targ; | 3697 | dev->target = targ; |
@@ -4264,28 +3794,9 @@ ahd_send_async(struct ahd_softc *ahd, char channel, | |||
4264 | } | 3794 | } |
4265 | case AC_SENT_BDR: | 3795 | case AC_SENT_BDR: |
4266 | { | 3796 | { |
4267 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
4268 | WARN_ON(lun != CAM_LUN_WILDCARD); | 3797 | WARN_ON(lun != CAM_LUN_WILDCARD); |
4269 | scsi_report_device_reset(ahd->platform_data->host, | 3798 | scsi_report_device_reset(ahd->platform_data->host, |
4270 | channel - 'A', target); | 3799 | channel - 'A', target); |
4271 | #else | ||
4272 | Scsi_Device *scsi_dev; | ||
4273 | |||
4274 | /* | ||
4275 | * Find the SCSI device associated with this | ||
4276 | * request and indicate that a UA is expected. | ||
4277 | */ | ||
4278 | for (scsi_dev = ahd->platform_data->host->host_queue; | ||
4279 | scsi_dev != NULL; scsi_dev = scsi_dev->next) { | ||
4280 | if (channel - 'A' == scsi_dev->channel | ||
4281 | && target == scsi_dev->id | ||
4282 | && (lun == CAM_LUN_WILDCARD | ||
4283 | || lun == scsi_dev->lun)) { | ||
4284 | scsi_dev->was_reset = 1; | ||
4285 | scsi_dev->expecting_cc_ua = 1; | ||
4286 | } | ||
4287 | } | ||
4288 | #endif | ||
4289 | break; | 3800 | break; |
4290 | } | 3801 | } |
4291 | case AC_BUS_RESET: | 3802 | case AC_BUS_RESET: |
@@ -4406,15 +3917,10 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb) | |||
4406 | if (dev->active == 0) | 3917 | if (dev->active == 0) |
4407 | dev->commands_since_idle_or_otag = 0; | 3918 | dev->commands_since_idle_or_otag = 0; |
4408 | 3919 | ||
4409 | if (TAILQ_EMPTY(&dev->busyq)) { | 3920 | if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0 |
4410 | if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0 | 3921 | && dev->active == 0 |
4411 | && dev->active == 0 | 3922 | && (dev->flags & AHD_DEV_TIMER_ACTIVE) == 0) |
4412 | && (dev->flags & AHD_DEV_TIMER_ACTIVE) == 0) | 3923 | ahd_linux_free_device(ahd, dev); |
4413 | ahd_linux_free_device(ahd, dev); | ||
4414 | } else if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) { | ||
4415 | TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links); | ||
4416 | dev->flags |= AHD_DEV_ON_RUN_LIST; | ||
4417 | } | ||
4418 | 3924 | ||
4419 | if ((scb->flags & SCB_RECOVERY_SCB) != 0) { | 3925 | if ((scb->flags & SCB_RECOVERY_SCB) != 0) { |
4420 | printf("Recovery SCB completes\n"); | 3926 | printf("Recovery SCB completes\n"); |
@@ -4887,7 +4393,6 @@ ahd_release_simq(struct ahd_softc *ahd) | |||
4887 | ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_RELEASE; | 4393 | ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_RELEASE; |
4888 | up(&ahd->platform_data->dv_sem); | 4394 | up(&ahd->platform_data->dv_sem); |
4889 | } | 4395 | } |
4890 | ahd_schedule_runq(ahd); | ||
4891 | ahd_unlock(ahd, &s); | 4396 | ahd_unlock(ahd, &s); |
4892 | /* | 4397 | /* |
4893 | * There is still a race here. The mid-layer | 4398 | * There is still a race here. The mid-layer |
@@ -4929,61 +4434,16 @@ ahd_linux_dev_timed_unfreeze(u_long arg) | |||
4929 | dev->flags &= ~AHD_DEV_TIMER_ACTIVE; | 4434 | dev->flags &= ~AHD_DEV_TIMER_ACTIVE; |
4930 | if (dev->qfrozen > 0) | 4435 | if (dev->qfrozen > 0) |
4931 | dev->qfrozen--; | 4436 | dev->qfrozen--; |
4932 | if (dev->qfrozen == 0 | ||
4933 | && (dev->flags & AHD_DEV_ON_RUN_LIST) == 0) | ||
4934 | ahd_linux_run_device_queue(ahd, dev); | ||
4935 | if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0 | 4437 | if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0 |
4936 | && dev->active == 0) | 4438 | && dev->active == 0) |
4937 | ahd_linux_free_device(ahd, dev); | 4439 | ahd_linux_free_device(ahd, dev); |
4938 | ahd_unlock(ahd, &s); | 4440 | ahd_unlock(ahd, &s); |
4939 | } | 4441 | } |
4940 | 4442 | ||
4941 | void | ||
4942 | ahd_platform_dump_card_state(struct ahd_softc *ahd) | ||
4943 | { | ||
4944 | struct ahd_linux_device *dev; | ||
4945 | int target; | ||
4946 | int maxtarget; | ||
4947 | int lun; | ||
4948 | int i; | ||
4949 | |||
4950 | maxtarget = (ahd->features & AHD_WIDE) ? 15 : 7; | ||
4951 | for (target = 0; target <=maxtarget; target++) { | ||
4952 | |||
4953 | for (lun = 0; lun < AHD_NUM_LUNS; lun++) { | ||
4954 | struct ahd_cmd *acmd; | ||
4955 | |||
4956 | dev = ahd_linux_get_device(ahd, 0, target, | ||
4957 | lun, /*alloc*/FALSE); | ||
4958 | if (dev == NULL) | ||
4959 | continue; | ||
4960 | |||
4961 | printf("DevQ(%d:%d:%d): ", 0, target, lun); | ||
4962 | i = 0; | ||
4963 | TAILQ_FOREACH(acmd, &dev->busyq, acmd_links.tqe) { | ||
4964 | if (i++ > AHD_SCB_MAX) | ||
4965 | break; | ||
4966 | } | ||
4967 | printf("%d waiting\n", i); | ||
4968 | } | ||
4969 | } | ||
4970 | } | ||
4971 | |||
4972 | static int __init | 4443 | static int __init |
4973 | ahd_linux_init(void) | 4444 | ahd_linux_init(void) |
4974 | { | 4445 | { |
4975 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
4976 | return ahd_linux_detect(&aic79xx_driver_template); | 4446 | return ahd_linux_detect(&aic79xx_driver_template); |
4977 | #else | ||
4978 | scsi_register_module(MODULE_SCSI_HA, &aic79xx_driver_template); | ||
4979 | if (aic79xx_driver_template.present == 0) { | ||
4980 | scsi_unregister_module(MODULE_SCSI_HA, | ||
4981 | &aic79xx_driver_template); | ||
4982 | return (-ENODEV); | ||
4983 | } | ||
4984 | |||
4985 | return (0); | ||
4986 | #endif | ||
4987 | } | 4447 | } |
4988 | 4448 | ||
4989 | static void __exit | 4449 | static void __exit |
@@ -5002,14 +4462,6 @@ ahd_linux_exit(void) | |||
5002 | ahd_linux_kill_dv_thread(ahd); | 4462 | ahd_linux_kill_dv_thread(ahd); |
5003 | } | 4463 | } |
5004 | 4464 | ||
5005 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
5006 | /* | ||
5007 | * In 2.4 we have to unregister from the PCI core _after_ | ||
5008 | * unregistering from the scsi midlayer to avoid dangling | ||
5009 | * references. | ||
5010 | */ | ||
5011 | scsi_unregister_module(MODULE_SCSI_HA, &aic79xx_driver_template); | ||
5012 | #endif | ||
5013 | ahd_linux_pci_exit(); | 4465 | ahd_linux_pci_exit(); |
5014 | } | 4466 | } |
5015 | 4467 | ||
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 7823e52e99ab..792e97fef5b8 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h | |||
@@ -252,11 +252,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec) | |||
252 | /***************************** SMP support ************************************/ | 252 | /***************************** SMP support ************************************/ |
253 | #include <linux/spinlock.h> | 253 | #include <linux/spinlock.h> |
254 | 254 | ||
255 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK)) | ||
256 | #define AHD_SCSI_HAS_HOST_LOCK 1 | 255 | #define AHD_SCSI_HAS_HOST_LOCK 1 |
257 | #else | ||
258 | #define AHD_SCSI_HAS_HOST_LOCK 0 | ||
259 | #endif | ||
260 | 256 | ||
261 | #define AIC79XX_DRIVER_VERSION "1.3.11" | 257 | #define AIC79XX_DRIVER_VERSION "1.3.11" |
262 | 258 | ||
@@ -297,12 +293,11 @@ struct ahd_cmd { | |||
297 | * after a successfully completed inquiry command to the target when | 293 | * after a successfully completed inquiry command to the target when |
298 | * that inquiry data indicates a lun is present. | 294 | * that inquiry data indicates a lun is present. |
299 | */ | 295 | */ |
300 | TAILQ_HEAD(ahd_busyq, ahd_cmd); | 296 | |
301 | typedef enum { | 297 | typedef enum { |
302 | AHD_DEV_UNCONFIGURED = 0x01, | 298 | AHD_DEV_UNCONFIGURED = 0x01, |
303 | AHD_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ | 299 | AHD_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ |
304 | AHD_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */ | 300 | AHD_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */ |
305 | AHD_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */ | ||
306 | AHD_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ | 301 | AHD_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ |
307 | AHD_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ | 302 | AHD_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ |
308 | AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ | 303 | AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ |
@@ -312,7 +307,6 @@ typedef enum { | |||
312 | struct ahd_linux_target; | 307 | struct ahd_linux_target; |
313 | struct ahd_linux_device { | 308 | struct ahd_linux_device { |
314 | TAILQ_ENTRY(ahd_linux_device) links; | 309 | TAILQ_ENTRY(ahd_linux_device) links; |
315 | struct ahd_busyq busyq; | ||
316 | 310 | ||
317 | /* | 311 | /* |
318 | * The number of transactions currently | 312 | * The number of transactions currently |
@@ -453,18 +447,7 @@ struct ahd_linux_target { | |||
453 | * manner and are allocated below 4GB, the number of S/G segments is | 447 | * manner and are allocated below 4GB, the number of S/G segments is |
454 | * unrestricted. | 448 | * unrestricted. |
455 | */ | 449 | */ |
456 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
457 | /* | ||
458 | * We dynamically adjust the number of segments in pre-2.5 kernels to | ||
459 | * avoid fragmentation issues in the SCSI mid-layer's private memory | ||
460 | * allocator. See aic79xx_osm.c ahd_linux_size_nseg() for details. | ||
461 | */ | ||
462 | extern u_int ahd_linux_nseg; | ||
463 | #define AHD_NSEG ahd_linux_nseg | ||
464 | #define AHD_LINUX_MIN_NSEG 64 | ||
465 | #else | ||
466 | #define AHD_NSEG 128 | 450 | #define AHD_NSEG 128 |
467 | #endif | ||
468 | 451 | ||
469 | /* | 452 | /* |
470 | * Per-SCB OSM storage. | 453 | * Per-SCB OSM storage. |
@@ -502,11 +485,9 @@ struct ahd_platform_data { | |||
502 | * Fields accessed from interrupt context. | 485 | * Fields accessed from interrupt context. |
503 | */ | 486 | */ |
504 | struct ahd_linux_target *targets[AHD_NUM_TARGETS]; | 487 | struct ahd_linux_target *targets[AHD_NUM_TARGETS]; |
505 | TAILQ_HEAD(, ahd_linux_device) device_runq; | ||
506 | struct ahd_completeq completeq; | 488 | struct ahd_completeq completeq; |
507 | 489 | ||
508 | spinlock_t spin_lock; | 490 | spinlock_t spin_lock; |
509 | struct tasklet_struct runq_tasklet; | ||
510 | u_int qfrozen; | 491 | u_int qfrozen; |
511 | pid_t dv_pid; | 492 | pid_t dv_pid; |
512 | struct timer_list completeq_timer; | 493 | struct timer_list completeq_timer; |
@@ -925,12 +906,8 @@ ahd_flush_device_writes(struct ahd_softc *ahd) | |||
925 | } | 906 | } |
926 | 907 | ||
927 | /**************************** Proc FS Support *********************************/ | 908 | /**************************** Proc FS Support *********************************/ |
928 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
929 | int ahd_linux_proc_info(char *, char **, off_t, int, int, int); | ||
930 | #else | ||
931 | int ahd_linux_proc_info(struct Scsi_Host *, char *, char **, | 909 | int ahd_linux_proc_info(struct Scsi_Host *, char *, char **, |
932 | off_t, int, int); | 910 | off_t, int, int); |
933 | #endif | ||
934 | 911 | ||
935 | /*************************** Domain Validation ********************************/ | 912 | /*************************** Domain Validation ********************************/ |
936 | #define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete) | 913 | #define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete) |
@@ -1117,7 +1094,6 @@ void ahd_done(struct ahd_softc*, struct scb*); | |||
1117 | void ahd_send_async(struct ahd_softc *, char channel, | 1094 | void ahd_send_async(struct ahd_softc *, char channel, |
1118 | u_int target, u_int lun, ac_code, void *); | 1095 | u_int target, u_int lun, ac_code, void *); |
1119 | void ahd_print_path(struct ahd_softc *, struct scb *); | 1096 | void ahd_print_path(struct ahd_softc *, struct scb *); |
1120 | void ahd_platform_dump_card_state(struct ahd_softc *ahd); | ||
1121 | 1097 | ||
1122 | #ifdef CONFIG_PCI | 1098 | #ifdef CONFIG_PCI |
1123 | #define AHD_PCI_CONFIG 1 | 1099 | #define AHD_PCI_CONFIG 1 |
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c index e01cd6175e34..9c631a494ed2 100644 --- a/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/drivers/scsi/aic7xxx/aic79xx_proc.c | |||
@@ -278,13 +278,8 @@ done: | |||
278 | * Return information to handle /proc support for the driver. | 278 | * Return information to handle /proc support for the driver. |
279 | */ | 279 | */ |
280 | int | 280 | int |
281 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
282 | ahd_linux_proc_info(char *buffer, char **start, off_t offset, | ||
283 | int length, int hostno, int inout) | ||
284 | #else | ||
285 | ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | 281 | ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, |
286 | off_t offset, int length, int inout) | 282 | off_t offset, int length, int inout) |
287 | #endif | ||
288 | { | 283 | { |
289 | struct ahd_softc *ahd; | 284 | struct ahd_softc *ahd; |
290 | struct info_str info; | 285 | struct info_str info; |
@@ -296,14 +291,7 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | |||
296 | 291 | ||
297 | retval = -EINVAL; | 292 | retval = -EINVAL; |
298 | ahd_list_lock(&l); | 293 | ahd_list_lock(&l); |
299 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
300 | TAILQ_FOREACH(ahd, &ahd_tailq, links) { | ||
301 | if (ahd->platform_data->host->host_no == hostno) | ||
302 | break; | ||
303 | } | ||
304 | #else | ||
305 | ahd = ahd_find_softc(*(struct ahd_softc **)shost->hostdata); | 294 | ahd = ahd_find_softc(*(struct ahd_softc **)shost->hostdata); |
306 | #endif | ||
307 | 295 | ||
308 | if (ahd == NULL) | 296 | if (ahd == NULL) |
309 | goto done; | 297 | goto done; |