aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic7xxx/aic7xxx_osm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aic7xxx/aic7xxx_osm.c')
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c223
1 files changed, 26 insertions, 197 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index b89094db14c1..116d0f51ca2c 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -136,10 +136,6 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL;
136#include <linux/blkdev.h> /* For block_size() */ 136#include <linux/blkdev.h> /* For block_size() */
137#include <linux/delay.h> /* For ssleep/msleep */ 137#include <linux/delay.h> /* For ssleep/msleep */
138 138
139/*
140 * Lock protecting manipulation of the ahc softc list.
141 */
142spinlock_t ahc_list_spinlock;
143 139
144/* 140/*
145 * Set this to the delay in seconds after SCSI bus reset. 141 * Set this to the delay in seconds after SCSI bus reset.
@@ -292,25 +288,6 @@ ahc_print_path(struct ahc_softc *ahc, struct scb *scb)
292static uint32_t aic7xxx_no_reset; 288static uint32_t aic7xxx_no_reset;
293 289
294/* 290/*
295 * Certain PCI motherboards will scan PCI devices from highest to lowest,
296 * others scan from lowest to highest, and they tend to do all kinds of
297 * strange things when they come into contact with PCI bridge chips. The
298 * net result of all this is that the PCI card that is actually used to boot
299 * the machine is very hard to detect. Most motherboards go from lowest
300 * PCI slot number to highest, and the first SCSI controller found is the
301 * one you boot from. The only exceptions to this are when a controller
302 * has its BIOS disabled. So, we by default sort all of our SCSI controllers
303 * from lowest PCI slot number to highest PCI slot number. We also force
304 * all controllers with their BIOS disabled to the end of the list. This
305 * works on *almost* all computers. Where it doesn't work, we have this
306 * option. Setting this option to non-0 will reverse the order of the sort
307 * to highest first, then lowest, but will still leave cards with their BIOS
308 * disabled at the very end. That should fix everyone up unless there are
309 * really strange cirumstances.
310 */
311static uint32_t aic7xxx_reverse_scan;
312
313/*
314 * Should we force EXTENDED translation on a controller. 291 * Should we force EXTENDED translation on a controller.
315 * 0 == Use whatever is in the SEEPROM or default to off 292 * 0 == Use whatever is in the SEEPROM or default to off
316 * 1 == Use whatever is in the SEEPROM or default to on 293 * 1 == Use whatever is in the SEEPROM or default to on
@@ -338,13 +315,6 @@ static uint32_t aic7xxx_pci_parity = ~0;
338uint32_t aic7xxx_allow_memio = ~0; 315uint32_t aic7xxx_allow_memio = ~0;
339 316
340/* 317/*
341 * aic7xxx_detect() has been run, so register all device arrivals
342 * immediately with the system rather than deferring to the sorted
343 * attachment performed by aic7xxx_detect().
344 */
345int aic7xxx_detect_complete;
346
347/*
348 * So that we can set how long each device is given as a selection timeout. 318 * So that we can set how long each device is given as a selection timeout.
349 * The table of values goes like this: 319 * The table of values goes like this:
350 * 0 - 256ms 320 * 0 - 256ms
@@ -423,7 +393,9 @@ static int ahc_linux_run_command(struct ahc_softc*,
423static void ahc_linux_setup_tag_info_global(char *p); 393static void ahc_linux_setup_tag_info_global(char *p);
424static aic_option_callback_t ahc_linux_setup_tag_info; 394static aic_option_callback_t ahc_linux_setup_tag_info;
425static int aic7xxx_setup(char *s); 395static int aic7xxx_setup(char *s);
426static int ahc_linux_next_unit(void); 396
397static int ahc_linux_unit;
398
427 399
428/********************************* Inlines ************************************/ 400/********************************* Inlines ************************************/
429static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); 401static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*);
@@ -476,48 +448,6 @@ ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
476} 448}
477 449
478/* 450/*
479 * Try to detect an Adaptec 7XXX controller.
480 */
481static int
482ahc_linux_detect(struct scsi_host_template *template)
483{
484 struct ahc_softc *ahc;
485 int found = 0;
486
487 /*
488 * If we've been passed any parameters, process them now.
489 */
490 if (aic7xxx)
491 aic7xxx_setup(aic7xxx);
492
493 template->proc_name = "aic7xxx";
494
495 /*
496 * Initialize our softc list lock prior to
497 * probing for any adapters.
498 */
499 ahc_list_lockinit();
500
501 found = ahc_linux_pci_init();
502 if (!ahc_linux_eisa_init())
503 found++;
504
505 /*
506 * Register with the SCSI layer all
507 * controllers we've found.
508 */
509 TAILQ_FOREACH(ahc, &ahc_tailq, links) {
510
511 if (ahc_linux_register_host(ahc, template) == 0)
512 found++;
513 }
514
515 aic7xxx_detect_complete++;
516
517 return (found);
518}
519
520/*
521 * Return a string describing the driver. 451 * Return a string describing the driver.
522 */ 452 */
523static const char * 453static const char *
@@ -848,6 +778,7 @@ ahc_linux_bus_reset(struct scsi_cmnd *cmd)
848struct scsi_host_template aic7xxx_driver_template = { 778struct scsi_host_template aic7xxx_driver_template = {
849 .module = THIS_MODULE, 779 .module = THIS_MODULE,
850 .name = "aic7xxx", 780 .name = "aic7xxx",
781 .proc_name = "aic7xxx",
851 .proc_info = ahc_linux_proc_info, 782 .proc_info = ahc_linux_proc_info,
852 .info = ahc_linux_info, 783 .info = ahc_linux_info,
853 .queuecommand = ahc_linux_queue, 784 .queuecommand = ahc_linux_queue,
@@ -959,99 +890,6 @@ ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
959 return (0); 890 return (0);
960} 891}
961 892
962/********************* Platform Dependent Functions ***************************/
963/*
964 * Compare "left hand" softc with "right hand" softc, returning:
965 * < 0 - lahc has a lower priority than rahc
966 * 0 - Softcs are equal
967 * > 0 - lahc has a higher priority than rahc
968 */
969int
970ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc)
971{
972 int value;
973 int rvalue;
974 int lvalue;
975
976 /*
977 * Under Linux, cards are ordered as follows:
978 * 1) VLB/EISA BIOS enabled devices sorted by BIOS address.
979 * 2) PCI devices with BIOS enabled sorted by bus/slot/func.
980 * 3) All remaining VLB/EISA devices sorted by ioport.
981 * 4) All remaining PCI devices sorted by bus/slot/func.
982 */
983 value = (lahc->flags & AHC_BIOS_ENABLED)
984 - (rahc->flags & AHC_BIOS_ENABLED);
985 if (value != 0)
986 /* Controllers with BIOS enabled have a *higher* priority */
987 return (value);
988
989 /*
990 * Same BIOS setting, now sort based on bus type.
991 * EISA and VL controllers sort together. EISA/VL
992 * have higher priority than PCI.
993 */
994 rvalue = (rahc->chip & AHC_BUS_MASK);
995 if (rvalue == AHC_VL)
996 rvalue = AHC_EISA;
997 lvalue = (lahc->chip & AHC_BUS_MASK);
998 if (lvalue == AHC_VL)
999 lvalue = AHC_EISA;
1000 value = rvalue - lvalue;
1001 if (value != 0)
1002 return (value);
1003
1004 /* Still equal. Sort by BIOS address, ioport, or bus/slot/func. */
1005 switch (rvalue) {
1006#ifdef CONFIG_PCI
1007 case AHC_PCI:
1008 {
1009 char primary_channel;
1010
1011 if (aic7xxx_reverse_scan != 0)
1012 value = ahc_get_pci_bus(lahc->dev_softc)
1013 - ahc_get_pci_bus(rahc->dev_softc);
1014 else
1015 value = ahc_get_pci_bus(rahc->dev_softc)
1016 - ahc_get_pci_bus(lahc->dev_softc);
1017 if (value != 0)
1018 break;
1019 if (aic7xxx_reverse_scan != 0)
1020 value = ahc_get_pci_slot(lahc->dev_softc)
1021 - ahc_get_pci_slot(rahc->dev_softc);
1022 else
1023 value = ahc_get_pci_slot(rahc->dev_softc)
1024 - ahc_get_pci_slot(lahc->dev_softc);
1025 if (value != 0)
1026 break;
1027 /*
1028 * On multi-function devices, the user can choose
1029 * to have function 1 probed before function 0.
1030 * Give whichever channel is the primary channel
1031 * the highest priority.
1032 */
1033 primary_channel = (lahc->flags & AHC_PRIMARY_CHANNEL) + 'A';
1034 value = -1;
1035 if (lahc->channel == primary_channel)
1036 value = 1;
1037 break;
1038 }
1039#endif
1040 case AHC_EISA:
1041 if ((rahc->flags & AHC_BIOS_ENABLED) != 0) {
1042 value = rahc->platform_data->bios_address
1043 - lahc->platform_data->bios_address;
1044 } else {
1045 value = rahc->bsh.ioport
1046 - lahc->bsh.ioport;
1047 }
1048 break;
1049 default:
1050 panic("ahc_softc_sort: invalid bus type");
1051 }
1052 return (value);
1053}
1054
1055static void 893static void
1056ahc_linux_setup_tag_info_global(char *p) 894ahc_linux_setup_tag_info_global(char *p)
1057{ 895{
@@ -1103,7 +941,6 @@ aic7xxx_setup(char *s)
1103#ifdef AHC_DEBUG 941#ifdef AHC_DEBUG
1104 { "debug", &ahc_debug }, 942 { "debug", &ahc_debug },
1105#endif 943#endif
1106 { "reverse_scan", &aic7xxx_reverse_scan },
1107 { "periodic_otag", &aic7xxx_periodic_otag }, 944 { "periodic_otag", &aic7xxx_periodic_otag },
1108 { "pci_parity", &aic7xxx_pci_parity }, 945 { "pci_parity", &aic7xxx_pci_parity },
1109 { "seltime", &aic7xxx_seltime }, 946 { "seltime", &aic7xxx_seltime },
@@ -1178,7 +1015,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
1178 host->max_lun = AHC_NUM_LUNS; 1015 host->max_lun = AHC_NUM_LUNS;
1179 host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0; 1016 host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
1180 host->sg_tablesize = AHC_NSEG; 1017 host->sg_tablesize = AHC_NSEG;
1181 ahc_set_unit(ahc, ahc_linux_next_unit()); 1018 ahc_set_unit(ahc, ahc_linux_unit++);
1182 sprintf(buf, "scsi%d", host->host_no); 1019 sprintf(buf, "scsi%d", host->host_no);
1183 new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); 1020 new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
1184 if (new_name != NULL) { 1021 if (new_name != NULL) {
@@ -1207,29 +1044,6 @@ ahc_linux_get_memsize(void)
1207} 1044}
1208 1045
1209/* 1046/*
1210 * Find the smallest available unit number to use
1211 * for a new device. We don't just use a static
1212 * count to handle the "repeated hot-(un)plug"
1213 * scenario.
1214 */
1215static int
1216ahc_linux_next_unit(void)
1217{
1218 struct ahc_softc *ahc;
1219 int unit;
1220
1221 unit = 0;
1222retry:
1223 TAILQ_FOREACH(ahc, &ahc_tailq, links) {
1224 if (ahc->unit == unit) {
1225 unit++;
1226 goto retry;
1227 }
1228 }
1229 return (unit);
1230}
1231
1232/*
1233 * Place the SCSI bus into a known state by either resetting it, 1047 * Place the SCSI bus into a known state by either resetting it,
1234 * or forcing transfer negotiations on the next command to any 1048 * or forcing transfer negotiations on the next command to any
1235 * target. 1049 * target.
@@ -2633,6 +2447,11 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
2633 ahc_unlock(ahc, &flags); 2447 ahc_unlock(ahc, &flags);
2634} 2448}
2635 2449
2450#if 0
2451/* FIXME: This code claims to support IU and QAS. However, the actual
2452 * sequencer code and aic7xxx_core have no support for these parameters and
2453 * will get into a bad state if they're negotiated. Do not enable this
2454 * unless you know what you're doing */
2636static void ahc_linux_set_qas(struct scsi_target *starget, int qas) 2455static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
2637{ 2456{
2638 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 2457 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -2688,6 +2507,7 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
2688 ppr_options, AHC_TRANS_GOAL, FALSE); 2507 ppr_options, AHC_TRANS_GOAL, FALSE);
2689 ahc_unlock(ahc, &flags); 2508 ahc_unlock(ahc, &flags);
2690} 2509}
2510#endif
2691 2511
2692static struct spi_function_template ahc_linux_transport_functions = { 2512static struct spi_function_template ahc_linux_transport_functions = {
2693 .set_offset = ahc_linux_set_offset, 2513 .set_offset = ahc_linux_set_offset,
@@ -2698,10 +2518,12 @@ static struct spi_function_template ahc_linux_transport_functions = {
2698 .show_width = 1, 2518 .show_width = 1,
2699 .set_dt = ahc_linux_set_dt, 2519 .set_dt = ahc_linux_set_dt,
2700 .show_dt = 1, 2520 .show_dt = 1,
2521#if 0
2701 .set_iu = ahc_linux_set_iu, 2522 .set_iu = ahc_linux_set_iu,
2702 .show_iu = 1, 2523 .show_iu = 1,
2703 .set_qas = ahc_linux_set_qas, 2524 .set_qas = ahc_linux_set_qas,
2704 .show_qas = 1, 2525 .show_qas = 1,
2526#endif
2705}; 2527};
2706 2528
2707 2529
@@ -2709,18 +2531,25 @@ static struct spi_function_template ahc_linux_transport_functions = {
2709static int __init 2531static int __init
2710ahc_linux_init(void) 2532ahc_linux_init(void)
2711{ 2533{
2712 ahc_linux_transport_template = spi_attach_transport(&ahc_linux_transport_functions); 2534 /*
2535 * If we've been passed any parameters, process them now.
2536 */
2537 if (aic7xxx)
2538 aic7xxx_setup(aic7xxx);
2539
2540 ahc_linux_transport_template =
2541 spi_attach_transport(&ahc_linux_transport_functions);
2713 if (!ahc_linux_transport_template) 2542 if (!ahc_linux_transport_template)
2714 return -ENODEV; 2543 return -ENODEV;
2544
2715 scsi_transport_reserve_target(ahc_linux_transport_template, 2545 scsi_transport_reserve_target(ahc_linux_transport_template,
2716 sizeof(struct ahc_linux_target)); 2546 sizeof(struct ahc_linux_target));
2717 scsi_transport_reserve_device(ahc_linux_transport_template, 2547 scsi_transport_reserve_device(ahc_linux_transport_template,
2718 sizeof(struct ahc_linux_device)); 2548 sizeof(struct ahc_linux_device));
2719 if (ahc_linux_detect(&aic7xxx_driver_template)) 2549
2720 return 0; 2550 ahc_linux_pci_init();
2721 spi_release_transport(ahc_linux_transport_template); 2551 ahc_linux_eisa_init();
2722 ahc_linux_exit(); 2552 return 0;
2723 return -ENODEV;
2724} 2553}
2725 2554
2726static void 2555static void