aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r--drivers/ide/ide-probe.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index e953b70706c2..09ea50118e63 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -918,6 +918,8 @@ static int ide_init_queue(ide_drive_t *drive)
918 return 0; 918 return 0;
919} 919}
920 920
921static DEFINE_MUTEX(ide_cfg_mtx);
922
921/* 923/*
922 * For any present drive: 924 * For any present drive:
923 * - allocate the block device queue 925 * - allocate the block device queue
@@ -1273,6 +1275,69 @@ static void ide_port_cable_detect(ide_hwif_t *hwif)
1273 } 1275 }
1274} 1276}
1275 1277
1278static const u8 ide_hwif_to_major[] =
1279 { IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR,
1280 IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR, IDE8_MAJOR, IDE9_MAJOR };
1281
1282static void ide_port_init_devices_data(ide_hwif_t *hwif)
1283{
1284 int unit;
1285
1286 for (unit = 0; unit < MAX_DRIVES; ++unit) {
1287 ide_drive_t *drive = &hwif->drives[unit];
1288 u8 j = (hwif->index * MAX_DRIVES) + unit;
1289
1290 memset(drive, 0, sizeof(*drive));
1291
1292 drive->media = ide_disk;
1293 drive->select = (unit << 4) | ATA_DEVICE_OBS;
1294 drive->hwif = hwif;
1295 drive->ready_stat = ATA_DRDY;
1296 drive->bad_wstat = BAD_W_STAT;
1297 drive->special.b.recalibrate = 1;
1298 drive->special.b.set_geometry = 1;
1299 drive->name[0] = 'h';
1300 drive->name[1] = 'd';
1301 drive->name[2] = 'a' + j;
1302 drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
1303
1304 INIT_LIST_HEAD(&drive->list);
1305 init_completion(&drive->gendev_rel_comp);
1306 }
1307}
1308
1309static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
1310{
1311 /* bulk initialize hwif & drive info with zeros */
1312 memset(hwif, 0, sizeof(ide_hwif_t));
1313
1314 /* fill in any non-zero initial values */
1315 hwif->index = index;
1316 hwif->major = ide_hwif_to_major[index];
1317
1318 hwif->name[0] = 'i';
1319 hwif->name[1] = 'd';
1320 hwif->name[2] = 'e';
1321 hwif->name[3] = '0' + index;
1322
1323 init_completion(&hwif->gendev_rel_comp);
1324
1325 hwif->tp_ops = &default_tp_ops;
1326
1327 ide_port_init_devices_data(hwif);
1328}
1329
1330static void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
1331{
1332 memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports));
1333 hwif->irq = hw->irq;
1334 hwif->chipset = hw->chipset;
1335 hwif->dev = hw->dev;
1336 hwif->gendev.parent = hw->parent ? hw->parent : hw->dev;
1337 hwif->ack_intr = hw->ack_intr;
1338 hwif->config_data = hw->config;
1339}
1340
1276static unsigned int ide_indexes; 1341static unsigned int ide_indexes;
1277 1342
1278/** 1343/**
@@ -1503,6 +1568,76 @@ int ide_host_add(const struct ide_port_info *d, hw_regs_t **hws,
1503} 1568}
1504EXPORT_SYMBOL_GPL(ide_host_add); 1569EXPORT_SYMBOL_GPL(ide_host_add);
1505 1570
1571static void __ide_port_unregister_devices(ide_hwif_t *hwif)
1572{
1573 int i;
1574
1575 for (i = 0; i < MAX_DRIVES; i++) {
1576 ide_drive_t *drive = &hwif->drives[i];
1577
1578 if (drive->dev_flags & IDE_DFLAG_PRESENT) {
1579 device_unregister(&drive->gendev);
1580 wait_for_completion(&drive->gendev_rel_comp);
1581 }
1582 }
1583}
1584
1585void ide_port_unregister_devices(ide_hwif_t *hwif)
1586{
1587 mutex_lock(&ide_cfg_mtx);
1588 __ide_port_unregister_devices(hwif);
1589 hwif->present = 0;
1590 ide_port_init_devices_data(hwif);
1591 mutex_unlock(&ide_cfg_mtx);
1592}
1593EXPORT_SYMBOL_GPL(ide_port_unregister_devices);
1594
1595/**
1596 * ide_unregister - free an IDE interface
1597 * @hwif: IDE interface
1598 *
1599 * Perform the final unregister of an IDE interface.
1600 *
1601 * Locking:
1602 * The caller must not hold the IDE locks.
1603 *
1604 * It is up to the caller to be sure there is no pending I/O here,
1605 * and that the interface will not be reopened (present/vanishing
1606 * locking isn't yet done BTW).
1607 */
1608
1609static void ide_unregister(ide_hwif_t *hwif)
1610{
1611 BUG_ON(in_interrupt());
1612 BUG_ON(irqs_disabled());
1613
1614 mutex_lock(&ide_cfg_mtx);
1615
1616 if (hwif->present) {
1617 __ide_port_unregister_devices(hwif);
1618 hwif->present = 0;
1619 }
1620
1621 ide_proc_unregister_port(hwif);
1622
1623 free_irq(hwif->irq, hwif);
1624
1625 device_unregister(hwif->portdev);
1626 device_unregister(&hwif->gendev);
1627 wait_for_completion(&hwif->gendev_rel_comp);
1628
1629 /*
1630 * Remove us from the kernel's knowledge
1631 */
1632 blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS);
1633 kfree(hwif->sg_table);
1634 unregister_blkdev(hwif->major, hwif->name);
1635
1636 ide_release_dma_engine(hwif);
1637
1638 mutex_unlock(&ide_cfg_mtx);
1639}
1640
1506void ide_host_free(struct ide_host *host) 1641void ide_host_free(struct ide_host *host)
1507{ 1642{
1508 ide_hwif_t *hwif; 1643 ide_hwif_t *hwif;