~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/usb/uss720.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*****************************************************************************/
  2 
  3 /*
  4  *      uss720.c  --  USS720 USB Parport Cable.
  5  *
  6  *      Copyright (C) 1999
  7  *          Thomas Sailer (sailer@ife.ee.ethz.ch)
  8  *
  9  *      This program is free software; you can redistribute it and/or modify
 10  *      it under the terms of the GNU General Public License as published by
 11  *      the Free Software Foundation; either version 2 of the License, or
 12  *      (at your option) any later version.
 13  *
 14  *      This program is distributed in the hope that it will be useful,
 15  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 16  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17  *      GNU General Public License for more details.
 18  *
 19  *      You should have received a copy of the GNU General Public License
 20  *      along with this program; if not, write to the Free Software
 21  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 22  *
 23  *  Based on parport_pc.c
 24  *
 25  *  History:
 26  *   0.1  04.08.99  Created
 27  *   0.2  07.08.99  Some fixes mainly suggested by Tim Waugh
 28  *                  Interrupt handling currently disabled because
 29  *                  usb_request_irq crashes somewhere within ohci.c
 30  *                  for no apparent reason (that is for me, anyway)
 31  *                  ECP currently untested
 32  *   0.3  10.08.99  fixing merge errors
 33  *   0.4  13.08.99  Added Vendor/Product ID of Brad Hard's cable
 34  *   0.5  20.09.99  usb_control_msg wrapper used
 35  *        Nov01.00  usb_device_table support by Adam J. Richter
 36  *
 37  */
 38 
 39 /*****************************************************************************/
 40 
 41 #include <linux/module.h>
 42 #include <linux/socket.h>
 43 #include <linux/parport.h>
 44 #include <linux/init.h>
 45 #include <linux/usb.h>
 46 
 47 /* --------------------------------------------------------------------- */
 48 
 49 struct parport_uss720_private {
 50         struct usb_device *usbdev;
 51         void *irqhandle;
 52         unsigned int irqpipe;
 53         unsigned char reg[7];  /* USB registers */
 54 };
 55 
 56 /* --------------------------------------------------------------------- */
 57 
 58 static int get_1284_register(struct parport *pp, unsigned char reg, unsigned char *val)
 59 {
 60         struct parport_uss720_private *priv = pp->private_data;
 61         struct usb_device *usbdev = priv->usbdev;
 62         static const unsigned char regindex[9] = {
 63                 4, 0, 1, 5, 5, 0, 2, 3, 6
 64         };
 65         int ret;
 66 
 67         if (!usbdev)
 68                 return -1;
 69         ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev,0), 3, 0xc0, ((unsigned int)reg) << 8, 0, priv->reg, 7, HZ);
 70         if (ret) {
 71                 printk(KERN_DEBUG "uss720: get_1284_register(%d) failed, status 0x%x\n",
 72                        (unsigned int)reg, ret);
 73         } else {
 74 #if 0
 75                 printk(KERN_DEBUG "uss720: get_1284_register(%d) return %02x %02x %02x %02x %02x %02x %02x\n",
 76                        (unsigned int)reg, (unsigned int)priv->reg[0], (unsigned int)priv->reg[1],
 77                        (unsigned int)priv->reg[2], (unsigned int)priv->reg[3], (unsigned int)priv->reg[4],
 78                        (unsigned int)priv->reg[5], (unsigned int)priv->reg[6]);
 79 #endif
 80                 /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
 81                 if (priv->reg[2] & priv->reg[1] & 0x10)
 82                         parport_generic_irq(0, pp, NULL);
 83         }
 84         if (val)
 85                 *val = priv->reg[(reg >= 9) ? 0 : regindex[reg]];
 86         return ret;
 87 }
 88 
 89 static int set_1284_register(struct parport *pp, unsigned char reg, unsigned char val)
 90 {
 91         struct parport_uss720_private *priv = pp->private_data;
 92         struct usb_device *usbdev = priv->usbdev;
 93         int ret;
 94 
 95         if (!usbdev)
 96                 return -1;
 97         ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev,0), 4, 0x40, (((unsigned int)reg) << 8) | val, 0, NULL, 0, HZ);
 98         if (ret) {
 99                 printk(KERN_DEBUG "uss720: set_1284_register(%u,0x%02x) failed, status 0x%x\n", 
100                        (unsigned int)reg, (unsigned int)val, ret);
101         } else {
102 #if 0
103                 printk(KERN_DEBUG "uss720: set_1284_register(%u,0x%02x)\n", 
104                        (unsigned int)reg, (unsigned int)val);
105 #endif
106         }
107         return ret;
108 }
109 
110 /* --------------------------------------------------------------------- */
111 
112 /* ECR modes */
113 #define ECR_SPP 00
114 #define ECR_PS2 01
115 #define ECR_PPF 02
116 #define ECR_ECP 03
117 #define ECR_EPP 04
118 
119 /* Safely change the mode bits in the ECR */
120 static int change_mode(struct parport *pp, int m)
121 {
122         struct parport_uss720_private *priv = pp->private_data;
123         int mode;
124 
125         if (get_1284_register(pp, 6, NULL))
126                 return -EIO;
127         /* Bits <7:5> contain the mode. */
128         mode = (priv->reg[2] >> 5) & 0x7;
129         if (mode == m)
130                 return 0;
131         /* We have to go through mode 000 or 001 */
132         if (mode > ECR_PS2 && m > ECR_PS2)
133                 if (change_mode(pp, ECR_PS2))
134                         return -EIO;
135 
136         if (m <= ECR_PS2 && !(priv->reg[1] & 0x20)) {
137                 /* This mode resets the FIFO, so we may
138                  * have to wait for it to drain first. */
139                 long expire = jiffies + pp->physport->cad->timeout;
140                 switch (mode) {
141                 case ECR_PPF: /* Parallel Port FIFO mode */
142                 case ECR_ECP: /* ECP Parallel Port mode */
143                         /* Poll slowly. */
144                         for (;;) {
145                                 if (get_1284_register(pp, 6, NULL))
146                                         return -EIO;
147                                 if (priv->reg[2] & 0x01)
148                                         break;
149                                 if (time_after_eq (jiffies, expire))
150                                         /* The FIFO is stuck. */
151                                         return -EBUSY;
152                                 current->state = TASK_INTERRUPTIBLE;
153                                 schedule_timeout((HZ + 99) / 100);
154                                 if (signal_pending (current))
155                                         break;
156                         }
157                 }
158         }
159         /* Set the mode. */
160         if (set_1284_register(pp, 6, m << 5))
161                 return -EIO;
162         return 0;
163 }
164 
165 /*
166  * Clear TIMEOUT BIT in EPP MODE
167  */
168 static int clear_epp_timeout(struct parport *pp)
169 {
170         unsigned char stat;
171 
172         if (get_1284_register(pp, 1, &stat))
173                 return 1;
174         return stat & 1;
175 }
176 
177 /*
178  * Access functions.
179  */
180 #if 0
181 static int uss720_irq(int usbstatus, void *buffer, int len, void *dev_id)
182 {
183         struct parport *pp = (struct parport *)dev_id;
184         struct parport_uss720_private *priv = pp->private_data; 
185 
186         if (usbstatus != USB_ST_NOERROR || len < 4 || !buffer)
187                 return 1;
188         memcpy(priv->reg, buffer, 4);
189         /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
190         if (priv->reg[2] & priv->reg[1] & 0x10)
191                 parport_generic_irq(0, pp, NULL);
192         return 1;
193 }
194 #endif
195 
196 static void parport_uss720_write_data(struct parport *pp, unsigned char d)
197 {
198         set_1284_register(pp, 0, d);
199 }
200 
201 static unsigned char parport_uss720_read_data(struct parport *pp)
202 {
203         unsigned char ret;
204 
205         if (get_1284_register(pp, 0, &ret))
206                 return 0;
207         return ret;
208 }
209 
210 static void parport_uss720_write_control(struct parport *pp, unsigned char d)
211 {
212         struct parport_uss720_private *priv = pp->private_data; 
213 
214         d = (d & 0xf) | (priv->reg[1] & 0xf0);
215         if (set_1284_register(pp, 2, d))
216                 return;
217         priv->reg[1] = d;
218 }
219 
220 static unsigned char parport_uss720_read_control(struct parport *pp)
221 {
222         struct parport_uss720_private *priv = pp->private_data; 
223         return priv->reg[1] & 0xf; /* Use soft copy */
224 }
225 
226 static unsigned char parport_uss720_frob_control(struct parport *pp, unsigned char mask, unsigned char val)
227 {
228         struct parport_uss720_private *priv = pp->private_data; 
229         unsigned char d;
230 
231         mask &= 0x0f;
232         val &= 0x0f;
233         d = (priv->reg[1] & (~mask)) ^ val;
234         if (set_1284_register(pp, 2, d))
235                 return 0;
236         priv->reg[1] = d;
237         return d & 0xf;
238 }
239 
240 static unsigned char parport_uss720_read_status(struct parport *pp)
241 {
242         unsigned char ret;
243 
244         if (get_1284_register(pp, 1, &ret))
245                 return 0;
246         return ret & 0xf8;
247 }
248 
249 static void parport_uss720_disable_irq(struct parport *pp)
250 {
251         struct parport_uss720_private *priv = pp->private_data; 
252         unsigned char d;
253 
254         d = priv->reg[1] & ~0x10;
255         if (set_1284_register(pp, 2, d))
256                 return;
257         priv->reg[1] = d;
258 }
259 
260 static void parport_uss720_enable_irq(struct parport *pp)
261 {
262         struct parport_uss720_private *priv = pp->private_data; 
263         unsigned char d;
264 
265         d = priv->reg[1] | 0x10;
266         if (set_1284_register(pp, 2, d))
267                 return;
268         priv->reg[1] = d;
269 }
270 
271 static void parport_uss720_data_forward (struct parport *pp)
272 {
273         struct parport_uss720_private *priv = pp->private_data; 
274         unsigned char d;
275 
276         d = priv->reg[1] & ~0x20;
277         if (set_1284_register(pp, 2, d))
278                 return;
279         priv->reg[1] = d;
280 }
281 
282 static void parport_uss720_data_reverse (struct parport *pp)
283 {
284         struct parport_uss720_private *priv = pp->private_data; 
285         unsigned char d;
286 
287         d = priv->reg[1] | 0x20;
288         if (set_1284_register(pp, 2, d))
289                 return;
290         priv->reg[1] = d;
291 }
292 
293 static void parport_uss720_init_state(struct pardevice *dev, struct parport_state *s)
294 {
295         s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
296         s->u.pc.ecr = 0x24;
297 }
298 
299 static void parport_uss720_save_state(struct parport *pp, struct parport_state *s)
300 {
301         struct parport_uss720_private *priv = pp->private_data; 
302 
303         if (get_1284_register(pp, 2, NULL))
304                 return;
305         s->u.pc.ctr = priv->reg[1];
306         s->u.pc.ecr = priv->reg[2];
307 }
308 
309 static void parport_uss720_restore_state(struct parport *pp, struct parport_state *s)
310 {
311         set_1284_register(pp, 2, s->u.pc.ctr);
312         set_1284_register(pp, 6, s->u.pc.ecr);
313         get_1284_register(pp, 2, NULL);
314 }
315 
316 static size_t parport_uss720_epp_read_data(struct parport *pp, void *buf, size_t length, int flags)
317 {
318         struct parport_uss720_private *priv = pp->private_data; 
319         size_t got = 0;
320 
321         if (change_mode(pp, ECR_EPP))
322                 return 0;
323         for (; got < length; got++) {
324                 if (get_1284_register(pp, 4, (char *)buf))
325                         break;
326                 ((char*)buf)++;
327                 if (priv->reg[0] & 0x01) {
328                         clear_epp_timeout(pp);
329                         break;
330                 }
331         }
332         change_mode(pp, ECR_PS2);
333         return got;
334 }
335 
336 static size_t parport_uss720_epp_write_data(struct parport *pp, const void *buf, size_t length, int flags)
337 {
338 #if 0
339         struct parport_uss720_private *priv = pp->private_data; 
340         size_t written = 0;
341 
342         if (change_mode(pp, ECR_EPP))
343                 return 0;
344         for (; written < length; written++) {
345                 if (set_1284_register(pp, 4, (char *)buf))
346                         break;
347                 ((char*)buf)++;
348                 if (get_1284_register(pp, 1, NULL))
349                         break;
350                 if (priv->reg[0] & 0x01) {
351                         clear_epp_timeout(pp);
352                         break;
353                 }
354         }
355         change_mode(pp, ECR_PS2);
356         return written;
357 #else
358         struct parport_uss720_private *priv = pp->private_data;
359         struct usb_device *usbdev = priv->usbdev;
360         int rlen;
361         int i;
362 
363         if (!usbdev)
364                 return 0;
365         if (change_mode(pp, ECR_EPP))
366                 return 0;
367         i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buf, length, &rlen, HZ*20);
368         if (i)
369                 printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %u\n", buf, length, rlen);
370         change_mode(pp, ECR_PS2);
371         return rlen;
372 #endif
373 }
374 
375 static size_t parport_uss720_epp_read_addr(struct parport *pp, void *buf, size_t length, int flags)
376 {
377         struct parport_uss720_private *priv = pp->private_data; 
378         size_t got = 0;
379 
380         if (change_mode(pp, ECR_EPP))
381                 return 0;
382         for (; got < length; got++) {
383                 if (get_1284_register(pp, 3, (char *)buf))
384                         break;
385                 ((char*)buf)++;
386                 if (priv->reg[0] & 0x01) {
387                         clear_epp_timeout(pp);
388                         break;
389                 }
390         }
391         change_mode(pp, ECR_PS2);
392         return got;
393 }
394 
395 static size_t parport_uss720_epp_write_addr(struct parport *pp, const void *buf, size_t length, int flags)
396 {
397         struct parport_uss720_private *priv = pp->private_data; 
398         size_t written = 0;
399 
400         if (change_mode(pp, ECR_EPP))
401                 return 0;
402         for (; written < length; written++) {
403                 if (set_1284_register(pp, 3, *(char *)buf))
404                         break;
405                 ((char*)buf)++;
406                 if (get_1284_register(pp, 1, NULL))
407                         break;
408                 if (priv->reg[0] & 0x01) {
409                         clear_epp_timeout(pp);
410                         break;
411                 }
412         }
413         change_mode(pp, ECR_PS2);
414         return written;
415 }
416 
417 static size_t parport_uss720_ecp_write_data(struct parport *pp, const void *buffer, size_t len, int flags)
418 {
419         struct parport_uss720_private *priv = pp->private_data;
420         struct usb_device *usbdev = priv->usbdev;
421         int rlen;
422         int i;
423 
424         if (!usbdev)
425                 return 0;
426         if (change_mode(pp, ECR_ECP))
427                 return 0;
428         i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, HZ*20);
429         if (i)
430                 printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %u\n", buffer, len, rlen);
431         change_mode(pp, ECR_PS2);
432         return rlen;
433 }
434 
435 static size_t parport_uss720_ecp_read_data(struct parport *pp, void *buffer, size_t len, int flags)
436 {
437         struct parport_uss720_private *priv = pp->private_data;
438         struct usb_device *usbdev = priv->usbdev;
439         int rlen;
440         int i;
441 
442         if (!usbdev)
443                 return 0;
444         if (change_mode(pp, ECR_ECP))
445                 return 0;
446         i = usb_bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), buffer, len, &rlen, HZ*20);
447         if (i)
448                 printk(KERN_ERR "uss720: recvbulk ep 2 buf %p len %u rlen %u\n", buffer, len, rlen);
449         change_mode(pp, ECR_PS2);
450         return rlen;
451 }
452 
453 static size_t parport_uss720_ecp_write_addr(struct parport *pp, const void *buffer, size_t len, int flags)
454 {
455         size_t written = 0;
456 
457         if (change_mode(pp, ECR_ECP))
458                 return 0;
459         for (; written < len; written++) {
460                 if (set_1284_register(pp, 5, *(char *)buffer))
461                         break;
462                 ((char*)buffer)++;
463         }
464         change_mode(pp, ECR_PS2);
465         return written;
466 }
467 
468 static size_t parport_uss720_write_compat(struct parport *pp, const void *buffer, size_t len, int flags)
469 {
470         struct parport_uss720_private *priv = pp->private_data;
471         struct usb_device *usbdev = priv->usbdev;
472         int rlen;
473         int i;
474 
475         if (!usbdev)
476                 return 0;
477         if (change_mode(pp, ECR_PPF))
478                 return 0;
479         i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, HZ*20);
480         if (i)
481                 printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %u\n", buffer, len, rlen);
482         change_mode(pp, ECR_PS2);
483         return rlen;
484 }
485 
486 void parport_uss720_inc_use_count(void)
487 {
488         MOD_INC_USE_COUNT;
489 }
490 
491 void parport_uss720_dec_use_count(void)
492 {
493         MOD_DEC_USE_COUNT;
494 }
495 
496 /* --------------------------------------------------------------------- */
497 
498 static struct parport_operations parport_uss720_ops = 
499 {
500         parport_uss720_write_data,
501         parport_uss720_read_data,
502 
503         parport_uss720_write_control,
504         parport_uss720_read_control,
505         parport_uss720_frob_control,
506 
507         parport_uss720_read_status,
508 
509         parport_uss720_enable_irq,
510         parport_uss720_disable_irq,
511 
512         parport_uss720_data_forward,
513         parport_uss720_data_reverse,
514 
515         parport_uss720_init_state,
516         parport_uss720_save_state,
517         parport_uss720_restore_state,
518 
519         parport_uss720_inc_use_count,
520         parport_uss720_dec_use_count,
521 
522         parport_uss720_epp_write_data,
523         parport_uss720_epp_read_data,
524         parport_uss720_epp_write_addr,
525         parport_uss720_epp_read_addr,
526 
527         parport_uss720_ecp_write_data,
528         parport_uss720_ecp_read_data,
529         parport_uss720_ecp_write_addr,
530 
531         parport_uss720_write_compat,
532         parport_ieee1284_read_nibble,
533         parport_ieee1284_read_byte,
534 };
535 
536 /* --------------------------------------------------------------------- */
537 
538 static void * uss720_probe(struct usb_device *usbdev, unsigned int ifnum,
539                            const struct usb_device_id *id)
540 {
541         struct usb_interface_descriptor *interface;
542         struct usb_endpoint_descriptor *endpoint;
543         struct parport_uss720_private *priv;
544         struct parport *pp;
545         int i;
546 
547         printk(KERN_DEBUG "uss720: probe: vendor id 0x%x, device id 0x%x\n",
548                usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);
549 
550         /* our known interfaces have 3 alternate settings */
551         if (usbdev->actconfig->interface[ifnum].num_altsetting != 3)
552                 return NULL;
553 
554         i = usb_set_interface(usbdev, ifnum, 2);
555         printk(KERN_DEBUG "uss720: set inteface result %d\n", i);
556 
557         interface = &usbdev->actconfig->interface[ifnum].altsetting[2];
558 
559         /*
560          * Allocate parport interface 
561          */
562         printk(KERN_INFO "uss720: (C) 1999 by Thomas Sailer, <sailer@ife.ee.ethz.ch>\n");
563 
564         if (!(priv = kmalloc(sizeof(struct parport_uss720_private), GFP_KERNEL)))
565                 return NULL;
566         if (!(pp = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &parport_uss720_ops))) {
567                 printk(KERN_WARNING "usb-uss720: could not register parport\n");
568                 goto probe_abort;
569         }
570 
571         pp->private_data = priv;
572         priv->usbdev = usbdev;
573         pp->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP | PARPORT_MODE_ECP | PARPORT_MODE_COMPAT;
574 
575         /* set the USS720 control register to manual mode, no ECP compression, enable all ints */
576         set_1284_register(pp, 7, 0x00);
577         set_1284_register(pp, 6, 0x30);  /* PS/2 mode */
578         set_1284_register(pp, 2, 0x0c);
579         /* debugging */
580         get_1284_register(pp, 0, NULL);
581         printk("uss720: reg: %02x %02x %02x %02x %02x %02x %02x\n",
582                priv->reg[0], priv->reg[1], priv->reg[2], priv->reg[3], priv->reg[4], priv->reg[5], priv->reg[6]);
583 
584         endpoint = &interface->endpoint[2];
585         printk(KERN_DEBUG "uss720: epaddr %d interval %d\n", endpoint->bEndpointAddress, endpoint->bInterval);
586 #if 0
587         priv->irqpipe = usb_rcvctrlpipe(usbdev, endpoint->bEndpointAddress);
588         i = usb_request_irq(usbdev, priv->irqpipe,
589                                   uss720_irq, endpoint->bInterval,
590                                   pp, &priv->irqhandle);
591         if (i) {
592                 printk (KERN_WARNING "usb-uss720: usb_request_irq failed (0x%x)\n", i);
593                 goto probe_abort_port;
594         }
595 #endif
596         parport_proc_register(pp);
597         parport_announce_port(pp);
598 
599         MOD_INC_USE_COUNT;
600         return pp;
601 
602 #if 0
603 probe_abort_port:
604         parport_unregister_port(pp);
605 #endif
606 probe_abort:
607         kfree(priv);
608         return NULL;
609 }
610 
611 static void uss720_disconnect(struct usb_device *usbdev, void *ptr)
612 {
613         struct parport *pp = (struct parport *)ptr;
614         struct parport_uss720_private *priv = pp->private_data;
615 
616 #if 0
617         usb_release_irq(usbdev, priv->irqhandle, priv->irqpipe);
618 #endif
619         priv->usbdev = NULL;
620         parport_proc_unregister(pp);
621         parport_unregister_port(pp);
622         kfree(priv);
623         MOD_DEC_USE_COUNT;
624 }
625 
626 /* table of cables that work through this driver */
627 static struct usb_device_id uss720_table [] = {
628         { USB_DEVICE(0x047e, 0x1001) },
629         { USB_DEVICE(0x0557, 0x2001) },
630         { USB_DEVICE(0x0729, 0x1284) },
631         { }                                             /* Terminating entry */
632 };
633 
634 MODULE_DEVICE_TABLE (usb, uss720_table);
635 
636 
637 static struct usb_driver uss720_driver = {
638         name:           "uss720",
639         probe:          uss720_probe,
640         disconnect:     uss720_disconnect,
641         id_table:       uss720_table,
642 };
643 
644 /* --------------------------------------------------------------------- */
645 
646 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch");
647 MODULE_DESCRIPTION("USB Parport Cable driver for Cables using the Lucent Technologies USS720 Chip");
648 
649 static int __init uss720_init(void)
650 {
651         if (usb_register(&uss720_driver) < 0)
652                 return -1;
653 
654         printk(KERN_INFO "uss720: USB<->IEEE1284 cable driver v0.4 registered.\n"
655                KERN_INFO "uss720: (C) 1999 by Thomas Sailer, <sailer@ife.ee.ethz.ch>\n");
656         return 0;
657 }
658 
659 static void __exit uss720_cleanup(void)
660 {
661         usb_deregister(&uss720_driver);
662 }
663 
664 module_init(uss720_init);
665 module_exit(uss720_cleanup);
666 
667 /* --------------------------------------------------------------------- */
668 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.