diff options
Diffstat (limited to 'drivers/usb/serial/keyspan.c')
| -rw-r--r-- | drivers/usb/serial/keyspan.c | 181 |
1 files changed, 88 insertions, 93 deletions
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 29c943d737d0..7179b0c5f814 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
| @@ -1374,13 +1374,9 @@ static struct callbacks { | |||
| 1374 | data in device_details */ | 1374 | data in device_details */ |
| 1375 | static void keyspan_setup_urbs(struct usb_serial *serial) | 1375 | static void keyspan_setup_urbs(struct usb_serial *serial) |
| 1376 | { | 1376 | { |
| 1377 | int i, j; | ||
| 1378 | struct keyspan_serial_private *s_priv; | 1377 | struct keyspan_serial_private *s_priv; |
| 1379 | const struct keyspan_device_details *d_details; | 1378 | const struct keyspan_device_details *d_details; |
| 1380 | struct usb_serial_port *port; | ||
| 1381 | struct keyspan_port_private *p_priv; | ||
| 1382 | struct callbacks *cback; | 1379 | struct callbacks *cback; |
| 1383 | int endp; | ||
| 1384 | 1380 | ||
| 1385 | s_priv = usb_get_serial_data(serial); | 1381 | s_priv = usb_get_serial_data(serial); |
| 1386 | d_details = s_priv->device_details; | 1382 | d_details = s_priv->device_details; |
| @@ -1404,45 +1400,6 @@ static void keyspan_setup_urbs(struct usb_serial *serial) | |||
| 1404 | (serial, d_details->glocont_endpoint, USB_DIR_OUT, | 1400 | (serial, d_details->glocont_endpoint, USB_DIR_OUT, |
| 1405 | serial, s_priv->glocont_buf, GLOCONT_BUFLEN, | 1401 | serial, s_priv->glocont_buf, GLOCONT_BUFLEN, |
| 1406 | cback->glocont_callback); | 1402 | cback->glocont_callback); |
| 1407 | |||
| 1408 | /* Setup endpoints for each port specific thing */ | ||
| 1409 | for (i = 0; i < d_details->num_ports; i++) { | ||
| 1410 | port = serial->port[i]; | ||
| 1411 | p_priv = usb_get_serial_port_data(port); | ||
| 1412 | |||
| 1413 | /* Do indat endpoints first, once for each flip */ | ||
| 1414 | endp = d_details->indat_endpoints[i]; | ||
| 1415 | for (j = 0; j <= d_details->indat_endp_flip; ++j, ++endp) { | ||
| 1416 | p_priv->in_urbs[j] = keyspan_setup_urb | ||
| 1417 | (serial, endp, USB_DIR_IN, port, | ||
| 1418 | p_priv->in_buffer[j], 64, | ||
| 1419 | cback->indat_callback); | ||
| 1420 | } | ||
| 1421 | for (; j < 2; ++j) | ||
| 1422 | p_priv->in_urbs[j] = NULL; | ||
| 1423 | |||
| 1424 | /* outdat endpoints also have flip */ | ||
| 1425 | endp = d_details->outdat_endpoints[i]; | ||
| 1426 | for (j = 0; j <= d_details->outdat_endp_flip; ++j, ++endp) { | ||
| 1427 | p_priv->out_urbs[j] = keyspan_setup_urb | ||
| 1428 | (serial, endp, USB_DIR_OUT, port, | ||
| 1429 | p_priv->out_buffer[j], 64, | ||
| 1430 | cback->outdat_callback); | ||
| 1431 | } | ||
| 1432 | for (; j < 2; ++j) | ||
| 1433 | p_priv->out_urbs[j] = NULL; | ||
| 1434 | |||
| 1435 | /* inack endpoint */ | ||
| 1436 | p_priv->inack_urb = keyspan_setup_urb | ||
| 1437 | (serial, d_details->inack_endpoints[i], USB_DIR_IN, | ||
| 1438 | port, p_priv->inack_buffer, 1, cback->inack_callback); | ||
| 1439 | |||
| 1440 | /* outcont endpoint */ | ||
| 1441 | p_priv->outcont_urb = keyspan_setup_urb | ||
| 1442 | (serial, d_details->outcont_endpoints[i], USB_DIR_OUT, | ||
| 1443 | port, p_priv->outcont_buffer, 64, | ||
| 1444 | cback->outcont_callback); | ||
| 1445 | } | ||
| 1446 | } | 1403 | } |
| 1447 | 1404 | ||
| 1448 | /* usa19 function doesn't require prescaler */ | 1405 | /* usa19 function doesn't require prescaler */ |
| @@ -2407,9 +2364,7 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) | |||
| 2407 | static int keyspan_startup(struct usb_serial *serial) | 2364 | static int keyspan_startup(struct usb_serial *serial) |
| 2408 | { | 2365 | { |
| 2409 | int i, err; | 2366 | int i, err; |
| 2410 | struct usb_serial_port *port; | ||
| 2411 | struct keyspan_serial_private *s_priv; | 2367 | struct keyspan_serial_private *s_priv; |
| 2412 | struct keyspan_port_private *p_priv; | ||
| 2413 | const struct keyspan_device_details *d_details; | 2368 | const struct keyspan_device_details *d_details; |
| 2414 | 2369 | ||
| 2415 | for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i) | 2370 | for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i) |
| @@ -2432,19 +2387,6 @@ static int keyspan_startup(struct usb_serial *serial) | |||
| 2432 | s_priv->device_details = d_details; | 2387 | s_priv->device_details = d_details; |
| 2433 | usb_set_serial_data(serial, s_priv); | 2388 | usb_set_serial_data(serial, s_priv); |
| 2434 | 2389 | ||
| 2435 | /* Now setup per port private data */ | ||
| 2436 | for (i = 0; i < serial->num_ports; i++) { | ||
| 2437 | port = serial->port[i]; | ||
| 2438 | p_priv = kzalloc(sizeof(struct keyspan_port_private), | ||
| 2439 | GFP_KERNEL); | ||
| 2440 | if (!p_priv) { | ||
| 2441 | dev_dbg(&port->dev, "%s - kmalloc for keyspan_port_private (%d) failed!.\n", __func__, i); | ||
| 2442 | return 1; | ||
| 2443 | } | ||
| 2444 | p_priv->device_details = d_details; | ||
| 2445 | usb_set_serial_port_data(port, p_priv); | ||
| 2446 | } | ||
| 2447 | |||
| 2448 | keyspan_setup_urbs(serial); | 2390 | keyspan_setup_urbs(serial); |
| 2449 | 2391 | ||
| 2450 | if (s_priv->instat_urb != NULL) { | 2392 | if (s_priv->instat_urb != NULL) { |
| @@ -2463,59 +2405,112 @@ static int keyspan_startup(struct usb_serial *serial) | |||
| 2463 | 2405 | ||
| 2464 | static void keyspan_disconnect(struct usb_serial *serial) | 2406 | static void keyspan_disconnect(struct usb_serial *serial) |
| 2465 | { | 2407 | { |
| 2466 | int i, j; | 2408 | struct keyspan_serial_private *s_priv; |
| 2467 | struct usb_serial_port *port; | ||
| 2468 | struct keyspan_serial_private *s_priv; | ||
| 2469 | struct keyspan_port_private *p_priv; | ||
| 2470 | 2409 | ||
| 2471 | s_priv = usb_get_serial_data(serial); | 2410 | s_priv = usb_get_serial_data(serial); |
| 2472 | 2411 | ||
| 2473 | /* Stop reading/writing urbs */ | ||
| 2474 | stop_urb(s_priv->instat_urb); | 2412 | stop_urb(s_priv->instat_urb); |
| 2475 | stop_urb(s_priv->glocont_urb); | 2413 | stop_urb(s_priv->glocont_urb); |
| 2476 | stop_urb(s_priv->indat_urb); | 2414 | stop_urb(s_priv->indat_urb); |
| 2477 | for (i = 0; i < serial->num_ports; ++i) { | 2415 | } |
| 2478 | port = serial->port[i]; | 2416 | |
| 2479 | p_priv = usb_get_serial_port_data(port); | 2417 | static void keyspan_release(struct usb_serial *serial) |
| 2480 | stop_urb(p_priv->inack_urb); | 2418 | { |
| 2481 | stop_urb(p_priv->outcont_urb); | 2419 | struct keyspan_serial_private *s_priv; |
| 2482 | for (j = 0; j < 2; j++) { | 2420 | |
| 2483 | stop_urb(p_priv->in_urbs[j]); | 2421 | s_priv = usb_get_serial_data(serial); |
| 2484 | stop_urb(p_priv->out_urbs[j]); | ||
| 2485 | } | ||
| 2486 | } | ||
| 2487 | 2422 | ||
| 2488 | /* Now free them */ | ||
| 2489 | usb_free_urb(s_priv->instat_urb); | 2423 | usb_free_urb(s_priv->instat_urb); |
| 2490 | usb_free_urb(s_priv->indat_urb); | 2424 | usb_free_urb(s_priv->indat_urb); |
| 2491 | usb_free_urb(s_priv->glocont_urb); | 2425 | usb_free_urb(s_priv->glocont_urb); |
| 2492 | for (i = 0; i < serial->num_ports; ++i) { | 2426 | |
| 2493 | port = serial->port[i]; | 2427 | kfree(s_priv); |
| 2494 | p_priv = usb_get_serial_port_data(port); | ||
| 2495 | usb_free_urb(p_priv->inack_urb); | ||
| 2496 | usb_free_urb(p_priv->outcont_urb); | ||
| 2497 | for (j = 0; j < 2; j++) { | ||
| 2498 | usb_free_urb(p_priv->in_urbs[j]); | ||
| 2499 | usb_free_urb(p_priv->out_urbs[j]); | ||
| 2500 | } | ||
| 2501 | } | ||
| 2502 | } | 2428 | } |
| 2503 | 2429 | ||
| 2504 | static void keyspan_release(struct usb_serial *serial) | 2430 | static int keyspan_port_probe(struct usb_serial_port *port) |
| 2505 | { | 2431 | { |
| 2506 | int i; | 2432 | struct usb_serial *serial = port->serial; |
| 2507 | struct usb_serial_port *port; | 2433 | struct keyspan_port_private *s_priv; |
| 2508 | struct keyspan_serial_private *s_priv; | 2434 | struct keyspan_port_private *p_priv; |
| 2435 | const struct keyspan_device_details *d_details; | ||
| 2436 | struct callbacks *cback; | ||
| 2437 | int endp; | ||
| 2438 | int port_num; | ||
| 2439 | int i; | ||
| 2509 | 2440 | ||
| 2510 | s_priv = usb_get_serial_data(serial); | 2441 | s_priv = usb_get_serial_data(serial); |
| 2442 | d_details = s_priv->device_details; | ||
| 2511 | 2443 | ||
| 2512 | kfree(s_priv); | 2444 | p_priv = kzalloc(sizeof(*p_priv), GFP_KERNEL); |
| 2445 | if (!p_priv) | ||
| 2446 | return -ENOMEM; | ||
| 2513 | 2447 | ||
| 2514 | /* Now free per port private data */ | 2448 | s_priv = usb_get_serial_data(port->serial); |
| 2515 | for (i = 0; i < serial->num_ports; i++) { | 2449 | p_priv->device_details = d_details; |
| 2516 | port = serial->port[i]; | 2450 | |
| 2517 | kfree(usb_get_serial_port_data(port)); | 2451 | /* Setup values for the various callback routines */ |
| 2452 | cback = &keyspan_callbacks[d_details->msg_format]; | ||
| 2453 | |||
| 2454 | port_num = port->number - port->serial->minor; | ||
| 2455 | |||
| 2456 | /* Do indat endpoints first, once for each flip */ | ||
| 2457 | endp = d_details->indat_endpoints[port_num]; | ||
| 2458 | for (i = 0; i <= d_details->indat_endp_flip; ++i, ++endp) { | ||
| 2459 | p_priv->in_urbs[i] = keyspan_setup_urb(serial, endp, | ||
| 2460 | USB_DIR_IN, port, | ||
| 2461 | p_priv->in_buffer[i], 64, | ||
| 2462 | cback->indat_callback); | ||
| 2463 | } | ||
| 2464 | /* outdat endpoints also have flip */ | ||
| 2465 | endp = d_details->outdat_endpoints[port_num]; | ||
| 2466 | for (i = 0; i <= d_details->outdat_endp_flip; ++i, ++endp) { | ||
| 2467 | p_priv->out_urbs[i] = keyspan_setup_urb(serial, endp, | ||
| 2468 | USB_DIR_OUT, port, | ||
| 2469 | p_priv->out_buffer[i], 64, | ||
| 2470 | cback->outdat_callback); | ||
| 2471 | } | ||
| 2472 | /* inack endpoint */ | ||
| 2473 | p_priv->inack_urb = keyspan_setup_urb(serial, | ||
| 2474 | d_details->inack_endpoints[port_num], | ||
| 2475 | USB_DIR_IN, port, | ||
| 2476 | p_priv->inack_buffer, 1, | ||
| 2477 | cback->inack_callback); | ||
| 2478 | /* outcont endpoint */ | ||
| 2479 | p_priv->outcont_urb = keyspan_setup_urb(serial, | ||
| 2480 | d_details->outcont_endpoints[port_num], | ||
| 2481 | USB_DIR_OUT, port, | ||
| 2482 | p_priv->outcont_buffer, 64, | ||
| 2483 | cback->outcont_callback); | ||
| 2484 | |||
| 2485 | usb_set_serial_port_data(port, p_priv); | ||
| 2486 | |||
| 2487 | return 0; | ||
| 2488 | } | ||
| 2489 | |||
| 2490 | static int keyspan_port_remove(struct usb_serial_port *port) | ||
| 2491 | { | ||
| 2492 | struct keyspan_port_private *p_priv; | ||
| 2493 | int i; | ||
| 2494 | |||
| 2495 | p_priv = usb_get_serial_port_data(port); | ||
| 2496 | |||
| 2497 | stop_urb(p_priv->inack_urb); | ||
| 2498 | stop_urb(p_priv->outcont_urb); | ||
| 2499 | for (i = 0; i < 2; i++) { | ||
| 2500 | stop_urb(p_priv->in_urbs[i]); | ||
| 2501 | stop_urb(p_priv->out_urbs[i]); | ||
| 2502 | } | ||
| 2503 | |||
| 2504 | usb_free_urb(p_priv->inack_urb); | ||
| 2505 | usb_free_urb(p_priv->outcont_urb); | ||
| 2506 | for (i = 0; i < 2; i++) { | ||
| 2507 | usb_free_urb(p_priv->in_urbs[i]); | ||
| 2508 | usb_free_urb(p_priv->out_urbs[i]); | ||
| 2518 | } | 2509 | } |
| 2510 | |||
| 2511 | kfree(p_priv); | ||
| 2512 | |||
| 2513 | return 0; | ||
| 2519 | } | 2514 | } |
| 2520 | 2515 | ||
| 2521 | MODULE_AUTHOR(DRIVER_AUTHOR); | 2516 | MODULE_AUTHOR(DRIVER_AUTHOR); |
