diff options
Diffstat (limited to 'drivers/ide/ide-generic.c')
| -rw-r--r-- | drivers/ide/ide-generic.c | 73 |
1 files changed, 37 insertions, 36 deletions
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index 2d92214096ab..31d98fec775f 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c | |||
| @@ -28,29 +28,21 @@ MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports"); | |||
| 28 | 28 | ||
| 29 | static ssize_t store_add(struct class *cls, const char *buf, size_t n) | 29 | static ssize_t store_add(struct class *cls, const char *buf, size_t n) |
| 30 | { | 30 | { |
| 31 | ide_hwif_t *hwif; | ||
| 32 | unsigned int base, ctl; | 31 | unsigned int base, ctl; |
| 33 | int irq; | 32 | int irq, rc; |
| 34 | hw_regs_t hw; | 33 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; |
| 35 | u8 idx[] = { 0xff, 0xff, 0xff, 0xff }; | ||
| 36 | 34 | ||
| 37 | if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3) | 35 | if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3) |
| 38 | return -EINVAL; | 36 | return -EINVAL; |
| 39 | 37 | ||
| 40 | hwif = ide_find_port(); | ||
| 41 | if (hwif == NULL) | ||
| 42 | return -ENOENT; | ||
| 43 | |||
| 44 | memset(&hw, 0, sizeof(hw)); | 38 | memset(&hw, 0, sizeof(hw)); |
| 45 | ide_std_init_ports(&hw, base, ctl); | 39 | ide_std_init_ports(&hw, base, ctl); |
| 46 | hw.irq = irq; | 40 | hw.irq = irq; |
| 47 | hw.chipset = ide_generic; | 41 | hw.chipset = ide_generic; |
| 48 | 42 | ||
| 49 | ide_init_port_hw(hwif, &hw); | 43 | rc = ide_host_add(NULL, hws, NULL); |
| 50 | 44 | if (rc) | |
| 51 | idx[0] = hwif->index; | 45 | return rc; |
| 52 | |||
| 53 | ide_device_add(idx, NULL); | ||
| 54 | 46 | ||
| 55 | return n; | 47 | return n; |
| 56 | }; | 48 | }; |
| @@ -90,18 +82,18 @@ static int __init ide_generic_sysfs_init(void) | |||
| 90 | 82 | ||
| 91 | static int __init ide_generic_init(void) | 83 | static int __init ide_generic_init(void) |
| 92 | { | 84 | { |
| 93 | u8 idx[MAX_HWIFS]; | 85 | hw_regs_t hw[MAX_HWIFS], *hws[MAX_HWIFS]; |
| 94 | int i; | 86 | struct ide_host *host; |
| 87 | unsigned long io_addr; | ||
| 88 | int i, rc; | ||
| 95 | 89 | ||
| 96 | printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module " | 90 | printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module " |
| 97 | "parameter for probing all legacy ISA IDE ports\n"); | 91 | "parameter for probing all legacy ISA IDE ports\n"); |
| 98 | 92 | ||
| 99 | for (i = 0; i < MAX_HWIFS; i++) { | 93 | for (i = 0; i < MAX_HWIFS; i++) { |
| 100 | ide_hwif_t *hwif; | 94 | io_addr = ide_default_io_base(i); |
| 101 | unsigned long io_addr = ide_default_io_base(i); | ||
| 102 | hw_regs_t hw; | ||
| 103 | 95 | ||
| 104 | idx[i] = 0xff; | 96 | hws[i] = NULL; |
| 105 | 97 | ||
| 106 | if ((probe_mask & (1 << i)) && io_addr) { | 98 | if ((probe_mask & (1 << i)) && io_addr) { |
| 107 | if (!request_region(io_addr, 8, DRV_NAME)) { | 99 | if (!request_region(io_addr, 8, DRV_NAME)) { |
| @@ -119,33 +111,42 @@ static int __init ide_generic_init(void) | |||
| 119 | continue; | 111 | continue; |
| 120 | } | 112 | } |
| 121 | 113 | ||
| 122 | /* | 114 | memset(&hw[i], 0, sizeof(hw[i])); |
| 123 | * Skip probing if the corresponding | 115 | ide_std_init_ports(&hw[i], io_addr, io_addr + 0x206); |
| 124 | * slot is already occupied. | 116 | hw[i].irq = ide_default_irq(io_addr); |
| 125 | */ | 117 | hw[i].chipset = ide_generic; |
| 126 | hwif = ide_find_port(); | ||
| 127 | if (hwif == NULL || hwif->index != i) { | ||
| 128 | idx[i] = 0xff; | ||
| 129 | continue; | ||
| 130 | } | ||
| 131 | |||
| 132 | memset(&hw, 0, sizeof(hw)); | ||
| 133 | ide_std_init_ports(&hw, io_addr, io_addr + 0x206); | ||
| 134 | hw.irq = ide_default_irq(io_addr); | ||
| 135 | hw.chipset = ide_generic; | ||
| 136 | ide_init_port_hw(hwif, &hw); | ||
| 137 | 118 | ||
| 138 | idx[i] = i; | 119 | hws[i] = &hw[i]; |
| 139 | } | 120 | } |
| 140 | } | 121 | } |
| 141 | 122 | ||
| 142 | ide_device_add_all(idx, NULL); | 123 | host = ide_host_alloc_all(NULL, hws); |
| 124 | if (host == NULL) { | ||
| 125 | rc = -ENOMEM; | ||
| 126 | goto err; | ||
| 127 | } | ||
| 128 | |||
| 129 | rc = ide_host_register(host, NULL, hws); | ||
| 130 | if (rc) | ||
| 131 | goto err_free; | ||
| 143 | 132 | ||
| 144 | if (ide_generic_sysfs_init()) | 133 | if (ide_generic_sysfs_init()) |
| 145 | printk(KERN_ERR DRV_NAME ": failed to create ide_generic " | 134 | printk(KERN_ERR DRV_NAME ": failed to create ide_generic " |
| 146 | "class\n"); | 135 | "class\n"); |
| 147 | 136 | ||
| 148 | return 0; | 137 | return 0; |
| 138 | err_free: | ||
| 139 | ide_host_free(host); | ||
| 140 | err: | ||
| 141 | for (i = 0; i < MAX_HWIFS; i++) { | ||
| 142 | if (hws[i] == NULL) | ||
| 143 | continue; | ||
| 144 | |||
| 145 | io_addr = hws[i]->io_ports.data_addr; | ||
| 146 | release_region(io_addr + 0x206, 1); | ||
| 147 | release_region(io_addr, 8); | ||
| 148 | } | ||
| 149 | return rc; | ||
| 149 | } | 150 | } |
| 150 | 151 | ||
| 151 | module_init(ide_generic_init); | 152 | module_init(ide_generic_init); |
