usb: misc: usbsevseg: don't print on ENOMEM
[linux-2.6-block.git] / drivers / usb / misc / uss720.c
CommitLineData
1da177e4
LT
1/*****************************************************************************/
2
3/*
4 * uss720.c -- USS720 USB Parport Cable.
5 *
ecc1624a 6 * Copyright (C) 1999, 2005, 2010
0f36163d 7 * Thomas Sailer (t.sailer@alumni.ethz.ch)
1da177e4
LT
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:
0f36163d
TS
26 * 0.1 04.08.1999 Created
27 * 0.2 07.08.1999 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.1999 fixing merge errors
33 * 0.4 13.08.1999 Added Vendor/Product ID of Brad Hard's cable
34 * 0.5 20.09.1999 usb_control_msg wrapper used
35 * Nov01.2000 usb_device_table support by Adam J. Richter
36 * 08.04.2001 Identify version on module load. gb
37 * 0.6 02.09.2005 Fix "scheduling in interrupt" problem by making save/restore
38 * context asynchronous
1da177e4
LT
39 *
40 */
41
42/*****************************************************************************/
43
44#include <linux/module.h>
45#include <linux/socket.h>
46#include <linux/parport.h>
47#include <linux/init.h>
48#include <linux/usb.h>
49#include <linux/delay.h>
0f36163d
TS
50#include <linux/completion.h>
51#include <linux/kref.h>
5a0e3ad6 52#include <linux/slab.h>
1da177e4
LT
53
54/*
55 * Version Information
56 */
0f36163d
TS
57#define DRIVER_VERSION "v0.6"
58#define DRIVER_AUTHOR "Thomas M. Sailer, t.sailer@alumni.ethz.ch"
1da177e4
LT
59#define DRIVER_DESC "USB Parport Cable driver for Cables using the Lucent Technologies USS720 Chip"
60
61/* --------------------------------------------------------------------- */
62
63struct parport_uss720_private {
64 struct usb_device *usbdev;
0f36163d
TS
65 struct parport *pp;
66 struct kref ref_count;
67 __u8 reg[7]; /* USB registers */
68 struct list_head asynclist;
69 spinlock_t asynclock;
70};
71
72struct uss720_async_request {
73 struct parport_uss720_private *priv;
74 struct kref ref_count;
75 struct list_head asynclist;
76 struct completion compl;
77 struct urb *urb;
9821aa9d 78 struct usb_ctrlrequest *dr;
0f36163d 79 __u8 reg[7];
1da177e4
LT
80};
81
82/* --------------------------------------------------------------------- */
83
0f36163d 84static void destroy_priv(struct kref *kref)
1da177e4 85{
0f36163d 86 struct parport_uss720_private *priv = container_of(kref, struct parport_uss720_private, ref_count);
1da177e4 87
7a2d2810 88 dev_dbg(&priv->usbdev->dev, "destroying priv datastructure\n");
0f36163d
TS
89 usb_put_dev(priv->usbdev);
90 kfree(priv);
0f36163d
TS
91}
92
93static void destroy_async(struct kref *kref)
94{
95 struct uss720_async_request *rq = container_of(kref, struct uss720_async_request, ref_count);
96 struct parport_uss720_private *priv = rq->priv;
97 unsigned long flags;
98
99 if (likely(rq->urb))
100 usb_free_urb(rq->urb);
9821aa9d 101 kfree(rq->dr);
0f36163d
TS
102 spin_lock_irqsave(&priv->asynclock, flags);
103 list_del_init(&rq->asynclist);
104 spin_unlock_irqrestore(&priv->asynclock, flags);
105 kfree(rq);
106 kref_put(&priv->ref_count, destroy_priv);
107}
108
109/* --------------------------------------------------------------------- */
110
7d12e780 111static void async_complete(struct urb *urb)
0f36163d
TS
112{
113 struct uss720_async_request *rq;
114 struct parport *pp;
115 struct parport_uss720_private *priv;
82210d37 116 int status = urb->status;
0f36163d
TS
117
118 rq = urb->context;
119 priv = rq->priv;
120 pp = priv->pp;
82210d37 121 if (status) {
d2b1ff71
GKH
122 dev_err(&urb->dev->dev, "async_complete: urb error %d\n",
123 status);
9821aa9d 124 } else if (rq->dr->bRequest == 3) {
0f36163d 125 memcpy(priv->reg, rq->reg, sizeof(priv->reg));
1da177e4 126#if 0
5d31a6dc
AS
127 dev_dbg(&priv->usbdev->dev, "async_complete regs %7ph\n",
128 priv->reg);
1da177e4
LT
129#endif
130 /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
0f36163d 131 if (rq->reg[2] & rq->reg[1] & 0x10 && pp)
f230d101 132 parport_generic_irq(pp);
1da177e4 133 }
0f36163d
TS
134 complete(&rq->compl);
135 kref_put(&rq->ref_count, destroy_async);
1da177e4
LT
136}
137
0f36163d
TS
138static struct uss720_async_request *submit_async_request(struct parport_uss720_private *priv,
139 __u8 request, __u8 requesttype, __u16 value, __u16 index,
55016f10 140 gfp_t mem_flags)
1da177e4 141{
0f36163d
TS
142 struct usb_device *usbdev;
143 struct uss720_async_request *rq;
144 unsigned long flags;
1da177e4
LT
145 int ret;
146
0f36163d
TS
147 if (!priv)
148 return NULL;
149 usbdev = priv->usbdev;
1da177e4 150 if (!usbdev)
0f36163d 151 return NULL;
9821aa9d 152 rq = kzalloc(sizeof(struct uss720_async_request), mem_flags);
0f36163d 153 if (!rq) {
d2b1ff71 154 dev_err(&usbdev->dev, "submit_async_request out of memory\n");
0f36163d
TS
155 return NULL;
156 }
157 kref_init(&rq->ref_count);
158 INIT_LIST_HEAD(&rq->asynclist);
159 init_completion(&rq->compl);
160 kref_get(&priv->ref_count);
161 rq->priv = priv;
162 rq->urb = usb_alloc_urb(0, mem_flags);
163 if (!rq->urb) {
164 kref_put(&rq->ref_count, destroy_async);
0f36163d
TS
165 return NULL;
166 }
9821aa9d
JH
167 rq->dr = kmalloc(sizeof(*rq->dr), mem_flags);
168 if (!rq->dr) {
169 kref_put(&rq->ref_count, destroy_async);
170 return NULL;
171 }
172 rq->dr->bRequestType = requesttype;
173 rq->dr->bRequest = request;
174 rq->dr->wValue = cpu_to_le16(value);
175 rq->dr->wIndex = cpu_to_le16(index);
176 rq->dr->wLength = cpu_to_le16((request == 3) ? sizeof(rq->reg) : 0);
0f36163d 177 usb_fill_control_urb(rq->urb, usbdev, (requesttype & 0x80) ? usb_rcvctrlpipe(usbdev, 0) : usb_sndctrlpipe(usbdev, 0),
9821aa9d 178 (unsigned char *)rq->dr,
0f36163d
TS
179 (request == 3) ? rq->reg : NULL, (request == 3) ? sizeof(rq->reg) : 0, async_complete, rq);
180 /* rq->urb->transfer_flags |= URB_ASYNC_UNLINK; */
181 spin_lock_irqsave(&priv->asynclock, flags);
182 list_add_tail(&rq->asynclist, &priv->asynclist);
183 spin_unlock_irqrestore(&priv->asynclock, flags);
adaa3c63 184 kref_get(&rq->ref_count);
0f36163d 185 ret = usb_submit_urb(rq->urb, mem_flags);
adaa3c63 186 if (!ret)
0f36163d 187 return rq;
adaa3c63 188 destroy_async(&rq->ref_count);
d2b1ff71 189 dev_err(&usbdev->dev, "submit_async_request submit_urb failed with %d\n", ret);
0f36163d
TS
190 return NULL;
191}
192
193static unsigned int kill_all_async_requests_priv(struct parport_uss720_private *priv)
194{
195 struct uss720_async_request *rq;
196 unsigned long flags;
197 unsigned int ret = 0;
198
199 spin_lock_irqsave(&priv->asynclock, flags);
200 list_for_each_entry(rq, &priv->asynclist, asynclist) {
201 usb_unlink_urb(rq->urb);
202 ret++;
203 }
204 spin_unlock_irqrestore(&priv->asynclock, flags);
1da177e4
LT
205 return ret;
206}
207
208/* --------------------------------------------------------------------- */
209
55016f10 210static int get_1284_register(struct parport *pp, unsigned char reg, unsigned char *val, gfp_t mem_flags)
0f36163d
TS
211{
212 struct parport_uss720_private *priv;
213 struct uss720_async_request *rq;
214 static const unsigned char regindex[9] = {
215 4, 0, 1, 5, 5, 0, 2, 3, 6
216 };
217 int ret;
218
219 if (!pp)
220 return -EIO;
221 priv = pp->private_data;
222 rq = submit_async_request(priv, 3, 0xc0, ((unsigned int)reg) << 8, 0, mem_flags);
223 if (!rq) {
d2b1ff71
GKH
224 dev_err(&priv->usbdev->dev, "get_1284_register(%u) failed",
225 (unsigned int)reg);
0f36163d
TS
226 return -EIO;
227 }
228 if (!val) {
229 kref_put(&rq->ref_count, destroy_async);
230 return 0;
231 }
232 if (wait_for_completion_timeout(&rq->compl, HZ)) {
233 ret = rq->urb->status;
234 *val = priv->reg[(reg >= 9) ? 0 : regindex[reg]];
235 if (ret)
3b6004f3
GKH
236 printk(KERN_WARNING "get_1284_register: "
237 "usb error %d\n", ret);
0f36163d
TS
238 kref_put(&rq->ref_count, destroy_async);
239 return ret;
240 }
3b6004f3 241 printk(KERN_WARNING "get_1284_register timeout\n");
0f36163d
TS
242 kill_all_async_requests_priv(priv);
243 return -EIO;
244}
245
55016f10 246static int set_1284_register(struct parport *pp, unsigned char reg, unsigned char val, gfp_t mem_flags)
0f36163d
TS
247{
248 struct parport_uss720_private *priv;
249 struct uss720_async_request *rq;
250
251 if (!pp)
252 return -EIO;
253 priv = pp->private_data;
254 rq = submit_async_request(priv, 4, 0x40, (((unsigned int)reg) << 8) | val, 0, mem_flags);
255 if (!rq) {
d2b1ff71
GKH
256 dev_err(&priv->usbdev->dev, "set_1284_register(%u,%u) failed",
257 (unsigned int)reg, (unsigned int)val);
0f36163d
TS
258 return -EIO;
259 }
260 kref_put(&rq->ref_count, destroy_async);
261 return 0;
262}
263
264/* --------------------------------------------------------------------- */
265
1da177e4
LT
266/* ECR modes */
267#define ECR_SPP 00
268#define ECR_PS2 01
269#define ECR_PPF 02
270#define ECR_ECP 03
271#define ECR_EPP 04
272
273/* Safely change the mode bits in the ECR */
274static int change_mode(struct parport *pp, int m)
275{
276 struct parport_uss720_private *priv = pp->private_data;
277 int mode;
0f36163d 278 __u8 reg;
1da177e4 279
0f36163d 280 if (get_1284_register(pp, 6, &reg, GFP_KERNEL))
1da177e4
LT
281 return -EIO;
282 /* Bits <7:5> contain the mode. */
283 mode = (priv->reg[2] >> 5) & 0x7;
284 if (mode == m)
285 return 0;
286 /* We have to go through mode 000 or 001 */
287 if (mode > ECR_PS2 && m > ECR_PS2)
288 if (change_mode(pp, ECR_PS2))
289 return -EIO;
290
291 if (m <= ECR_PS2 && !(priv->reg[1] & 0x20)) {
292 /* This mode resets the FIFO, so we may
293 * have to wait for it to drain first. */
294 unsigned long expire = jiffies + pp->physport->cad->timeout;
295 switch (mode) {
296 case ECR_PPF: /* Parallel Port FIFO mode */
297 case ECR_ECP: /* ECP Parallel Port mode */
298 /* Poll slowly. */
299 for (;;) {
0f36163d 300 if (get_1284_register(pp, 6, &reg, GFP_KERNEL))
1da177e4
LT
301 return -EIO;
302 if (priv->reg[2] & 0x01)
303 break;
304 if (time_after_eq (jiffies, expire))
305 /* The FIFO is stuck. */
306 return -EBUSY;
307 msleep_interruptible(10);
308 if (signal_pending (current))
309 break;
310 }
311 }
312 }
313 /* Set the mode. */
0f36163d
TS
314 if (set_1284_register(pp, 6, m << 5, GFP_KERNEL))
315 return -EIO;
316 if (get_1284_register(pp, 6, &reg, GFP_KERNEL))
1da177e4
LT
317 return -EIO;
318 return 0;
319}
320
321/*
322 * Clear TIMEOUT BIT in EPP MODE
323 */
324static int clear_epp_timeout(struct parport *pp)
325{
326 unsigned char stat;
327
0f36163d 328 if (get_1284_register(pp, 1, &stat, GFP_KERNEL))
1da177e4
LT
329 return 1;
330 return stat & 1;
331}
332
333/*
334 * Access functions.
335 */
336#if 0
337static int uss720_irq(int usbstatus, void *buffer, int len, void *dev_id)
338{
339 struct parport *pp = (struct parport *)dev_id;
340 struct parport_uss720_private *priv = pp->private_data;
341
342 if (usbstatus != 0 || len < 4 || !buffer)
343 return 1;
344 memcpy(priv->reg, buffer, 4);
345 /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
346 if (priv->reg[2] & priv->reg[1] & 0x10)
f230d101 347 parport_generic_irq(pp);
1da177e4
LT
348 return 1;
349}
350#endif
351
352static void parport_uss720_write_data(struct parport *pp, unsigned char d)
353{
0f36163d 354 set_1284_register(pp, 0, d, GFP_KERNEL);
1da177e4
LT
355}
356
357static unsigned char parport_uss720_read_data(struct parport *pp)
358{
359 unsigned char ret;
360
0f36163d 361 if (get_1284_register(pp, 0, &ret, GFP_KERNEL))
1da177e4
LT
362 return 0;
363 return ret;
364}
365
366static void parport_uss720_write_control(struct parport *pp, unsigned char d)
367{
368 struct parport_uss720_private *priv = pp->private_data;
369
370 d = (d & 0xf) | (priv->reg[1] & 0xf0);
0f36163d 371 if (set_1284_register(pp, 2, d, GFP_KERNEL))
1da177e4
LT
372 return;
373 priv->reg[1] = d;
374}
375
376static unsigned char parport_uss720_read_control(struct parport *pp)
377{
378 struct parport_uss720_private *priv = pp->private_data;
379 return priv->reg[1] & 0xf; /* Use soft copy */
380}
381
382static unsigned char parport_uss720_frob_control(struct parport *pp, unsigned char mask, unsigned char val)
383{
384 struct parport_uss720_private *priv = pp->private_data;
385 unsigned char d;
386
387 mask &= 0x0f;
388 val &= 0x0f;
389 d = (priv->reg[1] & (~mask)) ^ val;
0f36163d 390 if (set_1284_register(pp, 2, d, GFP_KERNEL))
1da177e4
LT
391 return 0;
392 priv->reg[1] = d;
393 return d & 0xf;
394}
395
396static unsigned char parport_uss720_read_status(struct parport *pp)
397{
398 unsigned char ret;
399
0f36163d 400 if (get_1284_register(pp, 1, &ret, GFP_KERNEL))
1da177e4
LT
401 return 0;
402 return ret & 0xf8;
403}
404
405static void parport_uss720_disable_irq(struct parport *pp)
406{
407 struct parport_uss720_private *priv = pp->private_data;
408 unsigned char d;
409
410 d = priv->reg[1] & ~0x10;
0f36163d 411 if (set_1284_register(pp, 2, d, GFP_KERNEL))
1da177e4
LT
412 return;
413 priv->reg[1] = d;
414}
415
416static void parport_uss720_enable_irq(struct parport *pp)
417{
418 struct parport_uss720_private *priv = pp->private_data;
419 unsigned char d;
420
421 d = priv->reg[1] | 0x10;
0f36163d 422 if (set_1284_register(pp, 2, d, GFP_KERNEL))
1da177e4
LT
423 return;
424 priv->reg[1] = d;
425}
426
427static void parport_uss720_data_forward (struct parport *pp)
428{
429 struct parport_uss720_private *priv = pp->private_data;
430 unsigned char d;
431
432 d = priv->reg[1] & ~0x20;
0f36163d 433 if (set_1284_register(pp, 2, d, GFP_KERNEL))
1da177e4
LT
434 return;
435 priv->reg[1] = d;
436}
437
438static void parport_uss720_data_reverse (struct parport *pp)
439{
440 struct parport_uss720_private *priv = pp->private_data;
441 unsigned char d;
442
443 d = priv->reg[1] | 0x20;
0f36163d 444 if (set_1284_register(pp, 2, d, GFP_KERNEL))
1da177e4
LT
445 return;
446 priv->reg[1] = d;
447}
448
449static void parport_uss720_init_state(struct pardevice *dev, struct parport_state *s)
450{
451 s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
452 s->u.pc.ecr = 0x24;
453}
454
455static void parport_uss720_save_state(struct parport *pp, struct parport_state *s)
456{
457 struct parport_uss720_private *priv = pp->private_data;
458
0f36163d
TS
459#if 0
460 if (get_1284_register(pp, 2, NULL, GFP_ATOMIC))
1da177e4 461 return;
0f36163d 462#endif
1da177e4
LT
463 s->u.pc.ctr = priv->reg[1];
464 s->u.pc.ecr = priv->reg[2];
465}
466
467static void parport_uss720_restore_state(struct parport *pp, struct parport_state *s)
468{
0f36163d
TS
469 struct parport_uss720_private *priv = pp->private_data;
470
471 set_1284_register(pp, 2, s->u.pc.ctr, GFP_ATOMIC);
472 set_1284_register(pp, 6, s->u.pc.ecr, GFP_ATOMIC);
473 get_1284_register(pp, 2, NULL, GFP_ATOMIC);
474 priv->reg[1] = s->u.pc.ctr;
475 priv->reg[2] = s->u.pc.ecr;
1da177e4
LT
476}
477
478static size_t parport_uss720_epp_read_data(struct parport *pp, void *buf, size_t length, int flags)
479{
480 struct parport_uss720_private *priv = pp->private_data;
481 size_t got = 0;
482
483 if (change_mode(pp, ECR_EPP))
484 return 0;
485 for (; got < length; got++) {
0f36163d 486 if (get_1284_register(pp, 4, (char *)buf, GFP_KERNEL))
1da177e4
LT
487 break;
488 buf++;
489 if (priv->reg[0] & 0x01) {
490 clear_epp_timeout(pp);
491 break;
492 }
493 }
494 change_mode(pp, ECR_PS2);
495 return got;
496}
497
498static size_t parport_uss720_epp_write_data(struct parport *pp, const void *buf, size_t length, int flags)
499{
500#if 0
501 struct parport_uss720_private *priv = pp->private_data;
502 size_t written = 0;
503
504 if (change_mode(pp, ECR_EPP))
505 return 0;
506 for (; written < length; written++) {
0f36163d 507 if (set_1284_register(pp, 4, (char *)buf, GFP_KERNEL))
1da177e4
LT
508 break;
509 ((char*)buf)++;
0f36163d 510 if (get_1284_register(pp, 1, NULL, GFP_KERNEL))
1da177e4
LT
511 break;
512 if (priv->reg[0] & 0x01) {
513 clear_epp_timeout(pp);
514 break;
515 }
516 }
517 change_mode(pp, ECR_PS2);
518 return written;
519#else
520 struct parport_uss720_private *priv = pp->private_data;
521 struct usb_device *usbdev = priv->usbdev;
522 int rlen;
523 int i;
524
525 if (!usbdev)
526 return 0;
527 if (change_mode(pp, ECR_EPP))
528 return 0;
529 i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buf, length, &rlen, 20000);
530 if (i)
531 printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %Zu rlen %u\n", buf, length, rlen);
532 change_mode(pp, ECR_PS2);
533 return rlen;
534#endif
535}
536
537static size_t parport_uss720_epp_read_addr(struct parport *pp, void *buf, size_t length, int flags)
538{
539 struct parport_uss720_private *priv = pp->private_data;
540 size_t got = 0;
541
542 if (change_mode(pp, ECR_EPP))
543 return 0;
544 for (; got < length; got++) {
0f36163d 545 if (get_1284_register(pp, 3, (char *)buf, GFP_KERNEL))
1da177e4
LT
546 break;
547 buf++;
548 if (priv->reg[0] & 0x01) {
549 clear_epp_timeout(pp);
550 break;
551 }
552 }
553 change_mode(pp, ECR_PS2);
554 return got;
555}
556
557static size_t parport_uss720_epp_write_addr(struct parport *pp, const void *buf, size_t length, int flags)
558{
559 struct parport_uss720_private *priv = pp->private_data;
560 size_t written = 0;
561
562 if (change_mode(pp, ECR_EPP))
563 return 0;
564 for (; written < length; written++) {
0f36163d 565 if (set_1284_register(pp, 3, *(char *)buf, GFP_KERNEL))
1da177e4
LT
566 break;
567 buf++;
0f36163d 568 if (get_1284_register(pp, 1, NULL, GFP_KERNEL))
1da177e4
LT
569 break;
570 if (priv->reg[0] & 0x01) {
571 clear_epp_timeout(pp);
572 break;
573 }
574 }
575 change_mode(pp, ECR_PS2);
576 return written;
577}
578
579static size_t parport_uss720_ecp_write_data(struct parport *pp, const void *buffer, size_t len, int flags)
580{
581 struct parport_uss720_private *priv = pp->private_data;
582 struct usb_device *usbdev = priv->usbdev;
583 int rlen;
584 int i;
585
586 if (!usbdev)
587 return 0;
588 if (change_mode(pp, ECR_ECP))
589 return 0;
590 i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, 20000);
591 if (i)
592 printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %Zu rlen %u\n", buffer, len, rlen);
593 change_mode(pp, ECR_PS2);
594 return rlen;
595}
596
597static size_t parport_uss720_ecp_read_data(struct parport *pp, void *buffer, size_t len, int flags)
598{
599 struct parport_uss720_private *priv = pp->private_data;
600 struct usb_device *usbdev = priv->usbdev;
601 int rlen;
602 int i;
603
604 if (!usbdev)
605 return 0;
606 if (change_mode(pp, ECR_ECP))
607 return 0;
608 i = usb_bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), buffer, len, &rlen, 20000);
609 if (i)
610 printk(KERN_ERR "uss720: recvbulk ep 2 buf %p len %Zu rlen %u\n", buffer, len, rlen);
611 change_mode(pp, ECR_PS2);
612 return rlen;
613}
614
615static size_t parport_uss720_ecp_write_addr(struct parport *pp, const void *buffer, size_t len, int flags)
616{
617 size_t written = 0;
618
619 if (change_mode(pp, ECR_ECP))
620 return 0;
621 for (; written < len; written++) {
0f36163d 622 if (set_1284_register(pp, 5, *(char *)buffer, GFP_KERNEL))
1da177e4
LT
623 break;
624 buffer++;
625 }
626 change_mode(pp, ECR_PS2);
627 return written;
628}
629
630static size_t parport_uss720_write_compat(struct parport *pp, const void *buffer, size_t len, int flags)
631{
632 struct parport_uss720_private *priv = pp->private_data;
633 struct usb_device *usbdev = priv->usbdev;
634 int rlen;
635 int i;
636
637 if (!usbdev)
638 return 0;
639 if (change_mode(pp, ECR_PPF))
640 return 0;
641 i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, 20000);
642 if (i)
643 printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %Zu rlen %u\n", buffer, len, rlen);
644 change_mode(pp, ECR_PS2);
645 return rlen;
646}
647
648/* --------------------------------------------------------------------- */
649
650static struct parport_operations parport_uss720_ops =
651{
652 .owner = THIS_MODULE,
653 .write_data = parport_uss720_write_data,
654 .read_data = parport_uss720_read_data,
655
656 .write_control = parport_uss720_write_control,
657 .read_control = parport_uss720_read_control,
658 .frob_control = parport_uss720_frob_control,
659
660 .read_status = parport_uss720_read_status,
661
662 .enable_irq = parport_uss720_enable_irq,
663 .disable_irq = parport_uss720_disable_irq,
664
665 .data_forward = parport_uss720_data_forward,
666 .data_reverse = parport_uss720_data_reverse,
667
668 .init_state = parport_uss720_init_state,
669 .save_state = parport_uss720_save_state,
670 .restore_state = parport_uss720_restore_state,
671
672 .epp_write_data = parport_uss720_epp_write_data,
673 .epp_read_data = parport_uss720_epp_read_data,
674 .epp_write_addr = parport_uss720_epp_write_addr,
675 .epp_read_addr = parport_uss720_epp_read_addr,
676
677 .ecp_write_data = parport_uss720_ecp_write_data,
678 .ecp_read_data = parport_uss720_ecp_read_data,
679 .ecp_write_addr = parport_uss720_ecp_write_addr,
680
681 .compat_write_data = parport_uss720_write_compat,
682 .nibble_read_data = parport_ieee1284_read_nibble,
683 .byte_read_data = parport_ieee1284_read_byte,
684};
685
686/* --------------------------------------------------------------------- */
687
688static int uss720_probe(struct usb_interface *intf,
689 const struct usb_device_id *id)
690{
0f36163d 691 struct usb_device *usbdev = usb_get_dev(interface_to_usbdev(intf));
1da177e4
LT
692 struct usb_host_interface *interface;
693 struct usb_host_endpoint *endpoint;
694 struct parport_uss720_private *priv;
695 struct parport *pp;
0f36163d 696 unsigned char reg;
1da177e4
LT
697 int i;
698
7a2d2810
GKH
699 dev_dbg(&intf->dev, "probe: vendor id 0x%x, device id 0x%x\n",
700 le16_to_cpu(usbdev->descriptor.idVendor),
701 le16_to_cpu(usbdev->descriptor.idProduct));
1da177e4
LT
702
703 /* our known interfaces have 3 alternate settings */
0f36163d
TS
704 if (intf->num_altsetting != 3) {
705 usb_put_dev(usbdev);
1da177e4 706 return -ENODEV;
0f36163d 707 }
1da177e4 708 i = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2);
cf2fbdd2 709 dev_dbg(&intf->dev, "set interface result %d\n", i);
1da177e4
LT
710
711 interface = intf->cur_altsetting;
712
713 /*
714 * Allocate parport interface
715 */
adde04c6
GKH
716 priv = kzalloc(sizeof(struct parport_uss720_private), GFP_KERNEL);
717 if (!priv) {
0f36163d 718 usb_put_dev(usbdev);
1da177e4 719 return -ENOMEM;
0f36163d
TS
720 }
721 priv->pp = NULL;
722 priv->usbdev = usbdev;
723 kref_init(&priv->ref_count);
724 spin_lock_init(&priv->asynclock);
725 INIT_LIST_HEAD(&priv->asynclist);
adde04c6
GKH
726 pp = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &parport_uss720_ops);
727 if (!pp) {
3b6004f3 728 printk(KERN_WARNING "uss720: could not register parport\n");
1da177e4
LT
729 goto probe_abort;
730 }
731
0f36163d 732 priv->pp = pp;
1da177e4 733 pp->private_data = priv;
1da177e4
LT
734 pp->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP | PARPORT_MODE_ECP | PARPORT_MODE_COMPAT;
735
736 /* set the USS720 control register to manual mode, no ECP compression, enable all ints */
0f36163d
TS
737 set_1284_register(pp, 7, 0x00, GFP_KERNEL);
738 set_1284_register(pp, 6, 0x30, GFP_KERNEL); /* PS/2 mode */
739 set_1284_register(pp, 2, 0x0c, GFP_KERNEL);
1da177e4 740 /* debugging */
0f36163d 741 get_1284_register(pp, 0, &reg, GFP_KERNEL);
5d31a6dc 742 dev_dbg(&intf->dev, "reg: %7ph\n", priv->reg);
1da177e4
LT
743
744 endpoint = &interface->endpoint[2];
7a2d2810
GKH
745 dev_dbg(&intf->dev, "epaddr %d interval %d\n",
746 endpoint->desc.bEndpointAddress, endpoint->desc.bInterval);
1da177e4
LT
747 parport_announce_port(pp);
748
0f36163d 749 usb_set_intfdata(intf, pp);
1da177e4
LT
750 return 0;
751
1da177e4 752probe_abort:
0f36163d
TS
753 kill_all_async_requests_priv(priv);
754 kref_put(&priv->ref_count, destroy_priv);
1da177e4
LT
755 return -ENODEV;
756}
757
758static void uss720_disconnect(struct usb_interface *intf)
759{
0f36163d 760 struct parport *pp = usb_get_intfdata(intf);
1da177e4 761 struct parport_uss720_private *priv;
0f36163d 762 struct usb_device *usbdev;
1da177e4 763
7a2d2810 764 dev_dbg(&intf->dev, "disconnect\n");
0f36163d 765 usb_set_intfdata(intf, NULL);
1da177e4
LT
766 if (pp) {
767 priv = pp->private_data;
0f36163d 768 usbdev = priv->usbdev;
1da177e4 769 priv->usbdev = NULL;
0f36163d 770 priv->pp = NULL;
7a2d2810 771 dev_dbg(&intf->dev, "parport_remove_port\n");
0f36163d 772 parport_remove_port(pp);
1da177e4 773 parport_put_port(pp);
0f36163d
TS
774 kill_all_async_requests_priv(priv);
775 kref_put(&priv->ref_count, destroy_priv);
1da177e4 776 }
7a2d2810 777 dev_dbg(&intf->dev, "disconnect done\n");
1da177e4
LT
778}
779
780/* table of cables that work through this driver */
33b9e162 781static const struct usb_device_id uss720_table[] = {
1da177e4
LT
782 { USB_DEVICE(0x047e, 0x1001) },
783 { USB_DEVICE(0x0557, 0x2001) },
784 { USB_DEVICE(0x0729, 0x1284) },
785 { USB_DEVICE(0x1293, 0x0002) },
ecc1624a 786 { USB_DEVICE(0x050d, 0x0002) },
1da177e4
LT
787 { } /* Terminating entry */
788};
789
790MODULE_DEVICE_TABLE (usb, uss720_table);
791
792
793static struct usb_driver uss720_driver = {
1da177e4
LT
794 .name = "uss720",
795 .probe = uss720_probe,
796 .disconnect = uss720_disconnect,
797 .id_table = uss720_table,
798};
799
800/* --------------------------------------------------------------------- */
801
0f36163d
TS
802MODULE_AUTHOR(DRIVER_AUTHOR);
803MODULE_DESCRIPTION(DRIVER_DESC);
1da177e4
LT
804MODULE_LICENSE("GPL");
805
806static int __init uss720_init(void)
807{
808 int retval;
809 retval = usb_register(&uss720_driver);
810 if (retval)
811 goto out;
812
1b29a375
GKH
813 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
814 DRIVER_DESC "\n");
815 printk(KERN_INFO KBUILD_MODNAME ": NOTE: this is a special purpose "
816 "driver to allow nonstandard\n");
817 printk(KERN_INFO KBUILD_MODNAME ": protocols (eg. bitbang) over "
818 "USS720 usb to parallel cables\n");
819 printk(KERN_INFO KBUILD_MODNAME ": If you just want to connect to a "
820 "printer, use usblp instead\n");
1da177e4
LT
821out:
822 return retval;
823}
824
825static void __exit uss720_cleanup(void)
826{
827 usb_deregister(&uss720_driver);
828}
829
830module_init(uss720_init);
831module_exit(uss720_cleanup);
832
833/* --------------------------------------------------------------------- */