diff options
-rw-r--r-- | drivers/ide/ide-probe.c | 135 | ||||
-rw-r--r-- | drivers/ide/ide.c | 146 | ||||
-rw-r--r-- | include/linux/ide.h | 9 |
3 files changed, 136 insertions, 154 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index e953b70706c2..09ea50118e63 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -918,6 +918,8 @@ static int ide_init_queue(ide_drive_t *drive) | |||
918 | return 0; | 918 | return 0; |
919 | } | 919 | } |
920 | 920 | ||
921 | static DEFINE_MUTEX(ide_cfg_mtx); | ||
922 | |||
921 | /* | 923 | /* |
922 | * For any present drive: | 924 | * For any present drive: |
923 | * - allocate the block device queue | 925 | * - allocate the block device queue |
@@ -1273,6 +1275,69 @@ static void ide_port_cable_detect(ide_hwif_t *hwif) | |||
1273 | } | 1275 | } |
1274 | } | 1276 | } |
1275 | 1277 | ||
1278 | static const u8 ide_hwif_to_major[] = | ||
1279 | { IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, | ||
1280 | IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR, IDE8_MAJOR, IDE9_MAJOR }; | ||
1281 | |||
1282 | static void ide_port_init_devices_data(ide_hwif_t *hwif) | ||
1283 | { | ||
1284 | int unit; | ||
1285 | |||
1286 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | ||
1287 | ide_drive_t *drive = &hwif->drives[unit]; | ||
1288 | u8 j = (hwif->index * MAX_DRIVES) + unit; | ||
1289 | |||
1290 | memset(drive, 0, sizeof(*drive)); | ||
1291 | |||
1292 | drive->media = ide_disk; | ||
1293 | drive->select = (unit << 4) | ATA_DEVICE_OBS; | ||
1294 | drive->hwif = hwif; | ||
1295 | drive->ready_stat = ATA_DRDY; | ||
1296 | drive->bad_wstat = BAD_W_STAT; | ||
1297 | drive->special.b.recalibrate = 1; | ||
1298 | drive->special.b.set_geometry = 1; | ||
1299 | drive->name[0] = 'h'; | ||
1300 | drive->name[1] = 'd'; | ||
1301 | drive->name[2] = 'a' + j; | ||
1302 | drive->max_failures = IDE_DEFAULT_MAX_FAILURES; | ||
1303 | |||
1304 | INIT_LIST_HEAD(&drive->list); | ||
1305 | init_completion(&drive->gendev_rel_comp); | ||
1306 | } | ||
1307 | } | ||
1308 | |||
1309 | static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) | ||
1310 | { | ||
1311 | /* bulk initialize hwif & drive info with zeros */ | ||
1312 | memset(hwif, 0, sizeof(ide_hwif_t)); | ||
1313 | |||
1314 | /* fill in any non-zero initial values */ | ||
1315 | hwif->index = index; | ||
1316 | hwif->major = ide_hwif_to_major[index]; | ||
1317 | |||
1318 | hwif->name[0] = 'i'; | ||
1319 | hwif->name[1] = 'd'; | ||
1320 | hwif->name[2] = 'e'; | ||
1321 | hwif->name[3] = '0' + index; | ||
1322 | |||
1323 | init_completion(&hwif->gendev_rel_comp); | ||
1324 | |||
1325 | hwif->tp_ops = &default_tp_ops; | ||
1326 | |||
1327 | ide_port_init_devices_data(hwif); | ||
1328 | } | ||
1329 | |||
1330 | static void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) | ||
1331 | { | ||
1332 | memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports)); | ||
1333 | hwif->irq = hw->irq; | ||
1334 | hwif->chipset = hw->chipset; | ||
1335 | hwif->dev = hw->dev; | ||
1336 | hwif->gendev.parent = hw->parent ? hw->parent : hw->dev; | ||
1337 | hwif->ack_intr = hw->ack_intr; | ||
1338 | hwif->config_data = hw->config; | ||
1339 | } | ||
1340 | |||
1276 | static unsigned int ide_indexes; | 1341 | static unsigned int ide_indexes; |
1277 | 1342 | ||
1278 | /** | 1343 | /** |
@@ -1503,6 +1568,76 @@ int ide_host_add(const struct ide_port_info *d, hw_regs_t **hws, | |||
1503 | } | 1568 | } |
1504 | EXPORT_SYMBOL_GPL(ide_host_add); | 1569 | EXPORT_SYMBOL_GPL(ide_host_add); |
1505 | 1570 | ||
1571 | static void __ide_port_unregister_devices(ide_hwif_t *hwif) | ||
1572 | { | ||
1573 | int i; | ||
1574 | |||
1575 | for (i = 0; i < MAX_DRIVES; i++) { | ||
1576 | ide_drive_t *drive = &hwif->drives[i]; | ||
1577 | |||
1578 | if (drive->dev_flags & IDE_DFLAG_PRESENT) { | ||
1579 | device_unregister(&drive->gendev); | ||
1580 | wait_for_completion(&drive->gendev_rel_comp); | ||
1581 | } | ||
1582 | } | ||
1583 | } | ||
1584 | |||
1585 | void ide_port_unregister_devices(ide_hwif_t *hwif) | ||
1586 | { | ||
1587 | mutex_lock(&ide_cfg_mtx); | ||
1588 | __ide_port_unregister_devices(hwif); | ||
1589 | hwif->present = 0; | ||
1590 | ide_port_init_devices_data(hwif); | ||
1591 | mutex_unlock(&ide_cfg_mtx); | ||
1592 | } | ||
1593 | EXPORT_SYMBOL_GPL(ide_port_unregister_devices); | ||
1594 | |||
1595 | /** | ||
1596 | * ide_unregister - free an IDE interface | ||
1597 | * @hwif: IDE interface | ||
1598 | * | ||
1599 | * Perform the final unregister of an IDE interface. | ||
1600 | * | ||
1601 | * Locking: | ||
1602 | * The caller must not hold the IDE locks. | ||
1603 | * | ||
1604 | * It is up to the caller to be sure there is no pending I/O here, | ||
1605 | * and that the interface will not be reopened (present/vanishing | ||
1606 | * locking isn't yet done BTW). | ||
1607 | */ | ||
1608 | |||
1609 | static void ide_unregister(ide_hwif_t *hwif) | ||
1610 | { | ||
1611 | BUG_ON(in_interrupt()); | ||
1612 | BUG_ON(irqs_disabled()); | ||
1613 | |||
1614 | mutex_lock(&ide_cfg_mtx); | ||
1615 | |||
1616 | if (hwif->present) { | ||
1617 | __ide_port_unregister_devices(hwif); | ||
1618 | hwif->present = 0; | ||
1619 | } | ||
1620 | |||
1621 | ide_proc_unregister_port(hwif); | ||
1622 | |||
1623 | free_irq(hwif->irq, hwif); | ||
1624 | |||
1625 | device_unregister(hwif->portdev); | ||
1626 | device_unregister(&hwif->gendev); | ||
1627 | wait_for_completion(&hwif->gendev_rel_comp); | ||
1628 | |||
1629 | /* | ||
1630 | * Remove us from the kernel's knowledge | ||
1631 | */ | ||
1632 | blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS); | ||
1633 | kfree(hwif->sg_table); | ||
1634 | unregister_blkdev(hwif->major, hwif->name); | ||
1635 | |||
1636 | ide_release_dma_engine(hwif); | ||
1637 | |||
1638 | mutex_unlock(&ide_cfg_mtx); | ||
1639 | } | ||
1640 | |||
1506 | void ide_host_free(struct ide_host *host) | 1641 | void ide_host_free(struct ide_host *host) |
1507 | { | 1642 | { |
1508 | ide_hwif_t *hwif; | 1643 | ide_hwif_t *hwif; |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 6538b63158bf..c1bb0f6784a9 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -60,154 +60,8 @@ | |||
60 | #include <linux/completion.h> | 60 | #include <linux/completion.h> |
61 | #include <linux/device.h> | 61 | #include <linux/device.h> |
62 | 62 | ||
63 | |||
64 | /* default maximum number of failures */ | ||
65 | #define IDE_DEFAULT_MAX_FAILURES 1 | ||
66 | |||
67 | struct class *ide_port_class; | 63 | struct class *ide_port_class; |
68 | 64 | ||
69 | static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, | ||
70 | IDE2_MAJOR, IDE3_MAJOR, | ||
71 | IDE4_MAJOR, IDE5_MAJOR, | ||
72 | IDE6_MAJOR, IDE7_MAJOR, | ||
73 | IDE8_MAJOR, IDE9_MAJOR }; | ||
74 | |||
75 | DEFINE_MUTEX(ide_cfg_mtx); | ||
76 | |||
77 | static void ide_port_init_devices_data(ide_hwif_t *); | ||
78 | |||
79 | /* | ||
80 | * Do not even *think* about calling this! | ||
81 | */ | ||
82 | void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) | ||
83 | { | ||
84 | /* bulk initialize hwif & drive info with zeros */ | ||
85 | memset(hwif, 0, sizeof(ide_hwif_t)); | ||
86 | |||
87 | /* fill in any non-zero initial values */ | ||
88 | hwif->index = index; | ||
89 | hwif->major = ide_hwif_to_major[index]; | ||
90 | |||
91 | hwif->name[0] = 'i'; | ||
92 | hwif->name[1] = 'd'; | ||
93 | hwif->name[2] = 'e'; | ||
94 | hwif->name[3] = '0' + index; | ||
95 | |||
96 | init_completion(&hwif->gendev_rel_comp); | ||
97 | |||
98 | hwif->tp_ops = &default_tp_ops; | ||
99 | |||
100 | ide_port_init_devices_data(hwif); | ||
101 | } | ||
102 | |||
103 | static void ide_port_init_devices_data(ide_hwif_t *hwif) | ||
104 | { | ||
105 | int unit; | ||
106 | |||
107 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | ||
108 | ide_drive_t *drive = &hwif->drives[unit]; | ||
109 | u8 j = (hwif->index * MAX_DRIVES) + unit; | ||
110 | |||
111 | memset(drive, 0, sizeof(*drive)); | ||
112 | |||
113 | drive->media = ide_disk; | ||
114 | drive->select = (unit << 4) | ATA_DEVICE_OBS; | ||
115 | drive->hwif = hwif; | ||
116 | drive->ready_stat = ATA_DRDY; | ||
117 | drive->bad_wstat = BAD_W_STAT; | ||
118 | drive->special.b.recalibrate = 1; | ||
119 | drive->special.b.set_geometry = 1; | ||
120 | drive->name[0] = 'h'; | ||
121 | drive->name[1] = 'd'; | ||
122 | drive->name[2] = 'a' + j; | ||
123 | drive->max_failures = IDE_DEFAULT_MAX_FAILURES; | ||
124 | |||
125 | INIT_LIST_HEAD(&drive->list); | ||
126 | init_completion(&drive->gendev_rel_comp); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | static void __ide_port_unregister_devices(ide_hwif_t *hwif) | ||
131 | { | ||
132 | int i; | ||
133 | |||
134 | for (i = 0; i < MAX_DRIVES; i++) { | ||
135 | ide_drive_t *drive = &hwif->drives[i]; | ||
136 | |||
137 | if (drive->dev_flags & IDE_DFLAG_PRESENT) { | ||
138 | device_unregister(&drive->gendev); | ||
139 | wait_for_completion(&drive->gendev_rel_comp); | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||
144 | void ide_port_unregister_devices(ide_hwif_t *hwif) | ||
145 | { | ||
146 | mutex_lock(&ide_cfg_mtx); | ||
147 | __ide_port_unregister_devices(hwif); | ||
148 | hwif->present = 0; | ||
149 | ide_port_init_devices_data(hwif); | ||
150 | mutex_unlock(&ide_cfg_mtx); | ||
151 | } | ||
152 | EXPORT_SYMBOL_GPL(ide_port_unregister_devices); | ||
153 | |||
154 | /** | ||
155 | * ide_unregister - free an IDE interface | ||
156 | * @hwif: IDE interface | ||
157 | * | ||
158 | * Perform the final unregister of an IDE interface. | ||
159 | * | ||
160 | * Locking: | ||
161 | * The caller must not hold the IDE locks. | ||
162 | * | ||
163 | * It is up to the caller to be sure there is no pending I/O here, | ||
164 | * and that the interface will not be reopened (present/vanishing | ||
165 | * locking isn't yet done BTW). | ||
166 | */ | ||
167 | |||
168 | void ide_unregister(ide_hwif_t *hwif) | ||
169 | { | ||
170 | BUG_ON(in_interrupt()); | ||
171 | BUG_ON(irqs_disabled()); | ||
172 | |||
173 | mutex_lock(&ide_cfg_mtx); | ||
174 | |||
175 | if (hwif->present) { | ||
176 | __ide_port_unregister_devices(hwif); | ||
177 | hwif->present = 0; | ||
178 | } | ||
179 | |||
180 | ide_proc_unregister_port(hwif); | ||
181 | |||
182 | free_irq(hwif->irq, hwif); | ||
183 | |||
184 | device_unregister(hwif->portdev); | ||
185 | device_unregister(&hwif->gendev); | ||
186 | wait_for_completion(&hwif->gendev_rel_comp); | ||
187 | |||
188 | /* | ||
189 | * Remove us from the kernel's knowledge | ||
190 | */ | ||
191 | blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS); | ||
192 | kfree(hwif->sg_table); | ||
193 | unregister_blkdev(hwif->major, hwif->name); | ||
194 | |||
195 | ide_release_dma_engine(hwif); | ||
196 | |||
197 | mutex_unlock(&ide_cfg_mtx); | ||
198 | } | ||
199 | |||
200 | void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) | ||
201 | { | ||
202 | memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports)); | ||
203 | hwif->irq = hw->irq; | ||
204 | hwif->chipset = hw->chipset; | ||
205 | hwif->dev = hw->dev; | ||
206 | hwif->gendev.parent = hw->parent ? hw->parent : hw->dev; | ||
207 | hwif->ack_intr = hw->ack_intr; | ||
208 | hwif->config_data = hw->config; | ||
209 | } | ||
210 | |||
211 | /* | 65 | /* |
212 | * Locks for IDE setting functionality | 66 | * Locks for IDE setting functionality |
213 | */ | 67 | */ |
diff --git a/include/linux/ide.h b/include/linux/ide.h index f27f130ba000..ee2f461882ad 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -37,6 +37,7 @@ typedef unsigned char byte; /* used everywhere */ | |||
37 | /* | 37 | /* |
38 | * Probably not wise to fiddle with these | 38 | * Probably not wise to fiddle with these |
39 | */ | 39 | */ |
40 | #define IDE_DEFAULT_MAX_FAILURES 1 | ||
40 | #define ERROR_MAX 8 /* Max read/write errors per sector */ | 41 | #define ERROR_MAX 8 /* Max read/write errors per sector */ |
41 | #define ERROR_RESET 3 /* Reset controller every 4th retry */ | 42 | #define ERROR_RESET 3 /* Reset controller every 4th retry */ |
42 | #define ERROR_RECAL 1 /* Recalibrate every 2nd retry */ | 43 | #define ERROR_RECAL 1 /* Recalibrate every 2nd retry */ |
@@ -184,9 +185,6 @@ typedef struct hw_regs_s { | |||
184 | unsigned long config; | 185 | unsigned long config; |
185 | } hw_regs_t; | 186 | } hw_regs_t; |
186 | 187 | ||
187 | void ide_init_port_data(struct hwif_s *, unsigned int); | ||
188 | void ide_init_port_hw(struct hwif_s *, hw_regs_t *); | ||
189 | |||
190 | static inline void ide_std_init_ports(hw_regs_t *hw, | 188 | static inline void ide_std_init_ports(hw_regs_t *hw, |
191 | unsigned long io_addr, | 189 | unsigned long io_addr, |
192 | unsigned long ctl_addr) | 190 | unsigned long ctl_addr) |
@@ -1506,8 +1504,6 @@ static inline void ide_acpi_port_init_devices(ide_hwif_t *hwif) { ; } | |||
1506 | static inline void ide_acpi_set_state(ide_hwif_t *hwif, int on) {} | 1504 | static inline void ide_acpi_set_state(ide_hwif_t *hwif, int on) {} |
1507 | #endif | 1505 | #endif |
1508 | 1506 | ||
1509 | void ide_unregister(ide_hwif_t *); | ||
1510 | |||
1511 | void ide_register_region(struct gendisk *); | 1507 | void ide_register_region(struct gendisk *); |
1512 | void ide_unregister_region(struct gendisk *); | 1508 | void ide_unregister_region(struct gendisk *); |
1513 | 1509 | ||
@@ -1592,9 +1588,6 @@ static inline void ide_set_max_pio(ide_drive_t *drive) | |||
1592 | ide_set_pio(drive, 255); | 1588 | ide_set_pio(drive, 255); |
1593 | } | 1589 | } |
1594 | 1590 | ||
1595 | extern spinlock_t ide_lock; | ||
1596 | extern struct mutex ide_cfg_mtx; | ||
1597 | |||
1598 | #define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0) | 1591 | #define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0) |
1599 | 1592 | ||
1600 | char *ide_media_string(ide_drive_t *); | 1593 | char *ide_media_string(ide_drive_t *); |