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); |