ugensa.c (187970) | ugensa.c (188413) |
---|---|
1/* $FreeBSD: head/sys/dev/usb2/serial/ugensa2.c 187970 2009-02-01 00:51:25Z thompsa $ */ | 1/* $FreeBSD: head/sys/dev/usb2/serial/ugensa2.c 188413 2009-02-09 22:05:25Z thompsa $ */ |
2/* $NetBSD: ugensa.c,v 1.9.2.1 2007/03/24 14:55:50 yamt Exp $ */ 3 4/* 5 * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Roland C. Dowdeswell <elric@netbsd.org>. --- 54 unchanged lines hidden (view full) --- 64#define UGENSA_BUF_SIZE 2048 /* bytes */ 65#define UGENSA_CONFIG_INDEX 0 66#define UGENSA_IFACE_INDEX 0 67#define UGENSA_IFACE_MAX 8 /* exclusivly */ 68 69enum { 70 UGENSA_BULK_DT_WR, 71 UGENSA_BULK_DT_RD, | 2/* $NetBSD: ugensa.c,v 1.9.2.1 2007/03/24 14:55:50 yamt Exp $ */ 3 4/* 5 * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Roland C. Dowdeswell <elric@netbsd.org>. --- 54 unchanged lines hidden (view full) --- 64#define UGENSA_BUF_SIZE 2048 /* bytes */ 65#define UGENSA_CONFIG_INDEX 0 66#define UGENSA_IFACE_INDEX 0 67#define UGENSA_IFACE_MAX 8 /* exclusivly */ 68 69enum { 70 UGENSA_BULK_DT_WR, 71 UGENSA_BULK_DT_RD, |
72 UGENSA_BULK_CS_WR, 73 UGENSA_BULK_CS_RD, 74 UGENSA_N_TRANSFER = 4, | 72 UGENSA_N_TRANSFER, |
75}; 76 77struct ugensa_sub_softc { 78 struct usb2_com_softc *sc_usb2_com_ptr; 79 struct usb2_xfer *sc_xfer[UGENSA_N_TRANSFER]; | 73}; 74 75struct ugensa_sub_softc { 76 struct usb2_com_softc *sc_usb2_com_ptr; 77 struct usb2_xfer *sc_xfer[UGENSA_N_TRANSFER]; |
80 81 uint8_t sc_flags; 82#define UGENSA_FLAG_BULK_READ_STALL 0x01 83#define UGENSA_FLAG_BULK_WRITE_STALL 0x02 | |
84}; 85 86struct ugensa_softc { 87 struct usb2_com_super_softc sc_super_ucom; 88 struct usb2_com_softc sc_ucom[UGENSA_IFACE_MAX]; 89 struct ugensa_sub_softc sc_sub[UGENSA_IFACE_MAX]; 90 91 struct mtx sc_mtx; 92 uint8_t sc_niface; 93}; 94 95/* prototypes */ 96 97static device_probe_t ugensa_probe; 98static device_attach_t ugensa_attach; 99static device_detach_t ugensa_detach; 100 101static usb2_callback_t ugensa_bulk_write_callback; | 78}; 79 80struct ugensa_softc { 81 struct usb2_com_super_softc sc_super_ucom; 82 struct usb2_com_softc sc_ucom[UGENSA_IFACE_MAX]; 83 struct ugensa_sub_softc sc_sub[UGENSA_IFACE_MAX]; 84 85 struct mtx sc_mtx; 86 uint8_t sc_niface; 87}; 88 89/* prototypes */ 90 91static device_probe_t ugensa_probe; 92static device_attach_t ugensa_attach; 93static device_detach_t ugensa_detach; 94 95static usb2_callback_t ugensa_bulk_write_callback; |
102static usb2_callback_t ugensa_bulk_write_clear_stall_callback; | |
103static usb2_callback_t ugensa_bulk_read_callback; | 96static usb2_callback_t ugensa_bulk_read_callback; |
104static usb2_callback_t ugensa_bulk_read_clear_stall_callback; | |
105 106static void ugensa_start_read(struct usb2_com_softc *); 107static void ugensa_stop_read(struct usb2_com_softc *); 108static void ugensa_start_write(struct usb2_com_softc *); 109static void ugensa_stop_write(struct usb2_com_softc *); 110 111static const struct usb2_config 112 ugensa_xfer_config[UGENSA_N_TRANSFER] = { --- 10 unchanged lines hidden (view full) --- 123 [UGENSA_BULK_DT_RD] = { 124 .type = UE_BULK, 125 .endpoint = UE_ADDR_ANY, 126 .direction = UE_DIR_IN, 127 .mh.bufsize = UGENSA_BUF_SIZE, 128 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 129 .mh.callback = &ugensa_bulk_read_callback, 130 }, | 97 98static void ugensa_start_read(struct usb2_com_softc *); 99static void ugensa_stop_read(struct usb2_com_softc *); 100static void ugensa_start_write(struct usb2_com_softc *); 101static void ugensa_stop_write(struct usb2_com_softc *); 102 103static const struct usb2_config 104 ugensa_xfer_config[UGENSA_N_TRANSFER] = { --- 10 unchanged lines hidden (view full) --- 115 [UGENSA_BULK_DT_RD] = { 116 .type = UE_BULK, 117 .endpoint = UE_ADDR_ANY, 118 .direction = UE_DIR_IN, 119 .mh.bufsize = UGENSA_BUF_SIZE, 120 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 121 .mh.callback = &ugensa_bulk_read_callback, 122 }, |
131 132 [UGENSA_BULK_CS_WR] = { 133 .type = UE_CONTROL, 134 .endpoint = 0x00, /* Control pipe */ 135 .direction = UE_DIR_ANY, 136 .mh.bufsize = sizeof(struct usb2_device_request), 137 .mh.flags = {}, 138 .mh.callback = &ugensa_bulk_write_clear_stall_callback, 139 .mh.timeout = 1000, /* 1 second */ 140 .mh.interval = 50, /* 50ms */ 141 }, 142 143 [UGENSA_BULK_CS_RD] = { 144 .type = UE_CONTROL, 145 .endpoint = 0x00, /* Control pipe */ 146 .direction = UE_DIR_ANY, 147 .mh.bufsize = sizeof(struct usb2_device_request), 148 .mh.flags = {}, 149 .mh.callback = &ugensa_bulk_read_clear_stall_callback, 150 .mh.timeout = 1000, /* 1 second */ 151 .mh.interval = 50, /* 50ms */ 152 }, | |
153}; 154 155static const struct usb2_com_callback ugensa_callback = { 156 .usb2_com_start_read = &ugensa_start_read, 157 .usb2_com_stop_read = &ugensa_stop_read, 158 .usb2_com_start_write = &ugensa_start_write, 159 .usb2_com_stop_write = &ugensa_stop_write, 160}; --- 85 unchanged lines hidden (view full) --- 246 UGENSA_N_TRANSFER, ssc, &sc->sc_mtx); 247 248 if (error) { 249 device_printf(dev, "allocating USB " 250 "transfers failed!\n"); 251 goto detach; 252 } 253 /* clear stall at first run */ | 123}; 124 125static const struct usb2_com_callback ugensa_callback = { 126 .usb2_com_start_read = &ugensa_start_read, 127 .usb2_com_stop_read = &ugensa_stop_read, 128 .usb2_com_start_write = &ugensa_start_write, 129 .usb2_com_stop_write = &ugensa_stop_write, 130}; --- 85 unchanged lines hidden (view full) --- 216 UGENSA_N_TRANSFER, ssc, &sc->sc_mtx); 217 218 if (error) { 219 device_printf(dev, "allocating USB " 220 "transfers failed!\n"); 221 goto detach; 222 } 223 /* clear stall at first run */ |
254 ssc->sc_flags |= (UGENSA_FLAG_BULK_WRITE_STALL | 255 UGENSA_FLAG_BULK_READ_STALL); | 224 usb2_transfer_set_stall(ssc->sc_xfer[UGENSA_BULK_DT_WR]); 225 usb2_transfer_set_stall(ssc->sc_xfer[UGENSA_BULK_DT_RD]); |
256 257 /* initialize port number */ 258 ssc->sc_usb2_com_ptr->sc_portno = sc->sc_niface; 259 sc->sc_niface++; 260 if (x != uaa->info.bIfaceIndex) 261 usb2_set_parent_iface(uaa->device, x, 262 uaa->info.bIfaceIndex); 263 } --- 32 unchanged lines hidden (view full) --- 296ugensa_bulk_write_callback(struct usb2_xfer *xfer) 297{ 298 struct ugensa_sub_softc *ssc = xfer->priv_sc; 299 uint32_t actlen; 300 301 switch (USB_GET_STATE(xfer)) { 302 case USB_ST_SETUP: 303 case USB_ST_TRANSFERRED: | 226 227 /* initialize port number */ 228 ssc->sc_usb2_com_ptr->sc_portno = sc->sc_niface; 229 sc->sc_niface++; 230 if (x != uaa->info.bIfaceIndex) 231 usb2_set_parent_iface(uaa->device, x, 232 uaa->info.bIfaceIndex); 233 } --- 32 unchanged lines hidden (view full) --- 266ugensa_bulk_write_callback(struct usb2_xfer *xfer) 267{ 268 struct ugensa_sub_softc *ssc = xfer->priv_sc; 269 uint32_t actlen; 270 271 switch (USB_GET_STATE(xfer)) { 272 case USB_ST_SETUP: 273 case USB_ST_TRANSFERRED: |
304 if (ssc->sc_flags & UGENSA_FLAG_BULK_WRITE_STALL) { 305 usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_CS_WR]); 306 return; 307 } | 274tr_setup: |
308 if (usb2_com_get_data(ssc->sc_usb2_com_ptr, xfer->frbuffers, 0, 309 UGENSA_BUF_SIZE, &actlen)) { 310 xfer->frlengths[0] = actlen; 311 usb2_start_hardware(xfer); 312 } 313 return; 314 315 default: /* Error */ 316 if (xfer->error != USB_ERR_CANCELLED) { | 275 if (usb2_com_get_data(ssc->sc_usb2_com_ptr, xfer->frbuffers, 0, 276 UGENSA_BUF_SIZE, &actlen)) { 277 xfer->frlengths[0] = actlen; 278 usb2_start_hardware(xfer); 279 } 280 return; 281 282 default: /* Error */ 283 if (xfer->error != USB_ERR_CANCELLED) { |
317 ssc->sc_flags |= UGENSA_FLAG_BULK_WRITE_STALL; 318 usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_CS_WR]); | 284 /* try to clear stall first */ 285 xfer->flags.stall_pipe = 1; 286 goto tr_setup; |
319 } 320 return; | 287 } 288 return; |
321 | |
322 } 323} 324 325static void | 289 } 290} 291 292static void |
326ugensa_bulk_write_clear_stall_callback(struct usb2_xfer *xfer) 327{ 328 struct ugensa_sub_softc *ssc = xfer->priv_sc; 329 struct usb2_xfer *xfer_other = ssc->sc_xfer[UGENSA_BULK_DT_WR]; 330 331 if (usb2_clear_stall_callback(xfer, xfer_other)) { 332 DPRINTF("stall cleared\n"); 333 ssc->sc_flags &= ~UGENSA_FLAG_BULK_WRITE_STALL; 334 usb2_transfer_start(xfer_other); 335 } 336} 337 338static void | |
339ugensa_bulk_read_callback(struct usb2_xfer *xfer) 340{ 341 struct ugensa_sub_softc *ssc = xfer->priv_sc; 342 343 switch (USB_GET_STATE(xfer)) { 344 case USB_ST_TRANSFERRED: 345 usb2_com_put_data(ssc->sc_usb2_com_ptr, xfer->frbuffers, 0, 346 xfer->actlen); 347 348 case USB_ST_SETUP: | 293ugensa_bulk_read_callback(struct usb2_xfer *xfer) 294{ 295 struct ugensa_sub_softc *ssc = xfer->priv_sc; 296 297 switch (USB_GET_STATE(xfer)) { 298 case USB_ST_TRANSFERRED: 299 usb2_com_put_data(ssc->sc_usb2_com_ptr, xfer->frbuffers, 0, 300 xfer->actlen); 301 302 case USB_ST_SETUP: |
349 if (ssc->sc_flags & UGENSA_FLAG_BULK_READ_STALL) { 350 usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_CS_RD]); 351 } else { 352 xfer->frlengths[0] = xfer->max_data_length; 353 usb2_start_hardware(xfer); 354 } | 303tr_setup: 304 xfer->frlengths[0] = xfer->max_data_length; 305 usb2_start_hardware(xfer); |
355 return; 356 357 default: /* Error */ 358 if (xfer->error != USB_ERR_CANCELLED) { | 306 return; 307 308 default: /* Error */ 309 if (xfer->error != USB_ERR_CANCELLED) { |
359 ssc->sc_flags |= UGENSA_FLAG_BULK_READ_STALL; 360 usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_CS_RD]); | 310 /* try to clear stall first */ 311 xfer->flags.stall_pipe = 1; 312 goto tr_setup; |
361 } 362 return; | 313 } 314 return; |
363 | |
364 } 365} 366 367static void | 315 } 316} 317 318static void |
368ugensa_bulk_read_clear_stall_callback(struct usb2_xfer *xfer) 369{ 370 struct ugensa_sub_softc *ssc = xfer->priv_sc; 371 struct usb2_xfer *xfer_other = ssc->sc_xfer[UGENSA_BULK_DT_RD]; 372 373 if (usb2_clear_stall_callback(xfer, xfer_other)) { 374 DPRINTF("stall cleared\n"); 375 ssc->sc_flags &= ~UGENSA_FLAG_BULK_READ_STALL; 376 usb2_transfer_start(xfer_other); 377 } 378} 379 380static void | |
381ugensa_start_read(struct usb2_com_softc *ucom) 382{ 383 struct ugensa_softc *sc = ucom->sc_parent; 384 struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno; 385 386 usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_DT_RD]); 387} 388 389static void 390ugensa_stop_read(struct usb2_com_softc *ucom) 391{ 392 struct ugensa_softc *sc = ucom->sc_parent; 393 struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno; 394 | 319ugensa_start_read(struct usb2_com_softc *ucom) 320{ 321 struct ugensa_softc *sc = ucom->sc_parent; 322 struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno; 323 324 usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_DT_RD]); 325} 326 327static void 328ugensa_stop_read(struct usb2_com_softc *ucom) 329{ 330 struct ugensa_softc *sc = ucom->sc_parent; 331 struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno; 332 |
395 usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_CS_RD]); | |
396 usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_DT_RD]); 397} 398 399static void 400ugensa_start_write(struct usb2_com_softc *ucom) 401{ 402 struct ugensa_softc *sc = ucom->sc_parent; 403 struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno; 404 405 usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_DT_WR]); 406} 407 408static void 409ugensa_stop_write(struct usb2_com_softc *ucom) 410{ 411 struct ugensa_softc *sc = ucom->sc_parent; 412 struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno; 413 | 333 usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_DT_RD]); 334} 335 336static void 337ugensa_start_write(struct usb2_com_softc *ucom) 338{ 339 struct ugensa_softc *sc = ucom->sc_parent; 340 struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno; 341 342 usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_DT_WR]); 343} 344 345static void 346ugensa_stop_write(struct usb2_com_softc *ucom) 347{ 348 struct ugensa_softc *sc = ucom->sc_parent; 349 struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno; 350 |
414 usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_CS_WR]); | |
415 usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_DT_WR]); 416} | 351 usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_DT_WR]); 352} |