diff options
Diffstat (limited to 'drivers/char/rio/rio_linux.c')
-rw-r--r-- | drivers/char/rio/rio_linux.c | 1516 |
1 files changed, 740 insertions, 776 deletions
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index 7085a38532b3..8825bd61b7d0 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -33,7 +33,7 @@ | |||
33 | * */ | 33 | * */ |
34 | 34 | ||
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/config.h> | 36 | #include <linux/config.h> |
37 | #include <linux/kdev_t.h> | 37 | #include <linux/kdev_t.h> |
38 | #include <asm/io.h> | 38 | #include <asm/io.h> |
39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
@@ -112,7 +112,7 @@ more than 512 ports.... */ | |||
112 | #define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 | 112 | #define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 |
113 | #endif | 113 | #endif |
114 | 114 | ||
115 | #ifndef RIO_WINDOW_LEN | 115 | #ifndef RIO_WINDOW_LEN |
116 | #define RIO_WINDOW_LEN 0x10000 | 116 | #define RIO_WINDOW_LEN 0x10000 |
117 | #endif | 117 | #endif |
118 | 118 | ||
@@ -140,34 +140,51 @@ more than 512 ports.... */ | |||
140 | */ | 140 | */ |
141 | #define RIO_REPORT_FIFO | 141 | #define RIO_REPORT_FIFO |
142 | #define RIO_REPORT_OVERRUN | 142 | #define RIO_REPORT_OVERRUN |
143 | #endif | 143 | #endif |
144 | 144 | ||
145 | 145 | ||
146 | /* These constants are derived from SCO Source */ | 146 | /* These constants are derived from SCO Source */ |
147 | static struct Conf | 147 | static struct Conf |
148 | RIOConf = | 148 | RIOConf = { |
149 | { | 149 | /* locator */ "RIO Config here", |
150 | /* locator */ "RIO Config here", | 150 | /* startuptime */ HZ * 2, |
151 | /* startuptime */ HZ*2, /* how long to wait for card to run */ | 151 | /* how long to wait for card to run */ |
152 | /* slowcook */ 0, /* TRUE -> always use line disc. */ | 152 | /* slowcook */ 0, |
153 | /* intrpolltime */ 1, /* The frequency of OUR polls */ | 153 | /* TRUE -> always use line disc. */ |
154 | /* breakinterval */ 25, /* x10 mS XXX: units seem to be 1ms not 10! -- REW*/ | 154 | /* intrpolltime */ 1, |
155 | /* timer */ 10, /* mS */ | 155 | /* The frequency of OUR polls */ |
156 | /* RtaLoadBase */ 0x7000, | 156 | /* breakinterval */ 25, |
157 | /* HostLoadBase */ 0x7C00, | 157 | /* x10 mS XXX: units seem to be 1ms not 10! -- REW */ |
158 | /* XpHz */ 5, /* number of Xprint hits per second */ | 158 | /* timer */ 10, |
159 | /* XpCps */ 120, /* Xprint characters per second */ | 159 | /* mS */ |
160 | /* XpOn */ "\033d#", /* start Xprint for a wyse 60 */ | 160 | /* RtaLoadBase */ 0x7000, |
161 | /* XpOff */ "\024", /* end Xprint for a wyse 60 */ | 161 | /* HostLoadBase */ 0x7C00, |
162 | /* MaxXpCps */ 2000, /* highest Xprint speed */ | 162 | /* XpHz */ 5, |
163 | /* MinXpCps */ 10, /* slowest Xprint speed */ | 163 | /* number of Xprint hits per second */ |
164 | /* SpinCmds */ 1, /* non-zero for mega fast boots */ | 164 | /* XpCps */ 120, |
165 | /* First Addr */ 0x0A0000, /* First address to look at */ | 165 | /* Xprint characters per second */ |
166 | /* Last Addr */ 0xFF0000, /* Last address looked at */ | 166 | /* XpOn */ "\033d#", |
167 | /* BufferSize */ 1024, /* Bytes per port of buffering */ | 167 | /* start Xprint for a wyse 60 */ |
168 | /* LowWater */ 256, /* how much data left before wakeup */ | 168 | /* XpOff */ "\024", |
169 | /* LineLength */ 80, /* how wide is the console? */ | 169 | /* end Xprint for a wyse 60 */ |
170 | /* CmdTimeout */ HZ, /* how long a close command may take */ | 170 | /* MaxXpCps */ 2000, |
171 | /* highest Xprint speed */ | ||
172 | /* MinXpCps */ 10, | ||
173 | /* slowest Xprint speed */ | ||
174 | /* SpinCmds */ 1, | ||
175 | /* non-zero for mega fast boots */ | ||
176 | /* First Addr */ 0x0A0000, | ||
177 | /* First address to look at */ | ||
178 | /* Last Addr */ 0xFF0000, | ||
179 | /* Last address looked at */ | ||
180 | /* BufferSize */ 1024, | ||
181 | /* Bytes per port of buffering */ | ||
182 | /* LowWater */ 256, | ||
183 | /* how much data left before wakeup */ | ||
184 | /* LineLength */ 80, | ||
185 | /* how wide is the console? */ | ||
186 | /* CmdTimeout */ HZ, | ||
187 | /* how long a close command may take */ | ||
171 | }; | 188 | }; |
172 | 189 | ||
173 | 190 | ||
@@ -175,21 +192,20 @@ RIOConf = | |||
175 | 192 | ||
176 | /* Function prototypes */ | 193 | /* Function prototypes */ |
177 | 194 | ||
178 | static void rio_disable_tx_interrupts (void * ptr); | 195 | static void rio_disable_tx_interrupts(void *ptr); |
179 | static void rio_enable_tx_interrupts (void * ptr); | 196 | static void rio_enable_tx_interrupts(void *ptr); |
180 | static void rio_disable_rx_interrupts (void * ptr); | 197 | static void rio_disable_rx_interrupts(void *ptr); |
181 | static void rio_enable_rx_interrupts (void * ptr); | 198 | static void rio_enable_rx_interrupts(void *ptr); |
182 | static int rio_get_CD (void * ptr); | 199 | static int rio_get_CD(void *ptr); |
183 | static void rio_shutdown_port (void * ptr); | 200 | static void rio_shutdown_port(void *ptr); |
184 | static int rio_set_real_termios (void *ptr); | 201 | static int rio_set_real_termios(void *ptr); |
185 | static void rio_hungup (void *ptr); | 202 | static void rio_hungup(void *ptr); |
186 | static void rio_close (void *ptr); | 203 | static void rio_close(void *ptr); |
187 | static int rio_chars_in_buffer (void * ptr); | 204 | static int rio_chars_in_buffer(void *ptr); |
188 | static int rio_fw_ioctl (struct inode *inode, struct file *filp, | 205 | static int rio_fw_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); |
189 | unsigned int cmd, unsigned long arg); | ||
190 | static int rio_init_drivers(void); | 206 | static int rio_init_drivers(void); |
191 | 207 | ||
192 | static void my_hd (void *addr, int len); | 208 | static void my_hd(void *addr, int len); |
193 | 209 | ||
194 | static struct tty_driver *rio_driver, *rio_driver2; | 210 | static struct tty_driver *rio_driver, *rio_driver2; |
195 | 211 | ||
@@ -209,7 +225,7 @@ static int rio_poll = 1; | |||
209 | 225 | ||
210 | /* These are the only open spaces in my computer. Yours may have more | 226 | /* These are the only open spaces in my computer. Yours may have more |
211 | or less.... */ | 227 | or less.... */ |
212 | static int rio_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000}; | 228 | static int rio_probe_addrs[] = { 0xc0000, 0xd0000, 0xe0000 }; |
213 | 229 | ||
214 | #define NR_RIO_ADDRS ARRAY_SIZE(rio_probe_addrs) | 230 | #define NR_RIO_ADDRS ARRAY_SIZE(rio_probe_addrs) |
215 | 231 | ||
@@ -227,17 +243,17 @@ module_param(rio_debug, int, 0644); | |||
227 | module_param(rio_irqmask, long, 0); | 243 | module_param(rio_irqmask, long, 0); |
228 | 244 | ||
229 | static struct real_driver rio_real_driver = { | 245 | static struct real_driver rio_real_driver = { |
230 | rio_disable_tx_interrupts, | 246 | rio_disable_tx_interrupts, |
231 | rio_enable_tx_interrupts, | 247 | rio_enable_tx_interrupts, |
232 | rio_disable_rx_interrupts, | 248 | rio_disable_rx_interrupts, |
233 | rio_enable_rx_interrupts, | 249 | rio_enable_rx_interrupts, |
234 | rio_get_CD, | 250 | rio_get_CD, |
235 | rio_shutdown_port, | 251 | rio_shutdown_port, |
236 | rio_set_real_termios, | 252 | rio_set_real_termios, |
237 | rio_chars_in_buffer, | 253 | rio_chars_in_buffer, |
238 | rio_close, | 254 | rio_close, |
239 | rio_hungup, | 255 | rio_hungup, |
240 | NULL | 256 | NULL |
241 | }; | 257 | }; |
242 | 258 | ||
243 | /* | 259 | /* |
@@ -246,8 +262,8 @@ static struct real_driver rio_real_driver = { | |||
246 | */ | 262 | */ |
247 | 263 | ||
248 | static struct file_operations rio_fw_fops = { | 264 | static struct file_operations rio_fw_fops = { |
249 | .owner = THIS_MODULE, | 265 | .owner = THIS_MODULE, |
250 | .ioctl = rio_fw_ioctl, | 266 | .ioctl = rio_fw_ioctl, |
251 | }; | 267 | }; |
252 | 268 | ||
253 | static struct miscdevice rio_fw_device = { | 269 | static struct miscdevice rio_fw_device = { |
@@ -262,25 +278,22 @@ static struct miscdevice rio_fw_device = { | |||
262 | 278 | ||
263 | /* This doesn't work. Who's paranoid around here? Not me! */ | 279 | /* This doesn't work. Who's paranoid around here? Not me! */ |
264 | 280 | ||
265 | static inline int rio_paranoia_check(struct rio_port const * port, | 281 | static inline int rio_paranoia_check(struct rio_port const *port, char *name, const char *routine) |
266 | char *name, const char *routine) | ||
267 | { | 282 | { |
268 | 283 | ||
269 | static const char *badmagic = | 284 | static const char *badmagic = KERN_ERR "rio: Warning: bad rio port magic number for device %s in %s\n"; |
270 | KERN_ERR "rio: Warning: bad rio port magic number for device %s in %s\n"; | 285 | static const char *badinfo = KERN_ERR "rio: Warning: null rio port for device %s in %s\n"; |
271 | static const char *badinfo = | 286 | |
272 | KERN_ERR "rio: Warning: null rio port for device %s in %s\n"; | 287 | if (!port) { |
273 | 288 | printk(badinfo, name, routine); | |
274 | if (!port) { | 289 | return 1; |
275 | printk (badinfo, name, routine); | 290 | } |
276 | return 1; | 291 | if (port->magic != RIO_MAGIC) { |
277 | } | 292 | printk(badmagic, name, routine); |
278 | if (port->magic != RIO_MAGIC) { | 293 | return 1; |
279 | printk (badmagic, name, routine); | 294 | } |
280 | return 1; | 295 | |
281 | } | 296 | return 0; |
282 | |||
283 | return 0; | ||
284 | } | 297 | } |
285 | #else | 298 | #else |
286 | #define rio_paranoia_check(a,b,c) 0 | 299 | #define rio_paranoia_check(a,b,c) 0 |
@@ -288,53 +301,53 @@ static inline int rio_paranoia_check(struct rio_port const * port, | |||
288 | 301 | ||
289 | 302 | ||
290 | #ifdef DEBUG | 303 | #ifdef DEBUG |
291 | static void my_hd (void *ad, int len) | 304 | static void my_hd(void *ad, int len) |
292 | { | 305 | { |
293 | int i, j, ch; | 306 | int i, j, ch; |
294 | unsigned char *addr = ad; | 307 | unsigned char *addr = ad; |
295 | 308 | ||
296 | for (i=0;i<len;i+=16) { | 309 | for (i = 0; i < len; i += 16) { |
297 | rio_dprintk (RIO_DEBUG_PARAM, "%08x ", (int) addr+i); | 310 | rio_dprintk(RIO_DEBUG_PARAM, "%08x ", (int) addr + i); |
298 | for (j=0;j<16;j++) { | 311 | for (j = 0; j < 16; j++) { |
299 | rio_dprintk (RIO_DEBUG_PARAM, "%02x %s", addr[j+i], (j==7)?" ":""); | 312 | rio_dprintk(RIO_DEBUG_PARAM, "%02x %s", addr[j + i], (j == 7) ? " " : ""); |
300 | } | 313 | } |
301 | for (j=0;j<16;j++) { | 314 | for (j = 0; j < 16; j++) { |
302 | ch = addr[j+i]; | 315 | ch = addr[j + i]; |
303 | rio_dprintk (RIO_DEBUG_PARAM, "%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch)); | 316 | rio_dprintk(RIO_DEBUG_PARAM, "%c", (ch < 0x20) ? '.' : ((ch > 0x7f) ? '.' : ch)); |
304 | } | 317 | } |
305 | rio_dprintk (RIO_DEBUG_PARAM, "\n"); | 318 | rio_dprintk(RIO_DEBUG_PARAM, "\n"); |
306 | } | 319 | } |
307 | } | 320 | } |
308 | #else | 321 | #else |
309 | #define my_hd(ad,len) do{/* nothing*/ } while (0) | 322 | #define my_hd(ad,len) do{/* nothing*/ } while (0) |
310 | #endif | 323 | #endif |
311 | 324 | ||
312 | 325 | ||
313 | /* Delay a number of jiffies, allowing a signal to interrupt */ | 326 | /* Delay a number of jiffies, allowing a signal to interrupt */ |
314 | int RIODelay (struct Port *PortP, int njiffies) | 327 | int RIODelay(struct Port *PortP, int njiffies) |
315 | { | 328 | { |
316 | func_enter (); | 329 | func_enter(); |
317 | 330 | ||
318 | rio_dprintk (RIO_DEBUG_DELAY, "delaying %d jiffies\n", njiffies); | 331 | rio_dprintk(RIO_DEBUG_DELAY, "delaying %d jiffies\n", njiffies); |
319 | msleep_interruptible(jiffies_to_msecs(njiffies)); | 332 | msleep_interruptible(jiffies_to_msecs(njiffies)); |
320 | func_exit(); | 333 | func_exit(); |
321 | 334 | ||
322 | if (signal_pending(current)) | 335 | if (signal_pending(current)) |
323 | return RIO_FAIL; | 336 | return RIO_FAIL; |
324 | else | 337 | else |
325 | return !RIO_FAIL; | 338 | return !RIO_FAIL; |
326 | } | 339 | } |
327 | 340 | ||
328 | 341 | ||
329 | /* Delay a number of jiffies, disallowing a signal to interrupt */ | 342 | /* Delay a number of jiffies, disallowing a signal to interrupt */ |
330 | int RIODelay_ni (struct Port *PortP, int njiffies) | 343 | int RIODelay_ni(struct Port *PortP, int njiffies) |
331 | { | 344 | { |
332 | func_enter (); | 345 | func_enter(); |
333 | 346 | ||
334 | rio_dprintk (RIO_DEBUG_DELAY, "delaying %d jiffies (ni)\n", njiffies); | 347 | rio_dprintk(RIO_DEBUG_DELAY, "delaying %d jiffies (ni)\n", njiffies); |
335 | msleep(jiffies_to_msecs(njiffies)); | 348 | msleep(jiffies_to_msecs(njiffies)); |
336 | func_exit(); | 349 | func_exit(); |
337 | return !RIO_FAIL; | 350 | return !RIO_FAIL; |
338 | } | 351 | } |
339 | 352 | ||
340 | 353 | ||
@@ -350,126 +363,121 @@ int rio_ismodem(struct tty_struct *tty) | |||
350 | } | 363 | } |
351 | 364 | ||
352 | 365 | ||
353 | static int rio_set_real_termios (void *ptr) | 366 | static int rio_set_real_termios(void *ptr) |
354 | { | 367 | { |
355 | int rv, modem; | 368 | int rv, modem; |
356 | struct tty_struct *tty; | 369 | struct tty_struct *tty; |
357 | func_enter(); | 370 | func_enter(); |
358 | 371 | ||
359 | tty = ((struct Port *)ptr)->gs.tty; | 372 | tty = ((struct Port *) ptr)->gs.tty; |
360 | 373 | ||
361 | modem = rio_ismodem(tty); | 374 | modem = rio_ismodem(tty); |
362 | 375 | ||
363 | rv = RIOParam( (struct Port *) ptr, CONFIG, modem, 1); | 376 | rv = RIOParam((struct Port *) ptr, CONFIG, modem, 1); |
364 | 377 | ||
365 | func_exit (); | 378 | func_exit(); |
366 | 379 | ||
367 | return rv; | 380 | return rv; |
368 | } | 381 | } |
369 | 382 | ||
370 | 383 | ||
371 | static void rio_reset_interrupt (struct Host *HostP) | 384 | static void rio_reset_interrupt(struct Host *HostP) |
372 | { | 385 | { |
373 | func_enter(); | 386 | func_enter(); |
374 | 387 | ||
375 | switch( HostP->Type ) { | 388 | switch (HostP->Type) { |
376 | case RIO_AT: | 389 | case RIO_AT: |
377 | case RIO_MCA: | 390 | case RIO_MCA: |
378 | case RIO_PCI: | 391 | case RIO_PCI: |
379 | WBYTE(HostP->ResetInt , 0xff); | 392 | WBYTE(HostP->ResetInt, 0xff); |
380 | } | 393 | } |
381 | 394 | ||
382 | func_exit(); | 395 | func_exit(); |
383 | } | 396 | } |
384 | 397 | ||
385 | 398 | ||
386 | static irqreturn_t rio_interrupt (int irq, void *ptr, struct pt_regs *regs) | 399 | static irqreturn_t rio_interrupt(int irq, void *ptr, struct pt_regs *regs) |
387 | { | 400 | { |
388 | struct Host *HostP; | 401 | struct Host *HostP; |
389 | func_enter (); | 402 | func_enter(); |
390 | 403 | ||
391 | HostP = (struct Host*)ptr; /* &p->RIOHosts[(long)ptr]; */ | 404 | HostP = (struct Host *) ptr; /* &p->RIOHosts[(long)ptr]; */ |
392 | rio_dprintk (RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", | 405 | rio_dprintk(RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", irq, HostP->Ivec); |
393 | irq, HostP->Ivec); | ||
394 | 406 | ||
395 | /* AAargh! The order in which to do these things is essential and | 407 | /* AAargh! The order in which to do these things is essential and |
396 | not trivial. | 408 | not trivial. |
397 | |||
398 | - Rate limit goes before "recursive". Otherwise a series of | ||
399 | recursive calls will hang the machine in the interrupt routine. | ||
400 | 409 | ||
401 | - hardware twiddling goes before "recursive". Otherwise when we | 410 | - Rate limit goes before "recursive". Otherwise a series of |
402 | poll the card, and a recursive interrupt happens, we won't | 411 | recursive calls will hang the machine in the interrupt routine. |
403 | ack the card, so it might keep on interrupting us. (especially | ||
404 | level sensitive interrupt systems like PCI). | ||
405 | 412 | ||
406 | - Rate limit goes before hardware twiddling. Otherwise we won't | 413 | - hardware twiddling goes before "recursive". Otherwise when we |
407 | catch a card that has gone bonkers. | 414 | poll the card, and a recursive interrupt happens, we won't |
415 | ack the card, so it might keep on interrupting us. (especially | ||
416 | level sensitive interrupt systems like PCI). | ||
408 | 417 | ||
409 | - The "initialized" test goes after the hardware twiddling. Otherwise | 418 | - Rate limit goes before hardware twiddling. Otherwise we won't |
410 | the card will stick us in the interrupt routine again. | 419 | catch a card that has gone bonkers. |
411 | 420 | ||
412 | - The initialized test goes before recursive. | 421 | - The "initialized" test goes after the hardware twiddling. Otherwise |
413 | */ | 422 | the card will stick us in the interrupt routine again. |
423 | |||
424 | - The initialized test goes before recursive. | ||
425 | */ | ||
414 | 426 | ||
415 | 427 | ||
416 | 428 | ||
417 | #ifdef IRQ_RATE_LIMIT | 429 | #ifdef IRQ_RATE_LIMIT |
418 | /* Aaargh! I'm ashamed. This costs more lines-of-code than the | 430 | /* Aaargh! I'm ashamed. This costs more lines-of-code than the |
419 | actual interrupt routine!. (Well, used to when I wrote that comment) */ | 431 | actual interrupt routine!. (Well, used to when I wrote that comment) */ |
420 | { | 432 | { |
421 | static int lastjif; | 433 | static int lastjif; |
422 | static int nintr=0; | 434 | static int nintr = 0; |
423 | 435 | ||
424 | if (lastjif == jiffies) { | 436 | if (lastjif == jiffies) { |
425 | if (++nintr > IRQ_RATE_LIMIT) { | 437 | if (++nintr > IRQ_RATE_LIMIT) { |
426 | free_irq (HostP->Ivec, ptr); | 438 | free_irq(HostP->Ivec, ptr); |
427 | printk (KERN_ERR "rio: Too many interrupts. Turning off interrupt %d.\n", | 439 | printk(KERN_ERR "rio: Too many interrupts. Turning off interrupt %d.\n", HostP->Ivec); |
428 | HostP->Ivec); | 440 | } |
429 | } | 441 | } else { |
430 | } else { | 442 | lastjif = jiffies; |
431 | lastjif = jiffies; | 443 | nintr = 0; |
432 | nintr = 0; | 444 | } |
433 | } | 445 | } |
434 | } | ||
435 | #endif | 446 | #endif |
436 | rio_dprintk (RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n"); | 447 | rio_dprintk(RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n"); |
437 | if (HostP->Ivec == irq) { | 448 | if (HostP->Ivec == irq) { |
438 | /* Tell the card we've noticed the interrupt. */ | 449 | /* Tell the card we've noticed the interrupt. */ |
439 | rio_reset_interrupt (HostP); | 450 | rio_reset_interrupt(HostP); |
440 | } | 451 | } |
441 | 452 | ||
442 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) | 453 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) |
443 | return IRQ_HANDLED; | 454 | return IRQ_HANDLED; |
444 | 455 | ||
445 | if (test_and_set_bit (RIO_BOARD_INTR_LOCK, &HostP->locks)) { | 456 | if (test_and_set_bit(RIO_BOARD_INTR_LOCK, &HostP->locks)) { |
446 | printk (KERN_ERR "Recursive interrupt! (host %d/irq%d)\n", | 457 | printk(KERN_ERR "Recursive interrupt! (host %d/irq%d)\n", (int) ptr, HostP->Ivec); |
447 | (int) ptr, HostP->Ivec); | 458 | return IRQ_HANDLED; |
448 | return IRQ_HANDLED; | 459 | } |
449 | } | 460 | |
450 | 461 | RIOServiceHost(p, HostP, irq); | |
451 | RIOServiceHost(p, HostP, irq); | 462 | |
452 | 463 | rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %d type %d\n", (int) ptr, HostP->Type); | |
453 | rio_dprintk ( RIO_DEBUG_IFLOW, "riointr() doing host %d type %d\n", | 464 | |
454 | (int) ptr, HostP->Type); | 465 | clear_bit(RIO_BOARD_INTR_LOCK, &HostP->locks); |
455 | 466 | rio_dprintk(RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", irq, HostP->Ivec); | |
456 | clear_bit (RIO_BOARD_INTR_LOCK, &HostP->locks); | 467 | func_exit(); |
457 | rio_dprintk (RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", | 468 | return IRQ_HANDLED; |
458 | irq, HostP->Ivec); | ||
459 | func_exit (); | ||
460 | return IRQ_HANDLED; | ||
461 | } | 469 | } |
462 | 470 | ||
463 | 471 | ||
464 | static void rio_pollfunc (unsigned long data) | 472 | static void rio_pollfunc(unsigned long data) |
465 | { | 473 | { |
466 | func_enter (); | 474 | func_enter(); |
467 | 475 | ||
468 | rio_interrupt (0, &p->RIOHosts[data], NULL); | 476 | rio_interrupt(0, &p->RIOHosts[data], NULL); |
469 | p->RIOHosts[data].timer.expires = jiffies + rio_poll; | 477 | p->RIOHosts[data].timer.expires = jiffies + rio_poll; |
470 | add_timer (&p->RIOHosts[data].timer); | 478 | add_timer(&p->RIOHosts[data].timer); |
471 | 479 | ||
472 | func_exit (); | 480 | func_exit(); |
473 | } | 481 | } |
474 | 482 | ||
475 | 483 | ||
@@ -481,106 +489,106 @@ static void rio_pollfunc (unsigned long data) | |||
481 | /* Ehhm. I don't know how to fiddle with interrupts on the Specialix | 489 | /* Ehhm. I don't know how to fiddle with interrupts on the Specialix |
482 | cards. .... Hmm. Ok I figured it out. You don't. -- REW */ | 490 | cards. .... Hmm. Ok I figured it out. You don't. -- REW */ |
483 | 491 | ||
484 | static void rio_disable_tx_interrupts (void * ptr) | 492 | static void rio_disable_tx_interrupts(void *ptr) |
485 | { | 493 | { |
486 | func_enter(); | 494 | func_enter(); |
487 | 495 | ||
488 | /* port->gs.flags &= ~GS_TX_INTEN; */ | 496 | /* port->gs.flags &= ~GS_TX_INTEN; */ |
489 | 497 | ||
490 | func_exit(); | 498 | func_exit(); |
491 | } | 499 | } |
492 | 500 | ||
493 | 501 | ||
494 | static void rio_enable_tx_interrupts (void * ptr) | 502 | static void rio_enable_tx_interrupts(void *ptr) |
495 | { | 503 | { |
496 | struct Port *PortP = ptr; | 504 | struct Port *PortP = ptr; |
497 | /* int hn; */ | 505 | /* int hn; */ |
498 | 506 | ||
499 | func_enter(); | 507 | func_enter(); |
500 | 508 | ||
501 | /* hn = PortP->HostP - p->RIOHosts; | 509 | /* hn = PortP->HostP - p->RIOHosts; |
502 | 510 | ||
503 | rio_dprintk (RIO_DEBUG_TTY, "Pushing host %d\n", hn); | 511 | rio_dprintk (RIO_DEBUG_TTY, "Pushing host %d\n", hn); |
504 | rio_interrupt (-1,(void *) hn, NULL); */ | 512 | rio_interrupt (-1,(void *) hn, NULL); */ |
505 | 513 | ||
506 | RIOTxEnable((char *) PortP); | 514 | RIOTxEnable((char *) PortP); |
507 | 515 | ||
508 | /* | 516 | /* |
509 | * In general we cannot count on "tx empty" interrupts, although | 517 | * In general we cannot count on "tx empty" interrupts, although |
510 | * the interrupt routine seems to be able to tell the difference. | 518 | * the interrupt routine seems to be able to tell the difference. |
511 | */ | 519 | */ |
512 | PortP->gs.flags &= ~GS_TX_INTEN; | 520 | PortP->gs.flags &= ~GS_TX_INTEN; |
513 | 521 | ||
514 | func_exit(); | 522 | func_exit(); |
515 | } | 523 | } |
516 | 524 | ||
517 | 525 | ||
518 | static void rio_disable_rx_interrupts (void * ptr) | 526 | static void rio_disable_rx_interrupts(void *ptr) |
519 | { | 527 | { |
520 | func_enter(); | 528 | func_enter(); |
521 | func_exit(); | 529 | func_exit(); |
522 | } | 530 | } |
523 | 531 | ||
524 | static void rio_enable_rx_interrupts (void * ptr) | 532 | static void rio_enable_rx_interrupts(void *ptr) |
525 | { | 533 | { |
526 | /* struct rio_port *port = ptr; */ | 534 | /* struct rio_port *port = ptr; */ |
527 | func_enter(); | 535 | func_enter(); |
528 | func_exit(); | 536 | func_exit(); |
529 | } | 537 | } |
530 | 538 | ||
531 | 539 | ||
532 | /* Jeez. Isn't this simple? */ | 540 | /* Jeez. Isn't this simple? */ |
533 | static int rio_get_CD (void * ptr) | 541 | static int rio_get_CD(void *ptr) |
534 | { | 542 | { |
535 | struct Port *PortP = ptr; | 543 | struct Port *PortP = ptr; |
536 | int rv; | 544 | int rv; |
545 | |||
546 | func_enter(); | ||
547 | rv = (PortP->ModemState & MSVR1_CD) != 0; | ||
537 | 548 | ||
538 | func_enter(); | 549 | rio_dprintk(RIO_DEBUG_INIT, "Getting CD status: %d\n", rv); |
539 | rv = (PortP->ModemState & MSVR1_CD) != 0; | ||
540 | 550 | ||
541 | rio_dprintk (RIO_DEBUG_INIT, "Getting CD status: %d\n", rv); | 551 | func_exit(); |
542 | 552 | return rv; | |
543 | func_exit(); | ||
544 | return rv; | ||
545 | } | 553 | } |
546 | 554 | ||
547 | 555 | ||
548 | /* Jeez. Isn't this simple? Actually, we can sync with the actual port | 556 | /* Jeez. Isn't this simple? Actually, we can sync with the actual port |
549 | by just pushing stuff into the queue going to the port... */ | 557 | by just pushing stuff into the queue going to the port... */ |
550 | static int rio_chars_in_buffer (void * ptr) | 558 | static int rio_chars_in_buffer(void *ptr) |
551 | { | 559 | { |
552 | func_enter(); | 560 | func_enter(); |
553 | 561 | ||
554 | func_exit(); | 562 | func_exit(); |
555 | return 0; | 563 | return 0; |
556 | } | 564 | } |
557 | 565 | ||
558 | 566 | ||
559 | /* Nothing special here... */ | 567 | /* Nothing special here... */ |
560 | static void rio_shutdown_port (void * ptr) | 568 | static void rio_shutdown_port(void *ptr) |
561 | { | 569 | { |
562 | struct Port *PortP; | 570 | struct Port *PortP; |
563 | 571 | ||
564 | func_enter(); | 572 | func_enter(); |
565 | 573 | ||
566 | PortP = (struct Port *)ptr; | 574 | PortP = (struct Port *) ptr; |
567 | PortP->gs.tty = NULL; | 575 | PortP->gs.tty = NULL; |
568 | #if 0 | 576 | #if 0 |
569 | port->gs.flags &= ~ GS_ACTIVE; | 577 | port->gs.flags &= ~GS_ACTIVE; |
570 | if (!port->gs.tty) { | 578 | if (!port->gs.tty) { |
571 | rio_dprintk (RIO_DBUG_TTY, "No tty.\n"); | 579 | rio_dprintk(RIO_DBUG_TTY, "No tty.\n"); |
572 | return; | 580 | return; |
573 | } | 581 | } |
574 | if (!port->gs.tty->termios) { | 582 | if (!port->gs.tty->termios) { |
575 | rio_dprintk (RIO_DEBUG_TTY, "No termios.\n"); | 583 | rio_dprintk(RIO_DEBUG_TTY, "No termios.\n"); |
576 | return; | 584 | return; |
577 | } | 585 | } |
578 | if (port->gs.tty->termios->c_cflag & HUPCL) { | 586 | if (port->gs.tty->termios->c_cflag & HUPCL) { |
579 | rio_setsignals (port, 0, 0); | 587 | rio_setsignals(port, 0, 0); |
580 | } | 588 | } |
581 | #endif | 589 | #endif |
582 | 590 | ||
583 | func_exit(); | 591 | func_exit(); |
584 | } | 592 | } |
585 | 593 | ||
586 | 594 | ||
@@ -591,16 +599,16 @@ static void rio_shutdown_port (void * ptr) | |||
591 | running minicom on a serial port that is driven by a modularized | 599 | running minicom on a serial port that is driven by a modularized |
592 | driver. Have the modem hangup. Then remove the driver module. Then | 600 | driver. Have the modem hangup. Then remove the driver module. Then |
593 | exit minicom. I expect an "oops". -- REW */ | 601 | exit minicom. I expect an "oops". -- REW */ |
594 | static void rio_hungup (void *ptr) | 602 | static void rio_hungup(void *ptr) |
595 | { | 603 | { |
596 | struct Port *PortP; | 604 | struct Port *PortP; |
605 | |||
606 | func_enter(); | ||
597 | 607 | ||
598 | func_enter(); | 608 | PortP = (struct Port *) ptr; |
599 | 609 | PortP->gs.tty = NULL; | |
600 | PortP = (struct Port *)ptr; | ||
601 | PortP->gs.tty = NULL; | ||
602 | 610 | ||
603 | func_exit (); | 611 | func_exit(); |
604 | } | 612 | } |
605 | 613 | ||
606 | 614 | ||
@@ -608,146 +616,135 @@ static void rio_hungup (void *ptr) | |||
608 | this. | 616 | this. |
609 | rs_close (...){save_flags;cli;real_close();dec_use_count;restore_flags;} | 617 | rs_close (...){save_flags;cli;real_close();dec_use_count;restore_flags;} |
610 | */ | 618 | */ |
611 | static void rio_close (void *ptr) | 619 | static void rio_close(void *ptr) |
612 | { | 620 | { |
613 | struct Port *PortP; | 621 | struct Port *PortP; |
614 | 622 | ||
615 | func_enter (); | 623 | func_enter(); |
616 | 624 | ||
617 | PortP = (struct Port *)ptr; | 625 | PortP = (struct Port *) ptr; |
618 | 626 | ||
619 | riotclose (ptr); | 627 | riotclose(ptr); |
620 | 628 | ||
621 | if(PortP->gs.count) { | 629 | if (PortP->gs.count) { |
622 | printk (KERN_ERR "WARNING port count:%d\n", PortP->gs.count); | 630 | printk(KERN_ERR "WARNING port count:%d\n", PortP->gs.count); |
623 | PortP->gs.count = 0; | 631 | PortP->gs.count = 0; |
624 | } | 632 | } |
625 | 633 | ||
626 | PortP->gs.tty = NULL; | 634 | PortP->gs.tty = NULL; |
627 | func_exit (); | 635 | func_exit(); |
628 | } | 636 | } |
629 | 637 | ||
630 | 638 | ||
631 | 639 | ||
632 | static int rio_fw_ioctl (struct inode *inode, struct file *filp, | 640 | static int rio_fw_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) |
633 | unsigned int cmd, unsigned long arg) | ||
634 | { | 641 | { |
635 | int rc = 0; | 642 | int rc = 0; |
636 | func_enter(); | 643 | func_enter(); |
637 | 644 | ||
638 | /* The "dev" argument isn't used. */ | 645 | /* The "dev" argument isn't used. */ |
639 | rc = riocontrol (p, 0, cmd, (void *)arg, capable(CAP_SYS_ADMIN)); | 646 | rc = riocontrol(p, 0, cmd, (void *) arg, capable(CAP_SYS_ADMIN)); |
640 | 647 | ||
641 | func_exit (); | 648 | func_exit(); |
642 | return rc; | 649 | return rc; |
643 | } | 650 | } |
644 | 651 | ||
645 | extern int RIOShortCommand(struct rio_info *p, struct Port *PortP, | 652 | extern int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg); |
646 | int command, int len, int arg); | ||
647 | 653 | ||
648 | static int rio_ioctl (struct tty_struct * tty, struct file * filp, | 654 | static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg) |
649 | unsigned int cmd, unsigned long arg) | ||
650 | { | 655 | { |
651 | int rc; | 656 | int rc; |
652 | struct Port *PortP; | 657 | struct Port *PortP; |
653 | int ival; | 658 | int ival; |
654 | 659 | ||
655 | func_enter(); | 660 | func_enter(); |
656 | 661 | ||
657 | PortP = (struct Port *)tty->driver_data; | 662 | PortP = (struct Port *) tty->driver_data; |
658 | 663 | ||
659 | rc = 0; | 664 | rc = 0; |
660 | switch (cmd) { | 665 | switch (cmd) { |
661 | #if 0 | 666 | #if 0 |
662 | case TIOCGSOFTCAR: | 667 | case TIOCGSOFTCAR: |
663 | rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), | 668 | rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), (unsigned int *) arg); |
664 | (unsigned int *) arg); | 669 | break; |
665 | break; | ||
666 | #endif | 670 | #endif |
667 | case TIOCSSOFTCAR: | 671 | case TIOCSSOFTCAR: |
668 | if ((rc = get_user(ival, (unsigned int *) arg)) == 0) { | 672 | if ((rc = get_user(ival, (unsigned int *) arg)) == 0) { |
669 | tty->termios->c_cflag = | 673 | tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (ival ? CLOCAL : 0); |
670 | (tty->termios->c_cflag & ~CLOCAL) | | 674 | } |
671 | (ival ? CLOCAL : 0); | 675 | break; |
672 | } | 676 | case TIOCGSERIAL: |
673 | break; | 677 | rc = -EFAULT; |
674 | case TIOCGSERIAL: | 678 | if (access_ok(VERIFY_WRITE, (void *) arg, sizeof(struct serial_struct))) |
675 | rc = -EFAULT; | 679 | rc = gs_getserial(&PortP->gs, (struct serial_struct *) arg); |
676 | if (access_ok(VERIFY_WRITE, (void *) arg, | 680 | break; |
677 | sizeof(struct serial_struct))) | 681 | case TCSBRK: |
678 | rc = gs_getserial(&PortP->gs, (struct serial_struct *) arg); | 682 | if (PortP->State & RIO_DELETED) { |
679 | break; | 683 | rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); |
680 | case TCSBRK: | 684 | rc = -EIO; |
681 | if ( PortP->State & RIO_DELETED ) { | 685 | } else { |
682 | rio_dprintk (RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); | 686 | if (RIOShortCommand(p, PortP, SBREAK, 2, 250) == RIO_FAIL) { |
683 | rc = -EIO; | 687 | rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); |
684 | } else { | 688 | rc = -EIO; |
685 | if (RIOShortCommand(p, PortP, SBREAK, 2, 250) == RIO_FAIL) { | 689 | } |
686 | rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); | 690 | } |
687 | rc = -EIO; | 691 | break; |
688 | } | 692 | case TCSBRKP: |
689 | } | 693 | if (PortP->State & RIO_DELETED) { |
690 | break; | 694 | rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); |
691 | case TCSBRKP: | 695 | rc = -EIO; |
692 | if ( PortP->State & RIO_DELETED ) { | 696 | } else { |
693 | rio_dprintk (RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); | 697 | int l; |
694 | rc = -EIO; | 698 | l = arg ? arg * 100 : 250; |
695 | } else { | 699 | if (l > 255) |
696 | int l; | 700 | l = 255; |
697 | l = arg?arg*100:250; | 701 | if (RIOShortCommand(p, PortP, SBREAK, 2, arg ? arg * 100 : 250) == RIO_FAIL) { |
698 | if (l > 255) l = 255; | 702 | rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); |
699 | if (RIOShortCommand(p, PortP, SBREAK, 2, arg?arg*100:250) == RIO_FAIL) { | 703 | rc = -EIO; |
700 | rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); | 704 | } |
701 | rc = -EIO; | 705 | } |
702 | } | 706 | break; |
703 | } | 707 | case TIOCSSERIAL: |
704 | break; | 708 | rc = -EFAULT; |
705 | case TIOCSSERIAL: | 709 | if (access_ok(VERIFY_READ, (void *) arg, sizeof(struct serial_struct))) |
706 | rc = -EFAULT; | 710 | rc = gs_setserial(&PortP->gs, (struct serial_struct *) arg); |
707 | if (access_ok(VERIFY_READ, (void *) arg, | 711 | break; |
708 | sizeof(struct serial_struct))) | ||
709 | rc = gs_setserial(&PortP->gs, (struct serial_struct *) arg); | ||
710 | break; | ||
711 | #if 0 | 712 | #if 0 |
712 | /* | 713 | /* |
713 | * note: these IOCTLs no longer reach here. Use | 714 | * note: these IOCTLs no longer reach here. Use |
714 | * tiocmset/tiocmget driver methods instead. The | 715 | * tiocmset/tiocmget driver methods instead. The |
715 | * #if 0 disablement predates this comment. | 716 | * #if 0 disablement predates this comment. |
716 | */ | 717 | */ |
717 | case TIOCMGET: | 718 | case TIOCMGET: |
718 | rc = -EFAULT; | 719 | rc = -EFAULT; |
719 | if (access_ok(VERIFY_WRITE, (void *) arg, | 720 | if (access_ok(VERIFY_WRITE, (void *) arg, sizeof(unsigned int))) { |
720 | sizeof(unsigned int))) { | 721 | rc = 0; |
721 | rc = 0; | 722 | ival = rio_getsignals(port); |
722 | ival = rio_getsignals(port); | 723 | put_user(ival, (unsigned int *) arg); |
723 | put_user(ival, (unsigned int *) arg); | 724 | } |
724 | } | 725 | break; |
725 | break; | 726 | case TIOCMBIS: |
726 | case TIOCMBIS: | 727 | if ((rc = get_user(ival, (unsigned int *) arg)) == 0) { |
727 | if ((rc = get_user(ival, (unsigned int *) arg)) == 0) { | 728 | rio_setsignals(port, ((ival & TIOCM_DTR) ? 1 : -1), ((ival & TIOCM_RTS) ? 1 : -1)); |
728 | rio_setsignals(port, ((ival & TIOCM_DTR) ? 1 : -1), | 729 | } |
729 | ((ival & TIOCM_RTS) ? 1 : -1)); | 730 | break; |
730 | } | 731 | case TIOCMBIC: |
731 | break; | 732 | if ((rc = get_user(ival, (unsigned int *) arg)) == 0) { |
732 | case TIOCMBIC: | 733 | rio_setsignals(port, ((ival & TIOCM_DTR) ? 0 : -1), ((ival & TIOCM_RTS) ? 0 : -1)); |
733 | if ((rc = get_user(ival, (unsigned int *) arg)) == 0) { | 734 | } |
734 | rio_setsignals(port, ((ival & TIOCM_DTR) ? 0 : -1), | 735 | break; |
735 | ((ival & TIOCM_RTS) ? 0 : -1)); | 736 | case TIOCMSET: |
736 | } | 737 | if ((rc = get_user(ival, (unsigned int *) arg)) == 0) { |
737 | break; | 738 | rio_setsignals(port, ((ival & TIOCM_DTR) ? 1 : 0), ((ival & TIOCM_RTS) ? 1 : 0)); |
738 | case TIOCMSET: | 739 | } |
739 | if ((rc = get_user(ival, (unsigned int *) arg)) == 0) { | 740 | break; |
740 | rio_setsignals(port, ((ival & TIOCM_DTR) ? 1 : 0), | ||
741 | ((ival & TIOCM_RTS) ? 1 : 0)); | ||
742 | } | ||
743 | break; | ||
744 | #endif | 741 | #endif |
745 | default: | 742 | default: |
746 | rc = -ENOIOCTLCMD; | 743 | rc = -ENOIOCTLCMD; |
747 | break; | 744 | break; |
748 | } | 745 | } |
749 | func_exit(); | 746 | func_exit(); |
750 | return rc; | 747 | return rc; |
751 | } | 748 | } |
752 | 749 | ||
753 | 750 | ||
@@ -767,37 +764,37 @@ static int rio_ioctl (struct tty_struct * tty, struct file * filp, | |||
767 | * flow control scheme is in use for that port. -- Simon Allen | 764 | * flow control scheme is in use for that port. -- Simon Allen |
768 | */ | 765 | */ |
769 | 766 | ||
770 | static void rio_throttle (struct tty_struct * tty) | 767 | static void rio_throttle(struct tty_struct *tty) |
771 | { | 768 | { |
772 | struct Port *port = (struct Port *)tty->driver_data; | 769 | struct Port *port = (struct Port *) tty->driver_data; |
773 | 770 | ||
774 | func_enter(); | 771 | func_enter(); |
775 | /* If the port is using any type of input flow | 772 | /* If the port is using any type of input flow |
776 | * control then throttle the port. | 773 | * control then throttle the port. |
777 | */ | 774 | */ |
778 | 775 | ||
779 | if((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty)) ) { | 776 | if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) { |
780 | port->State |= RIO_THROTTLE_RX; | 777 | port->State |= RIO_THROTTLE_RX; |
781 | } | 778 | } |
782 | 779 | ||
783 | func_exit(); | 780 | func_exit(); |
784 | } | 781 | } |
785 | 782 | ||
786 | 783 | ||
787 | static void rio_unthrottle (struct tty_struct * tty) | 784 | static void rio_unthrottle(struct tty_struct *tty) |
788 | { | 785 | { |
789 | struct Port *port = (struct Port *)tty->driver_data; | 786 | struct Port *port = (struct Port *) tty->driver_data; |
790 | 787 | ||
791 | func_enter(); | 788 | func_enter(); |
792 | /* Always unthrottle even if flow control is not enabled on | 789 | /* Always unthrottle even if flow control is not enabled on |
793 | * this port in case we disabled flow control while the port | 790 | * this port in case we disabled flow control while the port |
794 | * was throttled | 791 | * was throttled |
795 | */ | 792 | */ |
796 | 793 | ||
797 | port->State &= ~RIO_THROTTLE_RX; | 794 | port->State &= ~RIO_THROTTLE_RX; |
798 | 795 | ||
799 | func_exit(); | 796 | func_exit(); |
800 | return; | 797 | return; |
801 | } | 798 | } |
802 | 799 | ||
803 | 800 | ||
@@ -809,35 +806,34 @@ static void rio_unthrottle (struct tty_struct * tty) | |||
809 | * ********************************************************************** */ | 806 | * ********************************************************************** */ |
810 | 807 | ||
811 | 808 | ||
812 | static struct vpd_prom *get_VPD_PROM (struct Host *hp) | 809 | static struct vpd_prom *get_VPD_PROM(struct Host *hp) |
813 | { | 810 | { |
814 | static struct vpd_prom vpdp; | 811 | static struct vpd_prom vpdp; |
815 | char *p; | 812 | char *p; |
816 | int i; | 813 | int i; |
814 | |||
815 | func_enter(); | ||
816 | rio_dprintk(RIO_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", hp->Caddr + RIO_VPD_ROM); | ||
817 | 817 | ||
818 | func_enter(); | 818 | p = (char *) &vpdp; |
819 | rio_dprintk (RIO_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", | 819 | for (i = 0; i < sizeof(struct vpd_prom); i++) |
820 | hp->Caddr + RIO_VPD_ROM); | 820 | *p++ = readb(hp->Caddr + RIO_VPD_ROM + i * 2); |
821 | /* read_rio_byte (hp, RIO_VPD_ROM + i*2); */ | ||
821 | 822 | ||
822 | p = (char *) &vpdp; | 823 | /* Terminate the identifier string. |
823 | for (i=0;i< sizeof (struct vpd_prom);i++) | 824 | *** requires one extra byte in struct vpd_prom *** */ |
824 | *p++ = readb (hp->Caddr+RIO_VPD_ROM + i*2); | 825 | *p++ = 0; |
825 | /* read_rio_byte (hp, RIO_VPD_ROM + i*2); */ | ||
826 | 826 | ||
827 | /* Terminate the identifier string. | 827 | if (rio_debug & RIO_DEBUG_PROBE) |
828 | *** requires one extra byte in struct vpd_prom *** */ | 828 | my_hd((char *) &vpdp, 0x20); |
829 | *p++=0; | ||
830 | 829 | ||
831 | if (rio_debug & RIO_DEBUG_PROBE) | 830 | func_exit(); |
832 | my_hd ((char *)&vpdp, 0x20); | ||
833 | |||
834 | func_exit(); | ||
835 | 831 | ||
836 | return &vpdp; | 832 | return &vpdp; |
837 | } | 833 | } |
838 | 834 | ||
839 | static struct tty_operations rio_ops = { | 835 | static struct tty_operations rio_ops = { |
840 | .open = riotopen, | 836 | .open = riotopen, |
841 | .close = gs_close, | 837 | .close = gs_close, |
842 | .write = gs_write, | 838 | .write = gs_write, |
843 | .put_char = gs_put_char, | 839 | .put_char = gs_put_char, |
@@ -889,7 +885,7 @@ static int rio_init_drivers(void) | |||
889 | rio_driver2->flags = TTY_DRIVER_REAL_RAW; | 885 | rio_driver2->flags = TTY_DRIVER_REAL_RAW; |
890 | tty_set_operations(rio_driver2, &rio_ops); | 886 | tty_set_operations(rio_driver2, &rio_ops); |
891 | 887 | ||
892 | rio_dprintk (RIO_DEBUG_INIT, "set_termios = %p\n", gs_set_termios); | 888 | rio_dprintk(RIO_DEBUG_INIT, "set_termios = %p\n", gs_set_termios); |
893 | 889 | ||
894 | if ((error = tty_register_driver(rio_driver))) | 890 | if ((error = tty_register_driver(rio_driver))) |
895 | goto out2; | 891 | goto out2; |
@@ -897,116 +893,111 @@ static int rio_init_drivers(void) | |||
897 | goto out3; | 893 | goto out3; |
898 | func_exit(); | 894 | func_exit(); |
899 | return 0; | 895 | return 0; |
900 | out3: | 896 | out3: |
901 | tty_unregister_driver(rio_driver); | 897 | tty_unregister_driver(rio_driver); |
902 | out2: | 898 | out2: |
903 | put_tty_driver(rio_driver2); | 899 | put_tty_driver(rio_driver2); |
904 | out1: | 900 | out1: |
905 | put_tty_driver(rio_driver); | 901 | put_tty_driver(rio_driver); |
906 | out: | 902 | out: |
907 | printk(KERN_ERR "rio: Couldn't register a rio driver, error = %d\n", | 903 | printk(KERN_ERR "rio: Couldn't register a rio driver, error = %d\n", error); |
908 | error); | ||
909 | return 1; | 904 | return 1; |
910 | } | 905 | } |
911 | 906 | ||
912 | 907 | ||
913 | static void * ckmalloc (int size) | 908 | static void *ckmalloc(int size) |
914 | { | 909 | { |
915 | void *p; | 910 | void *p; |
916 | 911 | ||
917 | p = kmalloc(size, GFP_KERNEL); | 912 | p = kmalloc(size, GFP_KERNEL); |
918 | if (p) | 913 | if (p) |
919 | memset(p, 0, size); | 914 | memset(p, 0, size); |
920 | return p; | 915 | return p; |
921 | } | 916 | } |
922 | 917 | ||
923 | 918 | ||
924 | 919 | ||
925 | static int rio_init_datastructures (void) | 920 | static int rio_init_datastructures(void) |
926 | { | 921 | { |
927 | int i; | 922 | int i; |
928 | struct Port *port; | 923 | struct Port *port; |
929 | func_enter(); | 924 | func_enter(); |
930 | 925 | ||
931 | /* Many drivers statically allocate the maximum number of ports | 926 | /* Many drivers statically allocate the maximum number of ports |
932 | There is no reason not to allocate them dynamically. Is there? -- REW */ | 927 | There is no reason not to allocate them dynamically. Is there? -- REW */ |
933 | /* However, the RIO driver allows users to configure their first | 928 | /* However, the RIO driver allows users to configure their first |
934 | RTA as the ports numbered 504-511. We therefore need to allocate | 929 | RTA as the ports numbered 504-511. We therefore need to allocate |
935 | the whole range. :-( -- REW */ | 930 | the whole range. :-( -- REW */ |
936 | 931 | ||
937 | #define RI_SZ sizeof(struct rio_info) | 932 | #define RI_SZ sizeof(struct rio_info) |
938 | #define HOST_SZ sizeof(struct Host) | 933 | #define HOST_SZ sizeof(struct Host) |
939 | #define PORT_SZ sizeof(struct Port *) | 934 | #define PORT_SZ sizeof(struct Port *) |
940 | #define TMIO_SZ sizeof(struct termios *) | 935 | #define TMIO_SZ sizeof(struct termios *) |
941 | rio_dprintk (RIO_DEBUG_INIT, "getting : %d %d %d %d %d bytes\n", | 936 | rio_dprintk(RIO_DEBUG_INIT, "getting : %d %d %d %d %d bytes\n", RI_SZ, RIO_HOSTS * HOST_SZ, RIO_PORTS * PORT_SZ, RIO_PORTS * TMIO_SZ, RIO_PORTS * TMIO_SZ); |
942 | RI_SZ, | 937 | |
943 | RIO_HOSTS * HOST_SZ, | 938 | if (!(p = ckmalloc(RI_SZ))) |
944 | RIO_PORTS * PORT_SZ, | 939 | goto free0; |
945 | RIO_PORTS * TMIO_SZ, | 940 | if (!(p->RIOHosts = ckmalloc(RIO_HOSTS * HOST_SZ))) |
946 | RIO_PORTS * TMIO_SZ); | 941 | goto free1; |
947 | 942 | if (!(p->RIOPortp = ckmalloc(RIO_PORTS * PORT_SZ))) | |
948 | if (!(p = ckmalloc ( RI_SZ))) goto free0; | 943 | goto free2; |
949 | if (!(p->RIOHosts = ckmalloc (RIO_HOSTS * HOST_SZ))) goto free1; | 944 | p->RIOConf = RIOConf; |
950 | if (!(p->RIOPortp = ckmalloc (RIO_PORTS * PORT_SZ))) goto free2; | 945 | rio_dprintk(RIO_DEBUG_INIT, "Got : %p %p %p\n", p, p->RIOHosts, p->RIOPortp); |
951 | p->RIOConf = RIOConf; | ||
952 | rio_dprintk (RIO_DEBUG_INIT, "Got : %p %p %p\n", | ||
953 | p, p->RIOHosts, p->RIOPortp); | ||
954 | 946 | ||
955 | #if 1 | 947 | #if 1 |
956 | for (i = 0; i < RIO_PORTS; i++) { | 948 | for (i = 0; i < RIO_PORTS; i++) { |
957 | port = p->RIOPortp[i] = ckmalloc (sizeof (struct Port)); | 949 | port = p->RIOPortp[i] = ckmalloc(sizeof(struct Port)); |
958 | if (!port) { | 950 | if (!port) { |
959 | goto free6; | 951 | goto free6; |
960 | } | 952 | } |
961 | rio_dprintk (RIO_DEBUG_INIT, "initing port %d (%d)\n", i, port->Mapped); | 953 | rio_dprintk(RIO_DEBUG_INIT, "initing port %d (%d)\n", i, port->Mapped); |
962 | port->PortNum = i; | 954 | port->PortNum = i; |
963 | port->gs.magic = RIO_MAGIC; | 955 | port->gs.magic = RIO_MAGIC; |
964 | port->gs.close_delay = HZ/2; | 956 | port->gs.close_delay = HZ / 2; |
965 | port->gs.closing_wait = 30 * HZ; | 957 | port->gs.closing_wait = 30 * HZ; |
966 | port->gs.rd = &rio_real_driver; | 958 | port->gs.rd = &rio_real_driver; |
967 | spin_lock_init(&port->portSem); | 959 | spin_lock_init(&port->portSem); |
968 | /* | 960 | /* |
969 | * Initializing wait queue | 961 | * Initializing wait queue |
970 | */ | 962 | */ |
971 | init_waitqueue_head(&port->gs.open_wait); | 963 | init_waitqueue_head(&port->gs.open_wait); |
972 | init_waitqueue_head(&port->gs.close_wait); | 964 | init_waitqueue_head(&port->gs.close_wait); |
973 | } | 965 | } |
974 | #else | 966 | #else |
975 | /* We could postpone initializing them to when they are configured. */ | 967 | /* We could postpone initializing them to when they are configured. */ |
976 | #endif | 968 | #endif |
977 | 969 | ||
978 | 970 | ||
979 | |||
980 | if (rio_debug & RIO_DEBUG_INIT) { | ||
981 | my_hd (&rio_real_driver, sizeof (rio_real_driver)); | ||
982 | } | ||
983 | 971 | ||
984 | 972 | if (rio_debug & RIO_DEBUG_INIT) { | |
985 | func_exit(); | 973 | my_hd(&rio_real_driver, sizeof(rio_real_driver)); |
986 | return 0; | 974 | } |
975 | |||
987 | 976 | ||
988 | free6:for (i--;i>=0;i--) | 977 | func_exit(); |
989 | kfree (p->RIOPortp[i]); | 978 | return 0; |
979 | |||
980 | free6:for (i--; i >= 0; i--) | ||
981 | kfree(p->RIOPortp[i]); | ||
990 | /*free5: | 982 | /*free5: |
991 | free4: | 983 | free4: |
992 | free3:*/kfree (p->RIOPortp); | 984 | free3:*/ kfree(p->RIOPortp); |
993 | free2:kfree (p->RIOHosts); | 985 | free2:kfree(p->RIOHosts); |
994 | free1: | 986 | free1: |
995 | rio_dprintk (RIO_DEBUG_INIT, "Not enough memory! %p %p %p\n", | 987 | rio_dprintk(RIO_DEBUG_INIT, "Not enough memory! %p %p %p\n", p, p->RIOHosts, p->RIOPortp); |
996 | p, p->RIOHosts, p->RIOPortp); | 988 | kfree(p); |
997 | kfree(p); | 989 | free0: |
998 | free0: | 990 | return -ENOMEM; |
999 | return -ENOMEM; | ||
1000 | } | 991 | } |
1001 | 992 | ||
1002 | static void __exit rio_release_drivers(void) | 993 | static void __exit rio_release_drivers(void) |
1003 | { | 994 | { |
1004 | func_enter(); | 995 | func_enter(); |
1005 | tty_unregister_driver(rio_driver2); | 996 | tty_unregister_driver(rio_driver2); |
1006 | tty_unregister_driver(rio_driver); | 997 | tty_unregister_driver(rio_driver); |
1007 | put_tty_driver(rio_driver2); | 998 | put_tty_driver(rio_driver2); |
1008 | put_tty_driver(rio_driver); | 999 | put_tty_driver(rio_driver); |
1009 | func_exit(); | 1000 | func_exit(); |
1010 | } | 1001 | } |
1011 | 1002 | ||
1012 | 1003 | ||
@@ -1017,7 +1008,7 @@ static void __exit rio_release_drivers(void) | |||
1017 | There is another bit besides Bit 17. Turning that bit off | 1008 | There is another bit besides Bit 17. Turning that bit off |
1018 | (on boards shipped with the fix in the eeprom) results in a | 1009 | (on boards shipped with the fix in the eeprom) results in a |
1019 | hang on the next access to the card. | 1010 | hang on the next access to the card. |
1020 | */ | 1011 | */ |
1021 | 1012 | ||
1022 | /******************************************************** | 1013 | /******************************************************** |
1023 | * Setting bit 17 in the CNTRL register of the PLX 9050 * | 1014 | * Setting bit 17 in the CNTRL register of the PLX 9050 * |
@@ -1030,319 +1021,293 @@ static void __exit rio_release_drivers(void) | |||
1030 | EEprom. As the bit is read/write for the CPU, we can fix it here, | 1021 | EEprom. As the bit is read/write for the CPU, we can fix it here, |
1031 | if we detect that it isn't set correctly. -- REW */ | 1022 | if we detect that it isn't set correctly. -- REW */ |
1032 | 1023 | ||
1033 | static void fix_rio_pci (struct pci_dev *pdev) | 1024 | static void fix_rio_pci(struct pci_dev *pdev) |
1034 | { | 1025 | { |
1035 | unsigned int hwbase; | 1026 | unsigned int hwbase; |
1036 | unsigned long rebase; | 1027 | unsigned long rebase; |
1037 | unsigned int t; | 1028 | unsigned int t; |
1038 | 1029 | ||
1039 | #define CNTRL_REG_OFFSET 0x50 | 1030 | #define CNTRL_REG_OFFSET 0x50 |
1040 | #define CNTRL_REG_GOODVALUE 0x18260000 | 1031 | #define CNTRL_REG_GOODVALUE 0x18260000 |
1041 | 1032 | ||
1042 | pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); | 1033 | pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); |
1043 | hwbase &= PCI_BASE_ADDRESS_MEM_MASK; | 1034 | hwbase &= PCI_BASE_ADDRESS_MEM_MASK; |
1044 | rebase = (ulong) ioremap(hwbase, 0x80); | 1035 | rebase = (ulong) ioremap(hwbase, 0x80); |
1045 | t = readl (rebase + CNTRL_REG_OFFSET); | 1036 | t = readl(rebase + CNTRL_REG_OFFSET); |
1046 | if (t != CNTRL_REG_GOODVALUE) { | 1037 | if (t != CNTRL_REG_GOODVALUE) { |
1047 | printk (KERN_DEBUG "rio: performing cntrl reg fix: %08x -> %08x\n", | 1038 | printk(KERN_DEBUG "rio: performing cntrl reg fix: %08x -> %08x\n", t, CNTRL_REG_GOODVALUE); |
1048 | t, CNTRL_REG_GOODVALUE); | 1039 | writel(CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); |
1049 | writel (CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); | 1040 | } |
1050 | } | 1041 | iounmap((char *) rebase); |
1051 | iounmap((char*) rebase); | ||
1052 | } | 1042 | } |
1053 | #endif | 1043 | #endif |
1054 | 1044 | ||
1055 | 1045 | ||
1056 | static int __init rio_init(void) | 1046 | static int __init rio_init(void) |
1057 | { | 1047 | { |
1058 | int found = 0; | 1048 | int found = 0; |
1059 | int i; | 1049 | int i; |
1060 | struct Host *hp; | 1050 | struct Host *hp; |
1061 | int retval; | 1051 | int retval; |
1062 | struct vpd_prom *vpdp; | 1052 | struct vpd_prom *vpdp; |
1063 | int okboard; | 1053 | int okboard; |
1064 | 1054 | ||
1065 | #ifdef CONFIG_PCI | 1055 | #ifdef CONFIG_PCI |
1066 | struct pci_dev *pdev = NULL; | 1056 | struct pci_dev *pdev = NULL; |
1067 | unsigned int tint; | 1057 | unsigned int tint; |
1068 | unsigned short tshort; | 1058 | unsigned short tshort; |
1069 | #endif | 1059 | #endif |
1070 | 1060 | ||
1071 | func_enter(); | 1061 | func_enter(); |
1072 | rio_dprintk (RIO_DEBUG_INIT, "Initing rio module... (rio_debug=%d)\n", | 1062 | rio_dprintk(RIO_DEBUG_INIT, "Initing rio module... (rio_debug=%d)\n", rio_debug); |
1073 | rio_debug); | 1063 | |
1074 | 1064 | if (abs((long) (&rio_debug) - rio_debug) < 0x10000) { | |
1075 | if (abs ((long) (&rio_debug) - rio_debug) < 0x10000) { | 1065 | printk(KERN_WARNING "rio: rio_debug is an address, instead of a value. " "Assuming -1. Was %x/%p.\n", rio_debug, &rio_debug); |
1076 | printk (KERN_WARNING "rio: rio_debug is an address, instead of a value. " | 1066 | rio_debug = -1; |
1077 | "Assuming -1. Was %x/%p.\n", rio_debug, &rio_debug); | 1067 | } |
1078 | rio_debug=-1; | 1068 | |
1079 | } | 1069 | if (misc_register(&rio_fw_device) < 0) { |
1080 | 1070 | printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n"); | |
1081 | if (misc_register(&rio_fw_device) < 0) { | 1071 | return -EIO; |
1082 | printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n"); | 1072 | } |
1083 | return -EIO; | 1073 | |
1084 | } | 1074 | retval = rio_init_datastructures(); |
1085 | 1075 | if (retval < 0) { | |
1086 | retval = rio_init_datastructures (); | 1076 | misc_deregister(&rio_fw_device); |
1087 | if (retval < 0) { | 1077 | return retval; |
1088 | misc_deregister(&rio_fw_device); | 1078 | } |
1089 | return retval; | ||
1090 | } | ||
1091 | |||
1092 | #ifdef CONFIG_PCI | 1079 | #ifdef CONFIG_PCI |
1093 | /* First look for the JET devices: */ | 1080 | /* First look for the JET devices: */ |
1094 | while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, | 1081 | while ((pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, pdev))) { |
1095 | PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, | 1082 | if (pci_enable_device(pdev)) |
1096 | pdev))) { | 1083 | continue; |
1097 | if (pci_enable_device(pdev)) continue; | 1084 | |
1098 | 1085 | /* Specialix has a whole bunch of cards with | |
1099 | /* Specialix has a whole bunch of cards with | 1086 | 0x2000 as the device ID. They say its because |
1100 | 0x2000 as the device ID. They say its because | 1087 | the standard requires it. Stupid standard. */ |
1101 | the standard requires it. Stupid standard. */ | 1088 | /* It seems that reading a word doesn't work reliably on 2.0. |
1102 | /* It seems that reading a word doesn't work reliably on 2.0. | 1089 | Also, reading a non-aligned dword doesn't work. So we read the |
1103 | Also, reading a non-aligned dword doesn't work. So we read the | 1090 | whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID) |
1104 | whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID) | 1091 | ourselves */ |
1105 | ourselves */ | 1092 | /* I don't know why the define doesn't work, constant 0x2c does --REW */ |
1106 | /* I don't know why the define doesn't work, constant 0x2c does --REW */ | 1093 | pci_read_config_dword(pdev, 0x2c, &tint); |
1107 | pci_read_config_dword (pdev, 0x2c, &tint); | 1094 | tshort = (tint >> 16) & 0xffff; |
1108 | tshort = (tint >> 16) & 0xffff; | 1095 | rio_dprintk(RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint); |
1109 | rio_dprintk (RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint); | 1096 | if (tshort != 0x0100) { |
1110 | if (tshort != 0x0100) { | 1097 | rio_dprintk(RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n", tshort); |
1111 | rio_dprintk (RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n", | 1098 | continue; |
1112 | tshort); | 1099 | } |
1113 | continue; | 1100 | rio_dprintk(RIO_DEBUG_PROBE, "cp1\n"); |
1114 | } | 1101 | |
1115 | rio_dprintk (RIO_DEBUG_PROBE, "cp1\n"); | 1102 | pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2, &tint); |
1116 | 1103 | ||
1117 | pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2, &tint); | 1104 | hp = &p->RIOHosts[p->RIONumHosts]; |
1118 | 1105 | hp->PaddrP = tint & PCI_BASE_ADDRESS_MEM_MASK; | |
1119 | hp = &p->RIOHosts[p->RIONumHosts]; | 1106 | hp->Ivec = pdev->irq; |
1120 | hp->PaddrP = tint & PCI_BASE_ADDRESS_MEM_MASK; | 1107 | if (((1 << hp->Ivec) & rio_irqmask) == 0) |
1121 | hp->Ivec = pdev->irq; | 1108 | hp->Ivec = 0; |
1122 | if (((1 << hp->Ivec) & rio_irqmask) == 0) | 1109 | hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); |
1123 | hp->Ivec = 0; | 1110 | hp->CardP = (struct DpRam *) hp->Caddr; |
1124 | hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); | 1111 | hp->Type = RIO_PCI; |
1125 | hp->CardP = (struct DpRam *) hp->Caddr; | 1112 | hp->Copy = rio_pcicopy; |
1126 | hp->Type = RIO_PCI; | 1113 | hp->Mode = RIO_PCI_BOOT_FROM_RAM; |
1127 | hp->Copy = rio_pcicopy; | 1114 | spin_lock_init(&hp->HostLock); |
1128 | hp->Mode = RIO_PCI_BOOT_FROM_RAM; | 1115 | rio_reset_interrupt(hp); |
1129 | spin_lock_init(&hp->HostLock); | 1116 | rio_start_card_running(hp); |
1130 | rio_reset_interrupt (hp); | 1117 | |
1131 | rio_start_card_running (hp); | 1118 | rio_dprintk(RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *) p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); |
1132 | 1119 | if (RIOBoardTest(p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr, RIO_PCI, 0) == RIO_SUCCESS) { | |
1133 | rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", | 1120 | rio_dprintk(RIO_DEBUG_INIT, "Done RIOBoardTest\n"); |
1134 | (void *)p->RIOHosts[p->RIONumHosts].PaddrP, | 1121 | WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff); |
1135 | p->RIOHosts[p->RIONumHosts].Caddr); | 1122 | p->RIOHosts[p->RIONumHosts].UniqueNum = |
1136 | if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP, | 1123 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) & 0xFF) << 0) | |
1137 | p->RIOHosts[p->RIONumHosts].Caddr, | 1124 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); |
1138 | RIO_PCI, 0 ) == RIO_SUCCESS) { | 1125 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); |
1139 | rio_dprintk (RIO_DEBUG_INIT, "Done RIOBoardTest\n"); | 1126 | |
1140 | WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff); | 1127 | fix_rio_pci(pdev); |
1141 | p->RIOHosts[p->RIONumHosts].UniqueNum = | 1128 | p->RIOLastPCISearch = RIO_SUCCESS; |
1142 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)| | 1129 | p->RIONumHosts++; |
1143 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)| | 1130 | found++; |
1144 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)| | 1131 | } else { |
1145 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24); | 1132 | iounmap((char *) (p->RIOHosts[p->RIONumHosts].Caddr)); |
1146 | rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", | 1133 | } |
1147 | p->RIOHosts[p->RIONumHosts].UniqueNum); | 1134 | } |
1148 | 1135 | ||
1149 | fix_rio_pci (pdev); | 1136 | /* Then look for the older PCI card.... : */ |
1150 | p->RIOLastPCISearch = RIO_SUCCESS; | 1137 | |
1151 | p->RIONumHosts++; | 1138 | /* These older PCI cards have problems (only byte-mode access is |
1152 | found++; | 1139 | supported), which makes them a bit awkward to support. |
1153 | } else { | 1140 | They also have problems sharing interrupts. Be careful. |
1154 | iounmap((char*) (p->RIOHosts[p->RIONumHosts].Caddr)); | 1141 | (The driver now refuses to share interrupts for these |
1155 | } | 1142 | cards. This should be sufficient). |
1156 | } | 1143 | */ |
1157 | 1144 | ||
1158 | /* Then look for the older PCI card.... : */ | 1145 | /* Then look for the older RIO/PCI devices: */ |
1159 | 1146 | while ((pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_RIO, pdev))) { | |
1160 | /* These older PCI cards have problems (only byte-mode access is | 1147 | if (pci_enable_device(pdev)) |
1161 | supported), which makes them a bit awkward to support. | 1148 | continue; |
1162 | They also have problems sharing interrupts. Be careful. | ||
1163 | (The driver now refuses to share interrupts for these | ||
1164 | cards. This should be sufficient). | ||
1165 | */ | ||
1166 | |||
1167 | /* Then look for the older RIO/PCI devices: */ | ||
1168 | while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, | ||
1169 | PCI_DEVICE_ID_SPECIALIX_RIO, | ||
1170 | pdev))) { | ||
1171 | if (pci_enable_device(pdev)) continue; | ||
1172 | 1149 | ||
1173 | #ifdef CONFIG_RIO_OLDPCI | 1150 | #ifdef CONFIG_RIO_OLDPCI |
1174 | pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &tint); | 1151 | pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &tint); |
1175 | 1152 | ||
1176 | hp = &p->RIOHosts[p->RIONumHosts]; | 1153 | hp = &p->RIOHosts[p->RIONumHosts]; |
1177 | hp->PaddrP = tint & PCI_BASE_ADDRESS_MEM_MASK; | 1154 | hp->PaddrP = tint & PCI_BASE_ADDRESS_MEM_MASK; |
1178 | hp->Ivec = pdev->irq; | 1155 | hp->Ivec = pdev->irq; |
1179 | if (((1 << hp->Ivec) & rio_irqmask) == 0) | 1156 | if (((1 << hp->Ivec) & rio_irqmask) == 0) |
1180 | hp->Ivec = 0; | 1157 | hp->Ivec = 0; |
1181 | hp->Ivec |= 0x8000; /* Mark as non-sharable */ | 1158 | hp->Ivec |= 0x8000; /* Mark as non-sharable */ |
1182 | hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); | 1159 | hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); |
1183 | hp->CardP = (struct DpRam *) hp->Caddr; | 1160 | hp->CardP = (struct DpRam *) hp->Caddr; |
1184 | hp->Type = RIO_PCI; | 1161 | hp->Type = RIO_PCI; |
1185 | hp->Copy = rio_pcicopy; | 1162 | hp->Copy = rio_pcicopy; |
1186 | hp->Mode = RIO_PCI_BOOT_FROM_RAM; | 1163 | hp->Mode = RIO_PCI_BOOT_FROM_RAM; |
1187 | spin_lock_init(&hp->HostLock); | 1164 | spin_lock_init(&hp->HostLock); |
1188 | 1165 | ||
1189 | rio_dprintk (RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec); | 1166 | rio_dprintk(RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec); |
1190 | rio_dprintk (RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode); | 1167 | rio_dprintk(RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode); |
1191 | 1168 | ||
1192 | rio_reset_interrupt (hp); | 1169 | rio_reset_interrupt(hp); |
1193 | rio_start_card_running (hp); | 1170 | rio_start_card_running(hp); |
1194 | rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", | 1171 | rio_dprintk(RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *) p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); |
1195 | (void *)p->RIOHosts[p->RIONumHosts].PaddrP, | 1172 | if (RIOBoardTest(p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr, RIO_PCI, 0) == RIO_SUCCESS) { |
1196 | p->RIOHosts[p->RIONumHosts].Caddr); | 1173 | WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff); |
1197 | if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP, | 1174 | p->RIOHosts[p->RIONumHosts].UniqueNum = |
1198 | p->RIOHosts[p->RIONumHosts].Caddr, | 1175 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) & 0xFF) << 0) | |
1199 | RIO_PCI, 0 ) == RIO_SUCCESS) { | 1176 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); |
1200 | WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff); | 1177 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); |
1201 | p->RIOHosts[p->RIONumHosts].UniqueNum = | 1178 | |
1202 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)| | 1179 | p->RIOLastPCISearch = RIO_SUCCESS; |
1203 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)| | 1180 | p->RIONumHosts++; |
1204 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)| | 1181 | found++; |
1205 | ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24); | 1182 | } else { |
1206 | rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", | 1183 | iounmap((char *) (p->RIOHosts[p->RIONumHosts].Caddr)); |
1207 | p->RIOHosts[p->RIONumHosts].UniqueNum); | 1184 | } |
1208 | |||
1209 | p->RIOLastPCISearch = RIO_SUCCESS; | ||
1210 | p->RIONumHosts++; | ||
1211 | found++; | ||
1212 | } else { | ||
1213 | iounmap((char*) (p->RIOHosts[p->RIONumHosts].Caddr)); | ||
1214 | } | ||
1215 | #else | 1185 | #else |
1216 | printk (KERN_ERR "Found an older RIO PCI card, but the driver is not " | 1186 | printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n"); |
1217 | "compiled to support it.\n"); | ||
1218 | #endif | 1187 | #endif |
1219 | } | 1188 | } |
1220 | #endif /* PCI */ | 1189 | #endif /* PCI */ |
1221 | 1190 | ||
1222 | /* Now probe for ISA cards... */ | 1191 | /* Now probe for ISA cards... */ |
1223 | for (i=0;i<NR_RIO_ADDRS;i++) { | 1192 | for (i = 0; i < NR_RIO_ADDRS; i++) { |
1224 | hp = &p->RIOHosts[p->RIONumHosts]; | 1193 | hp = &p->RIOHosts[p->RIONumHosts]; |
1225 | hp->PaddrP = rio_probe_addrs[i]; | 1194 | hp->PaddrP = rio_probe_addrs[i]; |
1226 | /* There was something about the IRQs of these cards. 'Forget what.--REW */ | 1195 | /* There was something about the IRQs of these cards. 'Forget what.--REW */ |
1227 | hp->Ivec = 0; | 1196 | hp->Ivec = 0; |
1228 | hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); | 1197 | hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); |
1229 | hp->CardP = (struct DpRam *) hp->Caddr; | 1198 | hp->CardP = (struct DpRam *) hp->Caddr; |
1230 | hp->Type = RIO_AT; | 1199 | hp->Type = RIO_AT; |
1231 | hp->Copy = rio_pcicopy; /* AT card PCI???? - PVDL | 1200 | hp->Copy = rio_pcicopy; /* AT card PCI???? - PVDL |
1232 | * -- YES! this is now a normal copy. Only the | 1201 | * -- YES! this is now a normal copy. Only the |
1233 | * old PCI card uses the special PCI copy. | 1202 | * old PCI card uses the special PCI copy. |
1234 | * Moreover, the ISA card will work with the | 1203 | * Moreover, the ISA card will work with the |
1235 | * special PCI copy anyway. -- REW */ | 1204 | * special PCI copy anyway. -- REW */ |
1236 | hp->Mode = 0; | 1205 | hp->Mode = 0; |
1237 | spin_lock_init(&hp->HostLock); | 1206 | spin_lock_init(&hp->HostLock); |
1238 | 1207 | ||
1239 | vpdp = get_VPD_PROM (hp); | 1208 | vpdp = get_VPD_PROM(hp); |
1240 | rio_dprintk (RIO_DEBUG_PROBE, "Got VPD ROM\n"); | 1209 | rio_dprintk(RIO_DEBUG_PROBE, "Got VPD ROM\n"); |
1241 | okboard = 0; | 1210 | okboard = 0; |
1242 | if ((strncmp (vpdp->identifier, RIO_ISA_IDENT, 16) == 0) || | 1211 | if ((strncmp(vpdp->identifier, RIO_ISA_IDENT, 16) == 0) || (strncmp(vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) || (strncmp(vpdp->identifier, RIO_ISA3_IDENT, 16) == 0)) { |
1243 | (strncmp (vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) || | 1212 | /* Board is present... */ |
1244 | (strncmp (vpdp->identifier, RIO_ISA3_IDENT, 16) == 0)) { | 1213 | if (RIOBoardTest(hp->PaddrP, hp->Caddr, RIO_AT, 0) == RIO_SUCCESS) { |
1245 | /* Board is present... */ | 1214 | /* ... and feeling fine!!!! */ |
1246 | if (RIOBoardTest (hp->PaddrP, | 1215 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); |
1247 | hp->Caddr, RIO_AT, 0) == RIO_SUCCESS) { | 1216 | if (RIOAssignAT(p, hp->PaddrP, hp->Caddr, 0)) { |
1248 | /* ... and feeling fine!!!! */ | 1217 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, host%d uniqid = %x.\n", p->RIONumHosts, p->RIOHosts[p->RIONumHosts - 1].UniqueNum); |
1249 | rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", | 1218 | okboard++; |
1250 | p->RIOHosts[p->RIONumHosts].UniqueNum); | 1219 | found++; |
1251 | if (RIOAssignAT(p, hp->PaddrP, hp->Caddr, 0)) { | 1220 | } |
1252 | rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, host%d uniqid = %x.\n", | 1221 | } |
1253 | p->RIONumHosts, | 1222 | |
1254 | p->RIOHosts[p->RIONumHosts-1].UniqueNum); | 1223 | if (!okboard) |
1255 | okboard++; | 1224 | iounmap((char *) (hp->Caddr)); |
1256 | found++; | 1225 | } |
1257 | } | 1226 | } |
1258 | } | 1227 | |
1259 | 1228 | ||
1260 | if (!okboard) | 1229 | for (i = 0; i < p->RIONumHosts; i++) { |
1261 | iounmap ((char*) (hp->Caddr)); | 1230 | hp = &p->RIOHosts[i]; |
1262 | } | 1231 | if (hp->Ivec) { |
1263 | } | 1232 | int mode = SA_SHIRQ; |
1264 | 1233 | if (hp->Ivec & 0x8000) { | |
1265 | 1234 | mode = 0; | |
1266 | for (i=0;i<p->RIONumHosts;i++) { | 1235 | hp->Ivec &= 0x7fff; |
1267 | hp = &p->RIOHosts[i]; | 1236 | } |
1268 | if (hp->Ivec) { | 1237 | rio_dprintk(RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp, hp->Ivec, hp->Mode); |
1269 | int mode = SA_SHIRQ; | 1238 | retval = request_irq(hp->Ivec, rio_interrupt, mode, "rio", hp); |
1270 | if (hp->Ivec & 0x8000) {mode = 0; hp->Ivec &= 0x7fff;} | 1239 | rio_dprintk(RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval); |
1271 | rio_dprintk (RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp,hp->Ivec, hp->Mode); | 1240 | if (retval) { |
1272 | retval = request_irq (hp->Ivec, rio_interrupt, mode, "rio", hp); | 1241 | printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec); |
1273 | rio_dprintk (RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval); | 1242 | hp->Ivec = 0; |
1274 | if (retval) { | 1243 | } |
1275 | printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec); | 1244 | rio_dprintk(RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec); |
1276 | hp->Ivec = 0; | 1245 | if (hp->Ivec != 0) { |
1277 | } | 1246 | rio_dprintk(RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n"); |
1278 | rio_dprintk (RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec); | 1247 | hp->Mode |= RIO_PCI_INT_ENABLE; |
1279 | if (hp->Ivec != 0){ | 1248 | } else |
1280 | rio_dprintk (RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n"); | 1249 | hp->Mode &= !RIO_PCI_INT_ENABLE; |
1281 | hp->Mode |= RIO_PCI_INT_ENABLE; | 1250 | rio_dprintk(RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode); |
1282 | } else | 1251 | rio_start_card_running(hp); |
1283 | hp->Mode &= !RIO_PCI_INT_ENABLE; | 1252 | } |
1284 | rio_dprintk (RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode); | 1253 | /* Init the timer "always" to make sure that it can safely be |
1285 | rio_start_card_running (hp); | 1254 | deleted when we unload... */ |
1286 | } | 1255 | |
1287 | /* Init the timer "always" to make sure that it can safely be | 1256 | init_timer(&hp->timer); |
1288 | deleted when we unload... */ | 1257 | if (!hp->Ivec) { |
1289 | 1258 | rio_dprintk(RIO_DEBUG_INIT, "Starting polling at %dj intervals.\n", rio_poll); | |
1290 | init_timer (&hp->timer); | 1259 | hp->timer.data = i; |
1291 | if (!hp->Ivec) { | 1260 | hp->timer.function = rio_pollfunc; |
1292 | rio_dprintk (RIO_DEBUG_INIT, "Starting polling at %dj intervals.\n", | 1261 | hp->timer.expires = jiffies + rio_poll; |
1293 | rio_poll); | 1262 | add_timer(&hp->timer); |
1294 | hp->timer.data = i; | 1263 | } |
1295 | hp->timer.function = rio_pollfunc; | 1264 | } |
1296 | hp->timer.expires = jiffies + rio_poll; | 1265 | |
1297 | add_timer (&hp->timer); | 1266 | if (found) { |
1298 | } | 1267 | rio_dprintk(RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found); |
1299 | } | 1268 | rio_init_drivers(); |
1300 | 1269 | } else { | |
1301 | if (found) { | 1270 | /* deregister the misc device we created earlier */ |
1302 | rio_dprintk (RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found); | 1271 | misc_deregister(&rio_fw_device); |
1303 | rio_init_drivers (); | 1272 | } |
1304 | } else { | 1273 | |
1305 | /* deregister the misc device we created earlier */ | 1274 | func_exit(); |
1306 | misc_deregister(&rio_fw_device); | 1275 | return found ? 0 : -EIO; |
1307 | } | ||
1308 | |||
1309 | func_exit(); | ||
1310 | return found?0:-EIO; | ||
1311 | } | 1276 | } |
1312 | 1277 | ||
1313 | 1278 | ||
1314 | static void __exit rio_exit (void) | 1279 | static void __exit rio_exit(void) |
1315 | { | 1280 | { |
1316 | int i; | 1281 | int i; |
1317 | struct Host *hp; | 1282 | struct Host *hp; |
1318 | 1283 | ||
1319 | func_enter(); | 1284 | func_enter(); |
1320 | 1285 | ||
1321 | for (i=0,hp=p->RIOHosts;i<p->RIONumHosts;i++, hp++) { | 1286 | for (i = 0, hp = p->RIOHosts; i < p->RIONumHosts; i++, hp++) { |
1322 | RIOHostReset (hp->Type, hp->CardP, hp->Slot); | 1287 | RIOHostReset(hp->Type, hp->CardP, hp->Slot); |
1323 | if (hp->Ivec) { | 1288 | if (hp->Ivec) { |
1324 | free_irq (hp->Ivec, hp); | 1289 | free_irq(hp->Ivec, hp); |
1325 | rio_dprintk (RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec); | 1290 | rio_dprintk(RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec); |
1326 | } | 1291 | } |
1327 | /* It is safe/allowed to del_timer a non-active timer */ | 1292 | /* It is safe/allowed to del_timer a non-active timer */ |
1328 | del_timer (&hp->timer); | 1293 | del_timer(&hp->timer); |
1329 | } | 1294 | } |
1330 | 1295 | ||
1331 | if (misc_deregister(&rio_fw_device) < 0) { | 1296 | if (misc_deregister(&rio_fw_device) < 0) { |
1332 | printk (KERN_INFO "rio: couldn't deregister control-device\n"); | 1297 | printk(KERN_INFO "rio: couldn't deregister control-device\n"); |
1333 | } | 1298 | } |
1334 | 1299 | ||
1335 | 1300 | ||
1336 | rio_dprintk (RIO_DEBUG_CLEANUP, "Cleaning up drivers\n"); | 1301 | rio_dprintk(RIO_DEBUG_CLEANUP, "Cleaning up drivers\n"); |
1337 | 1302 | ||
1338 | rio_release_drivers (); | 1303 | rio_release_drivers(); |
1339 | 1304 | ||
1340 | /* Release dynamically allocated memory */ | 1305 | /* Release dynamically allocated memory */ |
1341 | kfree (p->RIOPortp); | 1306 | kfree(p->RIOPortp); |
1342 | kfree (p->RIOHosts); | 1307 | kfree(p->RIOHosts); |
1343 | kfree (p); | 1308 | kfree(p); |
1344 | 1309 | ||
1345 | func_exit(); | 1310 | func_exit(); |
1346 | } | 1311 | } |
1347 | 1312 | ||
1348 | module_init(rio_init); | 1313 | module_init(rio_init); |
@@ -1368,4 +1333,3 @@ module_exit(rio_exit); | |||
1368 | * tab-width: 8 | 1333 | * tab-width: 8 |
1369 | * End: | 1334 | * End: |
1370 | */ | 1335 | */ |
1371 | |||