aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_core.c1
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c824
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h26
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_proc.c12
4 files changed, 139 insertions, 724 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index 137fb1a37dd..d69bbffb34a 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 329cb233133..7463dd515d1 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 */
67spinlock_t ahd_list_spinlock; 62spinlock_t ahd_list_spinlock;
68 63
69#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
70/* For dynamic sglist size calculation. */
71u_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,
457static void ahd_linux_dev_timed_unfreeze(u_long arg); 447static void ahd_linux_dev_timed_unfreeze(u_long arg);
458static void ahd_linux_sem_timeout(u_long arg); 448static void ahd_linux_sem_timeout(u_long arg);
459static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd); 449static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd);
460static void ahd_linux_size_nseg(void);
461static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd); 450static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd);
462static void ahd_linux_start_dv(struct ahd_softc *ahd); 451static void ahd_linux_start_dv(struct ahd_softc *ahd);
463static void ahd_linux_dv_timeout(struct scsi_cmnd *cmd); 452static 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);
517static void ahd_linux_free_device(struct ahd_softc*, 506static void ahd_linux_free_device(struct ahd_softc*,
518 struct ahd_linux_device*); 507 struct ahd_linux_device*);
519static void ahd_linux_run_device_queue(struct ahd_softc*, 508static int ahd_linux_run_command(struct ahd_softc*,
520 struct ahd_linux_device*); 509 struct ahd_linux_device*,
510 struct scsi_cmnd *);
521static void ahd_linux_setup_tag_info_global(char *p); 511static void ahd_linux_setup_tag_info_global(char *p);
522static aic_option_callback_t ahd_linux_setup_tag_info; 512static aic_option_callback_t ahd_linux_setup_tag_info;
523static aic_option_callback_t ahd_linux_setup_rd_strm_info; 513static aic_option_callback_t ahd_linux_setup_rd_strm_info;
524static aic_option_callback_t ahd_linux_setup_dv; 514static aic_option_callback_t ahd_linux_setup_dv;
525static aic_option_callback_t ahd_linux_setup_iocell_info; 515static aic_option_callback_t ahd_linux_setup_iocell_info;
526static int ahd_linux_next_unit(void); 516static int ahd_linux_next_unit(void);
527static void ahd_runq_tasklet(unsigned long data);
528static int aic79xx_setup(char *c); 517static int aic79xx_setup(char *c);
529 518
530/****************************** Inlines ***************************************/ 519/****************************** Inlines ***************************************/
531static __inline void ahd_schedule_completeq(struct ahd_softc *ahd); 520static __inline void ahd_schedule_completeq(struct ahd_softc *ahd);
532static __inline void ahd_schedule_runq(struct ahd_softc *ahd);
533static __inline void ahd_setup_runq_tasklet(struct ahd_softc *ahd);
534static __inline void ahd_teardown_runq_tasklet(struct ahd_softc *ahd);
535static __inline struct ahd_linux_device* 521static __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);
538static struct ahd_cmd *ahd_linux_run_complete_queue(struct ahd_softc *ahd); 524static struct ahd_cmd *ahd_linux_run_complete_queue(struct ahd_softc *ahd);
539static __inline void ahd_linux_check_device_queue(struct ahd_softc *ahd,
540 struct ahd_linux_device *dev);
541static __inline struct ahd_linux_device *
542 ahd_linux_next_device_to_run(struct ahd_softc *ahd);
543static __inline void ahd_linux_run_device_queues(struct ahd_softc *ahd);
544static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*); 525static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
545 526
546static __inline void 527static __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 */
559static __inline void
560ahd_schedule_runq(struct ahd_softc *ahd)
561{
562 tasklet_schedule(&ahd->platform_data->runq_tasklet);
563}
564
565static __inline
566void 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
572static __inline void
573ahd_teardown_runq_tasklet(struct ahd_softc *ahd)
574{
575 tasklet_kill(&ahd->platform_data->runq_tasklet);
576}
577
578static __inline struct ahd_linux_device* 537static __inline struct ahd_linux_device*
579ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, u_int target, 538ahd_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
643static __inline void 602static __inline void
644ahd_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
660static __inline struct ahd_linux_device *
661ahd_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
671static __inline void
672ahd_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
683static __inline void
684ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb) 603ahd_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)
709static int ahd_linux_detect(Scsi_Host_Template *); 628static int ahd_linux_detect(Scsi_Host_Template *);
710static const char *ahd_linux_info(struct Scsi_Host *); 629static const char *ahd_linux_info(struct Scsi_Host *);
711static int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); 630static int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
712#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
713static int ahd_linux_slave_alloc(Scsi_Device *); 631static int ahd_linux_slave_alloc(Scsi_Device *);
714static int ahd_linux_slave_configure(Scsi_Device *); 632static int ahd_linux_slave_configure(Scsi_Device *);
715static void ahd_linux_slave_destroy(Scsi_Device *); 633static void ahd_linux_slave_destroy(Scsi_Device *);
@@ -717,78 +635,10 @@ static void ahd_linux_slave_destroy(Scsi_Device *);
717static int ahd_linux_biosparam(struct scsi_device*, 635static 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
721static int ahd_linux_release(struct Scsi_Host *);
722static void ahd_linux_select_queue_depth(struct Scsi_Host *host,
723 Scsi_Device *scsi_devs);
724#if defined(__i386__)
725static int ahd_linux_biosparam(Disk *, kdev_t, int[]);
726#endif
727#endif
728static int ahd_linux_bus_reset(Scsi_Cmnd *); 638static int ahd_linux_bus_reset(Scsi_Cmnd *);
729static int ahd_linux_dev_reset(Scsi_Cmnd *); 639static int ahd_linux_dev_reset(Scsi_Cmnd *);
730static int ahd_linux_abort(Scsi_Cmnd *); 640static 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 */
749static void
750ahd_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 */
870static int
871ahd_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)
987static int 768static int
988ahd_linux_slave_alloc(Scsi_Device *device) 769ahd_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 */
1064static void
1065ahd_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 */
1132static int 844static int
1133#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1134ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, 845ahd_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
1139ahd_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 */
1636static void
1637ahd_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 *************************************/
1658int 1303int
1659ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent, 1304ahd_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
2371int 1991int
2372ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel, 1992ahd_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
2429static void 1998static 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(&current->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
3906static void 3465static int
3907ahd_linux_run_device_queue(struct ahd_softc *ahd, struct ahd_linux_device *dev) 3466ahd_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
4941void
4942ahd_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
4972static int __init 4443static int __init
4973ahd_linux_init(void) 4444ahd_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
4989static void __exit 4449static 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 7823e52e99a..792e97fef5b 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 */
300TAILQ_HEAD(ahd_busyq, ahd_cmd); 296
301typedef enum { 297typedef 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 {
312struct ahd_linux_target; 307struct ahd_linux_target;
313struct ahd_linux_device { 308struct 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 */
462extern 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)
929int ahd_linux_proc_info(char *, char **, off_t, int, int, int);
930#else
931int ahd_linux_proc_info(struct Scsi_Host *, char *, char **, 909int 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*);
1117void ahd_send_async(struct ahd_softc *, char channel, 1094void 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 *);
1119void ahd_print_path(struct ahd_softc *, struct scb *); 1096void ahd_print_path(struct ahd_softc *, struct scb *);
1120void 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 e01cd6175e3..9c631a494ed 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 */
280int 280int
281#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
282ahd_linux_proc_info(char *buffer, char **start, off_t offset,
283 int length, int hostno, int inout)
284#else
285ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, 281ahd_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;