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.c166
1 files changed, 34 insertions, 132 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index c55bdbd22314..a64ec259f3d1 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -110,20 +110,22 @@ static void ide_disk_init_mult_count(ide_drive_t *drive)
110 * read and parse the results. This function is run with 110 * read and parse the results. This function is run with
111 * interrupts disabled. 111 * interrupts disabled.
112 */ 112 */
113 113
114static inline void do_identify (ide_drive_t *drive, u8 cmd) 114static void do_identify(ide_drive_t *drive, u8 cmd)
115{ 115{
116 ide_hwif_t *hwif = HWIF(drive); 116 ide_hwif_t *hwif = HWIF(drive);
117 u16 *id = drive->id; 117 u16 *id = drive->id;
118 char *m = (char *)&id[ATA_ID_PROD]; 118 char *m = (char *)&id[ATA_ID_PROD];
119 unsigned long flags;
119 int bswap = 1, is_cfa; 120 int bswap = 1, is_cfa;
120 121
122 /* local CPU only; some systems need this */
123 local_irq_save(flags);
121 /* read 512 bytes of id info */ 124 /* read 512 bytes of id info */
122 hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); 125 hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
126 local_irq_restore(flags);
123 127
124 drive->dev_flags |= IDE_DFLAG_ID_READ; 128 drive->dev_flags |= IDE_DFLAG_ID_READ;
125
126 local_irq_enable();
127#ifdef DEBUG 129#ifdef DEBUG
128 printk(KERN_INFO "%s: dumping identify data\n", drive->name); 130 printk(KERN_INFO "%s: dumping identify data\n", drive->name);
129 ide_dump_identify((u8 *)id); 131 ide_dump_identify((u8 *)id);
@@ -306,17 +308,12 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
306 s = tp_ops->read_status(hwif); 308 s = tp_ops->read_status(hwif);
307 309
308 if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) { 310 if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
309 unsigned long flags;
310
311 /* local CPU only; some systems need this */
312 local_irq_save(flags);
313 /* drive returned ID */ 311 /* drive returned ID */
314 do_identify(drive, cmd); 312 do_identify(drive, cmd);
315 /* drive responded with ID */ 313 /* drive responded with ID */
316 rc = 0; 314 rc = 0;
317 /* clear drive IRQ */ 315 /* clear drive IRQ */
318 (void)tp_ops->read_status(hwif); 316 (void)tp_ops->read_status(hwif);
319 local_irq_restore(flags);
320 } else { 317 } else {
321 /* drive refused ID */ 318 /* drive refused ID */
322 rc = 2; 319 rc = 2;
@@ -554,8 +551,8 @@ static void enable_nest (ide_drive_t *drive)
554 * 1 device was found 551 * 1 device was found
555 * (note: IDE_DFLAG_PRESENT might still be not set) 552 * (note: IDE_DFLAG_PRESENT might still be not set)
556 */ 553 */
557 554
558static inline u8 probe_for_drive (ide_drive_t *drive) 555static u8 probe_for_drive(ide_drive_t *drive)
559{ 556{
560 char *m; 557 char *m;
561 558
@@ -642,7 +639,7 @@ static int ide_register_port(ide_hwif_t *hwif)
642 int ret; 639 int ret;
643 640
644 /* register with global device tree */ 641 /* register with global device tree */
645 strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE); 642 dev_set_name(&hwif->gendev, hwif->name);
646 hwif->gendev.driver_data = hwif; 643 hwif->gendev.driver_data = hwif;
647 if (hwif->gendev.parent == NULL) { 644 if (hwif->gendev.parent == NULL) {
648 if (hwif->dev) 645 if (hwif->dev)
@@ -864,31 +861,6 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
864} 861}
865 862
866/* 863/*
867 * save_match() is used to simplify logic in init_irq() below.
868 *
869 * A loophole here is that we may not know about a particular
870 * hwif's irq until after that hwif is actually probed/initialized..
871 * This could be a problem for the case where an hwif is on a
872 * dual interface that requires serialization (eg. cmd640) and another
873 * hwif using one of the same irqs is initialized beforehand.
874 *
875 * This routine detects and reports such situations, but does not fix them.
876 */
877static void save_match(ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
878{
879 ide_hwif_t *m = *match;
880
881 if (m && m->hwgroup && m->hwgroup != new->hwgroup) {
882 if (!new->hwgroup)
883 return;
884 printk(KERN_WARNING "%s: potential IRQ problem with %s and %s\n",
885 hwif->name, new->name, m->name);
886 }
887 if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */
888 *match = new;
889}
890
891/*
892 * init request queue 864 * init request queue
893 */ 865 */
894static int ide_init_queue(ide_drive_t *drive) 866static int ide_init_queue(ide_drive_t *drive)
@@ -906,7 +878,8 @@ static int ide_init_queue(ide_drive_t *drive)
906 * do not. 878 * do not.
907 */ 879 */
908 880
909 q = blk_init_queue_node(do_ide_request, &ide_lock, hwif_to_node(hwif)); 881 q = blk_init_queue_node(do_ide_request, &hwif->hwgroup->lock,
882 hwif_to_node(hwif));
910 if (!q) 883 if (!q)
911 return 1; 884 return 1;
912 885
@@ -947,7 +920,7 @@ static void ide_add_drive_to_hwgroup(ide_drive_t *drive)
947{ 920{
948 ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; 921 ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
949 922
950 spin_lock_irq(&ide_lock); 923 spin_lock_irq(&hwgroup->lock);
951 if (!hwgroup->drive) { 924 if (!hwgroup->drive) {
952 /* first drive for hwgroup. */ 925 /* first drive for hwgroup. */
953 drive->next = drive; 926 drive->next = drive;
@@ -957,7 +930,7 @@ static void ide_add_drive_to_hwgroup(ide_drive_t *drive)
957 drive->next = hwgroup->drive->next; 930 drive->next = hwgroup->drive->next;
958 hwgroup->drive->next = drive; 931 hwgroup->drive->next = drive;
959 } 932 }
960 spin_unlock_irq(&ide_lock); 933 spin_unlock_irq(&hwgroup->lock);
961} 934}
962 935
963/* 936/*
@@ -1002,7 +975,7 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
1002 975
1003 ide_ports[hwif->index] = NULL; 976 ide_ports[hwif->index] = NULL;
1004 977
1005 spin_lock_irq(&ide_lock); 978 spin_lock_irq(&hwgroup->lock);
1006 /* 979 /*
1007 * Remove us from the hwgroup, and free 980 * Remove us from the hwgroup, and free
1008 * the hwgroup if we were the only member 981 * the hwgroup if we were the only member
@@ -1030,7 +1003,7 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
1030 } 1003 }
1031 BUG_ON(hwgroup->hwif == hwif); 1004 BUG_ON(hwgroup->hwif == hwif);
1032 } 1005 }
1033 spin_unlock_irq(&ide_lock); 1006 spin_unlock_irq(&hwgroup->lock);
1034} 1007}
1035 1008
1036/* 1009/*
@@ -1051,27 +1024,13 @@ static int init_irq (ide_hwif_t *hwif)
1051 mutex_lock(&ide_cfg_mtx); 1024 mutex_lock(&ide_cfg_mtx);
1052 hwif->hwgroup = NULL; 1025 hwif->hwgroup = NULL;
1053 1026
1054 /*
1055 * Group up with any other hwifs that share our irq(s).
1056 */
1057 for (index = 0; index < MAX_HWIFS; index++) { 1027 for (index = 0; index < MAX_HWIFS; index++) {
1058 ide_hwif_t *h = ide_ports[index]; 1028 ide_hwif_t *h = ide_ports[index];
1059 1029
1060 if (h && h->hwgroup) { /* scan only initialized ports */ 1030 if (h && h->hwgroup) { /* scan only initialized ports */
1061 if (hwif->irq == h->irq) { 1031 if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) {
1062 hwif->sharing_irq = h->sharing_irq = 1; 1032 if (hwif->host == h->host)
1063 if (hwif->chipset != ide_pci || 1033 match = h;
1064 h->chipset != ide_pci) {
1065 save_match(hwif, h, &match);
1066 }
1067 }
1068 if (hwif->serialized) {
1069 if (hwif->mate && hwif->mate->irq == h->irq)
1070 save_match(hwif, h, &match);
1071 }
1072 if (h->serialized) {
1073 if (h->mate && hwif->irq == h->mate->irq)
1074 save_match(hwif, h, &match);
1075 } 1034 }
1076 } 1035 }
1077 } 1036 }
@@ -1092,17 +1051,19 @@ static int init_irq (ide_hwif_t *hwif)
1092 * linked list, the first entry is the hwif that owns 1051 * linked list, the first entry is the hwif that owns
1093 * hwgroup->handler - do not change that. 1052 * hwgroup->handler - do not change that.
1094 */ 1053 */
1095 spin_lock_irq(&ide_lock); 1054 spin_lock_irq(&hwgroup->lock);
1096 hwif->next = hwgroup->hwif->next; 1055 hwif->next = hwgroup->hwif->next;
1097 hwgroup->hwif->next = hwif; 1056 hwgroup->hwif->next = hwif;
1098 BUG_ON(hwif->next == hwif); 1057 BUG_ON(hwif->next == hwif);
1099 spin_unlock_irq(&ide_lock); 1058 spin_unlock_irq(&hwgroup->lock);
1100 } else { 1059 } else {
1101 hwgroup = kmalloc_node(sizeof(*hwgroup), GFP_KERNEL|__GFP_ZERO, 1060 hwgroup = kmalloc_node(sizeof(*hwgroup), GFP_KERNEL|__GFP_ZERO,
1102 hwif_to_node(hwif)); 1061 hwif_to_node(hwif));
1103 if (hwgroup == NULL) 1062 if (hwgroup == NULL)
1104 goto out_up; 1063 goto out_up;
1105 1064
1065 spin_lock_init(&hwgroup->lock);
1066
1106 hwif->hwgroup = hwgroup; 1067 hwif->hwgroup = hwgroup;
1107 hwgroup->hwif = hwif->next = hwif; 1068 hwgroup->hwif = hwif->next = hwif;
1108 1069
@@ -1122,8 +1083,7 @@ static int init_irq (ide_hwif_t *hwif)
1122 sa = IRQF_SHARED; 1083 sa = IRQF_SHARED;
1123#endif /* __mc68000__ */ 1084#endif /* __mc68000__ */
1124 1085
1125 if (hwif->chipset == ide_pci || hwif->chipset == ide_cmd646 || 1086 if (hwif->chipset == ide_pci)
1126 hwif->chipset == ide_ali14xx)
1127 sa = IRQF_SHARED; 1087 sa = IRQF_SHARED;
1128 1088
1129 if (io_ports->ctl_addr) 1089 if (io_ports->ctl_addr)
@@ -1150,8 +1110,7 @@ static int init_irq (ide_hwif_t *hwif)
1150 io_ports->data_addr, hwif->irq); 1110 io_ports->data_addr, hwif->irq);
1151#endif /* __mc68000__ */ 1111#endif /* __mc68000__ */
1152 if (match) 1112 if (match)
1153 printk(KERN_CONT " (%sed with %s)", 1113 printk(KERN_CONT " (serialized with %s)", match->name);
1154 hwif->sharing_irq ? "shar" : "serializ", match->name);
1155 printk(KERN_CONT "\n"); 1114 printk(KERN_CONT "\n");
1156 1115
1157 mutex_unlock(&ide_cfg_mtx); 1116 mutex_unlock(&ide_cfg_mtx);
@@ -1263,20 +1222,21 @@ static void ide_remove_drive_from_hwgroup(ide_drive_t *drive)
1263static void drive_release_dev (struct device *dev) 1222static void drive_release_dev (struct device *dev)
1264{ 1223{
1265 ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); 1224 ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
1225 ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
1266 1226
1267 ide_proc_unregister_device(drive); 1227 ide_proc_unregister_device(drive);
1268 1228
1269 spin_lock_irq(&ide_lock); 1229 spin_lock_irq(&hwgroup->lock);
1270 ide_remove_drive_from_hwgroup(drive); 1230 ide_remove_drive_from_hwgroup(drive);
1271 kfree(drive->id); 1231 kfree(drive->id);
1272 drive->id = NULL; 1232 drive->id = NULL;
1273 drive->dev_flags &= ~IDE_DFLAG_PRESENT; 1233 drive->dev_flags &= ~IDE_DFLAG_PRESENT;
1274 /* Messed up locking ... */ 1234 /* Messed up locking ... */
1275 spin_unlock_irq(&ide_lock); 1235 spin_unlock_irq(&hwgroup->lock);
1276 blk_cleanup_queue(drive->queue); 1236 blk_cleanup_queue(drive->queue);
1277 spin_lock_irq(&ide_lock); 1237 spin_lock_irq(&hwgroup->lock);
1278 drive->queue = NULL; 1238 drive->queue = NULL;
1279 spin_unlock_irq(&ide_lock); 1239 spin_unlock_irq(&hwgroup->lock);
1280 1240
1281 complete(&drive->gendev_rel_comp); 1241 complete(&drive->gendev_rel_comp);
1282} 1242}
@@ -1352,7 +1312,7 @@ static void hwif_register_devices(ide_hwif_t *hwif)
1352 if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) 1312 if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
1353 continue; 1313 continue;
1354 1314
1355 snprintf(dev->bus_id, BUS_ID_SIZE, "%u.%u", hwif->index, i); 1315 dev_set_name(dev, "%u.%u", hwif->index, i);
1356 dev->parent = &hwif->gendev; 1316 dev->parent = &hwif->gendev;
1357 dev->bus = &ide_bus_type; 1317 dev->bus = &ide_bus_type;
1358 dev->driver_data = drive; 1318 dev->driver_data = drive;
@@ -1436,13 +1396,11 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
1436 } 1396 }
1437 1397
1438 if ((d->host_flags & IDE_HFLAG_SERIALIZE) || 1398 if ((d->host_flags & IDE_HFLAG_SERIALIZE) ||
1439 ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base)) { 1399 ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base))
1440 if (hwif->mate) 1400 hwif->host->host_flags |= IDE_HFLAG_SERIALIZE;
1441 hwif->mate->serialized = hwif->serialized = 1;
1442 }
1443 1401
1444 if (d->host_flags & IDE_HFLAG_RQSIZE_256) 1402 if (d->max_sectors)
1445 hwif->rqsize = 256; 1403 hwif->rqsize = d->max_sectors;
1446 1404
1447 /* call chipset specific routine for each enabled port */ 1405 /* call chipset specific routine for each enabled port */
1448 if (d->init_hwif) 1406 if (d->init_hwif)
@@ -1794,59 +1752,3 @@ void ide_port_scan(ide_hwif_t *hwif)
1794 ide_proc_port_register_devices(hwif); 1752 ide_proc_port_register_devices(hwif);
1795} 1753}
1796EXPORT_SYMBOL_GPL(ide_port_scan); 1754EXPORT_SYMBOL_GPL(ide_port_scan);
1797
1798static void ide_legacy_init_one(hw_regs_t **hws, hw_regs_t *hw,
1799 u8 port_no, const struct ide_port_info *d,
1800 unsigned long config)
1801{
1802 unsigned long base, ctl;
1803 int irq;
1804
1805 if (port_no == 0) {
1806 base = 0x1f0;
1807 ctl = 0x3f6;
1808 irq = 14;
1809 } else {
1810 base = 0x170;
1811 ctl = 0x376;
1812 irq = 15;
1813 }
1814
1815 if (!request_region(base, 8, d->name)) {
1816 printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
1817 d->name, base, base + 7);
1818 return;
1819 }
1820
1821 if (!request_region(ctl, 1, d->name)) {
1822 printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
1823 d->name, ctl);
1824 release_region(base, 8);
1825 return;
1826 }
1827
1828 ide_std_init_ports(hw, base, ctl);
1829 hw->irq = irq;
1830 hw->chipset = d->chipset;
1831 hw->config = config;
1832
1833 hws[port_no] = hw;
1834}
1835
1836int ide_legacy_device_add(const struct ide_port_info *d, unsigned long config)
1837{
1838 hw_regs_t hw[2], *hws[] = { NULL, NULL, NULL, NULL };
1839
1840 memset(&hw, 0, sizeof(hw));
1841
1842 if ((d->host_flags & IDE_HFLAG_QD_2ND_PORT) == 0)
1843 ide_legacy_init_one(hws, &hw[0], 0, d, config);
1844 ide_legacy_init_one(hws, &hw[1], 1, d, config);
1845
1846 if (hws[0] == NULL && hws[1] == NULL &&
1847 (d->host_flags & IDE_HFLAG_SINGLE))
1848 return -ENOENT;
1849
1850 return ide_host_add(d, hws, NULL);
1851}
1852EXPORT_SYMBOL_GPL(ide_legacy_device_add);