at v2.6.26-rc7 153 lines 3.2 kB view raw
1/* 2 * generic/default IDE host driver 3 * 4 * Copyright (C) 2004, 2008 Bartlomiej Zolnierkiewicz 5 * This code was split off from ide.c. See it for original copyrights. 6 * 7 * May be copied or modified under the terms of the GNU General Public License. 8 */ 9 10/* 11 * For special cases new interfaces may be added using sysfs, i.e. 12 * 13 * echo -n "0x168:0x36e:10" > /sys/class/ide_generic/add 14 * 15 * will add an interface using I/O ports 0x168-0x16f/0x36e and IRQ 10. 16 */ 17 18#include <linux/kernel.h> 19#include <linux/init.h> 20#include <linux/module.h> 21#include <linux/ide.h> 22 23#define DRV_NAME "ide_generic" 24 25static int probe_mask = 0x03; 26module_param(probe_mask, int, 0); 27MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports"); 28 29static ssize_t store_add(struct class *cls, const char *buf, size_t n) 30{ 31 ide_hwif_t *hwif; 32 unsigned int base, ctl; 33 int irq; 34 hw_regs_t hw; 35 u8 idx[] = { 0xff, 0xff, 0xff, 0xff }; 36 37 if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3) 38 return -EINVAL; 39 40 hwif = ide_find_port(); 41 if (hwif == NULL) 42 return -ENOENT; 43 44 memset(&hw, 0, sizeof(hw)); 45 ide_std_init_ports(&hw, base, ctl); 46 hw.irq = irq; 47 hw.chipset = ide_generic; 48 49 ide_init_port_hw(hwif, &hw); 50 51 idx[0] = hwif->index; 52 53 ide_device_add(idx, NULL); 54 55 return n; 56}; 57 58static struct class_attribute ide_generic_class_attrs[] = { 59 __ATTR(add, S_IWUSR, NULL, store_add), 60 __ATTR_NULL 61}; 62 63static void ide_generic_class_release(struct class *cls) 64{ 65 kfree(cls); 66} 67 68static int __init ide_generic_sysfs_init(void) 69{ 70 struct class *cls; 71 int rc; 72 73 cls = kzalloc(sizeof(*cls), GFP_KERNEL); 74 if (!cls) 75 return -ENOMEM; 76 77 cls->name = DRV_NAME; 78 cls->owner = THIS_MODULE; 79 cls->class_release = ide_generic_class_release; 80 cls->class_attrs = ide_generic_class_attrs; 81 82 rc = class_register(cls); 83 if (rc) { 84 kfree(cls); 85 return rc; 86 } 87 88 return 0; 89} 90 91static int __init ide_generic_init(void) 92{ 93 u8 idx[MAX_HWIFS]; 94 int i; 95 96 printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module " 97 "parameter for probing all legacy ISA IDE ports\n"); 98 99 for (i = 0; i < MAX_HWIFS; i++) { 100 ide_hwif_t *hwif; 101 unsigned long io_addr = ide_default_io_base(i); 102 hw_regs_t hw; 103 104 idx[i] = 0xff; 105 106 if ((probe_mask & (1 << i)) && io_addr) { 107 if (!request_region(io_addr, 8, DRV_NAME)) { 108 printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX " 109 "not free.\n", 110 DRV_NAME, io_addr, io_addr + 7); 111 continue; 112 } 113 114 if (!request_region(io_addr + 0x206, 1, DRV_NAME)) { 115 printk(KERN_ERR "%s: I/O resource 0x%lX " 116 "not free.\n", 117 DRV_NAME, io_addr + 0x206); 118 release_region(io_addr, 8); 119 continue; 120 } 121 122 /* 123 * Skip probing if the corresponding 124 * slot is already occupied. 125 */ 126 hwif = ide_find_port(); 127 if (hwif == NULL || hwif->index != i) { 128 idx[i] = 0xff; 129 continue; 130 } 131 132 memset(&hw, 0, sizeof(hw)); 133 ide_std_init_ports(&hw, io_addr, io_addr + 0x206); 134 hw.irq = ide_default_irq(io_addr); 135 hw.chipset = ide_generic; 136 ide_init_port_hw(hwif, &hw); 137 138 idx[i] = i; 139 } 140 } 141 142 ide_device_add_all(idx, NULL); 143 144 if (ide_generic_sysfs_init()) 145 printk(KERN_ERR DRV_NAME ": failed to create ide_generic " 146 "class\n"); 147 148 return 0; 149} 150 151module_init(ide_generic_init); 152 153MODULE_LICENSE("GPL");