Deleted Added
sdiff udiff text old ( 187176 ) new ( 187259 )
full compact
1#include <sys/cdefs.h>
2__FBSDID("$FreeBSD: head/sys/dev/usb2/serial/ulpt2.c 187259 2009-01-15 02:35:40Z thompsa $");
3
4/* $NetBSD: ulpt.c,v 1.60 2003/10/04 21:19:50 augustss Exp $ */
5
6/*-
7 * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
8 * All rights reserved.
9 *
10 * This code is derived from software contributed to The NetBSD Foundation

--- 59 unchanged lines hidden (view full) ---

70
71SYSCTL_NODE(_hw_usb2, OID_AUTO, ulpt, CTLFLAG_RW, 0, "USB ulpt");
72SYSCTL_INT(_hw_usb2_ulpt, OID_AUTO, debug, CTLFLAG_RW,
73 &ulpt_debug, 0, "Debug level");
74#endif
75
76#define ULPT_BSIZE (1<<15) /* bytes */
77#define ULPT_IFQ_MAXLEN 2 /* units */
78
79#define UR_GET_DEVICE_ID 0x00
80#define UR_GET_PORT_STATUS 0x01
81#define UR_SOFT_RESET 0x02
82
83#define LPS_NERR 0x08 /* printer no error */
84#define LPS_SELECT 0x10 /* printer selected */
85#define LPS_NOPAPER 0x20 /* printer out of paper */
86#define LPS_INVERT (LPS_SELECT|LPS_NERR)
87#define LPS_MASK (LPS_SELECT|LPS_NERR|LPS_NOPAPER)
88
89enum {
90 ULPT_BULK_DT_WR,
91 ULPT_BULK_DT_RD,
92 ULPT_INTR_DT_RD,
93 ULPT_BULK_CS_WR,
94 ULPT_BULK_CS_RD,
95 ULPT_N_TRANSFER = 5,
96};
97
98struct ulpt_softc {
99 struct usb2_fifo_sc sc_fifo;
100 struct usb2_fifo_sc sc_fifo_noreset;
101 struct mtx sc_mtx;
102 struct usb2_callout sc_watchdog;
103
104 device_t sc_dev;
105 struct usb2_device *sc_udev;

--- 104 unchanged lines hidden (view full) ---

210 return;
211 }
212 DPRINTF("state=0x%x\n", USB_GET_STATE(xfer));
213
214 switch (USB_GET_STATE(xfer)) {
215 case USB_ST_TRANSFERRED:
216 case USB_ST_SETUP:
217 if (sc->sc_flags & ULPT_FLAG_WRITE_STALL) {
218 usb2_transfer_start(sc->sc_xfer[ULPT_BULK_CS_WR]);
219 break;
220 }
221 if (usb2_fifo_get_data(f, xfer->frbuffers,
222 0, xfer->max_data_length, &actlen, 0)) {
223
224 xfer->frlengths[0] = actlen;
225 usb2_start_hardware(xfer);
226 }
227 break;
228
229 default: /* Error */
230 if (xfer->error != USB_ERR_CANCELLED) {
231 /* try to clear stall first */
232 sc->sc_flags |= ULPT_FLAG_WRITE_STALL;
233 usb2_transfer_start(sc->sc_xfer[ULPT_BULK_CS_WR]);
234 }
235 break;
236 }
237}
238
239static void
240ulpt_write_clear_stall_callback(struct usb2_xfer *xfer)
241{
242 struct ulpt_softc *sc = xfer->priv_sc;
243 struct usb2_xfer *xfer_other = sc->sc_xfer[ULPT_BULK_DT_WR];
244
245 if (usb2_clear_stall_callback(xfer, xfer_other)) {
246 DPRINTF("stall cleared\n");
247 sc->sc_flags &= ~ULPT_FLAG_WRITE_STALL;
248 usb2_transfer_start(xfer_other);
249 }
250}
251

--- 28 unchanged lines hidden (view full) ---

280 sc->sc_zlps = 0;
281 }
282
283 usb2_fifo_put_data(f, xfer->frbuffers,
284 0, xfer->actlen, 1);
285
286 case USB_ST_SETUP:
287 if (sc->sc_flags & ULPT_FLAG_READ_STALL) {
288 usb2_transfer_start(sc->sc_xfer[ULPT_BULK_CS_RD]);
289 break;
290 }
291 if (usb2_fifo_put_bytes_max(f) != 0) {
292 xfer->frlengths[0] = xfer->max_data_length;
293 usb2_start_hardware(xfer);
294 }
295 break;
296
297 default: /* Error */
298 /* disable BULK throttle */
299 xfer->interval = 0;
300 sc->sc_zlps = 0;
301
302 if (xfer->error != USB_ERR_CANCELLED) {
303 /* try to clear stall first */
304 sc->sc_flags |= ULPT_FLAG_READ_STALL;
305 usb2_transfer_start(sc->sc_xfer[ULPT_BULK_CS_RD]);
306 }
307 break;
308 }
309}
310
311static void
312ulpt_read_clear_stall_callback(struct usb2_xfer *xfer)
313{
314 struct ulpt_softc *sc = xfer->priv_sc;
315 struct usb2_xfer *xfer_other = sc->sc_xfer[ULPT_BULK_DT_RD];
316
317 if (usb2_clear_stall_callback(xfer, xfer_other)) {
318 DPRINTF("stall cleared\n");
319 sc->sc_flags &= ~ULPT_FLAG_READ_STALL;
320 usb2_transfer_start(xfer_other);
321 }
322}
323

--- 46 unchanged lines hidden (view full) ---

370 if (xfer->error != USB_ERR_CANCELLED) {
371 /* wait for next watchdog timeout */
372 }
373 break;
374 }
375}
376
377static const struct usb2_config ulpt_config[ULPT_N_TRANSFER] = {
378 [ULPT_BULK_DT_WR] = {
379 .type = UE_BULK,
380 .endpoint = UE_ADDR_ANY,
381 .direction = UE_DIR_OUT,
382 .mh.bufsize = ULPT_BSIZE,
383 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.proxy_buffer = 1},
384 .mh.callback = &ulpt_write_callback,
385 },
386
387 [ULPT_BULK_DT_RD] = {
388 .type = UE_BULK,
389 .endpoint = UE_ADDR_ANY,
390 .direction = UE_DIR_IN,
391 .mh.bufsize = ULPT_BSIZE,
392 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.proxy_buffer = 1},
393 .mh.callback = &ulpt_read_callback,
394 },
395
396 [ULPT_INTR_DT_RD] = {
397 .type = UE_CONTROL,
398 .endpoint = 0x00, /* Control pipe */
399 .direction = UE_DIR_ANY,
400 .mh.bufsize = sizeof(struct usb2_device_request) + 1,
401 .mh.callback = &ulpt_status_callback,
402 .mh.timeout = 1000, /* 1 second */
403 },
404
405 [ULPT_BULK_CS_WR] = {
406 .type = UE_CONTROL,
407 .endpoint = 0x00, /* Control pipe */
408 .direction = UE_DIR_ANY,
409 .mh.bufsize = sizeof(struct usb2_device_request),
410 .mh.callback = &ulpt_write_clear_stall_callback,
411 .mh.timeout = 1000, /* 1 second */
412 .mh.interval = 50, /* 50ms */
413 },
414
415 [ULPT_BULK_CS_RD] = {
416 .type = UE_CONTROL,
417 .endpoint = 0x00, /* Control pipe */
418 .direction = UE_DIR_ANY,
419 .mh.bufsize = sizeof(struct usb2_device_request),
420 .mh.callback = &ulpt_read_clear_stall_callback,
421 .mh.timeout = 1000, /* 1 second */
422 .mh.interval = 50, /* 50ms */
423 },
424};
425
426static void
427ulpt_start_read(struct usb2_fifo *fifo)
428{
429 struct ulpt_softc *sc = fifo->priv_sc0;
430
431 usb2_transfer_start(sc->sc_xfer[ULPT_BULK_DT_RD]);
432}
433
434static void
435ulpt_stop_read(struct usb2_fifo *fifo)
436{
437 struct ulpt_softc *sc = fifo->priv_sc0;
438
439 usb2_transfer_stop(sc->sc_xfer[ULPT_BULK_CS_RD]);
440 usb2_transfer_stop(sc->sc_xfer[ULPT_BULK_DT_RD]);
441}
442
443static void
444ulpt_start_write(struct usb2_fifo *fifo)
445{
446 struct ulpt_softc *sc = fifo->priv_sc0;
447
448 usb2_transfer_start(sc->sc_xfer[ULPT_BULK_DT_WR]);
449}
450
451static void
452ulpt_stop_write(struct usb2_fifo *fifo)
453{
454 struct ulpt_softc *sc = fifo->priv_sc0;
455
456 usb2_transfer_stop(sc->sc_xfer[ULPT_BULK_CS_WR]);
457 usb2_transfer_stop(sc->sc_xfer[ULPT_BULK_DT_WR]);
458}
459
460static int
461ulpt_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
462{
463 struct ulpt_softc *sc = fifo->priv_sc0;
464
465 /* we assume that open is a serial process */

--- 13 unchanged lines hidden (view full) ---

479 return (EBUSY);
480 }
481 if (fflags & FREAD) {
482 /* clear stall first */
483 mtx_lock(&sc->sc_mtx);
484 sc->sc_flags |= ULPT_FLAG_READ_STALL;
485 mtx_unlock(&sc->sc_mtx);
486 if (usb2_fifo_alloc_buffer(fifo,
487 sc->sc_xfer[ULPT_BULK_DT_RD]->max_data_length,
488 ULPT_IFQ_MAXLEN)) {
489 return (ENOMEM);
490 }
491 /* set which FIFO is opened */
492 sc->sc_fifo_open[USB_FIFO_RX] = fifo;
493 }
494 if (fflags & FWRITE) {
495 /* clear stall first */
496 mtx_lock(&sc->sc_mtx);
497 sc->sc_flags |= ULPT_FLAG_WRITE_STALL;
498 mtx_unlock(&sc->sc_mtx);
499 if (usb2_fifo_alloc_buffer(fifo,
500 sc->sc_xfer[ULPT_BULK_DT_WR]->max_data_length,
501 ULPT_IFQ_MAXLEN)) {
502 return (ENOMEM);
503 }
504 /* set which FIFO is opened */
505 sc->sc_fifo_open[USB_FIFO_TX] = fifo;
506 }
507 sc->sc_fflags |= fflags & (FREAD | FWRITE);
508 return (0);

--- 249 unchanged lines hidden (view full) ---

758
759static void
760ulpt_watchdog(void *arg)
761{
762 struct ulpt_softc *sc = arg;
763
764 mtx_assert(&sc->sc_mtx, MA_OWNED);
765
766 usb2_transfer_start(sc->sc_xfer[ULPT_INTR_DT_RD]);
767
768 usb2_callout_reset(&sc->sc_watchdog,
769 hz, &ulpt_watchdog, sc);
770}
771
772static devclass_t ulpt_devclass;
773
774static device_method_t ulpt_methods[] = {

--- 15 unchanged lines hidden ---