Blame view
drivers/ide/ide-probe.c
37.4 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
59bca8cc9 ide: update/add m... |
2 3 |
* Copyright (C) 1994-1998 Linus Torvalds & authors (see below) * Copyright (C) 2005, 2007 Bartlomiej Zolnierkiewicz |
1da177e4c Linux-2.6.12-rc2 |
4 5 6 7 8 9 10 11 12 13 14 |
*/ /* * Mostly written by Mark Lord <mlord@pobox.com> * and Gadi Oxman <gadio@netvision.net.il> * and Andre Hedrick <andre@linux-ide.org> * * See linux/MAINTAINERS for address of current maintainer. * * This is the IDE probe module, as evolved from hd.c and ide.c. * |
bbe4d6d86 ide: remove stale... |
15 16 |
* -- increase WAIT_PIDENTIFY to avoid CD-ROM locking at boot * by Andrea Arcangeli |
1da177e4c Linux-2.6.12-rc2 |
17 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <linux/module.h> #include <linux/types.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/timer.h> #include <linux/mm.h> #include <linux/interrupt.h> #include <linux/major.h> #include <linux/errno.h> #include <linux/genhd.h> #include <linux/slab.h> #include <linux/delay.h> #include <linux/ide.h> #include <linux/spinlock.h> #include <linux/kmod.h> #include <linux/pci.h> |
dc81785dd ide: build fix |
34 |
#include <linux/scatterlist.h> |
1da177e4c Linux-2.6.12-rc2 |
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
#include <asm/byteorder.h> #include <asm/irq.h> #include <asm/uaccess.h> #include <asm/io.h> /** * generic_id - add a generic drive id * @drive: drive to make an ID block for * * Add a fake id field to the drive we are passed. This allows * use to skip a ton of NULL checks (which people always miss) * and make drive properties unconditional outside of this file */ static void generic_id(ide_drive_t *drive) { |
4dde4492d ide: make drive->... |
52 53 54 55 56 |
u16 *id = drive->id; id[ATA_ID_CUR_CYLS] = id[ATA_ID_CYLS] = drive->cyl; id[ATA_ID_CUR_HEADS] = id[ATA_ID_HEADS] = drive->head; id[ATA_ID_CUR_SECTORS] = id[ATA_ID_SECTORS] = drive->sect; |
1da177e4c Linux-2.6.12-rc2 |
57 58 59 60 |
} static void ide_disk_init_chs(ide_drive_t *drive) { |
4dde4492d ide: make drive->... |
61 |
u16 *id = drive->id; |
1da177e4c Linux-2.6.12-rc2 |
62 63 64 |
/* Extract geometry if we did not already have one for the drive */ if (!drive->cyl || !drive->head || !drive->sect) { |
4dde4492d ide: make drive->... |
65 66 67 |
drive->cyl = drive->bios_cyl = id[ATA_ID_CYLS]; drive->head = drive->bios_head = id[ATA_ID_HEADS]; drive->sect = drive->bios_sect = id[ATA_ID_SECTORS]; |
1da177e4c Linux-2.6.12-rc2 |
68 69 70 |
} /* Handle logical geometry translation by the drive */ |
dd8f46f64 ide: use ata_id_c... |
71 |
if (ata_id_current_chs_valid(id)) { |
4dde4492d ide: make drive->... |
72 73 74 |
drive->cyl = id[ATA_ID_CUR_CYLS]; drive->head = id[ATA_ID_CUR_HEADS]; drive->sect = id[ATA_ID_CUR_SECTORS]; |
1da177e4c Linux-2.6.12-rc2 |
75 76 77 |
} /* Use physical geometry if what we have still makes no sense */ |
4dde4492d ide: make drive->... |
78 79 80 81 |
if (drive->head > 16 && id[ATA_ID_HEADS] && id[ATA_ID_HEADS] <= 16) { drive->cyl = id[ATA_ID_CYLS]; drive->head = id[ATA_ID_HEADS]; drive->sect = id[ATA_ID_SECTORS]; |
1da177e4c Linux-2.6.12-rc2 |
82 83 84 85 86 |
} } static void ide_disk_init_mult_count(ide_drive_t *drive) { |
48fb2688a ide: remove drive... |
87 88 |
u16 *id = drive->id; u8 max_multsect = id[ATA_ID_MAX_MULTSECT] & 0xff; |
1da177e4c Linux-2.6.12-rc2 |
89 |
|
48fb2688a ide: remove drive... |
90 |
if (max_multsect) { |
48fb2688a ide: remove drive... |
91 92 93 94 95 96 |
if ((max_multsect / 2) > 1) id[ATA_ID_MULTSECT] = max_multsect | 0x100; else id[ATA_ID_MULTSECT] &= ~0x1ff; drive->mult_req = id[ATA_ID_MULTSECT] & 0xff; |
7c51c17e0 ide: remove CONFI... |
97 98 |
if (drive->mult_req) |
ca1b96e00 ide: replace spec... |
99 |
drive->special_flags |= IDE_SFLAG_SET_MULTMODE; |
1da177e4c Linux-2.6.12-rc2 |
100 101 |
} } |
24630dc68 ide: factor out d... |
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
static void ide_classify_ata_dev(ide_drive_t *drive) { u16 *id = drive->id; char *m = (char *)&id[ATA_ID_PROD]; int is_cfa = ata_id_is_cfa(id); /* CF devices are *not* removable in Linux definition of the term */ if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7))) drive->dev_flags |= IDE_DFLAG_REMOVABLE; drive->media = ide_disk; if (!ata_id_has_unload(drive->id)) drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; printk(KERN_INFO "%s: %s, %s DISK drive ", drive->name, m, is_cfa ? "CFA" : "ATA"); } static void ide_classify_atapi_dev(ide_drive_t *drive) { u16 *id = drive->id; char *m = (char *)&id[ATA_ID_PROD]; u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f; printk(KERN_INFO "%s: %s, ATAPI ", drive->name, m); switch (type) { case ide_floppy: if (!strstr(m, "CD-ROM")) { if (!strstr(m, "oppy") && !strstr(m, "poyp") && !strstr(m, "ZIP")) printk(KERN_CONT "cdrom or floppy?, assuming "); if (drive->media != ide_cdrom) { printk(KERN_CONT "FLOPPY"); drive->dev_flags |= IDE_DFLAG_REMOVABLE; break; } } /* Early cdrom models used zero */ type = ide_cdrom; case ide_cdrom: drive->dev_flags |= IDE_DFLAG_REMOVABLE; #ifdef CONFIG_PPC /* kludge for Apple PowerBook internal zip */ if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) { printk(KERN_CONT "FLOPPY"); type = ide_floppy; break; } #endif printk(KERN_CONT "CD/DVD-ROM"); break; case ide_tape: printk(KERN_CONT "TAPE"); break; case ide_optical: printk(KERN_CONT "OPTICAL"); drive->dev_flags |= IDE_DFLAG_REMOVABLE; break; default: printk(KERN_CONT "UNKNOWN (type %d)", type); break; } printk(KERN_CONT " drive "); drive->media = type; /* an ATAPI device ignores DRDY */ drive->ready_stat = 0; if (ata_id_cdb_intr(id)) drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; drive->dev_flags |= IDE_DFLAG_DOORLOCKING; /* we don't do head unloading on ATAPI devices */ drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; } |
1da177e4c Linux-2.6.12-rc2 |
179 |
/** |
1da177e4c Linux-2.6.12-rc2 |
180 181 182 |
* do_identify - identify a drive * @drive: drive to identify * @cmd: command used |
2ebe1d9ef ide: use try_to_i... |
183 |
* @id: buffer for IDENTIFY data |
1da177e4c Linux-2.6.12-rc2 |
184 185 186 187 188 |
* * Called when we have issued a drive identify command to * read and parse the results. This function is run with * interrupts disabled. */ |
047140ae2 ide: remove inlin... |
189 |
|
2ebe1d9ef ide: use try_to_i... |
190 |
static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id) |
1da177e4c Linux-2.6.12-rc2 |
191 |
{ |
898ec223f ide: remove HWIF(... |
192 |
ide_hwif_t *hwif = drive->hwif; |
4dde4492d ide: make drive->... |
193 |
char *m = (char *)&id[ATA_ID_PROD]; |
94b9efdf5 ide: push local_i... |
194 |
unsigned long flags; |
24630dc68 ide: factor out d... |
195 |
int bswap = 1; |
1da177e4c Linux-2.6.12-rc2 |
196 |
|
94b9efdf5 ide: push local_i... |
197 198 |
/* local CPU only; some systems need this */ local_irq_save(flags); |
1da177e4c Linux-2.6.12-rc2 |
199 |
/* read 512 bytes of id info */ |
374e042c3 ide: add struct i... |
200 |
hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); |
94b9efdf5 ide: push local_i... |
201 |
local_irq_restore(flags); |
1da177e4c Linux-2.6.12-rc2 |
202 |
|
97100fc81 ide: add device f... |
203 |
drive->dev_flags |= IDE_DFLAG_ID_READ; |
7b9f25b53 ide: add ide_dump... |
204 205 206 207 208 |
#ifdef DEBUG printk(KERN_INFO "%s: dumping identify data ", drive->name); ide_dump_identify((u8 *)id); #endif |
1da177e4c Linux-2.6.12-rc2 |
209 |
ide_fix_driveid(id); |
1da177e4c Linux-2.6.12-rc2 |
210 |
/* |
aaaade3f0 ide: WIN_* -> ATA... |
211 212 |
* ATA_CMD_ID_ATA returns little-endian info, * ATA_CMD_ID_ATAPI *usually* returns little-endian info. |
1da177e4c Linux-2.6.12-rc2 |
213 |
*/ |
aaaade3f0 ide: WIN_* -> ATA... |
214 |
if (cmd == ATA_CMD_ID_ATAPI) { |
4dde4492d ide: make drive->... |
215 216 217 |
if ((m[0] == 'N' && m[1] == 'E') || /* NEC */ (m[0] == 'F' && m[1] == 'X') || /* Mitsumi */ (m[0] == 'P' && m[1] == 'i')) /* Pioneer */ |
1da177e4c Linux-2.6.12-rc2 |
218 |
/* Vertos drives may still be weird */ |
4dde4492d ide: make drive->... |
219 |
bswap ^= 1; |
1da177e4c Linux-2.6.12-rc2 |
220 |
} |
4dde4492d ide: make drive->... |
221 222 223 224 |
ide_fixstring(m, ATA_ID_PROD_LEN, bswap); ide_fixstring((char *)&id[ATA_ID_FW_REV], ATA_ID_FW_REV_LEN, bswap); ide_fixstring((char *)&id[ATA_ID_SERNO], ATA_ID_SERNO_LEN, bswap); |
1da177e4c Linux-2.6.12-rc2 |
225 |
|
699b052ad ide: do_identify(... |
226 |
/* we depend on this a lot! */ |
4dde4492d ide: make drive->... |
227 |
m[ATA_ID_PROD_LEN - 1] = '\0'; |
699b052ad ide: do_identify(... |
228 |
|
4dde4492d ide: make drive->... |
229 |
if (strstr(m, "E X A B Y T E N E S T")) |
69197ad70 ide: fix memleak ... |
230 231 232 |
drive->dev_flags &= ~IDE_DFLAG_PRESENT; else drive->dev_flags |= IDE_DFLAG_PRESENT; |
1da177e4c Linux-2.6.12-rc2 |
233 234 235 |
} /** |
2ebe1d9ef ide: use try_to_i... |
236 |
* ide_dev_read_id - send ATA/ATAPI IDENTIFY command |
1da177e4c Linux-2.6.12-rc2 |
237 238 |
* @drive: drive to identify * @cmd: command to use |
2ebe1d9ef ide: use try_to_i... |
239 |
* @id: buffer for IDENTIFY data |
fa56d4cb4 ide: allow ide_de... |
240 |
* @irq_ctx: flag set when called from the IRQ context |
1da177e4c Linux-2.6.12-rc2 |
241 |
* |
2ebe1d9ef ide: use try_to_i... |
242 |
* Sends an ATA(PI) IDENTIFY request to a drive and waits for a response. |
1da177e4c Linux-2.6.12-rc2 |
243 244 245 246 247 |
* * Returns: 0 device was identified * 1 device timed-out (no response to identify request) * 2 device aborted the command (refused to identify itself) */ |
fa56d4cb4 ide: allow ide_de... |
248 |
int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id, int irq_ctx) |
1da177e4c Linux-2.6.12-rc2 |
249 |
{ |
898ec223f ide: remove HWIF(... |
250 |
ide_hwif_t *hwif = drive->hwif; |
4c3032d8a ide: add struct i... |
251 |
struct ide_io_ports *io_ports = &hwif->io_ports; |
374e042c3 ide: add struct i... |
252 |
const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
c47137a99 ide: add ide_read... |
253 |
int use_altstatus = 0, rc; |
1da177e4c Linux-2.6.12-rc2 |
254 255 |
unsigned long timeout; u8 s = 0, a = 0; |
a182807a8 ide: remove try_t... |
256 257 258 259 260 |
/* * Disable device IRQ. Otherwise we'll get spurious interrupts * during the identify phase that the IRQ handler isn't expecting. */ if (io_ports->ctl_addr) |
ecf3a31d2 ide: turn set_irq... |
261 |
tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS); |
a182807a8 ide: remove try_t... |
262 |
|
1da177e4c Linux-2.6.12-rc2 |
263 |
/* take a deep breath */ |
fa56d4cb4 ide: allow ide_de... |
264 265 266 267 |
if (irq_ctx) mdelay(50); else msleep(50); |
1da177e4c Linux-2.6.12-rc2 |
268 |
|
6636487e8 amd74xx: workarou... |
269 270 |
if (io_ports->ctl_addr && (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) { |
374e042c3 ide: add struct i... |
271 272 |
a = tp_ops->read_altstatus(hwif); s = tp_ops->read_status(hwif); |
3a7d24841 ide: use ATA_* de... |
273 |
if ((a ^ s) & ~ATA_IDX) |
1da177e4c Linux-2.6.12-rc2 |
274 |
/* ancient Seagate drives, broken interfaces */ |
c47137a99 ide: add ide_read... |
275 276 277 278 279 |
printk(KERN_INFO "%s: probing with STATUS(0x%02x) " "instead of ALTSTATUS(0x%02x) ", drive->name, s, a); else |
1da177e4c Linux-2.6.12-rc2 |
280 |
/* use non-intrusive polling */ |
c47137a99 ide: add ide_read... |
281 282 |
use_altstatus = 1; } |
1da177e4c Linux-2.6.12-rc2 |
283 284 285 286 |
/* set features register for atapi * identify command to be sure of reply */ |
aaaade3f0 ide: WIN_* -> ATA... |
287 |
if (cmd == ATA_CMD_ID_ATAPI) { |
c9ff9e7b6 ide: refactor tf_... |
288 |
struct ide_taskfile tf; |
4e65837b2 ide: use ->tf_loa... |
289 |
|
c9ff9e7b6 ide: refactor tf_... |
290 |
memset(&tf, 0, sizeof(tf)); |
4e65837b2 ide: use ->tf_loa... |
291 |
/* disable DMA & overlap */ |
c9ff9e7b6 ide: refactor tf_... |
292 |
tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE); |
4e65837b2 ide: use ->tf_loa... |
293 |
} |
1da177e4c Linux-2.6.12-rc2 |
294 295 |
/* ask drive for ID */ |
374e042c3 ide: add struct i... |
296 |
tp_ops->exec_command(hwif, cmd); |
1da177e4c Linux-2.6.12-rc2 |
297 |
|
aaaade3f0 ide: WIN_* -> ATA... |
298 |
timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; |
b163f46d5 ide: enhance ide_... |
299 |
|
3a7d24841 ide: use ATA_* de... |
300 |
/* wait for IRQ and ATA_DRQ */ |
fa56d4cb4 ide: allow ide_de... |
301 302 303 304 305 306 307 308 309 310 311 312 |
if (irq_ctx) { rc = __ide_wait_stat(drive, ATA_DRQ, BAD_R_STAT, timeout, &s); if (rc) return 1; } else { rc = ide_busy_sleep(drive, timeout, use_altstatus); if (rc) return 1; msleep(50); s = tp_ops->read_status(hwif); } |
c47137a99 ide: add ide_read... |
313 |
|
3a7d24841 ide: use ATA_* de... |
314 |
if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) { |
1da177e4c Linux-2.6.12-rc2 |
315 |
/* drive returned ID */ |
2ebe1d9ef ide: use try_to_i... |
316 |
do_identify(drive, cmd, id); |
1da177e4c Linux-2.6.12-rc2 |
317 318 319 |
/* drive responded with ID */ rc = 0; /* clear drive IRQ */ |
374e042c3 ide: add struct i... |
320 |
(void)tp_ops->read_status(hwif); |
1da177e4c Linux-2.6.12-rc2 |
321 322 323 324 325 326 |
} else { /* drive refused ID */ rc = 2; } return rc; } |
28ee9bc5c ide: report timeo... |
327 |
int ide_busy_sleep(ide_drive_t *drive, unsigned long timeout, int altstatus) |
3a5015cc9 ide: add ide_busy... |
328 |
{ |
28ee9bc5c ide: report timeo... |
329 |
ide_hwif_t *hwif = drive->hwif; |
3a5015cc9 ide: add ide_busy... |
330 |
u8 stat; |
b163f46d5 ide: enhance ide_... |
331 |
timeout += jiffies; |
3a5015cc9 ide: add ide_busy... |
332 |
do { |
b163f46d5 ide: enhance ide_... |
333 334 335 |
msleep(50); /* give drive a breather */ stat = altstatus ? hwif->tp_ops->read_altstatus(hwif) : hwif->tp_ops->read_status(hwif); |
3a7d24841 ide: use ATA_* de... |
336 |
if ((stat & ATA_BUSY) == 0) |
3a5015cc9 ide: add ide_busy... |
337 338 |
return 0; } while (time_before(jiffies, timeout)); |
28ee9bc5c ide: report timeo... |
339 340 |
printk(KERN_ERR "%s: timeout in %s ", drive->name, __func__); |
b163f46d5 ide: enhance ide_... |
341 |
return 1; /* drive timed-out */ |
3a5015cc9 ide: add ide_busy... |
342 |
} |
1da177e4c Linux-2.6.12-rc2 |
343 |
|
1f2efb82a ide: add ide_read... |
344 345 |
static u8 ide_read_device(ide_drive_t *drive) { |
3153c26b5 ide: refactor tf_... |
346 |
struct ide_taskfile tf; |
1f2efb82a ide: add ide_read... |
347 |
|
3153c26b5 ide: refactor tf_... |
348 |
drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_DEVICE); |
1f2efb82a ide: add ide_read... |
349 |
|
3153c26b5 ide: refactor tf_... |
350 |
return tf.device; |
1f2efb82a ide: add ide_read... |
351 |
} |
1da177e4c Linux-2.6.12-rc2 |
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
/** * do_probe - probe an IDE device * @drive: drive to probe * @cmd: command to use * * do_probe() has the difficult job of finding a drive if it exists, * without getting hung up if it doesn't exist, without trampling on * ethernet cards, and without leaving any IRQs dangling to haunt us later. * * If a drive is "known" to exist (from CMOS or kernel parameters), * but does not respond right away, the probe will "hang in there" * for the maximum wait time (about 30 seconds), otherwise it will * exit much more quickly. * * Returns: 0 device was identified * 1 device timed-out (no response to identify request) * 2 device aborted the command (refused to identify itself) * 3 bad status from device (possible for ATAPI drives) * 4 probe was not attempted because failure was obvious */ static int do_probe (ide_drive_t *drive, u8 cmd) { |
898ec223f ide: remove HWIF(... |
375 |
ide_hwif_t *hwif = drive->hwif; |
374e042c3 ide: add struct i... |
376 |
const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
2ebe1d9ef ide: use try_to_i... |
377 |
u16 *id = drive->id; |
57b552757 ide-probe: remove... |
378 |
int rc; |
97100fc81 ide: add device f... |
379 380 381 382 383 |
u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat; /* avoid waiting for inappropriate probes */ if (present && drive->media != ide_disk && cmd == ATA_CMD_ID_ATA) return 4; |
1da177e4c Linux-2.6.12-rc2 |
384 |
|
1da177e4c Linux-2.6.12-rc2 |
385 |
#ifdef DEBUG |
1b8ebad87 ide: use proper p... |
386 387 |
printk(KERN_INFO "probing for %s: present=%d, media=%d, probetype=%s ", |
97100fc81 ide: add device f... |
388 |
drive->name, present, drive->media, |
aaaade3f0 ide: WIN_* -> ATA... |
389 |
(cmd == ATA_CMD_ID_ATA) ? "ATA" : "ATAPI"); |
1da177e4c Linux-2.6.12-rc2 |
390 391 392 393 394 395 |
#endif /* needed for some systems * (e.g. crw9624 as drive0 with disk as slave) */ msleep(50); |
fdd88f0af ide: inline SELEC... |
396 |
tp_ops->dev_select(drive); |
1da177e4c Linux-2.6.12-rc2 |
397 |
msleep(50); |
1f2efb82a ide: add ide_read... |
398 |
|
7f612f272 ide: remove [ata_... |
399 |
if (ide_read_device(drive) != drive->select && present == 0) { |
123995b97 ide: use 'drive->... |
400 |
if (drive->dn & 1) { |
1da177e4c Linux-2.6.12-rc2 |
401 |
/* exit with drive0 selected */ |
fdd88f0af ide: inline SELEC... |
402 |
tp_ops->dev_select(hwif->devices[0]); |
3a7d24841 ide: use ATA_* de... |
403 |
/* allow ATA_BUSY to assert & clear */ |
1da177e4c Linux-2.6.12-rc2 |
404 405 406 407 408 |
msleep(50); } /* no i/f present: mmm.. this should be a 4 -ml */ return 3; } |
374e042c3 ide: add struct i... |
409 |
stat = tp_ops->read_status(hwif); |
c47137a99 ide: add ide_read... |
410 |
|
3a7d24841 ide: use ATA_* de... |
411 |
if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) || |
97100fc81 ide: add device f... |
412 |
present || cmd == ATA_CMD_ID_ATAPI) { |
fa56d4cb4 ide: allow ide_de... |
413 |
rc = ide_dev_read_id(drive, cmd, id, 0); |
2ebe1d9ef ide: use try_to_i... |
414 |
if (rc) |
1da177e4c Linux-2.6.12-rc2 |
415 |
/* failed: try again */ |
fa56d4cb4 ide: allow ide_de... |
416 |
rc = ide_dev_read_id(drive, cmd, id, 0); |
57b552757 ide-probe: remove... |
417 |
|
374e042c3 ide: add struct i... |
418 |
stat = tp_ops->read_status(hwif); |
57b552757 ide-probe: remove... |
419 |
|
3a7d24841 ide: use ATA_* de... |
420 |
if (stat == (ATA_BUSY | ATA_DRDY)) |
1da177e4c Linux-2.6.12-rc2 |
421 |
return 4; |
aaaade3f0 ide: WIN_* -> ATA... |
422 |
if (rc == 1 && cmd == ATA_CMD_ID_ATAPI) { |
57b552757 ide-probe: remove... |
423 424 425 |
printk(KERN_ERR "%s: no response (status = 0x%02x), " "resetting drive ", drive->name, stat); |
1da177e4c Linux-2.6.12-rc2 |
426 |
msleep(50); |
fdd88f0af ide: inline SELEC... |
427 |
tp_ops->dev_select(drive); |
1da177e4c Linux-2.6.12-rc2 |
428 |
msleep(50); |
aaaade3f0 ide: WIN_* -> ATA... |
429 |
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); |
28ee9bc5c ide: report timeo... |
430 |
(void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0); |
fa56d4cb4 ide: allow ide_de... |
431 |
rc = ide_dev_read_id(drive, cmd, id, 0); |
1da177e4c Linux-2.6.12-rc2 |
432 |
} |
57b552757 ide-probe: remove... |
433 434 |
/* ensure drive IRQ is clear */ |
374e042c3 ide: add struct i... |
435 |
stat = tp_ops->read_status(hwif); |
57b552757 ide-probe: remove... |
436 |
|
1da177e4c Linux-2.6.12-rc2 |
437 |
if (rc == 1) |
57b552757 ide-probe: remove... |
438 439 440 |
printk(KERN_ERR "%s: no response (status = 0x%02x) ", drive->name, stat); |
1da177e4c Linux-2.6.12-rc2 |
441 442 443 444 |
} else { /* not present or maybe ATAPI */ rc = 3; } |
123995b97 ide: use 'drive->... |
445 |
if (drive->dn & 1) { |
1da177e4c Linux-2.6.12-rc2 |
446 |
/* exit with drive0 selected */ |
fdd88f0af ide: inline SELEC... |
447 |
tp_ops->dev_select(hwif->devices[0]); |
1da177e4c Linux-2.6.12-rc2 |
448 449 |
msleep(50); /* ensure drive irq is clear */ |
374e042c3 ide: add struct i... |
450 |
(void)tp_ops->read_status(hwif); |
1da177e4c Linux-2.6.12-rc2 |
451 452 453 |
} return rc; } |
1da177e4c Linux-2.6.12-rc2 |
454 455 456 457 458 459 460 461 |
/** * probe_for_drives - upper level drive probe * @drive: drive to probe for * * probe_for_drive() tests for existence of a given drive using do_probe() * and presents things to the user as needed. * * Returns: 0 no device was found |
97100fc81 ide: add device f... |
462 463 |
* 1 device was found * (note: IDE_DFLAG_PRESENT might still be not set) |
1da177e4c Linux-2.6.12-rc2 |
464 |
*/ |
047140ae2 ide: remove inlin... |
465 466 |
static u8 probe_for_drive(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
467 |
{ |
4dde4492d ide: make drive->... |
468 |
char *m; |
1bd4c1f4f ide: classify dev... |
469 470 |
int rc; u8 cmd; |
4dde4492d ide: make drive->... |
471 |
|
97100fc81 ide: add device f... |
472 |
drive->dev_flags &= ~IDE_DFLAG_ID_READ; |
4dde4492d ide: make drive->... |
473 474 |
m = (char *)&drive->id[ATA_ID_PROD]; strcpy(m, "UNKNOWN"); |
1da177e4c Linux-2.6.12-rc2 |
475 |
/* skip probing? */ |
97100fc81 ide: add device f... |
476 |
if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) { |
1da177e4c Linux-2.6.12-rc2 |
477 |
/* if !(success||timed-out) */ |
1bd4c1f4f ide: classify dev... |
478 479 480 |
cmd = ATA_CMD_ID_ATA; rc = do_probe(drive, cmd); if (rc >= 2) { |
1da177e4c Linux-2.6.12-rc2 |
481 |
/* look for ATAPI device */ |
1bd4c1f4f ide: classify dev... |
482 483 484 |
cmd = ATA_CMD_ID_ATAPI; rc = do_probe(drive, cmd); } |
c36a7e988 ide: fix EXABYTEN... |
485 |
|
97100fc81 ide: add device f... |
486 |
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) |
5f4417a15 ide: fix PowerMac... |
487 |
return 0; |
4dde4492d ide: make drive->... |
488 |
|
1da177e4c Linux-2.6.12-rc2 |
489 |
/* identification failed? */ |
97100fc81 ide: add device f... |
490 |
if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { |
1da177e4c Linux-2.6.12-rc2 |
491 492 493 494 495 496 497 498 499 500 501 502 |
if (drive->media == ide_disk) { printk(KERN_INFO "%s: non-IDE drive, CHS=%d/%d/%d ", drive->name, drive->cyl, drive->head, drive->sect); } else if (drive->media == ide_cdrom) { printk(KERN_INFO "%s: ATAPI cdrom (?) ", drive->name); } else { /* nuke it */ printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring. ", drive->name); |
97100fc81 ide: add device f... |
503 |
drive->dev_flags &= ~IDE_DFLAG_PRESENT; |
1da177e4c Linux-2.6.12-rc2 |
504 |
} |
1bd4c1f4f ide: classify dev... |
505 506 507 508 509 |
} else { if (cmd == ATA_CMD_ID_ATAPI) ide_classify_atapi_dev(drive); else ide_classify_ata_dev(drive); |
1da177e4c Linux-2.6.12-rc2 |
510 |
} |
1da177e4c Linux-2.6.12-rc2 |
511 |
} |
97100fc81 ide: add device f... |
512 513 |
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) |
5f4417a15 ide: fix PowerMac... |
514 |
return 0; |
97100fc81 ide: add device f... |
515 |
|
1da177e4c Linux-2.6.12-rc2 |
516 |
/* The drive wasn't being helpful. Add generic info only */ |
97100fc81 ide: add device f... |
517 |
if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { |
1da177e4c Linux-2.6.12-rc2 |
518 519 520 521 522 523 524 525 |
generic_id(drive); return 1; } if (drive->media == ide_disk) { ide_disk_init_chs(drive); ide_disk_init_mult_count(drive); } |
69197ad70 ide: fix memleak ... |
526 |
return 1; |
1da177e4c Linux-2.6.12-rc2 |
527 |
} |
fc410698e ide: small whites... |
528 |
static void hwif_release_dev(struct device *dev) |
1da177e4c Linux-2.6.12-rc2 |
529 530 |
{ ide_hwif_t *hwif = container_of(dev, ide_hwif_t, gendev); |
f36d4024c [PATCH] mutex sub... |
531 |
complete(&hwif->gendev_rel_comp); |
1da177e4c Linux-2.6.12-rc2 |
532 |
} |
f74c91413 ide: add warm-plu... |
533 |
static int ide_register_port(ide_hwif_t *hwif) |
1da177e4c Linux-2.6.12-rc2 |
534 |
{ |
349ae23fe [PATCH] IDE core:... |
535 |
int ret; |
1da177e4c Linux-2.6.12-rc2 |
536 |
/* register with global device tree */ |
dc09c7842 ide: struct devic... |
537 |
dev_set_name(&hwif->gendev, hwif->name); |
fcb520772 ide: remove drive... |
538 |
dev_set_drvdata(&hwif->gendev, hwif); |
bb54affa6 ide: fix IDE PMAC... |
539 540 |
if (hwif->gendev.parent == NULL) hwif->gendev.parent = hwif->dev; |
1da177e4c Linux-2.6.12-rc2 |
541 |
hwif->gendev.release = hwif_release_dev; |
96d409412 ide: small ide_re... |
542 |
|
349ae23fe [PATCH] IDE core:... |
543 |
ret = device_register(&hwif->gendev); |
f74c91413 ide: add warm-plu... |
544 |
if (ret < 0) { |
349ae23fe [PATCH] IDE core:... |
545 546 |
printk(KERN_WARNING "IDE: %s: device_register error: %d ", |
eb63963a5 ide: replace rema... |
547 |
__func__, ret); |
f74c91413 ide: add warm-plu... |
548 549 |
goto out; } |
3ee074bf4 device create: id... |
550 551 |
hwif->portdev = device_create(ide_port_class, &hwif->gendev, MKDEV(0, 0), hwif, hwif->name); |
f74c91413 ide: add warm-plu... |
552 553 554 555 |
if (IS_ERR(hwif->portdev)) { ret = PTR_ERR(hwif->portdev); device_unregister(&hwif->gendev); } |
f74c91413 ide: add warm-plu... |
556 557 |
out: return ret; |
1da177e4c Linux-2.6.12-rc2 |
558 |
} |
c860a8f2d ide: move wait_hw... |
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 |
/** * ide_port_wait_ready - wait for port to become ready * @hwif: IDE port * * This is needed on some PPCs and a bunch of BIOS-less embedded * platforms. Typical cases are: * * - The firmware hard reset the disk before booting the kernel, * the drive is still doing it's poweron-reset sequence, that * can take up to 30 seconds. * * - The firmware does nothing (or no firmware), the device is * still in POST state (same as above actually). * * - Some CD/DVD/Writer combo drives tend to drive the bus during * their reset sequence even when they are non-selected slave * devices, thus preventing discovery of the main HD. * * Doing this wait-for-non-busy should not harm any existing * configuration and fix some issues like the above. * * BenH. * * Returns 0 on success, error code (< 0) otherwise. */ static int ide_port_wait_ready(ide_hwif_t *hwif) |
1da177e4c Linux-2.6.12-rc2 |
586 |
{ |
fdd88f0af ide: inline SELEC... |
587 |
const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
2bd24a1cf ide: add port and... |
588 589 |
ide_drive_t *drive; int i, rc; |
1da177e4c Linux-2.6.12-rc2 |
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 |
printk(KERN_DEBUG "Probing IDE interface %s... ", hwif->name); /* Let HW settle down a bit from whatever init state we * come from */ mdelay(2); /* Wait for BSY bit to go away, spec timeout is 30 seconds, * I know of at least one disk who takes 31 seconds, I use 35 * here to be safe */ rc = ide_wait_not_busy(hwif, 35000); if (rc) return rc; /* Now make sure both master & slave are ready */ |
2bd24a1cf ide: add port and... |
607 |
ide_port_for_each_dev(i, drive, hwif) { |
8266105b1 ide: skip ide_wai... |
608 |
/* Ignore disks that we will not probe for later. */ |
97100fc81 ide: add device f... |
609 610 |
if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 || (drive->dev_flags & IDE_DFLAG_PRESENT)) { |
fdd88f0af ide: inline SELEC... |
611 612 |
tp_ops->dev_select(drive); tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); |
8266105b1 ide: skip ide_wai... |
613 614 615 616 617 618 619 620 621 622 |
mdelay(2); rc = ide_wait_not_busy(hwif, 35000); if (rc) goto out; } else printk(KERN_DEBUG "%s: ide_wait_not_busy() skipped ", drive->name); } out: |
1da177e4c Linux-2.6.12-rc2 |
623 |
/* Exit function with master reselected (let's be sane) */ |
2bd24a1cf ide: add port and... |
624 |
if (i) |
fdd88f0af ide: inline SELEC... |
625 |
tp_ops->dev_select(hwif->devices[0]); |
8266105b1 ide: skip ide_wai... |
626 |
|
1da177e4c Linux-2.6.12-rc2 |
627 628 629 630 631 |
return rc; } /** * ide_undecoded_slave - look for bad CF adapters |
4dde4492d ide: make drive->... |
632 |
* @dev1: slave device |
1da177e4c Linux-2.6.12-rc2 |
633 634 635 636 637 |
* * Analyse the drives on the interface and attempt to decide if we * have the same drive viewed twice. This occurs with crap CF adapters * and PCMCIA sometimes. */ |
4dde4492d ide: make drive->... |
638 |
void ide_undecoded_slave(ide_drive_t *dev1) |
1da177e4c Linux-2.6.12-rc2 |
639 |
{ |
5e7f3a466 ide: dynamic allo... |
640 |
ide_drive_t *dev0 = dev1->hwif->devices[0]; |
1da177e4c Linux-2.6.12-rc2 |
641 |
|
97100fc81 ide: add device f... |
642 |
if ((dev1->dn & 1) == 0 || (dev0->dev_flags & IDE_DFLAG_PRESENT) == 0) |
1da177e4c Linux-2.6.12-rc2 |
643 644 645 |
return; /* If the models don't match they are not the same product */ |
4dde4492d ide: make drive->... |
646 647 |
if (strcmp((char *)&dev0->id[ATA_ID_PROD], (char *)&dev1->id[ATA_ID_PROD])) |
1da177e4c Linux-2.6.12-rc2 |
648 649 650 |
return; /* Serial numbers do not match */ |
4dde4492d ide: make drive->... |
651 652 |
if (strncmp((char *)&dev0->id[ATA_ID_SERNO], (char *)&dev1->id[ATA_ID_SERNO], ATA_ID_SERNO_LEN)) |
1da177e4c Linux-2.6.12-rc2 |
653 654 655 |
return; /* No serial number, thankfully very rare for CF */ |
4dde4492d ide: make drive->... |
656 |
if (*(char *)&dev0->id[ATA_ID_SERNO] == 0) |
1da177e4c Linux-2.6.12-rc2 |
657 658 659 660 661 |
return; /* Appears to be an IDE flash adapter with decode bugs */ printk(KERN_WARNING "ide-probe: ignoring undecoded slave "); |
97100fc81 ide: add device f... |
662 |
dev1->dev_flags &= ~IDE_DFLAG_PRESENT; |
1da177e4c Linux-2.6.12-rc2 |
663 664 665 |
} EXPORT_SYMBOL_GPL(ide_undecoded_slave); |
9d501529b ide: make probe_h... |
666 |
static int ide_probe_port(ide_hwif_t *hwif) |
1da177e4c Linux-2.6.12-rc2 |
667 |
{ |
2bd24a1cf ide: add port and... |
668 |
ide_drive_t *drive; |
1da177e4c Linux-2.6.12-rc2 |
669 |
unsigned int irqd; |
2bd24a1cf ide: add port and... |
670 |
int i, rc = -ENODEV; |
a14dc5749 ide: move hwif_re... |
671 672 |
BUG_ON(hwif->present); |
1da177e4c Linux-2.6.12-rc2 |
673 |
|
5e7f3a466 ide: dynamic allo... |
674 675 |
if ((hwif->devices[0]->dev_flags & IDE_DFLAG_NOPROBE) && (hwif->devices[1]->dev_flags & IDE_DFLAG_NOPROBE)) |
9d501529b ide: make probe_h... |
676 |
return -EACCES; |
1da177e4c Linux-2.6.12-rc2 |
677 |
|
1da177e4c Linux-2.6.12-rc2 |
678 679 680 681 682 683 684 |
/* * We must always disable IRQ, as probe_for_drive will assert IRQ, but * we'll install our IRQ driver much later... */ irqd = hwif->irq; if (irqd) disable_irq(hwif->irq); |
9ce41aed0 Revert "ide: skip... |
685 686 687 |
if (ide_port_wait_ready(hwif) == -EBUSY) printk(KERN_DEBUG "%s: Wait for ready failed before probe ! ", hwif->name); |
1da177e4c Linux-2.6.12-rc2 |
688 689 |
/* |
f367bed00 Revert "ide: chan... |
690 691 |
* Second drive should only exist if first drive was found, * but a lot of cdrom drives are configured as single slaves. |
1da177e4c Linux-2.6.12-rc2 |
692 |
*/ |
2bd24a1cf ide: add port and... |
693 |
ide_port_for_each_dev(i, drive, hwif) { |
1da177e4c Linux-2.6.12-rc2 |
694 |
(void) probe_for_drive(drive); |
97100fc81 ide: add device f... |
695 |
if (drive->dev_flags & IDE_DFLAG_PRESENT) |
a14dc5749 ide: move hwif_re... |
696 |
rc = 0; |
1da177e4c Linux-2.6.12-rc2 |
697 |
} |
9ce41aed0 Revert "ide: skip... |
698 |
|
1da177e4c Linux-2.6.12-rc2 |
699 700 701 702 703 704 |
/* * Use cached IRQ number. It might be (and is...) changed by probe * code above */ if (irqd) enable_irq(irqd); |
a14dc5749 ide: move hwif_re... |
705 |
return rc; |
e84e7ea7c ide: factor out c... |
706 707 708 709 |
} static void ide_port_tune_devices(ide_hwif_t *hwif) { |
ac95beedf ide: add struct i... |
710 |
const struct ide_port_ops *port_ops = hwif->port_ops; |
2bd24a1cf ide: add port and... |
711 712 |
ide_drive_t *drive; int i; |
f01393e48 ide: merge ->fixu... |
713 |
|
7ed5b157d ide: add ide_for_... |
714 |
ide_port_for_each_present_dev(i, drive, hwif) { |
8bc1e5aa0 ide: respect quir... |
715 |
ide_check_nien_quirk_list(drive); |
7ed5b157d ide: add ide_for_... |
716 717 |
if (port_ops && port_ops->quirkproc) port_ops->quirkproc(drive); |
f01393e48 ide: merge ->fixu... |
718 |
} |
0380dad45 it821x: RAID mode... |
719 |
|
7ed5b157d ide: add ide_for_... |
720 721 |
ide_port_for_each_present_dev(i, drive, hwif) { ide_set_max_pio(drive); |
1da177e4c Linux-2.6.12-rc2 |
722 |
|
7ed5b157d ide: add ide_for_... |
723 |
drive->dev_flags |= IDE_DFLAG_NICE1; |
1da177e4c Linux-2.6.12-rc2 |
724 |
|
7ed5b157d ide: add ide_for_... |
725 726 |
if (hwif->dma_ops) ide_set_dma(drive); |
1da177e4c Linux-2.6.12-rc2 |
727 728 |
} } |
1da177e4c Linux-2.6.12-rc2 |
729 |
/* |
1da177e4c Linux-2.6.12-rc2 |
730 731 732 733 |
* init request queue */ static int ide_init_queue(ide_drive_t *drive) { |
165125e1e [BLOCK] Get rid o... |
734 |
struct request_queue *q; |
898ec223f ide: remove HWIF(... |
735 |
ide_hwif_t *hwif = drive->hwif; |
1da177e4c Linux-2.6.12-rc2 |
736 737 738 739 740 741 742 743 744 745 |
int max_sectors = 256; int max_sg_entries = PRD_ENTRIES; /* * Our default set up assumes the normal IDE case, * that is 64K segmenting, standard PRD setup * and LBA28. Some drivers then impose their own * limits and LBA48 we could raise it but as yet * do not. */ |
1946089a1 [PATCH] NUMA awar... |
746 |
|
201bffa46 ide: use per-devi... |
747 |
q = blk_init_queue_node(do_ide_request, NULL, hwif_to_node(hwif)); |
1da177e4c Linux-2.6.12-rc2 |
748 749 750 751 752 |
if (!q) return 1; q->queuedata = drive; blk_queue_segment_boundary(q, 0xffff); |
1da177e4c Linux-2.6.12-rc2 |
753 754 |
if (hwif->rqsize < max_sectors) max_sectors = hwif->rqsize; |
086fa5ff0 block: Rename blk... |
755 |
blk_queue_max_hw_sectors(q, max_sectors); |
1da177e4c Linux-2.6.12-rc2 |
756 757 758 759 760 761 762 763 764 765 766 767 768 769 |
#ifdef CONFIG_PCI /* When we have an IOMMU, we may have a problem where pci_map_sg() * creates segments that don't completely match our boundary * requirements and thus need to be broken up again. Because it * doesn't align properly either, we may actually have to break up * to more segments than what was we got in the first place, a max * worst case is twice as many. * This will be fixed once we teach pci_map_sg() about our boundary * requirements, hopefully soon. *FIXME* */ if (!PCI_DMA_BUS_IS_PHYS) max_sg_entries >>= 1; #endif /* CONFIG_PCI */ |
8a78362c4 block: Consolidat... |
770 |
blk_queue_max_segments(q, max_sg_entries); |
1da177e4c Linux-2.6.12-rc2 |
771 772 773 774 775 776 |
/* assign drive queue */ drive->queue = q; /* needs drive->queue to be set */ ide_toggle_bounce(drive, 1); |
1da177e4c Linux-2.6.12-rc2 |
777 778 |
return 0; } |
b40d1b88f ide: move ide_ini... |
779 |
static DEFINE_MUTEX(ide_cfg_mtx); |
1da177e4c Linux-2.6.12-rc2 |
780 |
/* |
d5bc6592d ide: factor out d... |
781 782 |
* For any present drive: * - allocate the block device queue |
d5bc6592d ide: factor out d... |
783 |
*/ |
e415e495f ide: Two fixes re... |
784 |
static int ide_port_setup_devices(ide_hwif_t *hwif) |
d5bc6592d ide: factor out d... |
785 |
{ |
2bd24a1cf ide: add port and... |
786 |
ide_drive_t *drive; |
e415e495f ide: Two fixes re... |
787 |
int i, j = 0; |
d5bc6592d ide: factor out d... |
788 |
|
26042d058 ide: move ide_por... |
789 |
mutex_lock(&ide_cfg_mtx); |
7ed5b157d ide: add ide_for_... |
790 |
ide_port_for_each_present_dev(i, drive, hwif) { |
d5bc6592d ide: factor out d... |
791 792 793 794 |
if (ide_init_queue(drive)) { printk(KERN_ERR "ide: failed to init %s ", drive->name); |
e415e495f ide: Two fixes re... |
795 |
drive->dev_flags &= ~IDE_DFLAG_PRESENT; |
d5bc6592d ide: factor out d... |
796 797 |
continue; } |
e415e495f ide: Two fixes re... |
798 |
j++; |
d5bc6592d ide: factor out d... |
799 |
} |
26042d058 ide: move ide_por... |
800 |
mutex_unlock(&ide_cfg_mtx); |
e415e495f ide: Two fixes re... |
801 802 |
return j; |
d5bc6592d ide: factor out d... |
803 |
} |
ffc36c761 ide: fix handling... |
804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 |
static void ide_host_enable_irqs(struct ide_host *host) { ide_hwif_t *hwif; int i; ide_host_for_each_port(i, hwif, host) { if (hwif == NULL) continue; /* clear any pending IRQs */ hwif->tp_ops->read_status(hwif); /* unmask IRQs */ if (hwif->io_ports.ctl_addr) hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); } } |
d5bc6592d ide: factor out d... |
821 |
/* |
b65fac32c ide: merge ide_hw... |
822 |
* This routine sets up the IRQ for an IDE interface. |
1da177e4c Linux-2.6.12-rc2 |
823 824 825 |
*/ static int init_irq (ide_hwif_t *hwif) { |
4c3032d8a ide: add struct i... |
826 |
struct ide_io_ports *io_ports = &hwif->io_ports; |
255115fb3 ide: allow host d... |
827 828 829 |
struct ide_host *host = hwif->host; irq_handler_t irq_handler = host->irq_handler; int sa = host->irq_flags; |
1da177e4c Linux-2.6.12-rc2 |
830 |
|
849d71300 ide: allow to wra... |
831 832 |
if (irq_handler == NULL) irq_handler = ide_intr; |
849d71300 ide: allow to wra... |
833 |
if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif)) |
b65fac32c ide: merge ide_hw... |
834 |
goto out_up; |
1da177e4c Linux-2.6.12-rc2 |
835 |
|
7b892806b cleanup after APU... |
836 |
#if !defined(__mc68000__) |
1b8ebad87 ide: use proper p... |
837 |
printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name, |
4c3032d8a ide: add struct i... |
838 839 |
io_ports->data_addr, io_ports->status_addr, io_ports->ctl_addr, hwif->irq); |
1da177e4c Linux-2.6.12-rc2 |
840 |
#else |
1b8ebad87 ide: use proper p... |
841 |
printk(KERN_INFO "%s at 0x%08lx on irq %d", hwif->name, |
4c3032d8a ide: add struct i... |
842 |
io_ports->data_addr, hwif->irq); |
7b892806b cleanup after APU... |
843 |
#endif /* __mc68000__ */ |
b65fac32c ide: merge ide_hw... |
844 845 |
if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) printk(KERN_CONT " (serialized)"); |
1b8ebad87 ide: use proper p... |
846 847 |
printk(KERN_CONT " "); |
d5bc6592d ide: factor out d... |
848 |
|
1da177e4c Linux-2.6.12-rc2 |
849 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
850 |
out_up: |
1da177e4c Linux-2.6.12-rc2 |
851 852 853 854 855 856 857 858 859 860 861 862 863 |
return 1; } static int ata_lock(dev_t dev, void *data) { /* FIXME: we want to pin hwif down */ return 0; } static struct kobject *ata_probe(dev_t dev, int *part, void *data) { ide_hwif_t *hwif = data; int unit = *part >> PARTN_BITS; |
5e7f3a466 ide: dynamic allo... |
864 |
ide_drive_t *drive = hwif->devices[unit]; |
97100fc81 ide: add device f... |
865 866 |
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) |
1da177e4c Linux-2.6.12-rc2 |
867 868 869 870 |
return NULL; if (drive->media == ide_disk) request_module("ide-disk"); |
1da177e4c Linux-2.6.12-rc2 |
871 872 873 874 875 876 877 878 879 880 881 882 883 884 |
if (drive->media == ide_cdrom || drive->media == ide_optical) request_module("ide-cd"); if (drive->media == ide_tape) request_module("ide-tape"); if (drive->media == ide_floppy) request_module("ide-floppy"); return NULL; } static struct kobject *exact_match(dev_t dev, int *part, void *data) { struct gendisk *p = data; *part &= (1 << PARTN_BITS) - 1; |
ed9e19823 block: implement ... |
885 |
return &disk_to_dev(p)->kobj; |
1da177e4c Linux-2.6.12-rc2 |
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 |
} static int exact_lock(dev_t dev, void *data) { struct gendisk *p = data; if (!get_disk(p)) return -1; return 0; } void ide_register_region(struct gendisk *disk) { blk_register_region(MKDEV(disk->major, disk->first_minor), disk->minors, NULL, exact_match, exact_lock, disk); } EXPORT_SYMBOL_GPL(ide_register_region); void ide_unregister_region(struct gendisk *disk) { blk_unregister_region(MKDEV(disk->major, disk->first_minor), disk->minors); } EXPORT_SYMBOL_GPL(ide_unregister_region); void ide_init_disk(struct gendisk *disk, ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; |
7f612f272 ide: remove [ata_... |
916 |
unsigned int unit = drive->dn & 1; |
1da177e4c Linux-2.6.12-rc2 |
917 918 919 920 921 922 923 924 925 926 927 928 |
disk->major = hwif->major; disk->first_minor = unit << PARTN_BITS; sprintf(disk->disk_name, "hd%c", 'a' + hwif->index * MAX_DRIVES + unit); disk->queue = drive->queue; } EXPORT_SYMBOL_GPL(ide_init_disk); static void drive_release_dev (struct device *dev) { ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); |
5b0c4b30a ide: remove IDE d... |
929 |
ide_proc_unregister_device(drive); |
b5479167f ide: fix locking ... |
930 931 |
blk_cleanup_queue(drive->queue); drive->queue = NULL; |
97100fc81 ide: add device f... |
932 |
drive->dev_flags &= ~IDE_DFLAG_PRESENT; |
8604affde [PATCH] convert I... |
933 |
|
f36d4024c [PATCH] mutex sub... |
934 |
complete(&drive->gendev_rel_comp); |
1da177e4c Linux-2.6.12-rc2 |
935 |
} |
1da177e4c Linux-2.6.12-rc2 |
936 937 |
static int hwif_init(ide_hwif_t *hwif) { |
1da177e4c Linux-2.6.12-rc2 |
938 |
if (!hwif->irq) { |
8b07ed26f ide: remove no lo... |
939 940 941 |
printk(KERN_ERR "%s: disabled, no IRQ ", hwif->name); return 0; |
1da177e4c Linux-2.6.12-rc2 |
942 |
} |
1da177e4c Linux-2.6.12-rc2 |
943 |
|
1da177e4c Linux-2.6.12-rc2 |
944 945 946 947 948 |
if (register_blkdev(hwif->major, hwif->name)) return 0; if (!hwif->sg_max_nents) hwif->sg_max_nents = PRD_ENTRIES; |
45711f1af [SG] Update drive... |
949 |
hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents, |
1da177e4c Linux-2.6.12-rc2 |
950 951 952 953 954 955 |
GFP_KERNEL); if (!hwif->sg_table) { printk(KERN_ERR "%s: unable to allocate SG table. ", hwif->name); goto out; } |
45711f1af [SG] Update drive... |
956 957 |
sg_init_table(hwif->sg_table, hwif->sg_max_nents); |
1da177e4c Linux-2.6.12-rc2 |
958 |
|
1da177e4c Linux-2.6.12-rc2 |
959 |
if (init_irq(hwif)) { |
8b07ed26f ide: remove no lo... |
960 961 962 |
printk(KERN_ERR "%s: disabled, unable to get IRQ %d ", hwif->name, hwif->irq); |
1da177e4c Linux-2.6.12-rc2 |
963 964 |
goto out; } |
1da177e4c Linux-2.6.12-rc2 |
965 |
|
3a4e7c96d ide: move blk_reg... |
966 967 |
blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS, THIS_MODULE, ata_probe, ata_lock, hwif); |
1da177e4c Linux-2.6.12-rc2 |
968 969 970 971 972 973 |
return 1; out: unregister_blkdev(hwif->major, hwif->name); return 0; } |
9601a607c ide: add hwif_reg... |
974 975 |
static void hwif_register_devices(ide_hwif_t *hwif) { |
2bd24a1cf ide: add port and... |
976 |
ide_drive_t *drive; |
9601a607c ide: add hwif_reg... |
977 |
unsigned int i; |
7ed5b157d ide: add ide_for_... |
978 |
ide_port_for_each_present_dev(i, drive, hwif) { |
c5d70cc73 ide: merge init_g... |
979 980 |
struct device *dev = &drive->gendev; int ret; |
9601a607c ide: add hwif_reg... |
981 |
|
dc09c7842 ide: struct devic... |
982 |
dev_set_name(dev, "%u.%u", hwif->index, i); |
fcb520772 ide: remove drive... |
983 |
dev_set_drvdata(dev, drive); |
c5d70cc73 ide: merge init_g... |
984 985 |
dev->parent = &hwif->gendev; dev->bus = &ide_bus_type; |
c5d70cc73 ide: merge init_g... |
986 987 988 989 990 991 992 |
dev->release = drive_release_dev; ret = device_register(dev); if (ret < 0) printk(KERN_WARNING "IDE: %s: device_register error: " "%d ", __func__, ret); |
9601a607c ide: add hwif_reg... |
993 994 |
} } |
7704ca2a3 ide: factor out c... |
995 996 |
static void ide_port_init_devices(ide_hwif_t *hwif) { |
ac95beedf ide: add struct i... |
997 |
const struct ide_port_ops *port_ops = hwif->port_ops; |
2bd24a1cf ide: add port and... |
998 |
ide_drive_t *drive; |
7704ca2a3 ide: factor out c... |
999 |
int i; |
2bd24a1cf ide: add port and... |
1000 |
ide_port_for_each_dev(i, drive, hwif) { |
123995b97 ide: use 'drive->... |
1001 |
drive->dn = i + hwif->channel * 2; |
7704ca2a3 ide: factor out c... |
1002 1003 |
if (hwif->host_flags & IDE_HFLAG_IO_32BIT) drive->io_32bit = 1; |
7610c4f5e ide: fix IDE_DFLA... |
1004 1005 |
if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT; |
7704ca2a3 ide: factor out c... |
1006 |
if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS) |
97100fc81 ide: add device f... |
1007 |
drive->dev_flags |= IDE_DFLAG_UNMASK; |
807b90d0b ide: add IDE_HFLA... |
1008 |
if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS) |
97100fc81 ide: add device f... |
1009 |
drive->dev_flags |= IDE_DFLAG_NO_UNMASK; |
1f2cf8b00 ide: add ->port_i... |
1010 |
|
d2d4e780a ide: add drive->p... |
1011 |
drive->pio_mode = XFER_PIO_0; |
e6d95bd14 ide: ->port_init_... |
1012 1013 1014 |
if (port_ops && port_ops->init_dev) port_ops->init_dev(drive); } |
7704ca2a3 ide: factor out c... |
1015 |
} |
c413b9b94 ide: add struct i... |
1016 1017 |
static void ide_init_port(ide_hwif_t *hwif, unsigned int port, const struct ide_port_info *d) |
8447d9d52 ide: add ide_devi... |
1018 |
{ |
b76916462 ide: remove the i... |
1019 |
hwif->channel = port; |
c413b9b94 ide: add struct i... |
1020 |
|
29e52cf79 ide: remove chips... |
1021 |
hwif->chipset = d->chipset ? d->chipset : ide_pci; |
c413b9b94 ide: add struct i... |
1022 1023 1024 |
if (d->init_iops) d->init_iops(hwif); |
23f8e4bf7 ide: fix early se... |
1025 1026 |
/* ->host_flags may be set by ->init_iops (or even earlier...) */ hwif->host_flags |= d->host_flags; |
c413b9b94 ide: add struct i... |
1027 |
hwif->pio_mask = d->pio_mask; |
374e042c3 ide: add struct i... |
1028 1029 |
if (d->tp_ops) hwif->tp_ops = d->tp_ops; |
ac95beedf ide: add struct i... |
1030 |
/* ->set_pio_mode for DTC2278 is currently limited to port 0 */ |
2787cb8ae ide: add IDE_HFLA... |
1031 |
if ((hwif->host_flags & IDE_HFLAG_DTC2278) == 0 || hwif->channel == 0) |
ac95beedf ide: add struct i... |
1032 |
hwif->port_ops = d->port_ops; |
c413b9b94 ide: add struct i... |
1033 1034 1035 |
hwif->swdma_mask = d->swdma_mask; hwif->mwdma_mask = d->mwdma_mask; hwif->ultra_mask = d->udma_mask; |
b123f56e0 ide: do complete ... |
1036 1037 |
if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { int rc; |
592b53152 ide: move read_sf... |
1038 |
hwif->dma_ops = d->dma_ops; |
b123f56e0 ide: do complete ... |
1039 1040 1041 1042 1043 1044 1045 1046 |
if (d->init_dma) rc = d->init_dma(hwif, d); else rc = ide_hwif_setup_dma(hwif, d); if (rc < 0) { printk(KERN_INFO "%s: DMA disabled ", hwif->name); |
592b53152 ide: move read_sf... |
1047 1048 |
hwif->dma_ops = NULL; |
ebb00fb55 ide: factor out s... |
1049 |
hwif->dma_base = 0; |
b123f56e0 ide: do complete ... |
1050 1051 1052 |
hwif->swdma_mask = 0; hwif->mwdma_mask = 0; hwif->ultra_mask = 0; |
592b53152 ide: move read_sf... |
1053 |
} |
b123f56e0 ide: do complete ... |
1054 |
} |
c413b9b94 ide: add struct i... |
1055 |
|
1024c5f4b ide: IDE_HFLAG_SE... |
1056 |
if ((d->host_flags & IDE_HFLAG_SERIALIZE) || |
702c026be ide: rework handl... |
1057 1058 |
((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base)) hwif->host->host_flags |= IDE_HFLAG_SERIALIZE; |
1024c5f4b ide: IDE_HFLAG_SE... |
1059 |
|
6b4924962 ide: add ->max_se... |
1060 1061 |
if (d->max_sectors) hwif->rqsize = d->max_sectors; |
70775e9c6 ide: move ->rqsiz... |
1062 1063 1064 1065 1066 1067 1068 |
else { if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) || (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA)) hwif->rqsize = 256; else hwif->rqsize = 65536; } |
c413b9b94 ide: add struct i... |
1069 1070 1071 1072 |
/* call chipset specific routine for each enabled port */ if (d->init_hwif) d->init_hwif(hwif); |
c7f6f21aa ide: factor out c... |
1073 |
} |
bfa14b42a ide: add ->cable_... |
1074 |
|
c7f6f21aa ide: factor out c... |
1075 1076 |
static void ide_port_cable_detect(ide_hwif_t *hwif) { |
ac95beedf ide: add struct i... |
1077 1078 1079 |
const struct ide_port_ops *port_ops = hwif->port_ops; if (port_ops && port_ops->cable_detect && (hwif->ultra_mask & 0x78)) { |
bfa14b42a ide: add ->cable_... |
1080 |
if (hwif->cbl != ATA_CBL_PATA40_SHORT) |
ac95beedf ide: add struct i... |
1081 |
hwif->cbl = port_ops->cable_detect(hwif); |
bfa14b42a ide: add ->cable_... |
1082 |
} |
c413b9b94 ide: add struct i... |
1083 |
} |
b40d1b88f ide: move ide_ini... |
1084 1085 1086 1087 1088 1089 |
static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR, IDE8_MAJOR, IDE9_MAJOR }; static void ide_port_init_devices_data(ide_hwif_t *hwif) { |
2bd24a1cf ide: add port and... |
1090 1091 |
ide_drive_t *drive; int i; |
b40d1b88f ide: move ide_ini... |
1092 |
|
2bd24a1cf ide: add port and... |
1093 1094 |
ide_port_for_each_dev(i, drive, hwif) { u8 j = (hwif->index * MAX_DRIVES) + i; |
5f4417a15 ide: fix PowerMac... |
1095 |
u16 *saved_id = drive->id; |
b40d1b88f ide: move ide_ini... |
1096 1097 |
memset(drive, 0, sizeof(*drive)); |
5f4417a15 ide: fix PowerMac... |
1098 1099 |
memset(saved_id, 0, SECTOR_SIZE); drive->id = saved_id; |
b40d1b88f ide: move ide_ini... |
1100 1101 |
drive->media = ide_disk; |
2bd24a1cf ide: add port and... |
1102 |
drive->select = (i << 4) | ATA_DEVICE_OBS; |
b40d1b88f ide: move ide_ini... |
1103 1104 1105 |
drive->hwif = hwif; drive->ready_stat = ATA_DRDY; drive->bad_wstat = BAD_W_STAT; |
ca1b96e00 ide: replace spec... |
1106 1107 |
drive->special_flags = IDE_SFLAG_RECALIBRATE | IDE_SFLAG_SET_GEOMETRY; |
b40d1b88f ide: move ide_ini... |
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 |
drive->name[0] = 'h'; drive->name[1] = 'd'; drive->name[2] = 'a' + j; drive->max_failures = IDE_DEFAULT_MAX_FAILURES; INIT_LIST_HEAD(&drive->list); init_completion(&drive->gendev_rel_comp); } } static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) { |
b40d1b88f ide: move ide_ini... |
1120 1121 1122 1123 1124 1125 1126 1127 |
/* fill in any non-zero initial values */ hwif->index = index; hwif->major = ide_hwif_to_major[index]; hwif->name[0] = 'i'; hwif->name[1] = 'd'; hwif->name[2] = 'e'; hwif->name[3] = '0' + index; |
7362951b4 ide: move ->lock ... |
1128 1129 1130 1131 1132 |
spin_lock_init(&hwif->lock); init_timer(&hwif->timer); hwif->timer.function = &ide_timer_expiry; hwif->timer.data = (unsigned long)hwif; |
b40d1b88f ide: move ide_ini... |
1133 1134 1135 1136 1137 1138 |
init_completion(&hwif->gendev_rel_comp); hwif->tp_ops = &default_tp_ops; ide_port_init_devices_data(hwif); } |
9f36d3143 ide: remove hw_re... |
1139 |
static void ide_init_port_hw(ide_hwif_t *hwif, struct ide_hw *hw) |
b40d1b88f ide: move ide_ini... |
1140 1141 1142 |
{ memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports)); hwif->irq = hw->irq; |
b40d1b88f ide: move ide_ini... |
1143 1144 |
hwif->dev = hw->dev; hwif->gendev.parent = hw->parent ? hw->parent : hw->dev; |
b40d1b88f ide: move ide_ini... |
1145 1146 |
hwif->config_data = hw->config; } |
8cdf31002 ide: fix IDE port... |
1147 |
static unsigned int ide_indexes; |
fe80b937c ide: merge ide_ma... |
1148 |
/** |
8cdf31002 ide: fix IDE port... |
1149 |
* ide_find_port_slot - find free port slot |
fe80b937c ide: merge ide_ma... |
1150 1151 |
* @d: IDE port info * |
8cdf31002 ide: fix IDE port... |
1152 |
* Return the new port slot index or -ENOENT if we are out of free slots. |
fe80b937c ide: merge ide_ma... |
1153 |
*/ |
8cdf31002 ide: fix IDE port... |
1154 |
static int ide_find_port_slot(const struct ide_port_info *d) |
fe80b937c ide: merge ide_ma... |
1155 |
{ |
8cdf31002 ide: fix IDE port... |
1156 |
int idx = -ENOENT; |
fe80b937c ide: merge ide_ma... |
1157 |
u8 bootable = (d && (d->host_flags & IDE_HFLAG_NON_BOOTABLE)) ? 0 : 1; |
a419aef8b trivial: remove u... |
1158 |
u8 i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0; |
fe80b937c ide: merge ide_ma... |
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 |
/* * Claim an unassigned slot. * * Give preference to claiming other slots before claiming ide0/ide1, * just in case there's another interface yet-to-be-scanned * which uses ports 0x1f0/0x170 (the ide0/ide1 defaults). * * Unless there is a bootable card that does not use the standard * ports 0x1f0/0x170 (the ide0/ide1 defaults). */ |
8cdf31002 ide: fix IDE port... |
1170 |
mutex_lock(&ide_cfg_mtx); |
75d21fffd ide: remove unnec... |
1171 1172 1173 |
if (bootable) { if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1) idx = ffz(ide_indexes | i); |
fe80b937c ide: merge ide_ma... |
1174 |
} else { |
75d21fffd ide: remove unnec... |
1175 1176 1177 1178 |
if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1) idx = ffz(ide_indexes | 3); else if ((ide_indexes & 3) != 3) idx = ffz(ide_indexes); |
fe80b937c ide: merge ide_ma... |
1179 |
} |
8cdf31002 ide: fix IDE port... |
1180 1181 1182 |
if (idx >= 0) ide_indexes |= (1 << idx); mutex_unlock(&ide_cfg_mtx); |
fe80b937c ide: merge ide_ma... |
1183 |
|
8cdf31002 ide: fix IDE port... |
1184 1185 |
return idx; } |
256c5f8ee ide: fix hwif-s i... |
1186 |
|
8cdf31002 ide: fix IDE port... |
1187 1188 1189 1190 1191 |
static void ide_free_port_slot(int idx) { mutex_lock(&ide_cfg_mtx); ide_indexes &= ~(1 << idx); mutex_unlock(&ide_cfg_mtx); |
fe80b937c ide: merge ide_ma... |
1192 |
} |
fe80b937c ide: merge ide_ma... |
1193 |
|
5e7f3a466 ide: dynamic allo... |
1194 1195 |
static void ide_port_free_devices(ide_hwif_t *hwif) { |
2bd24a1cf ide: add port and... |
1196 |
ide_drive_t *drive; |
5e7f3a466 ide: dynamic allo... |
1197 |
int i; |
5f4417a15 ide: fix PowerMac... |
1198 1199 |
ide_port_for_each_dev(i, drive, hwif) { kfree(drive->id); |
2bd24a1cf ide: add port and... |
1200 |
kfree(drive); |
5f4417a15 ide: fix PowerMac... |
1201 |
} |
5e7f3a466 ide: dynamic allo... |
1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 |
} static int ide_port_alloc_devices(ide_hwif_t *hwif, int node) { int i; for (i = 0; i < MAX_DRIVES; i++) { ide_drive_t *drive; drive = kzalloc_node(sizeof(*drive), GFP_KERNEL, node); if (drive == NULL) goto out_nomem; |
5f4417a15 ide: fix PowerMac... |
1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 |
/* * In order to keep things simple we have an id * block for all drives at all times. If the device * is pre ATA or refuses ATA/ATAPI identify we * will add faked data to this. * * Also note that 0 everywhere means "can't do X" */ drive->id = kzalloc_node(SECTOR_SIZE, GFP_KERNEL, node); if (drive->id == NULL) goto out_nomem; |
5e7f3a466 ide: dynamic allo... |
1225 1226 1227 1228 1229 1230 1231 1232 |
hwif->devices[i] = drive; } return 0; out_nomem: ide_port_free_devices(hwif); return -ENOMEM; } |
9f36d3143 ide: remove hw_re... |
1233 1234 |
struct ide_host *ide_host_alloc(const struct ide_port_info *d, struct ide_hw **hws, unsigned int n_ports) |
48c3c1072 ide: add struct i... |
1235 1236 |
{ struct ide_host *host; |
a32296f93 ide: NUMA aware a... |
1237 1238 |
struct device *dev = hws[0] ? hws[0]->dev : NULL; int node = dev ? dev_to_node(dev) : -1; |
48c3c1072 ide: add struct i... |
1239 |
int i; |
a32296f93 ide: NUMA aware a... |
1240 |
host = kzalloc_node(sizeof(*host), GFP_KERNEL, node); |
48c3c1072 ide: add struct i... |
1241 1242 |
if (host == NULL) return NULL; |
dca398305 ide: pass number ... |
1243 |
for (i = 0; i < n_ports; i++) { |
48c3c1072 ide: add struct i... |
1244 |
ide_hwif_t *hwif; |
8cdf31002 ide: fix IDE port... |
1245 |
int idx; |
48c3c1072 ide: add struct i... |
1246 1247 1248 |
if (hws[i] == NULL) continue; |
a32296f93 ide: NUMA aware a... |
1249 |
hwif = kzalloc_node(sizeof(*hwif), GFP_KERNEL, node); |
18de10170 ide: allocate ide... |
1250 1251 |
if (hwif == NULL) continue; |
5e7f3a466 ide: dynamic allo... |
1252 1253 1254 1255 |
if (ide_port_alloc_devices(hwif, node) < 0) { kfree(hwif); continue; } |
8cdf31002 ide: fix IDE port... |
1256 1257 1258 1259 1260 |
idx = ide_find_port_slot(d); if (idx < 0) { printk(KERN_ERR "%s: no free slot for interface ", d ? d->name : "ide"); |
5f4417a15 ide: fix PowerMac... |
1261 |
ide_port_free_devices(hwif); |
18de10170 ide: allocate ide... |
1262 |
kfree(hwif); |
8cdf31002 ide: fix IDE port... |
1263 |
continue; |
48c3c1072 ide: add struct i... |
1264 |
} |
8cdf31002 ide: fix IDE port... |
1265 |
|
8cdf31002 ide: fix IDE port... |
1266 |
ide_init_port_data(hwif, idx); |
08da591e1 ide: add ide_devi... |
1267 |
hwif->host = host; |
8cdf31002 ide: fix IDE port... |
1268 1269 |
host->ports[i] = hwif; host->n_ports++; |
48c3c1072 ide: add struct i... |
1270 1271 1272 1273 1274 1275 |
} if (host->n_ports == 0) { kfree(host); return NULL; } |
a32296f93 ide: NUMA aware a... |
1276 |
host->dev[0] = dev; |
6cdf6eb35 ide: add ->dev an... |
1277 |
|
feb22b7f8 ide: add proper P... |
1278 1279 |
if (d) { host->init_chipset = d->init_chipset; |
e354c1d80 ide: remove IDE_A... |
1280 1281 |
host->get_lock = d->get_lock; host->release_lock = d->release_lock; |
ef0b04276 ide: add ide_pci_... |
1282 |
host->host_flags = d->host_flags; |
aa07573b2 ide: Fix host dri... |
1283 |
host->irq_flags = d->irq_flags; |
feb22b7f8 ide: add proper P... |
1284 |
} |
ef0b04276 ide: add ide_pci_... |
1285 |
|
48c3c1072 ide: add struct i... |
1286 1287 |
return host; } |
48c3c1072 ide: add struct i... |
1288 |
EXPORT_SYMBOL_GPL(ide_host_alloc); |
9a100f4b7 ide: fix ide_regi... |
1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 |
static void ide_port_free(ide_hwif_t *hwif) { ide_port_free_devices(hwif); ide_free_port_slot(hwif->index); kfree(hwif); } static void ide_disable_port(ide_hwif_t *hwif) { struct ide_host *host = hwif->host; int i; printk(KERN_INFO "%s: disabling port ", hwif->name); for (i = 0; i < MAX_HOST_PORTS; i++) { if (host->ports[i] == hwif) { host->ports[i] = NULL; host->n_ports--; } } ide_port_free(hwif); } |
48c3c1072 ide: add struct i... |
1313 |
int ide_host_register(struct ide_host *host, const struct ide_port_info *d, |
9f36d3143 ide: remove hw_re... |
1314 |
struct ide_hw **hws) |
c413b9b94 ide: add struct i... |
1315 1316 |
{ ide_hwif_t *hwif, *mate = NULL; |
e0d002078 ide: fix ide_host... |
1317 |
int i, j = 0; |
8447d9d52 ide: add ide_devi... |
1318 |
|
2bd24a1cf ide: add port and... |
1319 |
ide_host_for_each_port(i, hwif, host) { |
e0d002078 ide: fix ide_host... |
1320 |
if (hwif == NULL) { |
c413b9b94 ide: add struct i... |
1321 1322 1323 |
mate = NULL; continue; } |
c97c6aca7 ide: pass hw_regs... |
1324 |
ide_init_port_hw(hwif, hws[i]); |
9fd91d959 ide: add "ignore_... |
1325 |
ide_port_apply_params(hwif); |
0a6e49e9b ide: remove now s... |
1326 1327 1328 |
if ((i & 1) && mate) { hwif->mate = mate; mate->mate = hwif; |
123995b97 ide: use 'drive->... |
1329 |
} |
c413b9b94 ide: add struct i... |
1330 |
|
0a6e49e9b ide: remove now s... |
1331 1332 1333 1334 |
mate = (i & 1) ? NULL : hwif; ide_init_port(hwif, i & 1, d); ide_port_cable_detect(hwif); |
5880b5de7 ide: don't enable... |
1335 1336 |
hwif->port_flags |= IDE_PFLAG_PROBING; |
7704ca2a3 ide: factor out c... |
1337 |
ide_port_init_devices(hwif); |
c413b9b94 ide: add struct i... |
1338 |
} |
2bd24a1cf ide: add port and... |
1339 |
ide_host_for_each_port(i, hwif, host) { |
e0d002078 ide: fix ide_host... |
1340 1341 |
if (hwif == NULL) continue; |
139ddfcab ide: move handlin... |
1342 |
|
eb716beb0 ide: register por... |
1343 1344 |
if (ide_probe_port(hwif) == 0) hwif->present = 1; |
a14dc5749 ide: move hwif_re... |
1345 |
|
5880b5de7 ide: don't enable... |
1346 |
hwif->port_flags &= ~IDE_PFLAG_PROBING; |
c094ea077 ide: add IDE_HFLA... |
1347 1348 |
if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 || hwif->mate == NULL || hwif->mate->present == 0) { |
9a100f4b7 ide: fix ide_regi... |
1349 1350 1351 1352 1353 |
if (ide_register_port(hwif)) { ide_disable_port(hwif); continue; } } |
a14dc5749 ide: move hwif_re... |
1354 |
|
eb716beb0 ide: register por... |
1355 1356 |
if (hwif->present) ide_port_tune_devices(hwif); |
2e13093a8 ide: fix probing ... |
1357 |
} |
ba6560aa4 ide: kill probe_h... |
1358 |
|
ffc36c761 ide: fix handling... |
1359 |
ide_host_enable_irqs(host); |
2bd24a1cf ide: add port and... |
1360 |
ide_host_for_each_port(i, hwif, host) { |
e0d002078 ide: fix ide_host... |
1361 1362 |
if (hwif == NULL) continue; |
ba6560aa4 ide: kill probe_h... |
1363 1364 1365 1366 1367 |
if (hwif_init(hwif) == 0) { printk(KERN_INFO "%s: failed to initialize IDE " "interface ", hwif->name); |
51d6ac701 IDE: Unregister a... |
1368 1369 |
device_unregister(&hwif->gendev); ide_disable_port(hwif); |
ba6560aa4 ide: kill probe_h... |
1370 1371 |
continue; } |
decdc3f0d ide: move ide_acp... |
1372 |
|
eb716beb0 ide: register por... |
1373 |
if (hwif->present) |
e415e495f ide: Two fixes re... |
1374 1375 1376 1377 1378 1379 |
if (ide_port_setup_devices(hwif) == 0) { hwif->present = 0; continue; } j++; |
26042d058 ide: move ide_por... |
1380 |
|
8b803bd18 ide: sanitize ACP... |
1381 |
ide_acpi_init_port(hwif); |
eb716beb0 ide: register por... |
1382 1383 1384 |
if (hwif->present) ide_acpi_port_init_devices(hwif); |
2e13093a8 ide: fix probing ... |
1385 |
} |
2bd24a1cf ide: add port and... |
1386 |
ide_host_for_each_port(i, hwif, host) { |
e0d002078 ide: fix ide_host... |
1387 1388 |
if (hwif == NULL) continue; |
ba6560aa4 ide: kill probe_h... |
1389 |
|
eb716beb0 ide: register por... |
1390 1391 |
ide_sysfs_register_port(hwif); ide_proc_register_port(hwif); |
dbee03229 ide: Fix ordering... |
1392 |
if (hwif->present) { |
d9270a3f1 ide: move create_... |
1393 |
ide_proc_port_register_devices(hwif); |
dbee03229 ide: Fix ordering... |
1394 1395 |
hwif_register_devices(hwif); } |
8447d9d52 ide: add ide_devi... |
1396 |
} |
e0d002078 ide: fix ide_host... |
1397 |
return j ? 0 : -1; |
8447d9d52 ide: add ide_devi... |
1398 |
} |
48c3c1072 ide: add struct i... |
1399 |
EXPORT_SYMBOL_GPL(ide_host_register); |
151575e46 ide: remove idepr... |
1400 |
|
9f36d3143 ide: remove hw_re... |
1401 |
int ide_host_add(const struct ide_port_info *d, struct ide_hw **hws, |
dca398305 ide: pass number ... |
1402 |
unsigned int n_ports, struct ide_host **hostp) |
6f904d015 ide: add ide_host... |
1403 1404 |
{ struct ide_host *host; |
8a69580e1 ide: add ide_host... |
1405 |
int rc; |
6f904d015 ide: add ide_host... |
1406 |
|
dca398305 ide: pass number ... |
1407 |
host = ide_host_alloc(d, hws, n_ports); |
6f904d015 ide: add ide_host... |
1408 1409 |
if (host == NULL) return -ENOMEM; |
8a69580e1 ide: add ide_host... |
1410 1411 1412 1413 1414 |
rc = ide_host_register(host, d, hws); if (rc) { ide_host_free(host); return rc; } |
6f904d015 ide: add ide_host... |
1415 1416 1417 1418 1419 1420 1421 |
if (hostp) *hostp = host; return 0; } EXPORT_SYMBOL_GPL(ide_host_add); |
b40d1b88f ide: move ide_ini... |
1422 1423 |
static void __ide_port_unregister_devices(ide_hwif_t *hwif) { |
2bd24a1cf ide: add port and... |
1424 |
ide_drive_t *drive; |
b40d1b88f ide: move ide_ini... |
1425 |
int i; |
7ed5b157d ide: add ide_for_... |
1426 1427 1428 |
ide_port_for_each_present_dev(i, drive, hwif) { device_unregister(&drive->gendev); wait_for_completion(&drive->gendev_rel_comp); |
b40d1b88f ide: move ide_ini... |
1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 |
} } void ide_port_unregister_devices(ide_hwif_t *hwif) { mutex_lock(&ide_cfg_mtx); __ide_port_unregister_devices(hwif); hwif->present = 0; ide_port_init_devices_data(hwif); mutex_unlock(&ide_cfg_mtx); } EXPORT_SYMBOL_GPL(ide_port_unregister_devices); /** * ide_unregister - free an IDE interface * @hwif: IDE interface * * Perform the final unregister of an IDE interface. * * Locking: * The caller must not hold the IDE locks. * * It is up to the caller to be sure there is no pending I/O here, * and that the interface will not be reopened (present/vanishing * locking isn't yet done BTW). */ static void ide_unregister(ide_hwif_t *hwif) { BUG_ON(in_interrupt()); BUG_ON(irqs_disabled()); mutex_lock(&ide_cfg_mtx); if (hwif->present) { __ide_port_unregister_devices(hwif); hwif->present = 0; } ide_proc_unregister_port(hwif); free_irq(hwif->irq, hwif); device_unregister(hwif->portdev); device_unregister(&hwif->gendev); wait_for_completion(&hwif->gendev_rel_comp); /* * Remove us from the kernel's knowledge */ blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS); kfree(hwif->sg_table); unregister_blkdev(hwif->major, hwif->name); ide_release_dma_engine(hwif); mutex_unlock(&ide_cfg_mtx); } |
8a69580e1 ide: add ide_host... |
1487 |
void ide_host_free(struct ide_host *host) |
151575e46 ide: remove idepr... |
1488 |
{ |
8cdf31002 ide: fix IDE port... |
1489 |
ide_hwif_t *hwif; |
151575e46 ide: remove idepr... |
1490 |
int i; |
8447d9d52 ide: add ide_devi... |
1491 |
|
2bd24a1cf ide: add port and... |
1492 |
ide_host_for_each_port(i, hwif, host) { |
9a100f4b7 ide: fix ide_regi... |
1493 1494 |
if (hwif) ide_port_free(hwif); |
c97c6aca7 ide: pass hw_regs... |
1495 |
} |
151575e46 ide: remove idepr... |
1496 |
|
48c3c1072 ide: add struct i... |
1497 |
kfree(host); |
151575e46 ide: remove idepr... |
1498 |
} |
8a69580e1 ide: add ide_host... |
1499 1500 1501 1502 |
EXPORT_SYMBOL_GPL(ide_host_free); void ide_host_remove(struct ide_host *host) { |
2bd24a1cf ide: add port and... |
1503 |
ide_hwif_t *hwif; |
8a69580e1 ide: add ide_host... |
1504 |
int i; |
2bd24a1cf ide: add port and... |
1505 1506 1507 |
ide_host_for_each_port(i, hwif, host) { if (hwif) ide_unregister(hwif); |
8a69580e1 ide: add ide_host... |
1508 1509 1510 1511 |
} ide_host_free(host); } |
48c3c1072 ide: add struct i... |
1512 |
EXPORT_SYMBOL_GPL(ide_host_remove); |
2dde7861a ide: rework Power... |
1513 1514 1515 |
void ide_port_scan(ide_hwif_t *hwif) { |
5880b5de7 ide: don't enable... |
1516 |
int rc; |
9fd91d959 ide: add "ignore_... |
1517 |
ide_port_apply_params(hwif); |
2dde7861a ide: rework Power... |
1518 |
ide_port_cable_detect(hwif); |
5880b5de7 ide: don't enable... |
1519 1520 |
hwif->port_flags |= IDE_PFLAG_PROBING; |
2dde7861a ide: rework Power... |
1521 |
ide_port_init_devices(hwif); |
5880b5de7 ide: don't enable... |
1522 1523 1524 1525 1526 |
rc = ide_probe_port(hwif); hwif->port_flags &= ~IDE_PFLAG_PROBING; if (rc < 0) |
2dde7861a ide: rework Power... |
1527 1528 1529 1530 1531 |
return; hwif->present = 1; ide_port_tune_devices(hwif); |
2dde7861a ide: rework Power... |
1532 |
ide_port_setup_devices(hwif); |
e630fcbe9 ide: fix ide_port... |
1533 |
ide_acpi_port_init_devices(hwif); |
2dde7861a ide: rework Power... |
1534 1535 1536 1537 |
hwif_register_devices(hwif); ide_proc_port_register_devices(hwif); } EXPORT_SYMBOL_GPL(ide_port_scan); |