diff options
| author | Christoph Hellwig <hch@lst.de> | 2005-06-10 18:17:03 -0400 |
|---|---|---|
| committer | James Bottomley <jejb@titanic.(none)> | 2005-06-11 19:45:06 -0400 |
| commit | d6cbbad7296538b6a38c0fe36e6ecf67f1e600a7 (patch) | |
| tree | 9cf9cfeedd3b5aaa2af0a548cc1c84b06bc76d48 | |
| parent | 8eb379425765bfc9a44f06f210224b10066fc46f (diff) | |
[SCSI] aic7xxx: clean up eisa support
- the eisa layer only probes when it's actually safe, no need for
a driver option
- store the id table directly in linux format instead of convering
at runtime
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
| -rw-r--r-- | drivers/scsi/aic7xxx/aic7770_osm.c | 175 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.c | 18 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.h | 1 |
3 files changed, 63 insertions, 131 deletions
diff --git a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c index d0e9b54ab008..d4ed5e9f830a 100644 --- a/drivers/scsi/aic7xxx/aic7770_osm.c +++ b/drivers/scsi/aic7xxx/aic7770_osm.c | |||
| @@ -44,109 +44,6 @@ | |||
| 44 | #include <linux/device.h> | 44 | #include <linux/device.h> |
| 45 | #include <linux/eisa.h> | 45 | #include <linux/eisa.h> |
| 46 | 46 | ||
| 47 | #define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@') /* Bits 26-30 */ | ||
| 48 | #define EISA_MFCTR_CHAR1(ID) (char)(((ID>>21) & 0x1F) | '@') /* Bits 21-25 */ | ||
| 49 | #define EISA_MFCTR_CHAR2(ID) (char)(((ID>>16) & 0x1F) | '@') /* Bits 16-20 */ | ||
| 50 | #define EISA_PRODUCT_ID(ID) (short)((ID>>4) & 0xFFF) /* Bits 4-15 */ | ||
| 51 | #define EISA_REVISION_ID(ID) (uint8_t)(ID & 0x0F) /* Bits 0-3 */ | ||
| 52 | |||
| 53 | static int aic7770_eisa_dev_probe(struct device *dev); | ||
| 54 | static int aic7770_eisa_dev_remove(struct device *dev); | ||
| 55 | static struct eisa_driver aic7770_driver = { | ||
| 56 | .driver = { | ||
| 57 | .name = "aic7xxx", | ||
| 58 | .probe = aic7770_eisa_dev_probe, | ||
| 59 | .remove = aic7770_eisa_dev_remove, | ||
| 60 | } | ||
| 61 | }; | ||
| 62 | |||
| 63 | typedef struct device *aic7770_dev_t; | ||
| 64 | |||
| 65 | static int aic7770_linux_config(struct aic7770_identity *entry, | ||
| 66 | aic7770_dev_t dev, u_int eisaBase); | ||
| 67 | |||
| 68 | int | ||
| 69 | ahc_linux_eisa_init(void) | ||
| 70 | { | ||
| 71 | struct eisa_device_id *eid; | ||
| 72 | struct aic7770_identity *id; | ||
| 73 | int i; | ||
| 74 | |||
| 75 | if (aic7xxx_probe_eisa_vl == 0) | ||
| 76 | return -ENODEV; | ||
| 77 | |||
| 78 | /* | ||
| 79 | * Linux requires the EISA IDs to be specified in | ||
| 80 | * the EISA ID string format. Perform the conversion | ||
| 81 | * and setup a table with a NUL terminal entry. | ||
| 82 | */ | ||
| 83 | aic7770_driver.id_table = malloc(sizeof(struct eisa_device_id) * | ||
| 84 | (ahc_num_aic7770_devs + 1), | ||
| 85 | M_DEVBUF, M_NOWAIT); | ||
| 86 | if (aic7770_driver.id_table == NULL) | ||
| 87 | return -ENOMEM; | ||
| 88 | |||
| 89 | for (eid = (struct eisa_device_id *)aic7770_driver.id_table, | ||
| 90 | id = aic7770_ident_table, i = 0; | ||
| 91 | i < ahc_num_aic7770_devs; eid++, id++, i++) { | ||
| 92 | |||
| 93 | sprintf(eid->sig, "%c%c%c%03X%01X", | ||
| 94 | EISA_MFCTR_CHAR0(id->full_id), | ||
| 95 | EISA_MFCTR_CHAR1(id->full_id), | ||
| 96 | EISA_MFCTR_CHAR2(id->full_id), | ||
| 97 | EISA_PRODUCT_ID(id->full_id), | ||
| 98 | EISA_REVISION_ID(id->full_id)); | ||
| 99 | eid->driver_data = i; | ||
| 100 | } | ||
| 101 | eid->sig[0] = 0; | ||
| 102 | |||
| 103 | return eisa_driver_register(&aic7770_driver); | ||
| 104 | } | ||
| 105 | |||
| 106 | void | ||
| 107 | ahc_linux_eisa_exit(void) | ||
| 108 | { | ||
| 109 | if(aic7xxx_probe_eisa_vl != 0 && aic7770_driver.id_table != NULL) { | ||
| 110 | eisa_driver_unregister(&aic7770_driver); | ||
| 111 | free(aic7770_driver.id_table, M_DEVBUF); | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | static int | ||
| 116 | aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev, | ||
| 117 | u_int eisaBase) | ||
| 118 | { | ||
| 119 | struct ahc_softc *ahc; | ||
| 120 | char buf[80]; | ||
| 121 | char *name; | ||
| 122 | int error; | ||
| 123 | |||
| 124 | /* | ||
| 125 | * Allocate a softc for this card and | ||
| 126 | * set it up for attachment by our | ||
| 127 | * common detect routine. | ||
| 128 | */ | ||
| 129 | sprintf(buf, "ahc_eisa:%d", eisaBase >> 12); | ||
| 130 | name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); | ||
| 131 | if (name == NULL) | ||
| 132 | return (ENOMEM); | ||
| 133 | strcpy(name, buf); | ||
| 134 | ahc = ahc_alloc(&aic7xxx_driver_template, name); | ||
| 135 | if (ahc == NULL) | ||
| 136 | return (ENOMEM); | ||
| 137 | error = aic7770_config(ahc, entry, eisaBase); | ||
| 138 | if (error != 0) { | ||
| 139 | ahc->bsh.ioport = 0; | ||
| 140 | ahc_free(ahc); | ||
| 141 | return (error); | ||
| 142 | } | ||
| 143 | |||
| 144 | dev->driver_data = (void *)ahc; | ||
| 145 | if (aic7xxx_detect_complete) | ||
| 146 | error = ahc_linux_register_host(ahc, &aic7xxx_driver_template); | ||
| 147 | return (error); | ||
| 148 | } | ||
| 149 | |||
| 150 | int | 47 | int |
| 151 | aic7770_map_registers(struct ahc_softc *ahc, u_int port) | 48 | aic7770_map_registers(struct ahc_softc *ahc, u_int port) |
| 152 | { | 49 | { |
| @@ -178,25 +75,79 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq) | |||
| 178 | } | 75 | } |
| 179 | 76 | ||
| 180 | static int | 77 | static int |
| 181 | aic7770_eisa_dev_probe(struct device *dev) | 78 | aic7770_probe(struct device *dev) |
| 182 | { | 79 | { |
| 183 | struct eisa_device *edev; | 80 | struct eisa_device *edev = to_eisa_device(dev); |
| 81 | u_int eisaBase = edev->base_addr+AHC_EISA_SLOT_OFFSET; | ||
| 82 | struct ahc_softc *ahc; | ||
| 83 | char buf[80]; | ||
| 84 | char *name; | ||
| 85 | int error; | ||
| 86 | |||
| 87 | sprintf(buf, "ahc_eisa:%d", eisaBase >> 12); | ||
| 88 | name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); | ||
| 89 | if (name == NULL) | ||
| 90 | return (ENOMEM); | ||
| 91 | strcpy(name, buf); | ||
| 92 | ahc = ahc_alloc(&aic7xxx_driver_template, name); | ||
| 93 | if (ahc == NULL) | ||
| 94 | return (ENOMEM); | ||
| 95 | error = aic7770_config(ahc, aic7770_ident_table + edev->id.driver_data, | ||
| 96 | eisaBase); | ||
| 97 | if (error != 0) { | ||
| 98 | ahc->bsh.ioport = 0; | ||
| 99 | ahc_free(ahc); | ||
| 100 | return (error); | ||
| 101 | } | ||
| 102 | |||
| 103 | dev_set_drvdata(dev, ahc); | ||
| 184 | 104 | ||
| 185 | edev = to_eisa_device(dev); | 105 | if (aic7xxx_detect_complete) |
| 186 | return (aic7770_linux_config(aic7770_ident_table + edev->id.driver_data, | 106 | error = ahc_linux_register_host(ahc, &aic7xxx_driver_template); |
| 187 | dev, edev->base_addr+AHC_EISA_SLOT_OFFSET)); | 107 | return (error); |
| 188 | } | 108 | } |
| 189 | 109 | ||
| 190 | static int | 110 | static int |
| 191 | aic7770_eisa_dev_remove(struct device *dev) | 111 | aic7770_remove(struct device *dev) |
| 192 | { | 112 | { |
| 193 | struct ahc_softc *ahc = dev_get_drvata(dev); | 113 | struct ahc_softc *ahc = dev_get_drvdata(dev); |
| 194 | u_long s; | 114 | u_long s; |
| 195 | 115 | ||
| 196 | ahc_lock(ahc, &s); | 116 | ahc_lock(ahc, &s); |
| 197 | ahc_intr_enable(ahc, FALSE); | 117 | ahc_intr_enable(ahc, FALSE); |
| 198 | ahc_unlock(ahc, &s); | 118 | ahc_unlock(ahc, &s); |
| 199 | ahc_free(ahc); | ||
| 200 | 119 | ||
| 201 | return (0); | 120 | ahc_free(ahc); |
| 121 | return 0; | ||
| 122 | } | ||
| 123 | |||
| 124 | static struct eisa_device_id aic7770_ids[] = { | ||
| 125 | { "ADP7771", 0 }, /* AHA 274x */ | ||
| 126 | { "ADP7756", 1 }, /* AHA 284x BIOS enabled */ | ||
| 127 | { "ADP7757", 2 }, /* AHA 284x BIOS disabled */ | ||
| 128 | { "ADP7782", 3 }, /* AHA 274x Olivetti OEM */ | ||
| 129 | { "ADP7783", 4 }, /* AHA 274x Olivetti OEM (Differential) */ | ||
| 130 | { "ADP7770", 5 }, /* AIC7770 generic */ | ||
| 131 | { "" } | ||
| 132 | }; | ||
| 133 | |||
| 134 | static struct eisa_driver aic7770_driver = { | ||
| 135 | .id_table = aic7770_ids, | ||
| 136 | .driver = { | ||
| 137 | .name = "aic7xxx", | ||
| 138 | .probe = aic7770_probe, | ||
| 139 | .remove = aic7770_remove, | ||
| 140 | } | ||
| 141 | }; | ||
| 142 | |||
| 143 | int | ||
| 144 | ahc_linux_eisa_init(void) | ||
| 145 | { | ||
| 146 | return eisa_driver_register(&aic7770_driver); | ||
| 147 | } | ||
| 148 | |||
| 149 | void | ||
| 150 | ahc_linux_eisa_exit(void) | ||
| 151 | { | ||
| 152 | eisa_driver_unregister(&aic7770_driver); | ||
| 202 | } | 153 | } |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 3287f8df1801..55e0b2875f99 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c | |||
| @@ -330,22 +330,6 @@ static uint32_t aic7xxx_extended; | |||
| 330 | static uint32_t aic7xxx_pci_parity = ~0; | 330 | static uint32_t aic7xxx_pci_parity = ~0; |
| 331 | 331 | ||
| 332 | /* | 332 | /* |
| 333 | * Certain newer motherboards have put new PCI based devices into the | ||
| 334 | * IO spaces that used to typically be occupied by VLB or EISA cards. | ||
| 335 | * This overlap can cause these newer motherboards to lock up when scanned | ||
| 336 | * for older EISA and VLB devices. Setting this option to non-0 will | ||
| 337 | * cause the driver to skip scanning for any VLB or EISA controllers and | ||
| 338 | * only support the PCI controllers. NOTE: this means that if the kernel | ||
| 339 | * os compiled with PCI support disabled, then setting this to non-0 | ||
| 340 | * would result in never finding any devices :) | ||
| 341 | */ | ||
| 342 | #ifndef CONFIG_AIC7XXX_PROBE_EISA_VL | ||
| 343 | uint32_t aic7xxx_probe_eisa_vl; | ||
| 344 | #else | ||
| 345 | uint32_t aic7xxx_probe_eisa_vl = ~0; | ||
| 346 | #endif | ||
| 347 | |||
| 348 | /* | ||
| 349 | * There are lots of broken chipsets in the world. Some of them will | 333 | * There are lots of broken chipsets in the world. Some of them will |
| 350 | * violate the PCI spec when we issue byte sized memory writes to our | 334 | * violate the PCI spec when we issue byte sized memory writes to our |
| 351 | * controller. I/O mapped register access, if allowed by the given | 335 | * controller. I/O mapped register access, if allowed by the given |
| @@ -1101,8 +1085,6 @@ aic7xxx_setup(char *s) | |||
| 1101 | { "debug", &ahc_debug }, | 1085 | { "debug", &ahc_debug }, |
| 1102 | #endif | 1086 | #endif |
| 1103 | { "reverse_scan", &aic7xxx_reverse_scan }, | 1087 | { "reverse_scan", &aic7xxx_reverse_scan }, |
| 1104 | { "no_probe", &aic7xxx_probe_eisa_vl }, | ||
| 1105 | { "probe_eisa_vl", &aic7xxx_probe_eisa_vl }, | ||
| 1106 | { "periodic_otag", &aic7xxx_periodic_otag }, | 1088 | { "periodic_otag", &aic7xxx_periodic_otag }, |
| 1107 | { "pci_parity", &aic7xxx_pci_parity }, | 1089 | { "pci_parity", &aic7xxx_pci_parity }, |
| 1108 | { "seltime", &aic7xxx_seltime }, | 1090 | { "seltime", &aic7xxx_seltime }, |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index b97f718dfe54..8ffe2d3e1d95 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h | |||
| @@ -605,7 +605,6 @@ typedef enum | |||
| 605 | 605 | ||
| 606 | /**************************** VL/EISA Routines ********************************/ | 606 | /**************************** VL/EISA Routines ********************************/ |
| 607 | #ifdef CONFIG_EISA | 607 | #ifdef CONFIG_EISA |
| 608 | extern uint32_t aic7xxx_probe_eisa_vl; | ||
| 609 | int ahc_linux_eisa_init(void); | 608 | int ahc_linux_eisa_init(void); |
| 610 | void ahc_linux_eisa_exit(void); | 609 | void ahc_linux_eisa_exit(void); |
| 611 | int aic7770_map_registers(struct ahc_softc *ahc, | 610 | int aic7770_map_registers(struct ahc_softc *ahc, |
