diff options
author | Christoph Hellwig <hch@lst.de> | 2005-08-15 07:28:46 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-08-15 10:18:55 -0400 |
commit | 85a46523ff68aa0e4d2477c51075ffd9fc7e7a14 (patch) | |
tree | c465c274ffe0e4118ed46ad4e0e09dca975aeb1f /drivers/scsi/aic7xxx | |
parent | d46b1d549e1414d673e0ec18219f4f5e30d5f3f5 (diff) |
[SCSI] aic79xx: sane pci probing
remove ahd_tailq and do sane pci probing. ported over from aic7xxx.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aic7xxx')
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx.h | 6 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_core.c | 103 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_osm.c | 108 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_osm.h | 30 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_osm_pci.c | 79 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_pci.c | 14 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_proc.c | 11 |
7 files changed, 60 insertions, 291 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index fd4b2f3eb0c2..653fb0b42aea 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h | |||
@@ -1247,9 +1247,6 @@ struct ahd_softc { | |||
1247 | uint16_t user_tagenable;/* Tagged Queuing allowed */ | 1247 | uint16_t user_tagenable;/* Tagged Queuing allowed */ |
1248 | }; | 1248 | }; |
1249 | 1249 | ||
1250 | TAILQ_HEAD(ahd_softc_tailq, ahd_softc); | ||
1251 | extern struct ahd_softc_tailq ahd_tailq; | ||
1252 | |||
1253 | /*************************** IO Cell Configuration ****************************/ | 1250 | /*************************** IO Cell Configuration ****************************/ |
1254 | #define AHD_PRECOMP_SLEW_INDEX \ | 1251 | #define AHD_PRECOMP_SLEW_INDEX \ |
1255 | (AHD_ANNEXCOL_PRECOMP_SLEW - AHD_ANNEXCOL_PER_DEV0) | 1252 | (AHD_ANNEXCOL_PRECOMP_SLEW - AHD_ANNEXCOL_PER_DEV0) |
@@ -1374,8 +1371,6 @@ void ahd_enable_coalescing(struct ahd_softc *ahd, | |||
1374 | void ahd_pause_and_flushwork(struct ahd_softc *ahd); | 1371 | void ahd_pause_and_flushwork(struct ahd_softc *ahd); |
1375 | int ahd_suspend(struct ahd_softc *ahd); | 1372 | int ahd_suspend(struct ahd_softc *ahd); |
1376 | int ahd_resume(struct ahd_softc *ahd); | 1373 | int ahd_resume(struct ahd_softc *ahd); |
1377 | void ahd_softc_insert(struct ahd_softc *); | ||
1378 | struct ahd_softc *ahd_find_softc(struct ahd_softc *ahd); | ||
1379 | void ahd_set_unit(struct ahd_softc *, int); | 1374 | void ahd_set_unit(struct ahd_softc *, int); |
1380 | void ahd_set_name(struct ahd_softc *, char *); | 1375 | void ahd_set_name(struct ahd_softc *, char *); |
1381 | struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); | 1376 | struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); |
@@ -1524,7 +1519,6 @@ void ahd_print_scb(struct scb *scb); | |||
1524 | void ahd_print_devinfo(struct ahd_softc *ahd, | 1519 | void ahd_print_devinfo(struct ahd_softc *ahd, |
1525 | struct ahd_devinfo *devinfo); | 1520 | struct ahd_devinfo *devinfo); |
1526 | void ahd_dump_sglist(struct scb *scb); | 1521 | void ahd_dump_sglist(struct scb *scb); |
1527 | void ahd_dump_all_cards_state(void); | ||
1528 | void ahd_dump_card_state(struct ahd_softc *ahd); | 1522 | void ahd_dump_card_state(struct ahd_softc *ahd); |
1529 | int ahd_print_register(ahd_reg_parse_entry_t *table, | 1523 | int ahd_print_register(ahd_reg_parse_entry_t *table, |
1530 | u_int num_entries, | 1524 | u_int num_entries, |
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index d69bbffb34a0..4e8f00df978d 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -52,8 +52,6 @@ | |||
52 | #include <dev/aic7xxx/aicasm/aicasm_insformat.h> | 52 | #include <dev/aic7xxx/aicasm/aicasm_insformat.h> |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | /******************************** Globals *************************************/ | ||
56 | struct ahd_softc_tailq ahd_tailq = TAILQ_HEAD_INITIALIZER(ahd_tailq); | ||
57 | 55 | ||
58 | /***************************** Lookup Tables **********************************/ | 56 | /***************************** Lookup Tables **********************************/ |
59 | char *ahd_chip_names[] = | 57 | char *ahd_chip_names[] = |
@@ -5180,74 +5178,6 @@ ahd_softc_init(struct ahd_softc *ahd) | |||
5180 | } | 5178 | } |
5181 | 5179 | ||
5182 | void | 5180 | void |
5183 | ahd_softc_insert(struct ahd_softc *ahd) | ||
5184 | { | ||
5185 | struct ahd_softc *list_ahd; | ||
5186 | |||
5187 | #if AHD_PCI_CONFIG > 0 | ||
5188 | /* | ||
5189 | * Second Function PCI devices need to inherit some | ||
5190 | * settings from function 0. | ||
5191 | */ | ||
5192 | if ((ahd->features & AHD_MULTI_FUNC) != 0) { | ||
5193 | TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { | ||
5194 | ahd_dev_softc_t list_pci; | ||
5195 | ahd_dev_softc_t pci; | ||
5196 | |||
5197 | list_pci = list_ahd->dev_softc; | ||
5198 | pci = ahd->dev_softc; | ||
5199 | if (ahd_get_pci_slot(list_pci) == ahd_get_pci_slot(pci) | ||
5200 | && ahd_get_pci_bus(list_pci) == ahd_get_pci_bus(pci)) { | ||
5201 | struct ahd_softc *master; | ||
5202 | struct ahd_softc *slave; | ||
5203 | |||
5204 | if (ahd_get_pci_function(list_pci) == 0) { | ||
5205 | master = list_ahd; | ||
5206 | slave = ahd; | ||
5207 | } else { | ||
5208 | master = ahd; | ||
5209 | slave = list_ahd; | ||
5210 | } | ||
5211 | slave->flags &= ~AHD_BIOS_ENABLED; | ||
5212 | slave->flags |= | ||
5213 | master->flags & AHD_BIOS_ENABLED; | ||
5214 | break; | ||
5215 | } | ||
5216 | } | ||
5217 | } | ||
5218 | #endif | ||
5219 | |||
5220 | /* | ||
5221 | * Insertion sort into our list of softcs. | ||
5222 | */ | ||
5223 | list_ahd = TAILQ_FIRST(&ahd_tailq); | ||
5224 | while (list_ahd != NULL | ||
5225 | && ahd_softc_comp(ahd, list_ahd) <= 0) | ||
5226 | list_ahd = TAILQ_NEXT(list_ahd, links); | ||
5227 | if (list_ahd != NULL) | ||
5228 | TAILQ_INSERT_BEFORE(list_ahd, ahd, links); | ||
5229 | else | ||
5230 | TAILQ_INSERT_TAIL(&ahd_tailq, ahd, links); | ||
5231 | ahd->init_level++; | ||
5232 | } | ||
5233 | |||
5234 | /* | ||
5235 | * Verify that the passed in softc pointer is for a | ||
5236 | * controller that is still configured. | ||
5237 | */ | ||
5238 | struct ahd_softc * | ||
5239 | ahd_find_softc(struct ahd_softc *ahd) | ||
5240 | { | ||
5241 | struct ahd_softc *list_ahd; | ||
5242 | |||
5243 | TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { | ||
5244 | if (list_ahd == ahd) | ||
5245 | return (ahd); | ||
5246 | } | ||
5247 | return (NULL); | ||
5248 | } | ||
5249 | |||
5250 | void | ||
5251 | ahd_set_unit(struct ahd_softc *ahd, int unit) | 5181 | ahd_set_unit(struct ahd_softc *ahd, int unit) |
5252 | { | 5182 | { |
5253 | ahd->unit = unit; | 5183 | ahd->unit = unit; |
@@ -7902,18 +7832,10 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) | |||
7902 | static void | 7832 | static void |
7903 | ahd_reset_poll(void *arg) | 7833 | ahd_reset_poll(void *arg) |
7904 | { | 7834 | { |
7905 | struct ahd_softc *ahd; | 7835 | struct ahd_softc *ahd = arg; |
7906 | u_int scsiseq1; | 7836 | u_int scsiseq1; |
7907 | u_long l; | ||
7908 | u_long s; | 7837 | u_long s; |
7909 | 7838 | ||
7910 | ahd_list_lock(&l); | ||
7911 | ahd = ahd_find_softc((struct ahd_softc *)arg); | ||
7912 | if (ahd == NULL) { | ||
7913 | printf("ahd_reset_poll: Instance %p no longer exists\n", arg); | ||
7914 | ahd_list_unlock(&l); | ||
7915 | return; | ||
7916 | } | ||
7917 | ahd_lock(ahd, &s); | 7839 | ahd_lock(ahd, &s); |
7918 | ahd_pause(ahd); | 7840 | ahd_pause(ahd); |
7919 | ahd_update_modes(ahd); | 7841 | ahd_update_modes(ahd); |
@@ -7924,7 +7846,6 @@ ahd_reset_poll(void *arg) | |||
7924 | ahd_reset_poll, ahd); | 7846 | ahd_reset_poll, ahd); |
7925 | ahd_unpause(ahd); | 7847 | ahd_unpause(ahd); |
7926 | ahd_unlock(ahd, &s); | 7848 | ahd_unlock(ahd, &s); |
7927 | ahd_list_unlock(&l); | ||
7928 | return; | 7849 | return; |
7929 | } | 7850 | } |
7930 | 7851 | ||
@@ -7936,25 +7857,16 @@ ahd_reset_poll(void *arg) | |||
7936 | ahd->flags &= ~AHD_RESET_POLL_ACTIVE; | 7857 | ahd->flags &= ~AHD_RESET_POLL_ACTIVE; |
7937 | ahd_unlock(ahd, &s); | 7858 | ahd_unlock(ahd, &s); |
7938 | ahd_release_simq(ahd); | 7859 | ahd_release_simq(ahd); |
7939 | ahd_list_unlock(&l); | ||
7940 | } | 7860 | } |
7941 | 7861 | ||
7942 | /**************************** Statistics Processing ***************************/ | 7862 | /**************************** Statistics Processing ***************************/ |
7943 | static void | 7863 | static void |
7944 | ahd_stat_timer(void *arg) | 7864 | ahd_stat_timer(void *arg) |
7945 | { | 7865 | { |
7946 | struct ahd_softc *ahd; | 7866 | struct ahd_softc *ahd = arg; |
7947 | u_long l; | ||
7948 | u_long s; | 7867 | u_long s; |
7949 | int enint_coal; | 7868 | int enint_coal; |
7950 | 7869 | ||
7951 | ahd_list_lock(&l); | ||
7952 | ahd = ahd_find_softc((struct ahd_softc *)arg); | ||
7953 | if (ahd == NULL) { | ||
7954 | printf("ahd_stat_timer: Instance %p no longer exists\n", arg); | ||
7955 | ahd_list_unlock(&l); | ||
7956 | return; | ||
7957 | } | ||
7958 | ahd_lock(ahd, &s); | 7870 | ahd_lock(ahd, &s); |
7959 | 7871 | ||
7960 | enint_coal = ahd->hs_mailbox & ENINT_COALESCE; | 7872 | enint_coal = ahd->hs_mailbox & ENINT_COALESCE; |
@@ -7981,7 +7893,6 @@ ahd_stat_timer(void *arg) | |||
7981 | ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US, | 7893 | ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US, |
7982 | ahd_stat_timer, ahd); | 7894 | ahd_stat_timer, ahd); |
7983 | ahd_unlock(ahd, &s); | 7895 | ahd_unlock(ahd, &s); |
7984 | ahd_list_unlock(&l); | ||
7985 | } | 7896 | } |
7986 | 7897 | ||
7987 | /****************************** Status Processing *****************************/ | 7898 | /****************************** Status Processing *****************************/ |
@@ -8745,16 +8656,6 @@ sized: | |||
8745 | return (last_probe); | 8656 | return (last_probe); |
8746 | } | 8657 | } |
8747 | 8658 | ||
8748 | void | ||
8749 | ahd_dump_all_cards_state(void) | ||
8750 | { | ||
8751 | struct ahd_softc *list_ahd; | ||
8752 | |||
8753 | TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { | ||
8754 | ahd_dump_card_state(list_ahd); | ||
8755 | } | ||
8756 | } | ||
8757 | |||
8758 | int | 8659 | int |
8759 | ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries, | 8660 | ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries, |
8760 | const char *name, u_int address, u_int value, | 8661 | const char *name, u_int address, u_int value, |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 2f158624c5d2..3feb739cd554 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -60,11 +60,6 @@ static struct scsi_transport_template *ahd_linux_transport_template = NULL; | |||
60 | #include <linux/delay.h> /* For ssleep/msleep */ | 60 | #include <linux/delay.h> /* For ssleep/msleep */ |
61 | 61 | ||
62 | /* | 62 | /* |
63 | * Lock protecting manipulation of the ahd softc list. | ||
64 | */ | ||
65 | spinlock_t ahd_list_spinlock; | ||
66 | |||
67 | /* | ||
68 | * Bucket size for counting good commands in between bad ones. | 63 | * Bucket size for counting good commands in between bad ones. |
69 | */ | 64 | */ |
70 | #define AHD_LINUX_ERR_THRESH 1000 | 65 | #define AHD_LINUX_ERR_THRESH 1000 |
@@ -303,13 +298,6 @@ static uint32_t aic79xx_pci_parity = ~0; | |||
303 | uint32_t aic79xx_allow_memio = ~0; | 298 | uint32_t aic79xx_allow_memio = ~0; |
304 | 299 | ||
305 | /* | 300 | /* |
306 | * aic79xx_detect() has been run, so register all device arrivals | ||
307 | * immediately with the system rather than deferring to the sorted | ||
308 | * attachment performed by aic79xx_detect(). | ||
309 | */ | ||
310 | int aic79xx_detect_complete; | ||
311 | |||
312 | /* | ||
313 | * So that we can set how long each device is given as a selection timeout. | 301 | * So that we can set how long each device is given as a selection timeout. |
314 | * The table of values goes like this: | 302 | * The table of values goes like this: |
315 | * 0 - 256ms | 303 | * 0 - 256ms |
@@ -387,7 +375,9 @@ static void ahd_linux_setup_tag_info_global(char *p); | |||
387 | static aic_option_callback_t ahd_linux_setup_tag_info; | 375 | static aic_option_callback_t ahd_linux_setup_tag_info; |
388 | static aic_option_callback_t ahd_linux_setup_iocell_info; | 376 | static aic_option_callback_t ahd_linux_setup_iocell_info; |
389 | static int aic79xx_setup(char *c); | 377 | static int aic79xx_setup(char *c); |
390 | static int ahd_linux_next_unit(void); | 378 | |
379 | static int ahd_linux_unit; | ||
380 | |||
391 | 381 | ||
392 | /****************************** Inlines ***************************************/ | 382 | /****************************** Inlines ***************************************/ |
393 | static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*); | 383 | static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*); |
@@ -418,50 +408,6 @@ ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb) | |||
418 | ((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id) | 408 | ((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id) |
419 | 409 | ||
420 | /* | 410 | /* |
421 | * Try to detect an Adaptec 79XX controller. | ||
422 | */ | ||
423 | static int | ||
424 | ahd_linux_detect(struct scsi_host_template *template) | ||
425 | { | ||
426 | struct ahd_softc *ahd; | ||
427 | int found; | ||
428 | int error = 0; | ||
429 | |||
430 | /* | ||
431 | * If we've been passed any parameters, process them now. | ||
432 | */ | ||
433 | if (aic79xx) | ||
434 | aic79xx_setup(aic79xx); | ||
435 | |||
436 | template->proc_name = "aic79xx"; | ||
437 | |||
438 | /* | ||
439 | * Initialize our softc list lock prior to | ||
440 | * probing for any adapters. | ||
441 | */ | ||
442 | ahd_list_lockinit(); | ||
443 | |||
444 | #ifdef CONFIG_PCI | ||
445 | error = ahd_linux_pci_init(); | ||
446 | if (error) | ||
447 | return error; | ||
448 | #endif | ||
449 | |||
450 | /* | ||
451 | * Register with the SCSI layer all | ||
452 | * controllers we've found. | ||
453 | */ | ||
454 | found = 0; | ||
455 | TAILQ_FOREACH(ahd, &ahd_tailq, links) { | ||
456 | |||
457 | if (ahd_linux_register_host(ahd, template) == 0) | ||
458 | found++; | ||
459 | } | ||
460 | aic79xx_detect_complete++; | ||
461 | return found; | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * Return a string describing the driver. | 411 | * Return a string describing the driver. |
466 | */ | 412 | */ |
467 | static const char * | 413 | static const char * |
@@ -760,6 +706,7 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmd) | |||
760 | struct scsi_host_template aic79xx_driver_template = { | 706 | struct scsi_host_template aic79xx_driver_template = { |
761 | .module = THIS_MODULE, | 707 | .module = THIS_MODULE, |
762 | .name = "aic79xx", | 708 | .name = "aic79xx", |
709 | .proc_name = "aic79xx", | ||
763 | .proc_info = ahd_linux_proc_info, | 710 | .proc_info = ahd_linux_proc_info, |
764 | .info = ahd_linux_info, | 711 | .info = ahd_linux_info, |
765 | .queuecommand = ahd_linux_queue, | 712 | .queuecommand = ahd_linux_queue, |
@@ -1072,7 +1019,7 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa | |||
1072 | host->max_lun = AHD_NUM_LUNS; | 1019 | host->max_lun = AHD_NUM_LUNS; |
1073 | host->max_channel = 0; | 1020 | host->max_channel = 0; |
1074 | host->sg_tablesize = AHD_NSEG; | 1021 | host->sg_tablesize = AHD_NSEG; |
1075 | ahd_set_unit(ahd, ahd_linux_next_unit()); | 1022 | ahd_set_unit(ahd, ahd_linux_unit++); |
1076 | sprintf(buf, "scsi%d", host->host_no); | 1023 | sprintf(buf, "scsi%d", host->host_no); |
1077 | new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); | 1024 | new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); |
1078 | if (new_name != NULL) { | 1025 | if (new_name != NULL) { |
@@ -1101,29 +1048,6 @@ ahd_linux_get_memsize(void) | |||
1101 | } | 1048 | } |
1102 | 1049 | ||
1103 | /* | 1050 | /* |
1104 | * Find the smallest available unit number to use | ||
1105 | * for a new device. We don't just use a static | ||
1106 | * count to handle the "repeated hot-(un)plug" | ||
1107 | * scenario. | ||
1108 | */ | ||
1109 | static int | ||
1110 | ahd_linux_next_unit(void) | ||
1111 | { | ||
1112 | struct ahd_softc *ahd; | ||
1113 | int unit; | ||
1114 | |||
1115 | unit = 0; | ||
1116 | retry: | ||
1117 | TAILQ_FOREACH(ahd, &ahd_tailq, links) { | ||
1118 | if (ahd->unit == unit) { | ||
1119 | unit++; | ||
1120 | goto retry; | ||
1121 | } | ||
1122 | } | ||
1123 | return (unit); | ||
1124 | } | ||
1125 | |||
1126 | /* | ||
1127 | * Place the SCSI bus into a known state by either resetting it, | 1051 | * Place the SCSI bus into a known state by either resetting it, |
1128 | * or forcing transfer negotiations on the next command to any | 1052 | * or forcing transfer negotiations on the next command to any |
1129 | * target. | 1053 | * target. |
@@ -2755,23 +2679,31 @@ static struct spi_function_template ahd_linux_transport_functions = { | |||
2755 | .show_hold_mcs = 1, | 2679 | .show_hold_mcs = 1, |
2756 | }; | 2680 | }; |
2757 | 2681 | ||
2758 | |||
2759 | |||
2760 | static int __init | 2682 | static int __init |
2761 | ahd_linux_init(void) | 2683 | ahd_linux_init(void) |
2762 | { | 2684 | { |
2763 | ahd_linux_transport_template = spi_attach_transport(&ahd_linux_transport_functions); | 2685 | int error = 0; |
2686 | |||
2687 | /* | ||
2688 | * If we've been passed any parameters, process them now. | ||
2689 | */ | ||
2690 | if (aic79xx) | ||
2691 | aic79xx_setup(aic79xx); | ||
2692 | |||
2693 | ahd_linux_transport_template = | ||
2694 | spi_attach_transport(&ahd_linux_transport_functions); | ||
2764 | if (!ahd_linux_transport_template) | 2695 | if (!ahd_linux_transport_template) |
2765 | return -ENODEV; | 2696 | return -ENODEV; |
2697 | |||
2766 | scsi_transport_reserve_target(ahd_linux_transport_template, | 2698 | scsi_transport_reserve_target(ahd_linux_transport_template, |
2767 | sizeof(struct ahd_linux_target)); | 2699 | sizeof(struct ahd_linux_target)); |
2768 | scsi_transport_reserve_device(ahd_linux_transport_template, | 2700 | scsi_transport_reserve_device(ahd_linux_transport_template, |
2769 | sizeof(struct ahd_linux_device)); | 2701 | sizeof(struct ahd_linux_device)); |
2770 | if (ahd_linux_detect(&aic79xx_driver_template) > 0) | ||
2771 | return 0; | ||
2772 | spi_release_transport(ahd_linux_transport_template); | ||
2773 | 2702 | ||
2774 | return -ENODEV; | 2703 | error = ahd_linux_pci_init(); |
2704 | if (error) | ||
2705 | spi_release_transport(ahd_linux_transport_template); | ||
2706 | return error; | ||
2775 | } | 2707 | } |
2776 | 2708 | ||
2777 | static void __exit | 2709 | static void __exit |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 296d3a59efe9..052c6619accc 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h | |||
@@ -120,7 +120,6 @@ typedef struct scsi_cmnd *ahd_io_ctx_t; | |||
120 | 120 | ||
121 | /************************* Configuration Data *********************************/ | 121 | /************************* Configuration Data *********************************/ |
122 | extern uint32_t aic79xx_allow_memio; | 122 | extern uint32_t aic79xx_allow_memio; |
123 | extern int aic79xx_detect_complete; | ||
124 | extern struct scsi_host_template aic79xx_driver_template; | 123 | extern struct scsi_host_template aic79xx_driver_template; |
125 | 124 | ||
126 | /***************************** Bus Space/DMA **********************************/ | 125 | /***************************** Bus Space/DMA **********************************/ |
@@ -532,17 +531,6 @@ void ahd_format_transinfo(struct info_str *info, | |||
532 | struct ahd_transinfo *tinfo); | 531 | struct ahd_transinfo *tinfo); |
533 | 532 | ||
534 | /******************************** Locking *************************************/ | 533 | /******************************** Locking *************************************/ |
535 | /* Lock protecting internal data structures */ | ||
536 | static __inline void ahd_lockinit(struct ahd_softc *); | ||
537 | static __inline void ahd_lock(struct ahd_softc *, unsigned long *flags); | ||
538 | static __inline void ahd_unlock(struct ahd_softc *, unsigned long *flags); | ||
539 | |||
540 | /* Lock held during ahd_list manipulation and ahd softc frees */ | ||
541 | extern spinlock_t ahd_list_spinlock; | ||
542 | static __inline void ahd_list_lockinit(void); | ||
543 | static __inline void ahd_list_lock(unsigned long *flags); | ||
544 | static __inline void ahd_list_unlock(unsigned long *flags); | ||
545 | |||
546 | static __inline void | 534 | static __inline void |
547 | ahd_lockinit(struct ahd_softc *ahd) | 535 | ahd_lockinit(struct ahd_softc *ahd) |
548 | { | 536 | { |
@@ -561,24 +549,6 @@ ahd_unlock(struct ahd_softc *ahd, unsigned long *flags) | |||
561 | spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags); | 549 | spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags); |
562 | } | 550 | } |
563 | 551 | ||
564 | static __inline void | ||
565 | ahd_list_lockinit(void) | ||
566 | { | ||
567 | spin_lock_init(&ahd_list_spinlock); | ||
568 | } | ||
569 | |||
570 | static __inline void | ||
571 | ahd_list_lock(unsigned long *flags) | ||
572 | { | ||
573 | spin_lock_irqsave(&ahd_list_spinlock, *flags); | ||
574 | } | ||
575 | |||
576 | static __inline void | ||
577 | ahd_list_unlock(unsigned long *flags) | ||
578 | { | ||
579 | spin_unlock_irqrestore(&ahd_list_spinlock, *flags); | ||
580 | } | ||
581 | |||
582 | /******************************* PCI Definitions ******************************/ | 552 | /******************************* PCI Definitions ******************************/ |
583 | /* | 553 | /* |
584 | * PCIM_xxx: mask to locate subfield in register | 554 | * PCIM_xxx: mask to locate subfield in register |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index 7cfb2eb2b868..390b53852d4b 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c | |||
@@ -92,27 +92,31 @@ struct pci_driver aic79xx_pci_driver = { | |||
92 | static void | 92 | static void |
93 | ahd_linux_pci_dev_remove(struct pci_dev *pdev) | 93 | ahd_linux_pci_dev_remove(struct pci_dev *pdev) |
94 | { | 94 | { |
95 | struct ahd_softc *ahd; | 95 | struct ahd_softc *ahd = pci_get_drvdata(pdev); |
96 | u_long l; | 96 | u_long s; |
97 | 97 | ||
98 | /* | 98 | ahd_lock(ahd, &s); |
99 | * We should be able to just perform | 99 | ahd_intr_enable(ahd, FALSE); |
100 | * the free directly, but check our | 100 | ahd_unlock(ahd, &s); |
101 | * list for extra sanity. | 101 | ahd_free(ahd); |
102 | */ | 102 | } |
103 | ahd_list_lock(&l); | 103 | |
104 | ahd = ahd_find_softc((struct ahd_softc *)pci_get_drvdata(pdev)); | 104 | static void |
105 | if (ahd != NULL) { | 105 | ahd_linux_pci_inherit_flags(struct ahd_softc *ahd) |
106 | u_long s; | 106 | { |
107 | 107 | struct pci_dev *pdev = ahd->dev_softc, *master_pdev; | |
108 | TAILQ_REMOVE(&ahd_tailq, ahd, links); | 108 | unsigned int master_devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0); |
109 | ahd_list_unlock(&l); | 109 | |
110 | ahd_lock(ahd, &s); | 110 | master_pdev = pci_get_slot(pdev->bus, master_devfn); |
111 | ahd_intr_enable(ahd, FALSE); | 111 | if (master_pdev) { |
112 | ahd_unlock(ahd, &s); | 112 | struct ahd_softc *master = pci_get_drvdata(master_pdev); |
113 | ahd_free(ahd); | 113 | if (master) { |
114 | } else | 114 | ahd->flags &= ~AHD_BIOS_ENABLED; |
115 | ahd_list_unlock(&l); | 115 | ahd->flags |= master->flags & AHD_BIOS_ENABLED; |
116 | } else | ||
117 | printk(KERN_ERR "aic79xx: no multichannel peer found!\n"); | ||
118 | pci_dev_put(master_pdev); | ||
119 | } | ||
116 | } | 120 | } |
117 | 121 | ||
118 | static int | 122 | static int |
@@ -125,22 +129,6 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
125 | char *name; | 129 | char *name; |
126 | int error; | 130 | int error; |
127 | 131 | ||
128 | /* | ||
129 | * Some BIOSen report the same device multiple times. | ||
130 | */ | ||
131 | TAILQ_FOREACH(ahd, &ahd_tailq, links) { | ||
132 | struct pci_dev *probed_pdev; | ||
133 | |||
134 | probed_pdev = ahd->dev_softc; | ||
135 | if (probed_pdev->bus->number == pdev->bus->number | ||
136 | && probed_pdev->devfn == pdev->devfn) | ||
137 | break; | ||
138 | } | ||
139 | if (ahd != NULL) { | ||
140 | /* Skip duplicate. */ | ||
141 | return (-ENODEV); | ||
142 | } | ||
143 | |||
144 | pci = pdev; | 132 | pci = pdev; |
145 | entry = ahd_find_pci_device(pci); | 133 | entry = ahd_find_pci_device(pci); |
146 | if (entry == NULL) | 134 | if (entry == NULL) |
@@ -190,16 +178,17 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
190 | ahd_free(ahd); | 178 | ahd_free(ahd); |
191 | return (-error); | 179 | return (-error); |
192 | } | 180 | } |
181 | |||
182 | /* | ||
183 | * Second Function PCI devices need to inherit some | ||
184 | * * settings from function 0. | ||
185 | */ | ||
186 | if ((ahd->features & AHD_MULTI_FUNC) && PCI_FUNC(pdev->devfn) != 0) | ||
187 | ahd_linux_pci_inherit_flags(ahd); | ||
188 | |||
193 | pci_set_drvdata(pdev, ahd); | 189 | pci_set_drvdata(pdev, ahd); |
194 | if (aic79xx_detect_complete) { | 190 | |
195 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | 191 | ahd_linux_register_host(ahd, &aic79xx_driver_template); |
196 | ahd_linux_register_host(ahd, &aic79xx_driver_template); | ||
197 | #else | ||
198 | printf("aic79xx: ignoring PCI device found after " | ||
199 | "initialization\n"); | ||
200 | return (-ENODEV); | ||
201 | #endif | ||
202 | } | ||
203 | return (0); | 192 | return (0); |
204 | } | 193 | } |
205 | 194 | ||
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c index 703f6e44889d..2131db60018a 100644 --- a/drivers/scsi/aic7xxx/aic79xx_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_pci.c | |||
@@ -283,7 +283,6 @@ int | |||
283 | ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry) | 283 | ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry) |
284 | { | 284 | { |
285 | struct scb_data *shared_scb_data; | 285 | struct scb_data *shared_scb_data; |
286 | u_long l; | ||
287 | u_int command; | 286 | u_int command; |
288 | uint32_t devconfig; | 287 | uint32_t devconfig; |
289 | uint16_t subvendor; | 288 | uint16_t subvendor; |
@@ -373,16 +372,9 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry) | |||
373 | * Allow interrupts now that we are completely setup. | 372 | * Allow interrupts now that we are completely setup. |
374 | */ | 373 | */ |
375 | error = ahd_pci_map_int(ahd); | 374 | error = ahd_pci_map_int(ahd); |
376 | if (error != 0) | 375 | if (!error) |
377 | return (error); | 376 | ahd->init_level++; |
378 | 377 | return error; | |
379 | ahd_list_lock(&l); | ||
380 | /* | ||
381 | * Link this softc in with all other ahd instances. | ||
382 | */ | ||
383 | ahd_softc_insert(ahd); | ||
384 | ahd_list_unlock(&l); | ||
385 | return (0); | ||
386 | } | 378 | } |
387 | 379 | ||
388 | /* | 380 | /* |
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c index cffdd104f9e4..32be1f55998c 100644 --- a/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/drivers/scsi/aic7xxx/aic79xx_proc.c | |||
@@ -285,21 +285,13 @@ int | |||
285 | ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | 285 | ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, |
286 | off_t offset, int length, int inout) | 286 | off_t offset, int length, int inout) |
287 | { | 287 | { |
288 | struct ahd_softc *ahd; | 288 | struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata; |
289 | struct info_str info; | 289 | struct info_str info; |
290 | char ahd_info[256]; | 290 | char ahd_info[256]; |
291 | u_long l; | ||
292 | u_int max_targ; | 291 | u_int max_targ; |
293 | u_int i; | 292 | u_int i; |
294 | int retval; | 293 | int retval; |
295 | 294 | ||
296 | retval = -EINVAL; | ||
297 | ahd_list_lock(&l); | ||
298 | ahd = ahd_find_softc(*(struct ahd_softc **)shost->hostdata); | ||
299 | |||
300 | if (ahd == NULL) | ||
301 | goto done; | ||
302 | |||
303 | /* Has data been written to the file? */ | 295 | /* Has data been written to the file? */ |
304 | if (inout == TRUE) { | 296 | if (inout == TRUE) { |
305 | retval = ahd_proc_write_seeprom(ahd, buffer, length); | 297 | retval = ahd_proc_write_seeprom(ahd, buffer, length); |
@@ -349,6 +341,5 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | |||
349 | } | 341 | } |
350 | retval = info.pos > info.offset ? info.pos - info.offset : 0; | 342 | retval = info.pos > info.offset ? info.pos - info.offset : 0; |
351 | done: | 343 | done: |
352 | ahd_list_unlock(&l); | ||
353 | return (retval); | 344 | return (retval); |
354 | } | 345 | } |