diff options
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r-- | drivers/ide/ide-probe.c | 285 |
1 files changed, 201 insertions, 84 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 6a196c27b0aa..862f02603f9b 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -264,6 +264,7 @@ err_misc: | |||
264 | static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | 264 | static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) |
265 | { | 265 | { |
266 | ide_hwif_t *hwif = HWIF(drive); | 266 | ide_hwif_t *hwif = HWIF(drive); |
267 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
267 | int use_altstatus = 0, rc; | 268 | int use_altstatus = 0, rc; |
268 | unsigned long timeout; | 269 | unsigned long timeout; |
269 | u8 s = 0, a = 0; | 270 | u8 s = 0, a = 0; |
@@ -271,7 +272,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
271 | /* take a deep breath */ | 272 | /* take a deep breath */ |
272 | msleep(50); | 273 | msleep(50); |
273 | 274 | ||
274 | if (hwif->io_ports[IDE_CONTROL_OFFSET]) { | 275 | if (io_ports->ctl_addr) { |
275 | a = ide_read_altstatus(drive); | 276 | a = ide_read_altstatus(drive); |
276 | s = ide_read_status(drive); | 277 | s = ide_read_status(drive); |
277 | if ((a ^ s) & ~INDEX_STAT) | 278 | if ((a ^ s) & ~INDEX_STAT) |
@@ -289,10 +290,10 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
289 | */ | 290 | */ |
290 | if ((cmd == WIN_PIDENTIFY)) | 291 | if ((cmd == WIN_PIDENTIFY)) |
291 | /* disable dma & overlap */ | 292 | /* disable dma & overlap */ |
292 | hwif->OUTB(0, hwif->io_ports[IDE_FEATURE_OFFSET]); | 293 | hwif->OUTB(0, io_ports->feature_addr); |
293 | 294 | ||
294 | /* ask drive for ID */ | 295 | /* ask drive for ID */ |
295 | hwif->OUTB(cmd, hwif->io_ports[IDE_COMMAND_OFFSET]); | 296 | hwif->OUTB(cmd, io_ports->command_addr); |
296 | 297 | ||
297 | timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; | 298 | timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; |
298 | timeout += jiffies; | 299 | timeout += jiffies; |
@@ -353,7 +354,7 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd) | |||
353 | * interrupts during the identify-phase that | 354 | * interrupts during the identify-phase that |
354 | * the irq handler isn't expecting. | 355 | * the irq handler isn't expecting. |
355 | */ | 356 | */ |
356 | if (hwif->io_ports[IDE_CONTROL_OFFSET]) { | 357 | if (hwif->io_ports.ctl_addr) { |
357 | if (!hwif->irq) { | 358 | if (!hwif->irq) { |
358 | autoprobe = 1; | 359 | autoprobe = 1; |
359 | cookie = probe_irq_on(); | 360 | cookie = probe_irq_on(); |
@@ -393,7 +394,7 @@ static int ide_busy_sleep(ide_hwif_t *hwif) | |||
393 | 394 | ||
394 | do { | 395 | do { |
395 | msleep(50); | 396 | msleep(50); |
396 | stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); | 397 | stat = hwif->INB(hwif->io_ports.status_addr); |
397 | if ((stat & BUSY_STAT) == 0) | 398 | if ((stat & BUSY_STAT) == 0) |
398 | return 0; | 399 | return 0; |
399 | } while (time_before(jiffies, timeout)); | 400 | } while (time_before(jiffies, timeout)); |
@@ -425,6 +426,7 @@ static int ide_busy_sleep(ide_hwif_t *hwif) | |||
425 | static int do_probe (ide_drive_t *drive, u8 cmd) | 426 | static int do_probe (ide_drive_t *drive, u8 cmd) |
426 | { | 427 | { |
427 | ide_hwif_t *hwif = HWIF(drive); | 428 | ide_hwif_t *hwif = HWIF(drive); |
429 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
428 | int rc; | 430 | int rc; |
429 | u8 stat; | 431 | u8 stat; |
430 | 432 | ||
@@ -445,7 +447,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
445 | msleep(50); | 447 | msleep(50); |
446 | SELECT_DRIVE(drive); | 448 | SELECT_DRIVE(drive); |
447 | msleep(50); | 449 | msleep(50); |
448 | if (hwif->INB(hwif->io_ports[IDE_SELECT_OFFSET]) != drive->select.all && | 450 | if (hwif->INB(io_ports->device_addr) != drive->select.all && |
449 | !drive->present) { | 451 | !drive->present) { |
450 | if (drive->select.b.unit != 0) { | 452 | if (drive->select.b.unit != 0) { |
451 | /* exit with drive0 selected */ | 453 | /* exit with drive0 selected */ |
@@ -472,17 +474,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
472 | if (stat == (BUSY_STAT | READY_STAT)) | 474 | if (stat == (BUSY_STAT | READY_STAT)) |
473 | return 4; | 475 | return 4; |
474 | 476 | ||
475 | if ((rc == 1 && cmd == WIN_PIDENTIFY) && | 477 | if (rc == 1 && cmd == WIN_PIDENTIFY) { |
476 | ((drive->autotune == IDE_TUNE_DEFAULT) || | ||
477 | (drive->autotune == IDE_TUNE_AUTO))) { | ||
478 | printk(KERN_ERR "%s: no response (status = 0x%02x), " | 478 | printk(KERN_ERR "%s: no response (status = 0x%02x), " |
479 | "resetting drive\n", drive->name, stat); | 479 | "resetting drive\n", drive->name, stat); |
480 | msleep(50); | 480 | msleep(50); |
481 | hwif->OUTB(drive->select.all, | 481 | hwif->OUTB(drive->select.all, io_ports->device_addr); |
482 | hwif->io_ports[IDE_SELECT_OFFSET]); | ||
483 | msleep(50); | 482 | msleep(50); |
484 | hwif->OUTB(WIN_SRST, | 483 | hwif->OUTB(WIN_SRST, io_ports->command_addr); |
485 | hwif->io_ports[IDE_COMMAND_OFFSET]); | ||
486 | (void)ide_busy_sleep(hwif); | 484 | (void)ide_busy_sleep(hwif); |
487 | rc = try_to_identify(drive, cmd); | 485 | rc = try_to_identify(drive, cmd); |
488 | } | 486 | } |
@@ -518,7 +516,7 @@ static void enable_nest (ide_drive_t *drive) | |||
518 | printk("%s: enabling %s -- ", hwif->name, drive->id->model); | 516 | printk("%s: enabling %s -- ", hwif->name, drive->id->model); |
519 | SELECT_DRIVE(drive); | 517 | SELECT_DRIVE(drive); |
520 | msleep(50); | 518 | msleep(50); |
521 | hwif->OUTB(EXABYTE_ENABLE_NEST, hwif->io_ports[IDE_COMMAND_OFFSET]); | 519 | hwif->OUTB(EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr); |
522 | 520 | ||
523 | if (ide_busy_sleep(hwif)) { | 521 | if (ide_busy_sleep(hwif)) { |
524 | printk(KERN_CONT "failed (timeout)\n"); | 522 | printk(KERN_CONT "failed (timeout)\n"); |
@@ -644,7 +642,7 @@ static int ide_register_port(ide_hwif_t *hwif) | |||
644 | ret = device_register(&hwif->gendev); | 642 | ret = device_register(&hwif->gendev); |
645 | if (ret < 0) { | 643 | if (ret < 0) { |
646 | printk(KERN_WARNING "IDE: %s: device_register error: %d\n", | 644 | printk(KERN_WARNING "IDE: %s: device_register error: %d\n", |
647 | __FUNCTION__, ret); | 645 | __func__, ret); |
648 | goto out; | 646 | goto out; |
649 | } | 647 | } |
650 | 648 | ||
@@ -773,8 +771,7 @@ static int ide_probe_port(ide_hwif_t *hwif) | |||
773 | 771 | ||
774 | BUG_ON(hwif->present); | 772 | BUG_ON(hwif->present); |
775 | 773 | ||
776 | if (hwif->noprobe || | 774 | if (hwif->drives[0].noprobe && hwif->drives[1].noprobe) |
777 | (hwif->drives[0].noprobe && hwif->drives[1].noprobe)) | ||
778 | return -EACCES; | 775 | return -EACCES; |
779 | 776 | ||
780 | /* | 777 | /* |
@@ -801,14 +798,9 @@ static int ide_probe_port(ide_hwif_t *hwif) | |||
801 | if (drive->present) | 798 | if (drive->present) |
802 | rc = 0; | 799 | rc = 0; |
803 | } | 800 | } |
804 | if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { | 801 | |
805 | printk(KERN_WARNING "%s: reset\n", hwif->name); | ||
806 | hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); | ||
807 | udelay(10); | ||
808 | hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); | ||
809 | (void)ide_busy_sleep(hwif); | ||
810 | } | ||
811 | local_irq_restore(flags); | 802 | local_irq_restore(flags); |
803 | |||
812 | /* | 804 | /* |
813 | * Use cached IRQ number. It might be (and is...) changed by probe | 805 | * Use cached IRQ number. It might be (and is...) changed by probe |
814 | * code above | 806 | * code above |
@@ -821,29 +813,25 @@ static int ide_probe_port(ide_hwif_t *hwif) | |||
821 | 813 | ||
822 | static void ide_port_tune_devices(ide_hwif_t *hwif) | 814 | static void ide_port_tune_devices(ide_hwif_t *hwif) |
823 | { | 815 | { |
816 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
824 | int unit; | 817 | int unit; |
825 | 818 | ||
826 | for (unit = 0; unit < MAX_DRIVES; unit++) { | 819 | for (unit = 0; unit < MAX_DRIVES; unit++) { |
827 | ide_drive_t *drive = &hwif->drives[unit]; | 820 | ide_drive_t *drive = &hwif->drives[unit]; |
828 | 821 | ||
829 | if (drive->present && hwif->quirkproc) | 822 | if (drive->present && port_ops && port_ops->quirkproc) |
830 | hwif->quirkproc(drive); | 823 | port_ops->quirkproc(drive); |
831 | } | 824 | } |
832 | 825 | ||
833 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 826 | for (unit = 0; unit < MAX_DRIVES; ++unit) { |
834 | ide_drive_t *drive = &hwif->drives[unit]; | 827 | ide_drive_t *drive = &hwif->drives[unit]; |
835 | 828 | ||
836 | if (drive->present) { | 829 | if (drive->present) { |
837 | if (drive->autotune == IDE_TUNE_AUTO) | 830 | ide_set_max_pio(drive); |
838 | ide_set_max_pio(drive); | ||
839 | |||
840 | if (drive->autotune != IDE_TUNE_DEFAULT && | ||
841 | drive->autotune != IDE_TUNE_AUTO) | ||
842 | continue; | ||
843 | 831 | ||
844 | drive->nice1 = 1; | 832 | drive->nice1 = 1; |
845 | 833 | ||
846 | if (hwif->dma_host_set) | 834 | if (hwif->dma_ops) |
847 | ide_set_dma(drive); | 835 | ide_set_dma(drive); |
848 | } | 836 | } |
849 | } | 837 | } |
@@ -994,6 +982,7 @@ static void ide_port_setup_devices(ide_hwif_t *hwif) | |||
994 | */ | 982 | */ |
995 | static int init_irq (ide_hwif_t *hwif) | 983 | static int init_irq (ide_hwif_t *hwif) |
996 | { | 984 | { |
985 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
997 | unsigned int index; | 986 | unsigned int index; |
998 | ide_hwgroup_t *hwgroup; | 987 | ide_hwgroup_t *hwgroup; |
999 | ide_hwif_t *match = NULL; | 988 | ide_hwif_t *match = NULL; |
@@ -1077,9 +1066,9 @@ static int init_irq (ide_hwif_t *hwif) | |||
1077 | if (IDE_CHIPSET_IS_PCI(hwif->chipset)) | 1066 | if (IDE_CHIPSET_IS_PCI(hwif->chipset)) |
1078 | sa = IRQF_SHARED; | 1067 | sa = IRQF_SHARED; |
1079 | 1068 | ||
1080 | if (hwif->io_ports[IDE_CONTROL_OFFSET]) | 1069 | if (io_ports->ctl_addr) |
1081 | /* clear nIEN */ | 1070 | /* clear nIEN */ |
1082 | hwif->OUTB(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]); | 1071 | hwif->OUTB(0x08, io_ports->ctl_addr); |
1083 | 1072 | ||
1084 | if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup)) | 1073 | if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup)) |
1085 | goto out_unlink; | 1074 | goto out_unlink; |
@@ -1095,12 +1084,11 @@ static int init_irq (ide_hwif_t *hwif) | |||
1095 | 1084 | ||
1096 | #if !defined(__mc68000__) | 1085 | #if !defined(__mc68000__) |
1097 | printk("%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name, | 1086 | printk("%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name, |
1098 | hwif->io_ports[IDE_DATA_OFFSET], | 1087 | io_ports->data_addr, io_ports->status_addr, |
1099 | hwif->io_ports[IDE_DATA_OFFSET]+7, | 1088 | io_ports->ctl_addr, hwif->irq); |
1100 | hwif->io_ports[IDE_CONTROL_OFFSET], hwif->irq); | ||
1101 | #else | 1089 | #else |
1102 | printk("%s at 0x%08lx on irq %d", hwif->name, | 1090 | printk("%s at 0x%08lx on irq %d", hwif->name, |
1103 | hwif->io_ports[IDE_DATA_OFFSET], hwif->irq); | 1091 | io_ports->data_addr, hwif->irq); |
1104 | #endif /* __mc68000__ */ | 1092 | #endif /* __mc68000__ */ |
1105 | if (match) | 1093 | if (match) |
1106 | printk(" (%sed with %s)", | 1094 | printk(" (%sed with %s)", |
@@ -1242,8 +1230,8 @@ static int hwif_init(ide_hwif_t *hwif) | |||
1242 | int old_irq; | 1230 | int old_irq; |
1243 | 1231 | ||
1244 | if (!hwif->irq) { | 1232 | if (!hwif->irq) { |
1245 | if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) | 1233 | hwif->irq = ide_default_irq(hwif->io_ports.data_addr); |
1246 | { | 1234 | if (!hwif->irq) { |
1247 | printk("%s: DISABLED, NO IRQ\n", hwif->name); | 1235 | printk("%s: DISABLED, NO IRQ\n", hwif->name); |
1248 | return 0; | 1236 | return 0; |
1249 | } | 1237 | } |
@@ -1272,7 +1260,8 @@ static int hwif_init(ide_hwif_t *hwif) | |||
1272 | * It failed to initialise. Find the default IRQ for | 1260 | * It failed to initialise. Find the default IRQ for |
1273 | * this port and try that. | 1261 | * this port and try that. |
1274 | */ | 1262 | */ |
1275 | if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) { | 1263 | hwif->irq = ide_default_irq(hwif->io_ports.data_addr); |
1264 | if (!hwif->irq) { | ||
1276 | printk("%s: Disabled unable to get IRQ %d.\n", | 1265 | printk("%s: Disabled unable to get IRQ %d.\n", |
1277 | hwif->name, old_irq); | 1266 | hwif->name, old_irq); |
1278 | goto out; | 1267 | goto out; |
@@ -1324,6 +1313,7 @@ static void hwif_register_devices(ide_hwif_t *hwif) | |||
1324 | 1313 | ||
1325 | static void ide_port_init_devices(ide_hwif_t *hwif) | 1314 | static void ide_port_init_devices(ide_hwif_t *hwif) |
1326 | { | 1315 | { |
1316 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
1327 | int i; | 1317 | int i; |
1328 | 1318 | ||
1329 | for (i = 0; i < MAX_DRIVES; i++) { | 1319 | for (i = 0; i < MAX_DRIVES; i++) { |
@@ -1335,12 +1325,10 @@ static void ide_port_init_devices(ide_hwif_t *hwif) | |||
1335 | drive->unmask = 1; | 1325 | drive->unmask = 1; |
1336 | if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS) | 1326 | if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS) |
1337 | drive->no_unmask = 1; | 1327 | drive->no_unmask = 1; |
1338 | if ((hwif->host_flags & IDE_HFLAG_NO_AUTOTUNE) == 0) | ||
1339 | drive->autotune = 1; | ||
1340 | } | 1328 | } |
1341 | 1329 | ||
1342 | if (hwif->port_init_devs) | 1330 | if (port_ops && port_ops->port_init_devs) |
1343 | hwif->port_init_devs(hwif); | 1331 | port_ops->port_init_devs(hwif); |
1344 | } | 1332 | } |
1345 | 1333 | ||
1346 | static void ide_init_port(ide_hwif_t *hwif, unsigned int port, | 1334 | static void ide_init_port(ide_hwif_t *hwif, unsigned int port, |
@@ -1355,9 +1343,6 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, | |||
1355 | if (d->init_iops) | 1343 | if (d->init_iops) |
1356 | d->init_iops(hwif); | 1344 | d->init_iops(hwif); |
1357 | 1345 | ||
1358 | if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) | ||
1359 | ide_hwif_setup_dma(hwif, d); | ||
1360 | |||
1361 | if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) || | 1346 | if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) || |
1362 | (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS)) | 1347 | (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS)) |
1363 | hwif->irq = port ? 15 : 14; | 1348 | hwif->irq = port ? 15 : 14; |
@@ -1365,16 +1350,36 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, | |||
1365 | hwif->host_flags = d->host_flags; | 1350 | hwif->host_flags = d->host_flags; |
1366 | hwif->pio_mask = d->pio_mask; | 1351 | hwif->pio_mask = d->pio_mask; |
1367 | 1352 | ||
1368 | if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate) | 1353 | /* ->set_pio_mode for DTC2278 is currently limited to port 0 */ |
1369 | hwif->mate->serialized = hwif->serialized = 1; | 1354 | if (hwif->chipset != ide_dtc2278 || hwif->channel == 0) |
1355 | hwif->port_ops = d->port_ops; | ||
1356 | |||
1357 | if ((d->host_flags & IDE_HFLAG_SERIALIZE) || | ||
1358 | ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base)) { | ||
1359 | if (hwif->mate) | ||
1360 | hwif->mate->serialized = hwif->serialized = 1; | ||
1361 | } | ||
1370 | 1362 | ||
1371 | hwif->swdma_mask = d->swdma_mask; | 1363 | hwif->swdma_mask = d->swdma_mask; |
1372 | hwif->mwdma_mask = d->mwdma_mask; | 1364 | hwif->mwdma_mask = d->mwdma_mask; |
1373 | hwif->ultra_mask = d->udma_mask; | 1365 | hwif->ultra_mask = d->udma_mask; |
1374 | 1366 | ||
1375 | /* reset DMA masks only for SFF-style DMA controllers */ | 1367 | if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { |
1376 | if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0 && hwif->dma_base == 0) | 1368 | int rc; |
1377 | hwif->swdma_mask = hwif->mwdma_mask = hwif->ultra_mask = 0; | 1369 | |
1370 | if (d->init_dma) | ||
1371 | rc = d->init_dma(hwif, d); | ||
1372 | else | ||
1373 | rc = ide_hwif_setup_dma(hwif, d); | ||
1374 | |||
1375 | if (rc < 0) { | ||
1376 | printk(KERN_INFO "%s: DMA disabled\n", hwif->name); | ||
1377 | hwif->swdma_mask = 0; | ||
1378 | hwif->mwdma_mask = 0; | ||
1379 | hwif->ultra_mask = 0; | ||
1380 | } else if (d->dma_ops) | ||
1381 | hwif->dma_ops = d->dma_ops; | ||
1382 | } | ||
1378 | 1383 | ||
1379 | if (d->host_flags & IDE_HFLAG_RQSIZE_256) | 1384 | if (d->host_flags & IDE_HFLAG_RQSIZE_256) |
1380 | hwif->rqsize = 256; | 1385 | hwif->rqsize = 256; |
@@ -1386,9 +1391,11 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, | |||
1386 | 1391 | ||
1387 | static void ide_port_cable_detect(ide_hwif_t *hwif) | 1392 | static void ide_port_cable_detect(ide_hwif_t *hwif) |
1388 | { | 1393 | { |
1389 | if (hwif->cable_detect && (hwif->ultra_mask & 0x78)) { | 1394 | const struct ide_port_ops *port_ops = hwif->port_ops; |
1395 | |||
1396 | if (port_ops && port_ops->cable_detect && (hwif->ultra_mask & 0x78)) { | ||
1390 | if (hwif->cbl != ATA_CBL_PATA40_SHORT) | 1397 | if (hwif->cbl != ATA_CBL_PATA40_SHORT) |
1391 | hwif->cbl = hwif->cable_detect(hwif); | 1398 | hwif->cbl = port_ops->cable_detect(hwif); |
1392 | } | 1399 | } |
1393 | } | 1400 | } |
1394 | 1401 | ||
@@ -1444,19 +1451,74 @@ static int ide_sysfs_register_port(ide_hwif_t *hwif) | |||
1444 | return rc; | 1451 | return rc; |
1445 | } | 1452 | } |
1446 | 1453 | ||
1454 | /** | ||
1455 | * ide_find_port_slot - find free ide_hwifs[] slot | ||
1456 | * @d: IDE port info | ||
1457 | * | ||
1458 | * Return the new hwif. If we are out of free slots return NULL. | ||
1459 | */ | ||
1460 | |||
1461 | ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d) | ||
1462 | { | ||
1463 | ide_hwif_t *hwif; | ||
1464 | int i; | ||
1465 | u8 bootable = (d && (d->host_flags & IDE_HFLAG_NON_BOOTABLE)) ? 0 : 1; | ||
1466 | |||
1467 | /* | ||
1468 | * Claim an unassigned slot. | ||
1469 | * | ||
1470 | * Give preference to claiming other slots before claiming ide0/ide1, | ||
1471 | * just in case there's another interface yet-to-be-scanned | ||
1472 | * which uses ports 0x1f0/0x170 (the ide0/ide1 defaults). | ||
1473 | * | ||
1474 | * Unless there is a bootable card that does not use the standard | ||
1475 | * ports 0x1f0/0x170 (the ide0/ide1 defaults). | ||
1476 | */ | ||
1477 | if (bootable) { | ||
1478 | i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0; | ||
1479 | |||
1480 | for (; i < MAX_HWIFS; i++) { | ||
1481 | hwif = &ide_hwifs[i]; | ||
1482 | if (hwif->chipset == ide_unknown) | ||
1483 | return hwif; | ||
1484 | } | ||
1485 | } else { | ||
1486 | for (i = 2; i < MAX_HWIFS; i++) { | ||
1487 | hwif = &ide_hwifs[i]; | ||
1488 | if (hwif->chipset == ide_unknown) | ||
1489 | return hwif; | ||
1490 | } | ||
1491 | for (i = 0; i < 2 && i < MAX_HWIFS; i++) { | ||
1492 | hwif = &ide_hwifs[i]; | ||
1493 | if (hwif->chipset == ide_unknown) | ||
1494 | return hwif; | ||
1495 | } | ||
1496 | } | ||
1497 | |||
1498 | return NULL; | ||
1499 | } | ||
1500 | EXPORT_SYMBOL_GPL(ide_find_port_slot); | ||
1501 | |||
1447 | int ide_device_add_all(u8 *idx, const struct ide_port_info *d) | 1502 | int ide_device_add_all(u8 *idx, const struct ide_port_info *d) |
1448 | { | 1503 | { |
1449 | ide_hwif_t *hwif, *mate = NULL; | 1504 | ide_hwif_t *hwif, *mate = NULL; |
1450 | int i, rc = 0; | 1505 | int i, rc = 0; |
1451 | 1506 | ||
1452 | for (i = 0; i < MAX_HWIFS; i++) { | 1507 | for (i = 0; i < MAX_HWIFS; i++) { |
1453 | if (d == NULL || idx[i] == 0xff) { | 1508 | if (idx[i] == 0xff) { |
1454 | mate = NULL; | 1509 | mate = NULL; |
1455 | continue; | 1510 | continue; |
1456 | } | 1511 | } |
1457 | 1512 | ||
1458 | hwif = &ide_hwifs[idx[i]]; | 1513 | hwif = &ide_hwifs[idx[i]]; |
1459 | 1514 | ||
1515 | ide_port_apply_params(hwif); | ||
1516 | |||
1517 | if (d == NULL) { | ||
1518 | mate = NULL; | ||
1519 | continue; | ||
1520 | } | ||
1521 | |||
1460 | if (d->chipset != ide_etrax100 && (i & 1) && mate) { | 1522 | if (d->chipset != ide_etrax100 && (i & 1) && mate) { |
1461 | hwif->mate = mate; | 1523 | hwif->mate = mate; |
1462 | mate->mate = hwif; | 1524 | mate->mate = hwif; |
@@ -1475,25 +1537,15 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d) | |||
1475 | 1537 | ||
1476 | hwif = &ide_hwifs[idx[i]]; | 1538 | hwif = &ide_hwifs[idx[i]]; |
1477 | 1539 | ||
1478 | if ((hwif->chipset != ide_4drives || !hwif->mate || | 1540 | if (ide_probe_port(hwif) == 0) |
1479 | !hwif->mate->present) && ide_hwif_request_regions(hwif)) { | 1541 | hwif->present = 1; |
1480 | printk(KERN_ERR "%s: ports already in use, " | ||
1481 | "skipping probe\n", hwif->name); | ||
1482 | continue; | ||
1483 | } | ||
1484 | |||
1485 | if (ide_probe_port(hwif) < 0) { | ||
1486 | ide_hwif_release_regions(hwif); | ||
1487 | continue; | ||
1488 | } | ||
1489 | |||
1490 | hwif->present = 1; | ||
1491 | 1542 | ||
1492 | if (hwif->chipset != ide_4drives || !hwif->mate || | 1543 | if (hwif->chipset != ide_4drives || !hwif->mate || |
1493 | !hwif->mate->present) | 1544 | !hwif->mate->present) |
1494 | ide_register_port(hwif); | 1545 | ide_register_port(hwif); |
1495 | 1546 | ||
1496 | ide_port_tune_devices(hwif); | 1547 | if (hwif->present) |
1548 | ide_port_tune_devices(hwif); | ||
1497 | } | 1549 | } |
1498 | 1550 | ||
1499 | for (i = 0; i < MAX_HWIFS; i++) { | 1551 | for (i = 0; i < MAX_HWIFS; i++) { |
@@ -1502,9 +1554,6 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d) | |||
1502 | 1554 | ||
1503 | hwif = &ide_hwifs[idx[i]]; | 1555 | hwif = &ide_hwifs[idx[i]]; |
1504 | 1556 | ||
1505 | if (!hwif->present) | ||
1506 | continue; | ||
1507 | |||
1508 | if (hwif_init(hwif) == 0) { | 1557 | if (hwif_init(hwif) == 0) { |
1509 | printk(KERN_INFO "%s: failed to initialize IDE " | 1558 | printk(KERN_INFO "%s: failed to initialize IDE " |
1510 | "interface\n", hwif->name); | 1559 | "interface\n", hwif->name); |
@@ -1513,10 +1562,13 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d) | |||
1513 | continue; | 1562 | continue; |
1514 | } | 1563 | } |
1515 | 1564 | ||
1516 | ide_port_setup_devices(hwif); | 1565 | if (hwif->present) |
1566 | ide_port_setup_devices(hwif); | ||
1517 | 1567 | ||
1518 | ide_acpi_init(hwif); | 1568 | ide_acpi_init(hwif); |
1519 | ide_acpi_port_init_devices(hwif); | 1569 | |
1570 | if (hwif->present) | ||
1571 | ide_acpi_port_init_devices(hwif); | ||
1520 | } | 1572 | } |
1521 | 1573 | ||
1522 | for (i = 0; i < MAX_HWIFS; i++) { | 1574 | for (i = 0; i < MAX_HWIFS; i++) { |
@@ -1525,11 +1577,11 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d) | |||
1525 | 1577 | ||
1526 | hwif = &ide_hwifs[idx[i]]; | 1578 | hwif = &ide_hwifs[idx[i]]; |
1527 | 1579 | ||
1528 | if (hwif->present) { | 1580 | if (hwif->chipset == ide_unknown) |
1529 | if (hwif->chipset == ide_unknown) | 1581 | hwif->chipset = ide_generic; |
1530 | hwif->chipset = ide_generic; | 1582 | |
1583 | if (hwif->present) | ||
1531 | hwif_register_devices(hwif); | 1584 | hwif_register_devices(hwif); |
1532 | } | ||
1533 | } | 1585 | } |
1534 | 1586 | ||
1535 | for (i = 0; i < MAX_HWIFS; i++) { | 1587 | for (i = 0; i < MAX_HWIFS; i++) { |
@@ -1538,11 +1590,11 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d) | |||
1538 | 1590 | ||
1539 | hwif = &ide_hwifs[idx[i]]; | 1591 | hwif = &ide_hwifs[idx[i]]; |
1540 | 1592 | ||
1541 | if (hwif->present) { | 1593 | ide_sysfs_register_port(hwif); |
1542 | ide_sysfs_register_port(hwif); | 1594 | ide_proc_register_port(hwif); |
1543 | ide_proc_register_port(hwif); | 1595 | |
1596 | if (hwif->present) | ||
1544 | ide_proc_port_register_devices(hwif); | 1597 | ide_proc_port_register_devices(hwif); |
1545 | } | ||
1546 | } | 1598 | } |
1547 | 1599 | ||
1548 | return rc; | 1600 | return rc; |
@@ -1563,6 +1615,7 @@ EXPORT_SYMBOL_GPL(ide_device_add); | |||
1563 | 1615 | ||
1564 | void ide_port_scan(ide_hwif_t *hwif) | 1616 | void ide_port_scan(ide_hwif_t *hwif) |
1565 | { | 1617 | { |
1618 | ide_port_apply_params(hwif); | ||
1566 | ide_port_cable_detect(hwif); | 1619 | ide_port_cable_detect(hwif); |
1567 | ide_port_init_devices(hwif); | 1620 | ide_port_init_devices(hwif); |
1568 | 1621 | ||
@@ -1578,3 +1631,67 @@ void ide_port_scan(ide_hwif_t *hwif) | |||
1578 | ide_proc_port_register_devices(hwif); | 1631 | ide_proc_port_register_devices(hwif); |
1579 | } | 1632 | } |
1580 | EXPORT_SYMBOL_GPL(ide_port_scan); | 1633 | EXPORT_SYMBOL_GPL(ide_port_scan); |
1634 | |||
1635 | static void ide_legacy_init_one(u8 *idx, hw_regs_t *hw, u8 port_no, | ||
1636 | const struct ide_port_info *d, | ||
1637 | unsigned long config) | ||
1638 | { | ||
1639 | ide_hwif_t *hwif; | ||
1640 | unsigned long base, ctl; | ||
1641 | int irq; | ||
1642 | |||
1643 | if (port_no == 0) { | ||
1644 | base = 0x1f0; | ||
1645 | ctl = 0x3f6; | ||
1646 | irq = 14; | ||
1647 | } else { | ||
1648 | base = 0x170; | ||
1649 | ctl = 0x376; | ||
1650 | irq = 15; | ||
1651 | } | ||
1652 | |||
1653 | if (!request_region(base, 8, d->name)) { | ||
1654 | printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", | ||
1655 | d->name, base, base + 7); | ||
1656 | return; | ||
1657 | } | ||
1658 | |||
1659 | if (!request_region(ctl, 1, d->name)) { | ||
1660 | printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", | ||
1661 | d->name, ctl); | ||
1662 | release_region(base, 8); | ||
1663 | return; | ||
1664 | } | ||
1665 | |||
1666 | ide_std_init_ports(hw, base, ctl); | ||
1667 | hw->irq = irq; | ||
1668 | |||
1669 | hwif = ide_find_port_slot(d); | ||
1670 | if (hwif) { | ||
1671 | ide_init_port_hw(hwif, hw); | ||
1672 | if (config) | ||
1673 | hwif->config_data = config; | ||
1674 | idx[port_no] = hwif->index; | ||
1675 | } | ||
1676 | } | ||
1677 | |||
1678 | int ide_legacy_device_add(const struct ide_port_info *d, unsigned long config) | ||
1679 | { | ||
1680 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
1681 | hw_regs_t hw[2]; | ||
1682 | |||
1683 | memset(&hw, 0, sizeof(hw)); | ||
1684 | |||
1685 | if ((d->host_flags & IDE_HFLAG_QD_2ND_PORT) == 0) | ||
1686 | ide_legacy_init_one(idx, &hw[0], 0, d, config); | ||
1687 | ide_legacy_init_one(idx, &hw[1], 1, d, config); | ||
1688 | |||
1689 | if (idx[0] == 0xff && idx[1] == 0xff && | ||
1690 | (d->host_flags & IDE_HFLAG_SINGLE)) | ||
1691 | return -ENOENT; | ||
1692 | |||
1693 | ide_device_add(idx, d); | ||
1694 | |||
1695 | return 0; | ||
1696 | } | ||
1697 | EXPORT_SYMBOL_GPL(ide_legacy_device_add); | ||