aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/mos7720.c
diff options
context:
space:
mode:
authorMike Dunn <mikedunn@newsguy.com>2010-04-15 17:01:33 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:39 -0400
commitb69578df7e98659b7d94c905971a6d1025b431ad (patch)
treef4cbfff73b9eb064a95a7101d239a83219b4e6d0 /drivers/usb/serial/mos7720.c
parentc220cc3e37f1596260870f99f751102f667384a5 (diff)
USB: usbserial: mos7720: add support for parallel port on moschip 7715
Add support for the parallel port on the moschip MCS7715 device. The port registers itself with the parport subsystem as a low-level driver. A separate entry to the kernel configuration is added beneath that for the mos7720, to avoid the need to link with the parport subsystem code for users who don't have or don't want the parallel port. Only compatibility mode is currently supported (no ECP/EPP). Tested with both moschip devices (7720 and 7715) on UP and SMP hosts, including regression testing of serial port, concurrent operation of serial and parallel ports, and various connect / disconnect scenarios. Signed-off-by: Mike Dunn <mikedunn@newsguy.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/mos7720.c')
-rw-r--r--drivers/usb/serial/mos7720.c806
1 files changed, 720 insertions, 86 deletions
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 0d47f2c4d59f..2d35d11d04e3 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -34,12 +34,12 @@
34#include <linux/usb.h> 34#include <linux/usb.h>
35#include <linux/usb/serial.h> 35#include <linux/usb/serial.h>
36#include <linux/uaccess.h> 36#include <linux/uaccess.h>
37 37#include <linux/parport.h>
38 38
39/* 39/*
40 * Version Information 40 * Version Information
41 */ 41 */
42#define DRIVER_VERSION "1.0.0.4F" 42#define DRIVER_VERSION "2.0"
43#define DRIVER_AUTHOR "Aspire Communications pvt Ltd." 43#define DRIVER_AUTHOR "Aspire Communications pvt Ltd."
44#define DRIVER_DESC "Moschip USB Serial Driver" 44#define DRIVER_DESC "Moschip USB Serial Driver"
45 45
@@ -63,7 +63,7 @@
63#define NUM_URBS 16 /* URB Count */ 63#define NUM_URBS 16 /* URB Count */
64#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ 64#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */
65 65
66/* This structure holds all of the local port information */ 66/* This structure holds all of the local serial port information */
67struct moschip_port { 67struct moschip_port {
68 __u8 shadowLCR; /* last LCR value received */ 68 __u8 shadowLCR; /* last LCR value received */
69 __u8 shadowMCR; /* last MCR value received */ 69 __u8 shadowMCR; /* last MCR value received */
@@ -74,11 +74,6 @@ struct moschip_port {
74 struct urb *write_urb_pool[NUM_URBS]; 74 struct urb *write_urb_pool[NUM_URBS];
75}; 75};
76 76
77/* This structure holds all of the individual serial device information */
78struct moschip_serial {
79 int interrupt_started;
80};
81
82static int debug; 77static int debug;
83 78
84static struct usb_serial_driver moschip7720_2port_driver; 79static struct usb_serial_driver moschip7720_2port_driver;
@@ -94,6 +89,649 @@ static const struct usb_device_id moschip_port_id_table[] = {
94}; 89};
95MODULE_DEVICE_TABLE(usb, moschip_port_id_table); 90MODULE_DEVICE_TABLE(usb, moschip_port_id_table);
96 91
92#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
93
94/* initial values for parport regs */
95#define DCR_INIT_VAL 0x0c /* SLCTIN, nINIT */
96#define ECR_INIT_VAL 0x00 /* SPP mode */
97
98struct urbtracker {
99 struct mos7715_parport *mos_parport;
100 struct list_head urblist_entry;
101 struct kref ref_count;
102 struct urb *urb;
103};
104
105enum mos7715_pp_modes {
106 SPP = 0<<5,
107 PS2 = 1<<5, /* moschip calls this 'NIBBLE' mode */
108 PPF = 2<<5, /* moschip calls this 'CB-FIFO mode */
109};
110
111struct mos7715_parport {
112 struct parport *pp; /* back to containing struct */
113 struct kref ref_count; /* to instance of this struct */
114 struct list_head deferred_urbs; /* list deferred async urbs */
115 struct list_head active_urbs; /* list async urbs in flight */
116 spinlock_t listlock; /* protects list access */
117 bool msg_pending; /* usb sync call pending */
118 struct completion syncmsg_compl; /* usb sync call completed */
119 struct tasklet_struct urb_tasklet; /* for sending deferred urbs */
120 struct usb_serial *serial; /* back to containing struct */
121 __u8 shadowECR; /* parallel port regs... */
122 __u8 shadowDCR;
123 atomic_t shadowDSR; /* updated in int-in callback */
124};
125
126/* lock guards against dereferencing NULL ptr in parport ops callbacks */
127static DEFINE_SPINLOCK(release_lock);
128
129enum mos_regs {
130 THR, /* serial port regs */
131 RHR,
132 IER,
133 FCR,
134 ISR,
135 LCR,
136 MCR,
137 LSR,
138 MSR,
139 SPR,
140 DLL,
141 DLM,
142 DPR, /* parallel port regs */
143 DSR,
144 DCR,
145 ECR,
146 SP1_REG, /* device control regs */
147 SP2_REG, /* serial port 2 (7720 only) */
148 PP_REG,
149 SP_CONTROL_REG,
150};
151
152/*
153 * Return the correct value for the Windex field of the setup packet
154 * for a control endpoint message. See the 7715 datasheet.
155 */
156static inline __u16 get_reg_index(enum mos_regs reg)
157{
158 static const __u16 mos7715_index_lookup_table[] = {
159 0x00, /* THR */
160 0x00, /* RHR */
161 0x01, /* IER */
162 0x02, /* FCR */
163 0x02, /* ISR */
164 0x03, /* LCR */
165 0x04, /* MCR */
166 0x05, /* LSR */
167 0x06, /* MSR */
168 0x07, /* SPR */
169 0x00, /* DLL */
170 0x01, /* DLM */
171 0x00, /* DPR */
172 0x01, /* DSR */
173 0x02, /* DCR */
174 0x0a, /* ECR */
175 0x01, /* SP1_REG */
176 0x02, /* SP2_REG (7720 only) */
177 0x04, /* PP_REG (7715 only) */
178 0x08, /* SP_CONTROL_REG */
179 };
180 return mos7715_index_lookup_table[reg];
181}
182
183/*
184 * Return the correct value for the upper byte of the Wvalue field of
185 * the setup packet for a control endpoint message.
186 */
187static inline __u16 get_reg_value(enum mos_regs reg)
188{
189 if (reg >= SP1_REG) /* control reg */
190 return 0x0000;
191 else /* parallel port reg (7715 only) */
192 return 0x0100;
193}
194
195/*
196 * Write data byte to the specified device register. The data is embedded in
197 * the value field of the setup packet.
198 */
199static int write_parport_reg(struct mos7715_parport *mos_parport,
200 enum mos_regs reg, __u8 data)
201{
202 struct usb_serial *serial = mos_parport->serial;
203 struct usb_device *usbdev = serial->dev;
204 unsigned int pipe = usb_sndctrlpipe(usbdev, 0);
205 __u8 request = (__u8)0x0e;
206 __u8 requesttype = (__u8)0x40;
207 __u16 value = get_reg_value(reg) + data;
208 __u16 index = get_reg_index(reg);
209 __u16 size = 0;
210 int status;
211 status = usb_control_msg(usbdev, pipe, request, requesttype, value,
212 index, NULL, size, MOS_WDR_TIMEOUT);
213 if (status < 0)
214 dev_err(&usbdev->dev,
215 "mos7720: usb_control_msg() failed: %d", status);
216 return status;
217}
218
219/*
220 * Read data byte from the specified device register. The data returned by the
221 * device is embedded in the value field of the setup packet.
222 */
223static int read_parport_reg(struct mos7715_parport *mos_parport,
224 enum mos_regs reg, __u8 *data)
225{
226 struct usb_device *usbdev = mos_parport->serial->dev;
227 unsigned int pipe = usb_rcvctrlpipe(usbdev, 0);
228 __u8 request = (__u8)0x0d;
229 __u8 requesttype = (__u8)0xc0;
230 __u16 value = get_reg_value(reg);
231 __u16 index = get_reg_index(reg);
232 __u16 size = 1;
233 int status = usb_control_msg(usbdev, pipe, request, requesttype, value,
234 index, data, size, MOS_WDR_TIMEOUT);
235 if (status < 0)
236 dev_err(&usbdev->dev,
237 "mos7720: usb_control_msg() failed: %d", status);
238 return status;
239}
240
241static inline int mos7715_change_mode(struct mos7715_parport *mos_parport,
242 enum mos7715_pp_modes mode)
243{
244 mos_parport->shadowECR = mode;
245 write_parport_reg(mos_parport, ECR, mos_parport->shadowECR);
246 return 0;
247}
248
249static void destroy_mos_parport(struct kref *kref)
250{
251 struct mos7715_parport *mos_parport =
252 container_of(kref, struct mos7715_parport, ref_count);
253
254 dbg("%s called", __func__);
255 kfree(mos_parport);
256}
257
258static void destroy_urbtracker(struct kref *kref)
259{
260 struct urbtracker *urbtrack =
261 container_of(kref, struct urbtracker, ref_count);
262 struct mos7715_parport *mos_parport = urbtrack->mos_parport;
263 dbg("%s called", __func__);
264 usb_free_urb(urbtrack->urb);
265 kfree(urbtrack);
266 kref_put(&mos_parport->ref_count, destroy_mos_parport);
267}
268
269/*
270 * This runs as a tasklet when sending an urb in a non-blocking parallel
271 * port callback had to be deferred because the disconnect mutex could not be
272 * obtained at the time.
273 */
274static void send_deferred_urbs(unsigned long _mos_parport)
275{
276 int ret_val;
277 unsigned long flags;
278 struct mos7715_parport *mos_parport = (void *)_mos_parport;
279 struct urbtracker *urbtrack;
280 struct list_head *cursor, *next;
281
282 dbg("%s called", __func__);
283
284 /* if release function ran, game over */
285 if (unlikely(mos_parport->serial == NULL))
286 return;
287
288 /* try again to get the mutex */
289 if (!mutex_trylock(&mos_parport->serial->disc_mutex)) {
290 dbg("%s: rescheduling tasklet", __func__);
291 tasklet_schedule(&mos_parport->urb_tasklet);
292 return;
293 }
294
295 /* if device disconnected, game over */
296 if (unlikely(mos_parport->serial->disconnected)) {
297 mutex_unlock(&mos_parport->serial->disc_mutex);
298 return;
299 }
300
301 spin_lock_irqsave(&mos_parport->listlock, flags);
302 if (list_empty(&mos_parport->deferred_urbs)) {
303 spin_unlock_irqrestore(&mos_parport->listlock, flags);
304 mutex_unlock(&mos_parport->serial->disc_mutex);
305 dbg("%s: deferred_urbs list empty", __func__);
306 return;
307 }
308
309 /* move contents of deferred_urbs list to active_urbs list and submit */
310 list_for_each_safe(cursor, next, &mos_parport->deferred_urbs)
311 list_move_tail(cursor, &mos_parport->active_urbs);
312 list_for_each_entry(urbtrack, &mos_parport->active_urbs,
313 urblist_entry) {
314 ret_val = usb_submit_urb(urbtrack->urb, GFP_ATOMIC);
315 dbg("%s: urb submitted", __func__);
316 if (ret_val) {
317 dev_err(&mos_parport->serial->dev->dev,
318 "usb_submit_urb() failed: %d", ret_val);
319 list_del(&urbtrack->urblist_entry);
320 kref_put(&urbtrack->ref_count, destroy_urbtracker);
321 }
322 }
323 spin_unlock_irqrestore(&mos_parport->listlock, flags);
324 mutex_unlock(&mos_parport->serial->disc_mutex);
325}
326
327/* callback for parallel port control urbs submitted asynchronously */
328static void async_complete(struct urb *urb)
329{
330 struct urbtracker *urbtrack = urb->context;
331 int status = urb->status;
332 dbg("%s called", __func__);
333 if (unlikely(status))
334 dbg("%s - nonzero urb status received: %d", __func__, status);
335
336 /* remove the urbtracker from the active_urbs list */
337 spin_lock(&urbtrack->mos_parport->listlock);
338 list_del(&urbtrack->urblist_entry);
339 spin_unlock(&urbtrack->mos_parport->listlock);
340 kref_put(&urbtrack->ref_count, destroy_urbtracker);
341}
342
343static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
344 enum mos_regs reg, __u8 data)
345{
346 struct urbtracker *urbtrack;
347 int ret_val;
348 unsigned long flags;
349 struct usb_ctrlrequest setup;
350 struct usb_serial *serial = mos_parport->serial;
351 struct usb_device *usbdev = serial->dev;
352 dbg("%s called", __func__);
353
354 /* create and initialize the control urb and containing urbtracker */
355 urbtrack = kmalloc(sizeof(struct urbtracker), GFP_ATOMIC);
356 if (urbtrack == NULL) {
357 dev_err(&usbdev->dev, "out of memory");
358 return -ENOMEM;
359 }
360 kref_get(&mos_parport->ref_count);
361 urbtrack->mos_parport = mos_parport;
362 urbtrack->urb = usb_alloc_urb(0, GFP_ATOMIC);
363 if (urbtrack->urb == NULL) {
364 dev_err(&usbdev->dev, "out of urbs");
365 kfree(urbtrack);
366 return -ENOMEM;
367 }
368 setup.bRequestType = (__u8)0x40;
369 setup.bRequest = (__u8)0x0e;
370 setup.wValue = get_reg_value(reg);
371 setup.wIndex = get_reg_index(reg);
372 setup.wLength = 0;
373 usb_fill_control_urb(urbtrack->urb, usbdev,
374 usb_sndctrlpipe(usbdev, 0),
375 (unsigned char *)&setup,
376 NULL, 0, async_complete, urbtrack);
377 kref_init(&urbtrack->ref_count);
378 INIT_LIST_HEAD(&urbtrack->urblist_entry);
379
380 /*
381 * get the disconnect mutex, or add tracker to the deferred_urbs list
382 * and schedule a tasklet to try again later
383 */
384 if (!mutex_trylock(&serial->disc_mutex)) {
385 spin_lock_irqsave(&mos_parport->listlock, flags);
386 list_add_tail(&urbtrack->urblist_entry,
387 &mos_parport->deferred_urbs);
388 spin_unlock_irqrestore(&mos_parport->listlock, flags);
389 tasklet_schedule(&mos_parport->urb_tasklet);
390 dbg("tasklet scheduled");
391 return 0;
392 }
393
394 /* bail if device disconnected */
395 if (serial->disconnected) {
396 kref_put(&urbtrack->ref_count, destroy_urbtracker);
397 mutex_unlock(&serial->disc_mutex);
398 return -ENODEV;
399 }
400
401 /* add the tracker to the active_urbs list and submit */
402 spin_lock_irqsave(&mos_parport->listlock, flags);
403 list_add_tail(&urbtrack->urblist_entry, &mos_parport->active_urbs);
404 spin_unlock_irqrestore(&mos_parport->listlock, flags);
405 ret_val = usb_submit_urb(urbtrack->urb, GFP_ATOMIC);
406 mutex_unlock(&serial->disc_mutex);
407 if (ret_val) {
408 dev_err(&usbdev->dev,
409 "%s: submit_urb() failed: %d", __func__, ret_val);
410 spin_lock_irqsave(&mos_parport->listlock, flags);
411 list_del(&urbtrack->urblist_entry);
412 spin_unlock_irqrestore(&mos_parport->listlock, flags);
413 kref_put(&urbtrack->ref_count, destroy_urbtracker);
414 return ret_val;
415 }
416 return 0;
417}
418
419/*
420 * This is the the common top part of all parallel port callback operations that
421 * send synchronous messages to the device. This implements convoluted locking
422 * that avoids two scenarios: (1) a port operation is called after usbserial
423 * has called our release function, at which point struct mos7715_parport has
424 * been destroyed, and (2) the device has been disconnected, but usbserial has
425 * not called the release function yet because someone has a serial port open.
426 * The shared release_lock prevents the first, and the mutex and disconnected
427 * flag maintained by usbserial covers the second. We also use the msg_pending
428 * flag to ensure that all synchronous usb messgage calls have completed before
429 * our release function can return.
430 */
431static int parport_prologue(struct parport *pp)
432{
433 struct mos7715_parport *mos_parport;
434
435 spin_lock(&release_lock);
436 mos_parport = pp->private_data;
437 if (unlikely(mos_parport == NULL)) {
438 /* release fn called, port struct destroyed */
439 spin_unlock(&release_lock);
440 return -1;
441 }
442 mos_parport->msg_pending = true; /* synch usb call pending */
443 INIT_COMPLETION(mos_parport->syncmsg_compl);
444 spin_unlock(&release_lock);
445
446 mutex_lock(&mos_parport->serial->disc_mutex);
447 if (mos_parport->serial->disconnected) {
448 /* device disconnected */
449 mutex_unlock(&mos_parport->serial->disc_mutex);
450 mos_parport->msg_pending = false;
451 complete(&mos_parport->syncmsg_compl);
452 return -1;
453 }
454
455 return 0;
456}
457
458/*
459 * This is the the common bottom part of all parallel port functions that send
460 * synchronous messages to the device.
461 */
462static inline void parport_epilogue(struct parport *pp)
463{
464 struct mos7715_parport *mos_parport = pp->private_data;
465 mutex_unlock(&mos_parport->serial->disc_mutex);
466 mos_parport->msg_pending = false;
467 complete(&mos_parport->syncmsg_compl);
468}
469
470static void parport_mos7715_write_data(struct parport *pp, unsigned char d)
471{
472 struct mos7715_parport *mos_parport = pp->private_data;
473 dbg("%s called: %2.2x", __func__, d);
474 if (parport_prologue(pp) < 0)
475 return;
476 mos7715_change_mode(mos_parport, SPP);
477 write_parport_reg(mos_parport, DPR, (__u8)d);
478 parport_epilogue(pp);
479}
480
481static unsigned char parport_mos7715_read_data(struct parport *pp)
482{
483 struct mos7715_parport *mos_parport = pp->private_data;
484 unsigned char d;
485 dbg("%s called", __func__);
486 if (parport_prologue(pp) < 0)
487 return 0;
488 read_parport_reg(mos_parport, DPR, &d);
489 parport_epilogue(pp);
490 return d;
491}
492
493static void parport_mos7715_write_control(struct parport *pp, unsigned char d)
494{
495 struct mos7715_parport *mos_parport = pp->private_data;
496 __u8 data;
497 dbg("%s called: %2.2x", __func__, d);
498 if (parport_prologue(pp) < 0)
499 return;
500 data = ((__u8)d & 0x0f) | (mos_parport->shadowDCR & 0xf0);
501 write_parport_reg(mos_parport, DCR, data);
502 mos_parport->shadowDCR = data;
503 parport_epilogue(pp);
504}
505
506static unsigned char parport_mos7715_read_control(struct parport *pp)
507{
508 struct mos7715_parport *mos_parport = pp->private_data;
509 __u8 dcr;
510 dbg("%s called", __func__);
511 spin_lock(&release_lock);
512 mos_parport = pp->private_data;
513 if (unlikely(mos_parport == NULL)) {
514 spin_unlock(&release_lock);
515 return 0;
516 }
517 dcr = mos_parport->shadowDCR & 0x0f;
518 spin_unlock(&release_lock);
519 return dcr;
520}
521
522static unsigned char parport_mos7715_frob_control(struct parport *pp,
523 unsigned char mask,
524 unsigned char val)
525{
526 struct mos7715_parport *mos_parport = pp->private_data;
527 __u8 dcr;
528 dbg("%s called", __func__);
529 mask &= 0x0f;
530 val &= 0x0f;
531 if (parport_prologue(pp) < 0)
532 return 0;
533 mos_parport->shadowDCR = (mos_parport->shadowDCR & (~mask)) ^ val;
534 write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
535 dcr = mos_parport->shadowDCR & 0x0f;
536 parport_epilogue(pp);
537 return dcr;
538}
539
540static unsigned char parport_mos7715_read_status(struct parport *pp)
541{
542 unsigned char status;
543 struct mos7715_parport *mos_parport = pp->private_data;
544 dbg("%s called", __func__);
545 spin_lock(&release_lock);
546 mos_parport = pp->private_data;
547 if (unlikely(mos_parport == NULL)) { /* release called */
548 spin_unlock(&release_lock);
549 return 0;
550 }
551 status = atomic_read(&mos_parport->shadowDSR) & 0xf8;
552 spin_unlock(&release_lock);
553 return status;
554}
555
556static void parport_mos7715_enable_irq(struct parport *pp)
557{
558 dbg("%s called", __func__);
559}
560static void parport_mos7715_disable_irq(struct parport *pp)
561{
562 dbg("%s called", __func__);
563}
564
565static void parport_mos7715_data_forward(struct parport *pp)
566{
567 struct mos7715_parport *mos_parport = pp->private_data;
568 dbg("%s called", __func__);
569 if (parport_prologue(pp) < 0)
570 return;
571 mos7715_change_mode(mos_parport, PS2);
572 mos_parport->shadowDCR &= ~0x20;
573 write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
574 parport_epilogue(pp);
575}
576
577static void parport_mos7715_data_reverse(struct parport *pp)
578{
579 struct mos7715_parport *mos_parport = pp->private_data;
580 dbg("%s called", __func__);
581 if (parport_prologue(pp) < 0)
582 return;
583 mos7715_change_mode(mos_parport, PS2);
584 mos_parport->shadowDCR |= 0x20;
585 write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
586 parport_epilogue(pp);
587}
588
589static void parport_mos7715_init_state(struct pardevice *dev,
590 struct parport_state *s)
591{
592 dbg("%s called", __func__);
593 s->u.pc.ctr = DCR_INIT_VAL;
594 s->u.pc.ecr = ECR_INIT_VAL;
595}
596
597/* N.B. Parport core code requires that this function not block */
598static void parport_mos7715_save_state(struct parport *pp,
599 struct parport_state *s)
600{
601 struct mos7715_parport *mos_parport;
602 dbg("%s called", __func__);
603 spin_lock(&release_lock);
604 mos_parport = pp->private_data;
605 if (unlikely(mos_parport == NULL)) { /* release called */
606 spin_unlock(&release_lock);
607 return;
608 }
609 s->u.pc.ctr = mos_parport->shadowDCR;
610 s->u.pc.ecr = mos_parport->shadowECR;
611 spin_unlock(&release_lock);
612}
613
614/* N.B. Parport core code requires that this function not block */
615static void parport_mos7715_restore_state(struct parport *pp,
616 struct parport_state *s)
617{
618 struct mos7715_parport *mos_parport;
619 dbg("%s called", __func__);
620 spin_lock(&release_lock);
621 mos_parport = pp->private_data;
622 if (unlikely(mos_parport == NULL)) { /* release called */
623 spin_unlock(&release_lock);
624 return;
625 }
626 write_parport_reg_nonblock(mos_parport, DCR, mos_parport->shadowDCR);
627 write_parport_reg_nonblock(mos_parport, ECR, mos_parport->shadowECR);
628 spin_unlock(&release_lock);
629}
630
631static size_t parport_mos7715_write_compat(struct parport *pp,
632 const void *buffer,
633 size_t len, int flags)
634{
635 int retval;
636 struct mos7715_parport *mos_parport = pp->private_data;
637 int actual_len;
638 dbg("%s called: %u chars", __func__, (unsigned int)len);
639 if (parport_prologue(pp) < 0)
640 return 0;
641 mos7715_change_mode(mos_parport, PPF);
642 retval = usb_bulk_msg(mos_parport->serial->dev,
643 usb_sndbulkpipe(mos_parport->serial->dev, 2),
644 (void *)buffer, len, &actual_len,
645 MOS_WDR_TIMEOUT);
646 parport_epilogue(pp);
647 if (retval) {
648 dev_err(&mos_parport->serial->dev->dev,
649 "mos7720: usb_bulk_msg() failed: %d", retval);
650 return 0;
651 }
652 return actual_len;
653}
654
655static struct parport_operations parport_mos7715_ops = {
656 .owner = THIS_MODULE,
657 .write_data = parport_mos7715_write_data,
658 .read_data = parport_mos7715_read_data,
659
660 .write_control = parport_mos7715_write_control,
661 .read_control = parport_mos7715_read_control,
662 .frob_control = parport_mos7715_frob_control,
663
664 .read_status = parport_mos7715_read_status,
665
666 .enable_irq = parport_mos7715_enable_irq,
667 .disable_irq = parport_mos7715_disable_irq,
668
669 .data_forward = parport_mos7715_data_forward,
670 .data_reverse = parport_mos7715_data_reverse,
671
672 .init_state = parport_mos7715_init_state,
673 .save_state = parport_mos7715_save_state,
674 .restore_state = parport_mos7715_restore_state,
675
676 .compat_write_data = parport_mos7715_write_compat,
677
678 .nibble_read_data = parport_ieee1284_read_nibble,
679 .byte_read_data = parport_ieee1284_read_byte,
680};
681
682/*
683 * Allocate and initialize parallel port control struct, initialize
684 * the parallel port hardware device, and register with the parport subsystem.
685 */
686static int mos7715_parport_init(struct usb_serial *serial)
687{
688 struct mos7715_parport *mos_parport;
689
690 /* allocate and initialize parallel port control struct */
691 mos_parport = kzalloc(sizeof(struct mos7715_parport), GFP_KERNEL);
692 if (mos_parport == NULL) {
693 dbg("mos7715_parport_init: kzalloc failed");
694 return -ENOMEM;
695 }
696 mos_parport->msg_pending = false;
697 kref_init(&mos_parport->ref_count);
698 spin_lock_init(&mos_parport->listlock);
699 INIT_LIST_HEAD(&mos_parport->active_urbs);
700 INIT_LIST_HEAD(&mos_parport->deferred_urbs);
701 usb_set_serial_data(serial, mos_parport); /* hijack private pointer */
702 mos_parport->serial = serial;
703 tasklet_init(&mos_parport->urb_tasklet, send_deferred_urbs,
704 (unsigned long) mos_parport);
705 init_completion(&mos_parport->syncmsg_compl);
706
707 /* cycle parallel port reset bit */
708 write_parport_reg(mos_parport, PP_REG, (__u8)0x80);
709 write_parport_reg(mos_parport, PP_REG, (__u8)0x00);
710
711 /* initialize device registers */
712 mos_parport->shadowDCR = DCR_INIT_VAL;
713 write_parport_reg(mos_parport, DCR, mos_parport->shadowDCR);
714 mos_parport->shadowECR = ECR_INIT_VAL;
715 write_parport_reg(mos_parport, ECR, mos_parport->shadowECR);
716
717 /* register with parport core */
718 mos_parport->pp = parport_register_port(0, PARPORT_IRQ_NONE,
719 PARPORT_DMA_NONE,
720 &parport_mos7715_ops);
721 if (mos_parport->pp == NULL) {
722 dev_err(&serial->interface->dev,
723 "Could not register parport\n");
724 kref_put(&mos_parport->ref_count, destroy_mos_parport);
725 return -EIO;
726 }
727 mos_parport->pp->private_data = mos_parport;
728 mos_parport->pp->modes = PARPORT_MODE_COMPAT | PARPORT_MODE_PCSPP;
729 mos_parport->pp->dev = &serial->interface->dev;
730 parport_announce_port(mos_parport->pp);
731
732 return 0;
733}
734#endif /* CONFIG_USB_SERIAL_MOS7715_PARPORT */
97 735
98/* 736/*
99 * mos7720_interrupt_callback 737 * mos7720_interrupt_callback
@@ -109,8 +747,6 @@ static void mos7720_interrupt_callback(struct urb *urb)
109 __u8 sp1; 747 __u8 sp1;
110 __u8 sp2; 748 __u8 sp2;
111 749
112 dbg(" : Entering");
113
114 switch (status) { 750 switch (status) {
115 case 0: 751 case 0:
116 /* success */ 752 /* success */
@@ -118,6 +754,7 @@ static void mos7720_interrupt_callback(struct urb *urb)
118 case -ECONNRESET: 754 case -ECONNRESET:
119 case -ENOENT: 755 case -ENOENT:
120 case -ESHUTDOWN: 756 case -ESHUTDOWN:
757 case -ENODEV:
121 /* this urb is terminated, clean up */ 758 /* this urb is terminated, clean up */
122 dbg("%s - urb shutting down with status: %d", __func__, 759 dbg("%s - urb shutting down with status: %d", __func__,
123 status); 760 status);
@@ -161,7 +798,7 @@ static void mos7720_interrupt_callback(struct urb *urb)
161 dbg("Serial Port 1: Receiver time out"); 798 dbg("Serial Port 1: Receiver time out");
162 break; 799 break;
163 case SERIAL_IIR_MS: 800 case SERIAL_IIR_MS:
164 dbg("Serial Port 1: Modem status change"); 801 /* dbg("Serial Port 1: Modem status change"); */
165 break; 802 break;
166 } 803 }
167 804
@@ -174,7 +811,7 @@ static void mos7720_interrupt_callback(struct urb *urb)
174 dbg("Serial Port 2: Receiver time out"); 811 dbg("Serial Port 2: Receiver time out");
175 break; 812 break;
176 case SERIAL_IIR_MS: 813 case SERIAL_IIR_MS:
177 dbg("Serial Port 2: Modem status change"); 814 /* dbg("Serial Port 2: Modem status change"); */
178 break; 815 break;
179 } 816 }
180 } 817 }
@@ -208,6 +845,7 @@ static void mos7715_interrupt_callback(struct urb *urb)
208 case -ECONNRESET: 845 case -ECONNRESET:
209 case -ENOENT: 846 case -ENOENT:
210 case -ESHUTDOWN: 847 case -ESHUTDOWN:
848 case -ENODEV:
211 /* this urb is terminated, clean up */ 849 /* this urb is terminated, clean up */
212 dbg("%s - urb shutting down with status: %d", __func__, 850 dbg("%s - urb shutting down with status: %d", __func__,
213 status); 851 status);
@@ -243,11 +881,21 @@ static void mos7715_interrupt_callback(struct urb *urb)
243 dbg("Serial Port: Receiver time out"); 881 dbg("Serial Port: Receiver time out");
244 break; 882 break;
245 case SERIAL_IIR_MS: 883 case SERIAL_IIR_MS:
246 dbg("Serial Port: Modem status change"); 884 /* dbg("Serial Port: Modem status change"); */
247 break; 885 break;
248 } 886 }
249 } 887 }
250 888
889#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
890 { /* update local copy of DSR reg */
891 struct usb_serial_port *port = urb->context;
892 struct mos7715_parport *mos_parport = port->serial->private;
893 if (unlikely(mos_parport == NULL))
894 return;
895 atomic_set(&mos_parport->shadowDSR, data[2]);
896 }
897#endif
898
251exit: 899exit:
252 result = usb_submit_urb(urb, GFP_ATOMIC); 900 result = usb_submit_urb(urb, GFP_ATOMIC);
253 if (result) 901 if (result)
@@ -267,7 +915,6 @@ static void mos7720_bulk_in_callback(struct urb *urb)
267 int retval; 915 int retval;
268 unsigned char *data ; 916 unsigned char *data ;
269 struct usb_serial_port *port; 917 struct usb_serial_port *port;
270 struct moschip_port *mos7720_port;
271 struct tty_struct *tty; 918 struct tty_struct *tty;
272 int status = urb->status; 919 int status = urb->status;
273 920
@@ -276,13 +923,7 @@ static void mos7720_bulk_in_callback(struct urb *urb)
276 return; 923 return;
277 } 924 }
278 925
279 mos7720_port = urb->context; 926 port = urb->context;
280 if (!mos7720_port) {
281 dbg("NULL mos7720_port pointer");
282 return ;
283 }
284
285 port = mos7720_port->port;
286 927
287 dbg("Entering...%s", __func__); 928 dbg("Entering...%s", __func__);
288 929
@@ -332,8 +973,6 @@ static void mos7720_bulk_out_data_callback(struct urb *urb)
332 return ; 973 return ;
333 } 974 }
334 975
335 dbg("Entering .........");
336
337 tty = tty_port_tty_get(&mos7720_port->port->port); 976 tty = tty_port_tty_get(&mos7720_port->port->port);
338 977
339 if (tty && mos7720_port->open) 978 if (tty && mos7720_port->open)
@@ -424,7 +1063,6 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port)
424 struct usb_serial *serial; 1063 struct usb_serial *serial;
425 struct usb_serial_port *port0; 1064 struct usb_serial_port *port0;
426 struct urb *urb; 1065 struct urb *urb;
427 struct moschip_serial *mos7720_serial;
428 struct moschip_port *mos7720_port; 1066 struct moschip_port *mos7720_port;
429 int response; 1067 int response;
430 int port_number; 1068 int port_number;
@@ -440,11 +1078,6 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port)
440 1078
441 port0 = serial->port[0]; 1079 port0 = serial->port[0];
442 1080
443 mos7720_serial = usb_get_serial_data(serial);
444
445 if (mos7720_serial == NULL || port0 == NULL)
446 return -ENODEV;
447
448 usb_clear_halt(serial->dev, port->write_urb->pipe); 1081 usb_clear_halt(serial->dev, port->write_urb->pipe);
449 usb_clear_halt(serial->dev, port->read_urb->pipe); 1082 usb_clear_halt(serial->dev, port->read_urb->pipe);
450 1083
@@ -549,43 +1182,6 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port)
549 data = 0x0c; 1182 data = 0x0c;
550 send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); 1183 send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
551 1184
552 /* see if we've set up our endpoint info yet *
553 * (can't set it up in mos7720_startup as the *
554 * structures were not set up at that time.) */
555 if (!mos7720_serial->interrupt_started) {
556 dbg("Interrupt buffer NULL !!!");
557
558 /* not set up yet, so do it now */
559 mos7720_serial->interrupt_started = 1;
560
561 dbg("To Submit URB !!!");
562
563 /* set up our interrupt urb */
564 usb_fill_int_urb(port0->interrupt_in_urb, serial->dev,
565 usb_rcvintpipe(serial->dev,
566 port->interrupt_in_endpointAddress),
567 port0->interrupt_in_buffer,
568 port0->interrupt_in_urb->transfer_buffer_length,
569 mos7720_interrupt_callback, mos7720_port,
570 port0->interrupt_in_urb->interval);
571
572 /* start interrupt read for this mos7720 this interrupt *
573 * will continue as long as the mos7720 is connected */
574 dbg("Submit URB over !!!");
575 response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL);
576 if (response)
577 dev_err(&port->dev,
578 "%s - Error %d submitting control urb\n",
579 __func__, response);
580 }
581
582 /* set up our bulk in urb */
583 usb_fill_bulk_urb(port->read_urb, serial->dev,
584 usb_rcvbulkpipe(serial->dev,
585 port->bulk_in_endpointAddress),
586 port->bulk_in_buffer,
587 port->read_urb->transfer_buffer_length,
588 mos7720_bulk_in_callback, mos7720_port);
589 response = usb_submit_urb(port->read_urb, GFP_KERNEL); 1185 response = usb_submit_urb(port->read_urb, GFP_KERNEL);
590 if (response) 1186 if (response)
591 dev_err(&port->dev, "%s - Error %d submitting read urb\n", 1187 dev_err(&port->dev, "%s - Error %d submitting read urb\n",
@@ -897,6 +1493,7 @@ static void mos7720_unthrottle(struct tty_struct *tty)
897 } 1493 }
898} 1494}
899 1495
1496/* FIXME: this function does not work */
900static int set_higher_rates(struct moschip_port *mos7720_port, 1497static int set_higher_rates(struct moschip_port *mos7720_port,
901 unsigned int baud) 1498 unsigned int baud)
902{ 1499{
@@ -939,6 +1536,7 @@ static int set_higher_rates(struct moschip_port *mos7720_port,
939 * Set for higher rates * 1536 * Set for higher rates *
940 ***********************************************/ 1537 ***********************************************/
941 1538
1539 /* writing baud rate verbatum into uart clock field clearly not right */
942 data = baud * 0x10; 1540 data = baud * 0x10;
943 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data); 1541 send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
944 1542
@@ -1308,7 +1906,7 @@ static void mos7720_set_termios(struct tty_struct *tty,
1308 return; 1906 return;
1309 } 1907 }
1310 1908
1311 dbg("setting termios - ASPIRE"); 1909 dbg("%s\n", "setting termios - ASPIRE");
1312 1910
1313 cflag = tty->termios->c_cflag; 1911 cflag = tty->termios->c_cflag;
1314 1912
@@ -1326,7 +1924,7 @@ static void mos7720_set_termios(struct tty_struct *tty,
1326 change_port_settings(tty, mos7720_port, old_termios); 1924 change_port_settings(tty, mos7720_port, old_termios);
1327 1925
1328 if (!port->read_urb) { 1926 if (!port->read_urb) {
1329 dbg("URB KILLED !!!!!"); 1927 dbg("%s", "URB KILLED !!!!!");
1330 return; 1928 return;
1331 } 1929 }
1332 1930
@@ -1590,12 +2188,12 @@ static int mos7720_ioctl(struct tty_struct *tty, struct file *file,
1590 2188
1591static int mos7720_startup(struct usb_serial *serial) 2189static int mos7720_startup(struct usb_serial *serial)
1592{ 2190{
1593 struct moschip_serial *mos7720_serial;
1594 struct moschip_port *mos7720_port; 2191 struct moschip_port *mos7720_port;
1595 struct usb_device *dev; 2192 struct usb_device *dev;
1596 int i; 2193 int i;
1597 char data; 2194 char data;
1598 u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); 2195 u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
2196 int ret_val;
1599 2197
1600 dbg("%s: Entering ..........", __func__); 2198 dbg("%s: Entering ..........", __func__);
1601 2199
@@ -1606,15 +2204,6 @@ static int mos7720_startup(struct usb_serial *serial)
1606 2204
1607 dev = serial->dev; 2205 dev = serial->dev;
1608 2206
1609 /* create our private serial structure */
1610 mos7720_serial = kzalloc(sizeof(struct moschip_serial), GFP_KERNEL);
1611 if (mos7720_serial == NULL) {
1612 dev_err(&dev->dev, "%s - Out of memory\n", __func__);
1613 return -ENOMEM;
1614 }
1615
1616 usb_set_serial_data(serial, mos7720_serial);
1617
1618 /* 2207 /*
1619 * The 7715 uses the first bulk in/out endpoint pair for the parallel 2208 * The 7715 uses the first bulk in/out endpoint pair for the parallel
1620 * port, and the second for the serial port. Because the usbserial core 2209 * port, and the second for the serial port. Because the usbserial core
@@ -1638,16 +2227,12 @@ static int mos7720_startup(struct usb_serial *serial)
1638 serial->port[1]->interrupt_in_buffer = NULL; 2227 serial->port[1]->interrupt_in_buffer = NULL;
1639 } 2228 }
1640 2229
1641 /* we set up the pointers to the endpoints in the mos7720_open *
1642 * function, as the structures aren't created yet. */
1643 2230
1644 /* set up port private structures */ 2231 /* set up serial port private structures */
1645 for (i = 0; i < serial->num_ports; ++i) { 2232 for (i = 0; i < serial->num_ports; ++i) {
1646 mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); 2233 mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
1647 if (mos7720_port == NULL) { 2234 if (mos7720_port == NULL) {
1648 dev_err(&dev->dev, "%s - Out of memory\n", __func__); 2235 dev_err(&dev->dev, "%s - Out of memory\n", __func__);
1649 usb_set_serial_data(serial, NULL);
1650 kfree(mos7720_serial);
1651 return -ENOMEM; 2236 return -ENOMEM;
1652 } 2237 }
1653 2238
@@ -1669,6 +2254,20 @@ static int mos7720_startup(struct usb_serial *serial)
1669 usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 2254 usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
1670 (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); 2255 (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
1671 2256
2257 /* start the interrupt urb */
2258 ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
2259 if (ret_val)
2260 dev_err(&dev->dev,
2261 "%s - Error %d submitting control urb\n",
2262 __func__, ret_val);
2263
2264#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
2265 if (product == MOSCHIP_DEVICE_ID_7715) {
2266 ret_val = mos7715_parport_init(serial);
2267 if (ret_val < 0)
2268 return ret_val;
2269 }
2270#endif
1672 /* LSR For Port 1 */ 2271 /* LSR For Port 1 */
1673 send_mos_cmd(serial, MOS_READ, 0x00, UART_LSR, &data); 2272 send_mos_cmd(serial, MOS_READ, 0x00, UART_LSR, &data);
1674 dbg("LSR:%x", data); 2273 dbg("LSR:%x", data);
@@ -1684,12 +2283,47 @@ static void mos7720_release(struct usb_serial *serial)
1684{ 2283{
1685 int i; 2284 int i;
1686 2285
2286#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
2287 /* close the parallel port */
2288
2289 if (le16_to_cpu(serial->dev->descriptor.idProduct)
2290 == MOSCHIP_DEVICE_ID_7715) {
2291 struct urbtracker *urbtrack;
2292 unsigned long flags;
2293 struct mos7715_parport *mos_parport =
2294 usb_get_serial_data(serial);
2295
2296 /* prevent NULL ptr dereference in port callbacks */
2297 spin_lock(&release_lock);
2298 mos_parport->pp->private_data = NULL;
2299 spin_unlock(&release_lock);
2300
2301 /* wait for synchronous usb calls to return */
2302 if (mos_parport->msg_pending)
2303 wait_for_completion_timeout(&mos_parport->syncmsg_compl,
2304 MOS_WDR_TIMEOUT);
2305
2306 parport_remove_port(mos_parport->pp);
2307 usb_set_serial_data(serial, NULL);
2308 mos_parport->serial = NULL;
2309
2310 /* if tasklet currently scheduled, wait for it to complete */
2311 tasklet_kill(&mos_parport->urb_tasklet);
2312
2313 /* unlink any urbs sent by the tasklet */
2314 spin_lock_irqsave(&mos_parport->listlock, flags);
2315 list_for_each_entry(urbtrack,
2316 &mos_parport->active_urbs,
2317 urblist_entry)
2318 usb_unlink_urb(urbtrack->urb);
2319 spin_unlock_irqrestore(&mos_parport->listlock, flags);
2320
2321 kref_put(&mos_parport->ref_count, destroy_mos_parport);
2322 }
2323#endif
1687 /* free private structure allocated for serial port */ 2324 /* free private structure allocated for serial port */
1688 for (i = 0; i < serial->num_ports; ++i) 2325 for (i = 0; i < serial->num_ports; ++i)
1689 kfree(usb_get_serial_port_data(serial->port[i])); 2326 kfree(usb_get_serial_port_data(serial->port[i]));
1690
1691 /* free private structure allocated for serial device */
1692 kfree(usb_get_serial_data(serial));
1693} 2327}
1694 2328
1695static struct usb_driver usb_driver = { 2329static struct usb_driver usb_driver = {