Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/dio/dio.c (Version 2.6.31.13) and /linux/drivers/dio/dio.c (Version 2.6.11.8)


  1 /* Code to support devices on the DIO and DIO-      1 /* Code to support devices on the DIO and DIO-II bus
  2  * Copyright (C) 05/1998 Peter Maydell <pmayde      2  * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
  3  * Copyright (C) 2004 Jochen Friedrich <jochen      3  * Copyright (C) 2004 Jochen Friedrich <jochen@scram.de>
  4  *                                                  4  * 
  5  * This code has basically these routines at t      5  * This code has basically these routines at the moment:
  6  * int dio_find(u_int deviceid)                     6  * int dio_find(u_int deviceid)
  7  *    Search the list of DIO devices and retur      7  *    Search the list of DIO devices and return the select code
  8  *    of the next unconfigured device found th      8  *    of the next unconfigured device found that matches the given device ID.
  9  *    Note that the deviceid parameter should       9  *    Note that the deviceid parameter should be the encoded ID.
 10  *    This means that framebuffers should pass     10  *    This means that framebuffers should pass it as 
 11  *    DIO_ENCODE_ID(DIO_ID_FBUFFER,DIO_ID2_TOP     11  *    DIO_ENCODE_ID(DIO_ID_FBUFFER,DIO_ID2_TOPCAT)
 12  *    (or whatever); everybody else just uses      12  *    (or whatever); everybody else just uses DIO_ID_FOOBAR.
 13  * unsigned long dio_scodetophysaddr(int scode     13  * unsigned long dio_scodetophysaddr(int scode)
 14  *    Return the physical address correspondin     14  *    Return the physical address corresponding to the given select code.
 15  * int dio_scodetoipl(int scode)                   15  * int dio_scodetoipl(int scode)
 16  *    Every DIO card has a fixed interrupt pri     16  *    Every DIO card has a fixed interrupt priority level. This function 
 17  *    returns it, whatever it is.                  17  *    returns it, whatever it is.
 18  * const char *dio_scodetoname(int scode)          18  * const char *dio_scodetoname(int scode)
 19  *    Return a character string describing thi     19  *    Return a character string describing this board [might be "" if 
 20  *    not CONFIG_DIO_CONSTANTS]                    20  *    not CONFIG_DIO_CONSTANTS]
 21  * void dio_config_board(int scode)     mark b     21  * void dio_config_board(int scode)     mark board as configured in the list
 22  * void dio_unconfig_board(int scode)   mark b     22  * void dio_unconfig_board(int scode)   mark board as no longer configured
 23  *                                                 23  *
 24  * This file is based on the way the Amiga por     24  * This file is based on the way the Amiga port handles Zorro II cards, 
 25  * although we aren't so complicated...            25  * although we aren't so complicated...
 26  */                                                26  */
 27 #include <linux/module.h>                          27 #include <linux/module.h>
 28 #include <linux/string.h>                          28 #include <linux/string.h>
 29 #include <linux/types.h>                           29 #include <linux/types.h>
 30 #include <linux/kernel.h>                          30 #include <linux/kernel.h>
 31 #include <linux/init.h>                            31 #include <linux/init.h>
 32 #include <linux/dio.h>                             32 #include <linux/dio.h>
 33 #include <linux/slab.h>                            33 #include <linux/slab.h>                         /* kmalloc() */
 34 #include <asm/uaccess.h>                           34 #include <asm/uaccess.h>
 35 #include <asm/io.h>                                35 #include <asm/io.h>                             /* readb() */
 36                                                    36 
 37 struct dio_bus dio_bus = {                         37 struct dio_bus dio_bus = {
 38         .resources = {                             38         .resources = {
 39                 /* DIO range */                    39                 /* DIO range */
 40                 { .name = "DIO mem", .start =      40                 { .name = "DIO mem", .start = 0x00600000, .end = 0x007fffff },
 41                 /* DIO-II range */                 41                 /* DIO-II range */
 42                 { .name = "DIO-II mem", .start     42                 { .name = "DIO-II mem", .start = 0x01000000, .end = 0x1fffffff }
 43         },                                         43         },
 44         .name = "DIO bus"                          44         .name = "DIO bus"
 45 };                                                 45 };
 46                                                    46 
 47 /* not a real config option yet! */                47 /* not a real config option yet! */
 48 #define CONFIG_DIO_CONSTANTS                       48 #define CONFIG_DIO_CONSTANTS
 49                                                    49 
 50 #ifdef CONFIG_DIO_CONSTANTS                        50 #ifdef CONFIG_DIO_CONSTANTS
 51 /* We associate each numeric ID with an approp     51 /* We associate each numeric ID with an appropriate descriptive string
 52  * using a constant array of these structs.        52  * using a constant array of these structs.
 53  * FIXME: we should be able to arrange to thro     53  * FIXME: we should be able to arrange to throw away most of the strings
 54  * using the initdata stuff. Then we wouldn't      54  * using the initdata stuff. Then we wouldn't need to worry about 
 55  * carrying them around...                         55  * carrying them around...
 56  * I think we do this by copying them into new     56  * I think we do this by copying them into newly kmalloc()ed memory and 
 57  * marking the names[] array as .initdata ?        57  * marking the names[] array as .initdata ?
 58  */                                                58  */
 59 struct dioname                                     59 struct dioname
 60 {                                                  60 {
 61         int id;                                    61         int id;
 62         const char *name;                          62         const char *name;
 63 };                                                 63 };
 64                                                    64 
 65 /* useful macro */                                 65 /* useful macro */
 66 #define DIONAME(x) { DIO_ID_##x, DIO_DESC_##x      66 #define DIONAME(x) { DIO_ID_##x, DIO_DESC_##x }
 67 #define DIOFBNAME(x) { DIO_ENCODE_ID( DIO_ID_F     67 #define DIOFBNAME(x) { DIO_ENCODE_ID( DIO_ID_FBUFFER, DIO_ID2_##x), DIO_DESC2_##x }
 68                                                    68 
 69 static struct dioname names[] =                    69 static struct dioname names[] = 
 70 {                                                  70 {
 71         DIONAME(DCA0), DIONAME(DCA0REM), DIONA     71         DIONAME(DCA0), DIONAME(DCA0REM), DIONAME(DCA1), DIONAME(DCA1REM),
 72         DIONAME(DCM), DIONAME(DCMREM),             72         DIONAME(DCM), DIONAME(DCMREM),
 73         DIONAME(LAN),                              73         DIONAME(LAN),
 74         DIONAME(FHPIB), DIONAME(NHPIB),            74         DIONAME(FHPIB), DIONAME(NHPIB),
 75         DIONAME(SCSI0), DIONAME(SCSI1), DIONAM     75         DIONAME(SCSI0), DIONAME(SCSI1), DIONAME(SCSI2), DIONAME(SCSI3),
 76         DIONAME(FBUFFER),                          76         DIONAME(FBUFFER),
 77         DIONAME(PARALLEL), DIONAME(VME), DIONA     77         DIONAME(PARALLEL), DIONAME(VME), DIONAME(DCL), DIONAME(DCLREM),
 78         DIONAME(MISC0), DIONAME(MISC1), DIONAM     78         DIONAME(MISC0), DIONAME(MISC1), DIONAME(MISC2), DIONAME(MISC3),
 79         DIONAME(MISC4), DIONAME(MISC5), DIONAM     79         DIONAME(MISC4), DIONAME(MISC5), DIONAME(MISC6), DIONAME(MISC7),
 80         DIONAME(MISC8), DIONAME(MISC9), DIONAM     80         DIONAME(MISC8), DIONAME(MISC9), DIONAME(MISC10), DIONAME(MISC11), 
 81         DIONAME(MISC12), DIONAME(MISC13),          81         DIONAME(MISC12), DIONAME(MISC13),
 82         DIOFBNAME(GATORBOX), DIOFBNAME(TOPCAT)     82         DIOFBNAME(GATORBOX), DIOFBNAME(TOPCAT), DIOFBNAME(RENAISSANCE),
 83         DIOFBNAME(LRCATSEYE), DIOFBNAME(HRCCAT     83         DIOFBNAME(LRCATSEYE), DIOFBNAME(HRCCATSEYE), DIOFBNAME(HRMCATSEYE),
 84         DIOFBNAME(DAVINCI), DIOFBNAME(XXXCATSE     84         DIOFBNAME(DAVINCI), DIOFBNAME(XXXCATSEYE), DIOFBNAME(HYPERION),
 85         DIOFBNAME(XGENESIS), DIOFBNAME(TIGER),     85         DIOFBNAME(XGENESIS), DIOFBNAME(TIGER), DIOFBNAME(YGENESIS)   
 86 };                                                 86 };
 87                                                    87 
 88 #undef DIONAME                                     88 #undef DIONAME
 89 #undef DIOFBNAME                                   89 #undef DIOFBNAME
 90                                                    90 
                                                   >>  91 #define NUMNAMES (sizeof(names) / sizeof(struct dioname))
                                                   >>  92 
 91 static const char *unknowndioname                  93 static const char *unknowndioname 
 92         = "unknown DIO board -- please email <     94         = "unknown DIO board -- please email <linux-m68k@lists.linux-m68k.org>!";
 93                                                    95 
 94 static const char *dio_getname(int id)             96 static const char *dio_getname(int id)
 95 {                                                  97 {
 96         /* return pointer to a constant string     98         /* return pointer to a constant string describing the board with given ID */
 97         unsigned int i;                            99         unsigned int i;
 98         for (i = 0; i < ARRAY_SIZE(names); i++ !! 100         for (i = 0; i < NUMNAMES; i++)
 99                 if (names[i].id == id)            101                 if (names[i].id == id) 
100                         return names[i].name;     102                         return names[i].name;
101                                                   103 
102         return unknowndioname;                    104         return unknowndioname;
103 }                                                 105 }
104                                                   106 
105 #else                                             107 #else
106                                                   108 
107 static char dio_no_name[] = { 0 };                109 static char dio_no_name[] = { 0 };
108 #define dio_getname(_id)        (dio_no_name)     110 #define dio_getname(_id)        (dio_no_name)
109                                                   111 
110 #endif /* CONFIG_DIO_CONSTANTS */                 112 #endif /* CONFIG_DIO_CONSTANTS */
111                                                   113 
112 int __init dio_find(int deviceid)                 114 int __init dio_find(int deviceid)
113 {                                                 115 {
114         /* Called to find a DIO device before     116         /* Called to find a DIO device before the full bus scan has run.
115          * Only used by the console driver.       117          * Only used by the console driver.
116          */                                       118          */
117         int scode, id;                            119         int scode, id;
118         u_char prid, secid, i;                    120         u_char prid, secid, i;
119         mm_segment_t fs;                          121         mm_segment_t fs;
120                                                   122 
121         for (scode = 0; scode < DIO_SCMAX; sco    123         for (scode = 0; scode < DIO_SCMAX; scode++) {
122                 void *va;                         124                 void *va;
123                 unsigned long pa;                 125                 unsigned long pa;
124                                                   126 
125                 if (DIO_SCINHOLE(scode))          127                 if (DIO_SCINHOLE(scode))
126                         continue;                 128                         continue;
127                                                   129 
128                 pa = dio_scodetophysaddr(scode    130                 pa = dio_scodetophysaddr(scode);
129                                                   131 
130                 if (!pa)                          132                 if (!pa)
131                         continue;                 133                         continue;
132                                                   134 
133                 if (scode < DIOII_SCBASE)         135                 if (scode < DIOII_SCBASE)
134                         va = (void *)(pa + DIO    136                         va = (void *)(pa + DIO_VIRADDRBASE);
135                 else                              137                 else
136                         va = ioremap(pa, PAGE_    138                         va = ioremap(pa, PAGE_SIZE);
137                                                   139 
138                 fs = get_fs();                    140                 fs = get_fs();
139                 set_fs(KERNEL_DS);                141                 set_fs(KERNEL_DS);
140                                                   142 
141                 if (get_user(i, (unsigned char    143                 if (get_user(i, (unsigned char *)va + DIO_IDOFF)) {
142                         set_fs(fs);               144                         set_fs(fs);
143                         if (scode >= DIOII_SCB    145                         if (scode >= DIOII_SCBASE)
144                                 iounmap(va);      146                                 iounmap(va);
145                         continue;                 147                         continue;             /* no board present at that select code */
146                 }                                 148                 }
147                                                   149 
148                 set_fs(fs);                       150                 set_fs(fs);
149                 prid = DIO_ID(va);                151                 prid = DIO_ID(va);
150                                                   152 
151                 if (DIO_NEEDSSECID(prid)) {       153                 if (DIO_NEEDSSECID(prid)) {
152                         secid = DIO_SECID(va);    154                         secid = DIO_SECID(va);
153                         id = DIO_ENCODE_ID(pri    155                         id = DIO_ENCODE_ID(prid, secid);
154                 } else                            156                 } else
155                         id = prid;                157                         id = prid;
156                                                   158 
157                 if (id == deviceid) {             159                 if (id == deviceid) {
158                         if (scode >= DIOII_SCB    160                         if (scode >= DIOII_SCBASE)
159                                 iounmap(va);      161                                 iounmap(va);
160                         return scode;             162                         return scode;
161                 }                                 163                 }
162         }                                         164         }
163                                                   165 
164         return -1;                                166         return -1;
165 }                                                 167 }
166                                                   168 
167 /* This is the function that scans the DIO spa    169 /* This is the function that scans the DIO space and works out what
168  * hardware is actually present.                  170  * hardware is actually present.
169  */                                               171  */
170 static int __init dio_init(void)                  172 static int __init dio_init(void)
171 {                                                 173 {
172         int scode;                                174         int scode;
173         mm_segment_t fs;                          175         mm_segment_t fs;
174         int i;                                    176         int i;
175         struct dio_dev *dev;                      177         struct dio_dev *dev;
176         int error;                             << 
177                                                   178 
178         if (!MACH_IS_HP300)                       179         if (!MACH_IS_HP300)
179                 return 0;                         180                 return 0;
180                                                   181 
181         printk(KERN_INFO "Scanning for DIO dev    182         printk(KERN_INFO "Scanning for DIO devices...\n");
182                                                   183 
183         /* Initialize the DIO bus */              184         /* Initialize the DIO bus */ 
184         INIT_LIST_HEAD(&dio_bus.devices);         185         INIT_LIST_HEAD(&dio_bus.devices);
185         dev_set_name(&dio_bus.dev, "dio");     !! 186         strcpy(dio_bus.dev.bus_id, "dio");
186         error = device_register(&dio_bus.dev); !! 187         device_register(&dio_bus.dev);
187         if (error) {                           << 
188                 pr_err("DIO: Error registering << 
189                 return error;                  << 
190         }                                      << 
191                                                   188 
192         /* Request all resources */               189         /* Request all resources */
193         dio_bus.num_resources = (hp300_model =    190         dio_bus.num_resources = (hp300_model == HP_320 ? 1 : 2);
194         for (i = 0; i < dio_bus.num_resources;    191         for (i = 0; i < dio_bus.num_resources; i++)
195                 request_resource(&iomem_resour    192                 request_resource(&iomem_resource, &dio_bus.resources[i]);
196                                                   193 
197         /* Register all devices */                194         /* Register all devices */
198         for (scode = 0; scode < DIO_SCMAX; ++s    195         for (scode = 0; scode < DIO_SCMAX; ++scode)
199         {                                         196         {
200                 u_char prid, secid = 0;           197                 u_char prid, secid = 0;        /* primary, secondary ID bytes */
201                 u_char *va;                       198                 u_char *va;
202                 unsigned long pa;                 199                 unsigned long pa;
203                                                   200                 
204                 if (DIO_SCINHOLE(scode))          201                 if (DIO_SCINHOLE(scode))
205                         continue;                 202                         continue;
206                                                   203 
207                 pa = dio_scodetophysaddr(scode    204                 pa = dio_scodetophysaddr(scode);
208                                                   205 
209                 if (!pa)                          206                 if (!pa)
210                         continue;                 207                         continue;
211                                                   208 
212                 if (scode < DIOII_SCBASE)         209                 if (scode < DIOII_SCBASE)
213                         va = (void *)(pa + DIO    210                         va = (void *)(pa + DIO_VIRADDRBASE);
214                 else                              211                 else
215                         va = ioremap(pa, PAGE_    212                         va = ioremap(pa, PAGE_SIZE);
216                                                   213 
217                 fs = get_fs();                    214                 fs = get_fs();
218                 set_fs(KERNEL_DS);                215                 set_fs(KERNEL_DS);
219                                                   216 
220                 if (get_user(i, (unsigned char    217                 if (get_user(i, (unsigned char *)va + DIO_IDOFF)) {
221                         set_fs(fs);               218                         set_fs(fs);
222                         if (scode >= DIOII_SCB    219                         if (scode >= DIOII_SCBASE)
223                                 iounmap(va);      220                                 iounmap(va);
224                         continue;                 221                         continue;              /* no board present at that select code */
225                 }                                 222                 }
226                                                   223 
227                 set_fs(fs);                       224                 set_fs(fs);
228                                                   225 
229                 /* Found a board, allocate it     226                 /* Found a board, allocate it an entry in the list */
230                 dev = kzalloc(sizeof(struct di !! 227                 dev = kmalloc(sizeof(struct dio_dev), GFP_KERNEL);
231                 if (!dev)                         228                 if (!dev)
232                         return 0;                 229                         return 0;
233                                                   230 
                                                   >> 231                 memset(dev, 0, sizeof(struct dio_dev));
234                 dev->bus = &dio_bus;              232                 dev->bus = &dio_bus;
235                 dev->dev.parent = &dio_bus.dev    233                 dev->dev.parent = &dio_bus.dev;
236                 dev->dev.bus = &dio_bus_type;     234                 dev->dev.bus = &dio_bus_type;
237                 dev->scode = scode;               235                 dev->scode = scode;
238                 dev->resource.start = pa;         236                 dev->resource.start = pa;
239                 dev->resource.end = pa + DIO_S    237                 dev->resource.end = pa + DIO_SIZE(scode, va);
240                 dev_set_name(&dev->dev, "%02x" !! 238                 sprintf(dev->dev.bus_id,"%02x", scode);
241                                                   239 
242                 /* read the ID byte(s) and enc    240                 /* read the ID byte(s) and encode if necessary. */
243                 prid = DIO_ID(va);                241                 prid = DIO_ID(va);
244                                                   242 
245                 if (DIO_NEEDSSECID(prid)) {       243                 if (DIO_NEEDSSECID(prid)) {
246                         secid = DIO_SECID(va);    244                         secid = DIO_SECID(va);
247                         dev->id = DIO_ENCODE_I    245                         dev->id = DIO_ENCODE_ID(prid, secid);
248                 } else                            246                 } else
249                         dev->id = prid;           247                         dev->id = prid;
250                                                   248 
251                 dev->ipl = DIO_IPL(va);           249                 dev->ipl = DIO_IPL(va);
252                 strcpy(dev->name,dio_getname(d    250                 strcpy(dev->name,dio_getname(dev->id));
253                 printk(KERN_INFO "select code     251                 printk(KERN_INFO "select code %3d: ipl %d: ID %02X", dev->scode, dev->ipl, prid);
254                 if (DIO_NEEDSSECID(prid))         252                 if (DIO_NEEDSSECID(prid))
255                         printk(":%02X", secid)    253                         printk(":%02X", secid);
256                 printk(": %s\n", dev->name);      254                 printk(": %s\n", dev->name);
257                                                   255 
258                 if (scode >= DIOII_SCBASE)        256                 if (scode >= DIOII_SCBASE)
259                         iounmap(va);              257                         iounmap(va);
260                 error = device_register(&dev-> !! 258                 device_register(&dev->dev);
261                 if (error) {                   !! 259                 dio_create_sysfs_dev_files(dev);
262                         pr_err("DIO: Error reg << 
263                                dev->name);     << 
264                         continue;              << 
265                 }                              << 
266                 error = dio_create_sysfs_dev_f << 
267                 if (error)                     << 
268                         dev_err(&dev->dev, "Er << 
269         }                                         260         }
270         return 0;                                 261         return 0;
271 }                                                 262 }
272                                                   263 
273 subsys_initcall(dio_init);                        264 subsys_initcall(dio_init);
274                                                   265 
275 /* Bear in mind that this is called in the ver    266 /* Bear in mind that this is called in the very early stages of initialisation
276  * in order to get the address of the serial p    267  * in order to get the address of the serial port for the console...
277  */                                               268  */
278 unsigned long dio_scodetophysaddr(int scode)      269 unsigned long dio_scodetophysaddr(int scode)
279 {                                                 270 {
280         if (scode >= DIOII_SCBASE) {              271         if (scode >= DIOII_SCBASE) {
281                 return (DIOII_BASE + (scode -     272                 return (DIOII_BASE + (scode - 132) * DIOII_DEVSIZE);
282         } else if (scode > DIO_SCMAX || scode     273         } else if (scode > DIO_SCMAX || scode < 0)
283                 return 0;                         274                 return 0;
284         else if (DIO_SCINHOLE(scode))             275         else if (DIO_SCINHOLE(scode))
285                 return 0;                         276                 return 0;
286                                                   277 
287         return (DIO_BASE + scode * DIO_DEVSIZE    278         return (DIO_BASE + scode * DIO_DEVSIZE);
288 }                                                 279 }
289                                                   280 
  This page was automatically generated by the LXR engine.