diff options
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r-- | drivers/ide/ide-probe.c | 278 |
1 files changed, 193 insertions, 85 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 98a8af44bf64..9c07bdb68d1a 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -423,8 +423,9 @@ static int ide_busy_sleep(ide_hwif_t *hwif) | |||
423 | 423 | ||
424 | static int do_probe (ide_drive_t *drive, u8 cmd) | 424 | static int do_probe (ide_drive_t *drive, u8 cmd) |
425 | { | 425 | { |
426 | int rc; | ||
427 | ide_hwif_t *hwif = HWIF(drive); | 426 | ide_hwif_t *hwif = HWIF(drive); |
427 | int rc; | ||
428 | u8 stat; | ||
428 | 429 | ||
429 | if (drive->present) { | 430 | if (drive->present) { |
430 | /* avoid waiting for inappropriate probes */ | 431 | /* avoid waiting for inappropriate probes */ |
@@ -461,15 +462,17 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
461 | /* failed: try again */ | 462 | /* failed: try again */ |
462 | rc = try_to_identify(drive,cmd); | 463 | rc = try_to_identify(drive,cmd); |
463 | } | 464 | } |
464 | if (hwif->INB(IDE_STATUS_REG) == (BUSY_STAT|READY_STAT)) | 465 | |
466 | stat = hwif->INB(IDE_STATUS_REG); | ||
467 | |||
468 | if (stat == (BUSY_STAT | READY_STAT)) | ||
465 | return 4; | 469 | return 4; |
466 | 470 | ||
467 | if ((rc == 1 && cmd == WIN_PIDENTIFY) && | 471 | if ((rc == 1 && cmd == WIN_PIDENTIFY) && |
468 | ((drive->autotune == IDE_TUNE_DEFAULT) || | 472 | ((drive->autotune == IDE_TUNE_DEFAULT) || |
469 | (drive->autotune == IDE_TUNE_AUTO))) { | 473 | (drive->autotune == IDE_TUNE_AUTO))) { |
470 | printk("%s: no response (status = 0x%02x), " | 474 | printk(KERN_ERR "%s: no response (status = 0x%02x), " |
471 | "resetting drive\n", drive->name, | 475 | "resetting drive\n", drive->name, stat); |
472 | hwif->INB(IDE_STATUS_REG)); | ||
473 | msleep(50); | 476 | msleep(50); |
474 | hwif->OUTB(drive->select.all, IDE_SELECT_REG); | 477 | hwif->OUTB(drive->select.all, IDE_SELECT_REG); |
475 | msleep(50); | 478 | msleep(50); |
@@ -477,11 +480,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
477 | (void)ide_busy_sleep(hwif); | 480 | (void)ide_busy_sleep(hwif); |
478 | rc = try_to_identify(drive, cmd); | 481 | rc = try_to_identify(drive, cmd); |
479 | } | 482 | } |
483 | |||
484 | /* ensure drive IRQ is clear */ | ||
485 | stat = hwif->INB(IDE_STATUS_REG); | ||
486 | |||
480 | if (rc == 1) | 487 | if (rc == 1) |
481 | printk("%s: no response (status = 0x%02x)\n", | 488 | printk(KERN_ERR "%s: no response (status = 0x%02x)\n", |
482 | drive->name, hwif->INB(IDE_STATUS_REG)); | 489 | drive->name, stat); |
483 | /* ensure drive irq is clear */ | ||
484 | (void) hwif->INB(IDE_STATUS_REG); | ||
485 | } else { | 490 | } else { |
486 | /* not present or maybe ATAPI */ | 491 | /* not present or maybe ATAPI */ |
487 | rc = 3; | 492 | rc = 3; |
@@ -502,6 +507,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
502 | static void enable_nest (ide_drive_t *drive) | 507 | static void enable_nest (ide_drive_t *drive) |
503 | { | 508 | { |
504 | ide_hwif_t *hwif = HWIF(drive); | 509 | ide_hwif_t *hwif = HWIF(drive); |
510 | u8 stat; | ||
505 | 511 | ||
506 | printk("%s: enabling %s -- ", hwif->name, drive->id->model); | 512 | printk("%s: enabling %s -- ", hwif->name, drive->id->model); |
507 | SELECT_DRIVE(drive); | 513 | SELECT_DRIVE(drive); |
@@ -515,11 +521,12 @@ static void enable_nest (ide_drive_t *drive) | |||
515 | 521 | ||
516 | msleep(50); | 522 | msleep(50); |
517 | 523 | ||
518 | if (!OK_STAT((hwif->INB(IDE_STATUS_REG)), 0, BAD_STAT)) { | 524 | stat = hwif->INB(IDE_STATUS_REG); |
519 | printk("failed (status = 0x%02x)\n", hwif->INB(IDE_STATUS_REG)); | 525 | |
520 | } else { | 526 | if (!OK_STAT(stat, 0, BAD_STAT)) |
521 | printk("success\n"); | 527 | printk(KERN_CONT "failed (status = 0x%02x)\n", stat); |
522 | } | 528 | else |
529 | printk(KERN_CONT "success\n"); | ||
523 | 530 | ||
524 | /* if !(success||timed-out) */ | 531 | /* if !(success||timed-out) */ |
525 | if (do_probe(drive, WIN_IDENTIFY) >= 2) { | 532 | if (do_probe(drive, WIN_IDENTIFY) >= 2) { |
@@ -822,7 +829,7 @@ static void ide_port_tune_devices(ide_hwif_t *hwif) | |||
822 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 829 | for (unit = 0; unit < MAX_DRIVES; ++unit) { |
823 | ide_drive_t *drive = &hwif->drives[unit]; | 830 | ide_drive_t *drive = &hwif->drives[unit]; |
824 | 831 | ||
825 | if (hwif->no_io_32bit) | 832 | if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) |
826 | drive->no_io_32bit = 1; | 833 | drive->no_io_32bit = 1; |
827 | else | 834 | else |
828 | drive->no_io_32bit = drive->id->dword_io ? 1 : 0; | 835 | drive->no_io_32bit = drive->id->dword_io ? 1 : 0; |
@@ -881,13 +888,6 @@ static int ide_init_queue(ide_drive_t *drive) | |||
881 | q->queuedata = drive; | 888 | q->queuedata = drive; |
882 | blk_queue_segment_boundary(q, 0xffff); | 889 | blk_queue_segment_boundary(q, 0xffff); |
883 | 890 | ||
884 | if (!hwif->rqsize) { | ||
885 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) || | ||
886 | (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA)) | ||
887 | hwif->rqsize = 256; | ||
888 | else | ||
889 | hwif->rqsize = 65536; | ||
890 | } | ||
891 | if (hwif->rqsize < max_sectors) | 891 | if (hwif->rqsize < max_sectors) |
892 | max_sectors = hwif->rqsize; | 892 | max_sectors = hwif->rqsize; |
893 | blk_queue_max_sectors(q, max_sectors); | 893 | blk_queue_max_sectors(q, max_sectors); |
@@ -918,6 +918,48 @@ static int ide_init_queue(ide_drive_t *drive) | |||
918 | return 0; | 918 | return 0; |
919 | } | 919 | } |
920 | 920 | ||
921 | static void ide_add_drive_to_hwgroup(ide_drive_t *drive) | ||
922 | { | ||
923 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | ||
924 | |||
925 | spin_lock_irq(&ide_lock); | ||
926 | if (!hwgroup->drive) { | ||
927 | /* first drive for hwgroup. */ | ||
928 | drive->next = drive; | ||
929 | hwgroup->drive = drive; | ||
930 | hwgroup->hwif = HWIF(hwgroup->drive); | ||
931 | } else { | ||
932 | drive->next = hwgroup->drive->next; | ||
933 | hwgroup->drive->next = drive; | ||
934 | } | ||
935 | spin_unlock_irq(&ide_lock); | ||
936 | } | ||
937 | |||
938 | /* | ||
939 | * For any present drive: | ||
940 | * - allocate the block device queue | ||
941 | * - link drive into the hwgroup | ||
942 | */ | ||
943 | static void ide_port_setup_devices(ide_hwif_t *hwif) | ||
944 | { | ||
945 | int i; | ||
946 | |||
947 | for (i = 0; i < MAX_DRIVES; i++) { | ||
948 | ide_drive_t *drive = &hwif->drives[i]; | ||
949 | |||
950 | if (!drive->present) | ||
951 | continue; | ||
952 | |||
953 | if (ide_init_queue(drive)) { | ||
954 | printk(KERN_ERR "ide: failed to init %s\n", | ||
955 | drive->name); | ||
956 | continue; | ||
957 | } | ||
958 | |||
959 | ide_add_drive_to_hwgroup(drive); | ||
960 | } | ||
961 | } | ||
962 | |||
921 | /* | 963 | /* |
922 | * This routine sets up the irq for an ide interface, and creates a new | 964 | * This routine sets up the irq for an ide interface, and creates a new |
923 | * hwgroup for the irq/hwif if none was previously assigned. | 965 | * hwgroup for the irq/hwif if none was previously assigned. |
@@ -1019,30 +1061,12 @@ static int init_irq (ide_hwif_t *hwif) | |||
1019 | goto out_unlink; | 1061 | goto out_unlink; |
1020 | } | 1062 | } |
1021 | 1063 | ||
1022 | /* | 1064 | if (!hwif->rqsize) { |
1023 | * For any present drive: | 1065 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) || |
1024 | * - allocate the block device queue | 1066 | (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA)) |
1025 | * - link drive into the hwgroup | 1067 | hwif->rqsize = 256; |
1026 | */ | 1068 | else |
1027 | for (index = 0; index < MAX_DRIVES; ++index) { | 1069 | hwif->rqsize = 65536; |
1028 | ide_drive_t *drive = &hwif->drives[index]; | ||
1029 | if (!drive->present) | ||
1030 | continue; | ||
1031 | if (ide_init_queue(drive)) { | ||
1032 | printk(KERN_ERR "ide: failed to init %s\n",drive->name); | ||
1033 | continue; | ||
1034 | } | ||
1035 | spin_lock_irq(&ide_lock); | ||
1036 | if (!hwgroup->drive) { | ||
1037 | /* first drive for hwgroup. */ | ||
1038 | drive->next = drive; | ||
1039 | hwgroup->drive = drive; | ||
1040 | hwgroup->hwif = HWIF(hwgroup->drive); | ||
1041 | } else { | ||
1042 | drive->next = hwgroup->drive->next; | ||
1043 | hwgroup->drive->next = drive; | ||
1044 | } | ||
1045 | spin_unlock_irq(&ide_lock); | ||
1046 | } | 1070 | } |
1047 | 1071 | ||
1048 | #if !defined(__mc68000__) && !defined(CONFIG_APUS) | 1072 | #if !defined(__mc68000__) && !defined(CONFIG_APUS) |
@@ -1058,6 +1082,9 @@ static int init_irq (ide_hwif_t *hwif) | |||
1058 | printk(" (%sed with %s)", | 1082 | printk(" (%sed with %s)", |
1059 | hwif->sharing_irq ? "shar" : "serializ", match->name); | 1083 | hwif->sharing_irq ? "shar" : "serializ", match->name); |
1060 | printk("\n"); | 1084 | printk("\n"); |
1085 | |||
1086 | ide_port_setup_devices(hwif); | ||
1087 | |||
1061 | mutex_unlock(&ide_cfg_mtx); | 1088 | mutex_unlock(&ide_cfg_mtx); |
1062 | return 0; | 1089 | return 0; |
1063 | out_unlink: | 1090 | out_unlink: |
@@ -1182,30 +1209,6 @@ static void drive_release_dev (struct device *dev) | |||
1182 | complete(&drive->gendev_rel_comp); | 1209 | complete(&drive->gendev_rel_comp); |
1183 | } | 1210 | } |
1184 | 1211 | ||
1185 | /* | ||
1186 | * init_gendisk() (as opposed to ide_geninit) is called for each major device, | ||
1187 | * after probing for drives, to allocate partition tables and other data | ||
1188 | * structures needed for the routines in genhd.c. ide_geninit() gets called | ||
1189 | * somewhat later, during the partition check. | ||
1190 | */ | ||
1191 | static void init_gendisk (ide_hwif_t *hwif) | ||
1192 | { | ||
1193 | unsigned int unit; | ||
1194 | |||
1195 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | ||
1196 | ide_drive_t * drive = &hwif->drives[unit]; | ||
1197 | ide_add_generic_settings(drive); | ||
1198 | snprintf(drive->gendev.bus_id,BUS_ID_SIZE,"%u.%u", | ||
1199 | hwif->index,unit); | ||
1200 | drive->gendev.parent = &hwif->gendev; | ||
1201 | drive->gendev.bus = &ide_bus_type; | ||
1202 | drive->gendev.driver_data = drive; | ||
1203 | drive->gendev.release = drive_release_dev; | ||
1204 | } | ||
1205 | blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS, | ||
1206 | THIS_MODULE, ata_probe, ata_lock, hwif); | ||
1207 | } | ||
1208 | |||
1209 | static int hwif_init(ide_hwif_t *hwif) | 1212 | static int hwif_init(ide_hwif_t *hwif) |
1210 | { | 1213 | { |
1211 | int old_irq; | 1214 | int old_irq; |
@@ -1262,8 +1265,8 @@ static int hwif_init(ide_hwif_t *hwif) | |||
1262 | hwif->name, hwif->irq); | 1265 | hwif->name, hwif->irq); |
1263 | 1266 | ||
1264 | done: | 1267 | done: |
1265 | init_gendisk(hwif); | 1268 | blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS, |
1266 | ide_acpi_init(hwif); | 1269 | THIS_MODULE, ata_probe, ata_lock, hwif); |
1267 | return 1; | 1270 | return 1; |
1268 | 1271 | ||
1269 | out: | 1272 | out: |
@@ -1277,24 +1280,119 @@ static void hwif_register_devices(ide_hwif_t *hwif) | |||
1277 | 1280 | ||
1278 | for (i = 0; i < MAX_DRIVES; i++) { | 1281 | for (i = 0; i < MAX_DRIVES; i++) { |
1279 | ide_drive_t *drive = &hwif->drives[i]; | 1282 | ide_drive_t *drive = &hwif->drives[i]; |
1283 | struct device *dev = &drive->gendev; | ||
1284 | int ret; | ||
1280 | 1285 | ||
1281 | if (drive->present) { | 1286 | if (!drive->present) |
1282 | int ret = device_register(&drive->gendev); | 1287 | continue; |
1283 | 1288 | ||
1284 | if (ret < 0) | 1289 | ide_add_generic_settings(drive); |
1285 | printk(KERN_WARNING "IDE: %s: " | 1290 | |
1286 | "device_register error: %d\n", | 1291 | snprintf(dev->bus_id, BUS_ID_SIZE, "%u.%u", hwif->index, i); |
1287 | __FUNCTION__, ret); | 1292 | dev->parent = &hwif->gendev; |
1288 | } | 1293 | dev->bus = &ide_bus_type; |
1294 | dev->driver_data = drive; | ||
1295 | dev->release = drive_release_dev; | ||
1296 | |||
1297 | ret = device_register(dev); | ||
1298 | if (ret < 0) | ||
1299 | printk(KERN_WARNING "IDE: %s: device_register error: " | ||
1300 | "%d\n", __func__, ret); | ||
1301 | } | ||
1302 | } | ||
1303 | |||
1304 | static void ide_port_init_devices(ide_hwif_t *hwif) | ||
1305 | { | ||
1306 | int i; | ||
1307 | |||
1308 | for (i = 0; i < MAX_DRIVES; i++) { | ||
1309 | ide_drive_t *drive = &hwif->drives[i]; | ||
1310 | |||
1311 | if (hwif->host_flags & IDE_HFLAG_IO_32BIT) | ||
1312 | drive->io_32bit = 1; | ||
1313 | if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS) | ||
1314 | drive->unmask = 1; | ||
1315 | if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS) | ||
1316 | drive->no_unmask = 1; | ||
1317 | if ((hwif->host_flags & IDE_HFLAG_NO_AUTOTUNE) == 0) | ||
1318 | drive->autotune = 1; | ||
1319 | } | ||
1320 | |||
1321 | if (hwif->port_init_devs) | ||
1322 | hwif->port_init_devs(hwif); | ||
1323 | } | ||
1324 | |||
1325 | static void ide_init_port(ide_hwif_t *hwif, unsigned int port, | ||
1326 | const struct ide_port_info *d) | ||
1327 | { | ||
1328 | if (d->chipset != ide_etrax100) | ||
1329 | hwif->channel = port; | ||
1330 | |||
1331 | if (d->chipset) | ||
1332 | hwif->chipset = d->chipset; | ||
1333 | |||
1334 | if (d->init_iops) | ||
1335 | d->init_iops(hwif); | ||
1336 | |||
1337 | if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) | ||
1338 | ide_hwif_setup_dma(hwif, d); | ||
1339 | |||
1340 | if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) || | ||
1341 | (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS)) | ||
1342 | hwif->irq = port ? 15 : 14; | ||
1343 | |||
1344 | hwif->host_flags = d->host_flags; | ||
1345 | hwif->pio_mask = d->pio_mask; | ||
1346 | |||
1347 | if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate) | ||
1348 | hwif->mate->serialized = hwif->serialized = 1; | ||
1349 | |||
1350 | hwif->swdma_mask = d->swdma_mask; | ||
1351 | hwif->mwdma_mask = d->mwdma_mask; | ||
1352 | hwif->ultra_mask = d->udma_mask; | ||
1353 | |||
1354 | /* reset DMA masks only for SFF-style DMA controllers */ | ||
1355 | if ((d->host_flags && IDE_HFLAG_NO_DMA) == 0 && hwif->dma_base == 0) | ||
1356 | hwif->swdma_mask = hwif->mwdma_mask = hwif->ultra_mask = 0; | ||
1357 | |||
1358 | if (d->host_flags & IDE_HFLAG_RQSIZE_256) | ||
1359 | hwif->rqsize = 256; | ||
1360 | |||
1361 | /* call chipset specific routine for each enabled port */ | ||
1362 | if (d->init_hwif) | ||
1363 | d->init_hwif(hwif); | ||
1364 | |||
1365 | if (hwif->cable_detect && (hwif->ultra_mask & 0x78)) { | ||
1366 | if (hwif->cbl != ATA_CBL_PATA40_SHORT) | ||
1367 | hwif->cbl = hwif->cable_detect(hwif); | ||
1289 | } | 1368 | } |
1290 | } | 1369 | } |
1291 | 1370 | ||
1292 | int ide_device_add_all(u8 *idx) | 1371 | int ide_device_add_all(u8 *idx, const struct ide_port_info *d) |
1293 | { | 1372 | { |
1294 | ide_hwif_t *hwif; | 1373 | ide_hwif_t *hwif, *mate = NULL; |
1295 | int i, rc = 0; | 1374 | int i, rc = 0; |
1296 | 1375 | ||
1297 | for (i = 0; i < MAX_HWIFS; i++) { | 1376 | for (i = 0; i < MAX_HWIFS; i++) { |
1377 | if (d == NULL || idx[i] == 0xff) { | ||
1378 | mate = NULL; | ||
1379 | continue; | ||
1380 | } | ||
1381 | |||
1382 | hwif = &ide_hwifs[idx[i]]; | ||
1383 | |||
1384 | if (d->chipset != ide_etrax100 && (i & 1) && mate) { | ||
1385 | hwif->mate = mate; | ||
1386 | mate->mate = hwif; | ||
1387 | } | ||
1388 | |||
1389 | mate = (i & 1) ? NULL : hwif; | ||
1390 | |||
1391 | ide_init_port(hwif, i & 1, d); | ||
1392 | ide_port_init_devices(hwif); | ||
1393 | } | ||
1394 | |||
1395 | for (i = 0; i < MAX_HWIFS; i++) { | ||
1298 | if (idx[i] == 0xff) | 1396 | if (idx[i] == 0xff) |
1299 | continue; | 1397 | continue; |
1300 | 1398 | ||
@@ -1337,6 +1435,9 @@ int ide_device_add_all(u8 *idx) | |||
1337 | rc = -1; | 1435 | rc = -1; |
1338 | continue; | 1436 | continue; |
1339 | } | 1437 | } |
1438 | |||
1439 | ide_acpi_init(hwif); | ||
1440 | ide_acpi_port_init_devices(hwif); | ||
1340 | } | 1441 | } |
1341 | 1442 | ||
1342 | for (i = 0; i < MAX_HWIFS; i++) { | 1443 | for (i = 0; i < MAX_HWIFS; i++) { |
@@ -1354,15 +1455,22 @@ int ide_device_add_all(u8 *idx) | |||
1354 | } | 1455 | } |
1355 | 1456 | ||
1356 | for (i = 0; i < MAX_HWIFS; i++) { | 1457 | for (i = 0; i < MAX_HWIFS; i++) { |
1357 | if (idx[i] != 0xff) | 1458 | if (idx[i] == 0xff) |
1358 | ide_proc_register_port(&ide_hwifs[idx[i]]); | 1459 | continue; |
1460 | |||
1461 | hwif = &ide_hwifs[idx[i]]; | ||
1462 | |||
1463 | if (hwif->present) { | ||
1464 | ide_proc_register_port(hwif); | ||
1465 | ide_proc_port_register_devices(hwif); | ||
1466 | } | ||
1359 | } | 1467 | } |
1360 | 1468 | ||
1361 | return rc; | 1469 | return rc; |
1362 | } | 1470 | } |
1363 | EXPORT_SYMBOL_GPL(ide_device_add_all); | 1471 | EXPORT_SYMBOL_GPL(ide_device_add_all); |
1364 | 1472 | ||
1365 | int ide_device_add(u8 idx[4]) | 1473 | int ide_device_add(u8 idx[4], const struct ide_port_info *d) |
1366 | { | 1474 | { |
1367 | u8 idx_all[MAX_HWIFS]; | 1475 | u8 idx_all[MAX_HWIFS]; |
1368 | int i; | 1476 | int i; |
@@ -1370,6 +1478,6 @@ int ide_device_add(u8 idx[4]) | |||
1370 | for (i = 0; i < MAX_HWIFS; i++) | 1478 | for (i = 0; i < MAX_HWIFS; i++) |
1371 | idx_all[i] = (i < 4) ? idx[i] : 0xff; | 1479 | idx_all[i] = (i < 4) ? idx[i] : 0xff; |
1372 | 1480 | ||
1373 | return ide_device_add_all(idx_all); | 1481 | return ide_device_add_all(idx_all, d); |
1374 | } | 1482 | } |
1375 | EXPORT_SYMBOL_GPL(ide_device_add); | 1483 | EXPORT_SYMBOL_GPL(ide_device_add); |