diff options
author | Johan Hovold <jhovold@gmail.com> | 2012-10-25 12:56:34 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-10-25 14:11:19 -0400 |
commit | 80c00750f0c9867a65b30a17880939b6bc660a77 (patch) | |
tree | b8bc2072f4df67ad5889b95fc19957b4af466ee0 /drivers | |
parent | e681b66f2e19fadbe8a7e2a17900978cb6bc921f (diff) |
USB: mos7840: fix port-data memory leak
Fix port-data memory leak by moving port data allocation and
deallocation to port_probe and port_remove.
Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no
driver is bound) the port private data is no longer freed at release as
it is no longer accessible.
Note that the indentation was kept intact using a do-while(0) in order
to facilitate review. A follow-up patch will remove it.
Compile-only tested.
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/serial/mos7840.c | 219 |
1 files changed, 89 insertions, 130 deletions
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 84f8c106e5e9..bc3df86134fe 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -2327,49 +2327,45 @@ static int mos7840_calc_num_ports(struct usb_serial *serial) | |||
2327 | return mos7840_num_ports; | 2327 | return mos7840_num_ports; |
2328 | } | 2328 | } |
2329 | 2329 | ||
2330 | /**************************************************************************** | 2330 | static int mos7840_port_probe(struct usb_serial_port *port) |
2331 | * mos7840_startup | ||
2332 | ****************************************************************************/ | ||
2333 | |||
2334 | static int mos7840_startup(struct usb_serial *serial) | ||
2335 | { | 2331 | { |
2332 | struct usb_serial *serial = port->serial; | ||
2336 | struct moschip_port *mos7840_port; | 2333 | struct moschip_port *mos7840_port; |
2337 | struct usb_device *dev; | 2334 | int status; |
2338 | int i, status; | 2335 | int pnum; |
2339 | __u16 Data; | 2336 | __u16 Data; |
2340 | 2337 | ||
2341 | dev = serial->dev; | ||
2342 | |||
2343 | /* we set up the pointers to the endpoints in the mos7840_open * | 2338 | /* we set up the pointers to the endpoints in the mos7840_open * |
2344 | * function, as the structures aren't created yet. */ | 2339 | * function, as the structures aren't created yet. */ |
2345 | 2340 | ||
2346 | /* set up port private structures */ | 2341 | pnum = port->number - serial->minor; |
2347 | for (i = 0; i < serial->num_ports; ++i) { | 2342 | |
2348 | dev_dbg(&dev->dev, "mos7840_startup: configuring port %d............\n", i); | 2343 | /* FIXME: remove do-while(0) loop used to keep stable patch minimal. |
2344 | */ | ||
2345 | do { | ||
2346 | dev_dbg(&port->dev, "mos7840_startup: configuring port %d............\n", pnum); | ||
2349 | mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); | 2347 | mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); |
2350 | if (mos7840_port == NULL) { | 2348 | if (mos7840_port == NULL) { |
2351 | dev_err(&dev->dev, "%s - Out of memory\n", __func__); | 2349 | dev_err(&port->dev, "%s - Out of memory\n", __func__); |
2352 | status = -ENOMEM; | 2350 | return -ENOMEM; |
2353 | i--; /* don't follow NULL pointer cleaning up */ | ||
2354 | goto error; | ||
2355 | } | 2351 | } |
2356 | 2352 | ||
2357 | /* Initialize all port interrupt end point to port 0 int | 2353 | /* Initialize all port interrupt end point to port 0 int |
2358 | * endpoint. Our device has only one interrupt end point | 2354 | * endpoint. Our device has only one interrupt end point |
2359 | * common to all port */ | 2355 | * common to all port */ |
2360 | 2356 | ||
2361 | mos7840_port->port = serial->port[i]; | 2357 | mos7840_port->port = port; |
2362 | mos7840_set_port_private(serial->port[i], mos7840_port); | 2358 | mos7840_set_port_private(port, mos7840_port); |
2363 | spin_lock_init(&mos7840_port->pool_lock); | 2359 | spin_lock_init(&mos7840_port->pool_lock); |
2364 | 2360 | ||
2365 | /* minor is not initialised until later by | 2361 | /* minor is not initialised until later by |
2366 | * usb-serial.c:get_free_serial() and cannot therefore be used | 2362 | * usb-serial.c:get_free_serial() and cannot therefore be used |
2367 | * to index device instances */ | 2363 | * to index device instances */ |
2368 | mos7840_port->port_num = i + 1; | 2364 | mos7840_port->port_num = pnum + 1; |
2369 | dev_dbg(&dev->dev, "serial->port[i]->number = %d\n", serial->port[i]->number); | 2365 | dev_dbg(&port->dev, "port->number = %d\n", port->number); |
2370 | dev_dbg(&dev->dev, "serial->port[i]->serial->minor = %d\n", serial->port[i]->serial->minor); | 2366 | dev_dbg(&port->dev, "port->serial->minor = %d\n", port->serial->minor); |
2371 | dev_dbg(&dev->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num); | 2367 | dev_dbg(&port->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num); |
2372 | dev_dbg(&dev->dev, "serial->minor = %d\n", serial->minor); | 2368 | dev_dbg(&port->dev, "serial->minor = %d\n", serial->minor); |
2373 | 2369 | ||
2374 | if (mos7840_port->port_num == 1) { | 2370 | if (mos7840_port->port_num == 1) { |
2375 | mos7840_port->SpRegOffset = 0x0; | 2371 | mos7840_port->SpRegOffset = 0x0; |
@@ -2396,115 +2392,115 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2396 | mos7840_port->ControlRegOffset = 0xd; | 2392 | mos7840_port->ControlRegOffset = 0xd; |
2397 | mos7840_port->DcrRegOffset = 0x1c; | 2393 | mos7840_port->DcrRegOffset = 0x1c; |
2398 | } | 2394 | } |
2399 | mos7840_dump_serial_port(serial->port[i], mos7840_port); | 2395 | mos7840_dump_serial_port(port, mos7840_port); |
2400 | mos7840_set_port_private(serial->port[i], mos7840_port); | 2396 | mos7840_set_port_private(port, mos7840_port); |
2401 | 2397 | ||
2402 | /* enable rx_disable bit in control register */ | 2398 | /* enable rx_disable bit in control register */ |
2403 | status = mos7840_get_reg_sync(serial->port[i], | 2399 | status = mos7840_get_reg_sync(port, |
2404 | mos7840_port->ControlRegOffset, &Data); | 2400 | mos7840_port->ControlRegOffset, &Data); |
2405 | if (status < 0) { | 2401 | if (status < 0) { |
2406 | dev_dbg(&dev->dev, "Reading ControlReg failed status-0x%x\n", status); | 2402 | dev_dbg(&port->dev, "Reading ControlReg failed status-0x%x\n", status); |
2407 | break; | 2403 | break; |
2408 | } else | 2404 | } else |
2409 | dev_dbg(&dev->dev, "ControlReg Reading success val is %x, status%d\n", Data, status); | 2405 | dev_dbg(&port->dev, "ControlReg Reading success val is %x, status%d\n", Data, status); |
2410 | Data |= 0x08; /* setting driver done bit */ | 2406 | Data |= 0x08; /* setting driver done bit */ |
2411 | Data |= 0x04; /* sp1_bit to have cts change reflect in | 2407 | Data |= 0x04; /* sp1_bit to have cts change reflect in |
2412 | modem status reg */ | 2408 | modem status reg */ |
2413 | 2409 | ||
2414 | /* Data |= 0x20; //rx_disable bit */ | 2410 | /* Data |= 0x20; //rx_disable bit */ |
2415 | status = mos7840_set_reg_sync(serial->port[i], | 2411 | status = mos7840_set_reg_sync(port, |
2416 | mos7840_port->ControlRegOffset, Data); | 2412 | mos7840_port->ControlRegOffset, Data); |
2417 | if (status < 0) { | 2413 | if (status < 0) { |
2418 | dev_dbg(&dev->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status); | 2414 | dev_dbg(&port->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status); |
2419 | break; | 2415 | break; |
2420 | } else | 2416 | } else |
2421 | dev_dbg(&dev->dev, "ControlReg Writing success(rx_disable) status%d\n", status); | 2417 | dev_dbg(&port->dev, "ControlReg Writing success(rx_disable) status%d\n", status); |
2422 | 2418 | ||
2423 | /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 | 2419 | /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 |
2424 | and 0x24 in DCR3 */ | 2420 | and 0x24 in DCR3 */ |
2425 | Data = 0x01; | 2421 | Data = 0x01; |
2426 | status = mos7840_set_reg_sync(serial->port[i], | 2422 | status = mos7840_set_reg_sync(port, |
2427 | (__u16) (mos7840_port->DcrRegOffset + 0), Data); | 2423 | (__u16) (mos7840_port->DcrRegOffset + 0), Data); |
2428 | if (status < 0) { | 2424 | if (status < 0) { |
2429 | dev_dbg(&dev->dev, "Writing DCR0 failed status-0x%x\n", status); | 2425 | dev_dbg(&port->dev, "Writing DCR0 failed status-0x%x\n", status); |
2430 | break; | 2426 | break; |
2431 | } else | 2427 | } else |
2432 | dev_dbg(&dev->dev, "DCR0 Writing success status%d\n", status); | 2428 | dev_dbg(&port->dev, "DCR0 Writing success status%d\n", status); |
2433 | 2429 | ||
2434 | Data = 0x05; | 2430 | Data = 0x05; |
2435 | status = mos7840_set_reg_sync(serial->port[i], | 2431 | status = mos7840_set_reg_sync(port, |
2436 | (__u16) (mos7840_port->DcrRegOffset + 1), Data); | 2432 | (__u16) (mos7840_port->DcrRegOffset + 1), Data); |
2437 | if (status < 0) { | 2433 | if (status < 0) { |
2438 | dev_dbg(&dev->dev, "Writing DCR1 failed status-0x%x\n", status); | 2434 | dev_dbg(&port->dev, "Writing DCR1 failed status-0x%x\n", status); |
2439 | break; | 2435 | break; |
2440 | } else | 2436 | } else |
2441 | dev_dbg(&dev->dev, "DCR1 Writing success status%d\n", status); | 2437 | dev_dbg(&port->dev, "DCR1 Writing success status%d\n", status); |
2442 | 2438 | ||
2443 | Data = 0x24; | 2439 | Data = 0x24; |
2444 | status = mos7840_set_reg_sync(serial->port[i], | 2440 | status = mos7840_set_reg_sync(port, |
2445 | (__u16) (mos7840_port->DcrRegOffset + 2), Data); | 2441 | (__u16) (mos7840_port->DcrRegOffset + 2), Data); |
2446 | if (status < 0) { | 2442 | if (status < 0) { |
2447 | dev_dbg(&dev->dev, "Writing DCR2 failed status-0x%x\n", status); | 2443 | dev_dbg(&port->dev, "Writing DCR2 failed status-0x%x\n", status); |
2448 | break; | 2444 | break; |
2449 | } else | 2445 | } else |
2450 | dev_dbg(&dev->dev, "DCR2 Writing success status%d\n", status); | 2446 | dev_dbg(&port->dev, "DCR2 Writing success status%d\n", status); |
2451 | 2447 | ||
2452 | /* write values in clkstart0x0 and clkmulti 0x20 */ | 2448 | /* write values in clkstart0x0 and clkmulti 0x20 */ |
2453 | Data = 0x0; | 2449 | Data = 0x0; |
2454 | status = mos7840_set_reg_sync(serial->port[i], | 2450 | status = mos7840_set_reg_sync(port, |
2455 | CLK_START_VALUE_REGISTER, Data); | 2451 | CLK_START_VALUE_REGISTER, Data); |
2456 | if (status < 0) { | 2452 | if (status < 0) { |
2457 | dev_dbg(&dev->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status); | 2453 | dev_dbg(&port->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status); |
2458 | break; | 2454 | break; |
2459 | } else | 2455 | } else |
2460 | dev_dbg(&dev->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status); | 2456 | dev_dbg(&port->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status); |
2461 | 2457 | ||
2462 | Data = 0x20; | 2458 | Data = 0x20; |
2463 | status = mos7840_set_reg_sync(serial->port[i], | 2459 | status = mos7840_set_reg_sync(port, |
2464 | CLK_MULTI_REGISTER, Data); | 2460 | CLK_MULTI_REGISTER, Data); |
2465 | if (status < 0) { | 2461 | if (status < 0) { |
2466 | dev_dbg(&dev->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status); | 2462 | dev_dbg(&port->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status); |
2467 | goto error; | 2463 | goto error; |
2468 | } else | 2464 | } else |
2469 | dev_dbg(&dev->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status); | 2465 | dev_dbg(&port->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status); |
2470 | 2466 | ||
2471 | /* write value 0x0 to scratchpad register */ | 2467 | /* write value 0x0 to scratchpad register */ |
2472 | Data = 0x00; | 2468 | Data = 0x00; |
2473 | status = mos7840_set_uart_reg(serial->port[i], | 2469 | status = mos7840_set_uart_reg(port, |
2474 | SCRATCH_PAD_REGISTER, Data); | 2470 | SCRATCH_PAD_REGISTER, Data); |
2475 | if (status < 0) { | 2471 | if (status < 0) { |
2476 | dev_dbg(&dev->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status); | 2472 | dev_dbg(&port->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status); |
2477 | break; | 2473 | break; |
2478 | } else | 2474 | } else |
2479 | dev_dbg(&dev->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status); | 2475 | dev_dbg(&port->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status); |
2480 | 2476 | ||
2481 | /* Zero Length flag register */ | 2477 | /* Zero Length flag register */ |
2482 | if ((mos7840_port->port_num != 1) | 2478 | if ((mos7840_port->port_num != 1) |
2483 | && (serial->num_ports == 2)) { | 2479 | && (serial->num_ports == 2)) { |
2484 | 2480 | ||
2485 | Data = 0xff; | 2481 | Data = 0xff; |
2486 | status = mos7840_set_reg_sync(serial->port[i], | 2482 | status = mos7840_set_reg_sync(port, |
2487 | (__u16) (ZLP_REG1 + | 2483 | (__u16) (ZLP_REG1 + |
2488 | ((__u16)mos7840_port->port_num)), Data); | 2484 | ((__u16)mos7840_port->port_num)), Data); |
2489 | dev_dbg(&dev->dev, "ZLIP offset %x\n", | 2485 | dev_dbg(&port->dev, "ZLIP offset %x\n", |
2490 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num))); | 2486 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num))); |
2491 | if (status < 0) { | 2487 | if (status < 0) { |
2492 | dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 2, status); | 2488 | dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 2, status); |
2493 | break; | 2489 | break; |
2494 | } else | 2490 | } else |
2495 | dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 2, status); | 2491 | dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 2, status); |
2496 | } else { | 2492 | } else { |
2497 | Data = 0xff; | 2493 | Data = 0xff; |
2498 | status = mos7840_set_reg_sync(serial->port[i], | 2494 | status = mos7840_set_reg_sync(port, |
2499 | (__u16) (ZLP_REG1 + | 2495 | (__u16) (ZLP_REG1 + |
2500 | ((__u16)mos7840_port->port_num) - 0x1), Data); | 2496 | ((__u16)mos7840_port->port_num) - 0x1), Data); |
2501 | dev_dbg(&dev->dev, "ZLIP offset %x\n", | 2497 | dev_dbg(&port->dev, "ZLIP offset %x\n", |
2502 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1)); | 2498 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1)); |
2503 | if (status < 0) { | 2499 | if (status < 0) { |
2504 | dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 1, status); | 2500 | dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 1, status); |
2505 | break; | 2501 | break; |
2506 | } else | 2502 | } else |
2507 | dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 1, status); | 2503 | dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 1, status); |
2508 | 2504 | ||
2509 | } | 2505 | } |
2510 | mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); | 2506 | mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); |
@@ -2541,92 +2537,56 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2541 | mos7840_port->led_flag = false; | 2537 | mos7840_port->led_flag = false; |
2542 | 2538 | ||
2543 | /* Turn off LED */ | 2539 | /* Turn off LED */ |
2544 | mos7840_set_led_sync(serial->port[i], | 2540 | mos7840_set_led_sync(port, |
2545 | MODEM_CONTROL_REGISTER, 0x0300); | 2541 | MODEM_CONTROL_REGISTER, 0x0300); |
2546 | } | 2542 | } |
2547 | } | 2543 | } while (0); |
2548 | 2544 | ||
2549 | /* Zero Length flag enable */ | 2545 | if (pnum == serial->num_ports - 1) { |
2550 | Data = 0x0f; | 2546 | /* Zero Length flag enable */ |
2551 | status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); | 2547 | Data = 0x0f; |
2552 | if (status < 0) { | 2548 | status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); |
2553 | dev_dbg(&dev->dev, "Writing ZLP_REG5 failed status-0x%x\n", status); | 2549 | if (status < 0) { |
2554 | goto error; | 2550 | dev_dbg(&port->dev, "Writing ZLP_REG5 failed status-0x%x\n", status); |
2555 | } else | 2551 | goto error; |
2556 | dev_dbg(&dev->dev, "ZLP_REG5 Writing success status%d\n", status); | 2552 | } else |
2557 | 2553 | dev_dbg(&port->dev, "ZLP_REG5 Writing success status%d\n", status); | |
2558 | /* setting configuration feature to one */ | 2554 | |
2559 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 2555 | /* setting configuration feature to one */ |
2560 | (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT); | 2556 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
2557 | 0x03, 0x00, 0x01, 0x00, NULL, 0x00, | ||
2558 | MOS_WDR_TIMEOUT); | ||
2559 | } | ||
2561 | return 0; | 2560 | return 0; |
2562 | error: | 2561 | error: |
2563 | for (/* nothing */; i >= 0; i--) { | 2562 | kfree(mos7840_port->dr); |
2564 | mos7840_port = mos7840_get_port_private(serial->port[i]); | 2563 | kfree(mos7840_port->ctrl_buf); |
2564 | usb_free_urb(mos7840_port->control_urb); | ||
2565 | kfree(mos7840_port); | ||
2565 | 2566 | ||
2566 | kfree(mos7840_port->dr); | ||
2567 | kfree(mos7840_port->ctrl_buf); | ||
2568 | usb_free_urb(mos7840_port->control_urb); | ||
2569 | kfree(mos7840_port); | ||
2570 | } | ||
2571 | return status; | 2567 | return status; |
2572 | } | 2568 | } |
2573 | 2569 | ||
2574 | /**************************************************************************** | 2570 | static int mos7840_port_remove(struct usb_serial_port *port) |
2575 | * mos7840_disconnect | ||
2576 | * This function is called whenever the device is removed from the usb bus. | ||
2577 | ****************************************************************************/ | ||
2578 | |||
2579 | static void mos7840_disconnect(struct usb_serial *serial) | ||
2580 | { | 2571 | { |
2581 | int i; | ||
2582 | unsigned long flags; | ||
2583 | struct moschip_port *mos7840_port; | 2572 | struct moschip_port *mos7840_port; |
2584 | 2573 | ||
2585 | /* check for the ports to be closed,close the ports and disconnect */ | 2574 | mos7840_port = mos7840_get_port_private(port); |
2586 | 2575 | ||
2587 | /* free private structure allocated for serial port * | 2576 | if (mos7840_port->has_led) { |
2588 | * stop reads and writes on all ports */ | 2577 | /* Turn off LED */ |
2578 | mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300); | ||
2589 | 2579 | ||
2590 | for (i = 0; i < serial->num_ports; ++i) { | 2580 | del_timer_sync(&mos7840_port->led_timer1); |
2591 | mos7840_port = mos7840_get_port_private(serial->port[i]); | 2581 | del_timer_sync(&mos7840_port->led_timer2); |
2592 | if (mos7840_port) { | ||
2593 | usb_kill_urb(mos7840_port->control_urb); | ||
2594 | } | ||
2595 | } | 2582 | } |
2596 | } | 2583 | usb_kill_urb(mos7840_port->control_urb); |
2597 | 2584 | usb_free_urb(mos7840_port->control_urb); | |
2598 | /**************************************************************************** | 2585 | kfree(mos7840_port->ctrl_buf); |
2599 | * mos7840_release | 2586 | kfree(mos7840_port->dr); |
2600 | * This function is called when the usb_serial structure is freed. | 2587 | kfree(mos7840_port); |
2601 | ****************************************************************************/ | ||
2602 | |||
2603 | static void mos7840_release(struct usb_serial *serial) | ||
2604 | { | ||
2605 | int i; | ||
2606 | struct moschip_port *mos7840_port; | ||
2607 | 2588 | ||
2608 | /* check for the ports to be closed,close the ports and disconnect */ | 2589 | return 0; |
2609 | |||
2610 | /* free private structure allocated for serial port * | ||
2611 | * stop reads and writes on all ports */ | ||
2612 | |||
2613 | for (i = 0; i < serial->num_ports; ++i) { | ||
2614 | mos7840_port = mos7840_get_port_private(serial->port[i]); | ||
2615 | if (mos7840_port) { | ||
2616 | if (mos7840_port->has_led) { | ||
2617 | /* Turn off LED */ | ||
2618 | mos7840_set_led_sync(mos7840_port->port, | ||
2619 | MODEM_CONTROL_REGISTER, 0x0300); | ||
2620 | |||
2621 | del_timer_sync(&mos7840_port->led_timer1); | ||
2622 | del_timer_sync(&mos7840_port->led_timer2); | ||
2623 | } | ||
2624 | usb_free_urb(mos7840_port->control_urb); | ||
2625 | kfree(mos7840_port->ctrl_buf); | ||
2626 | kfree(mos7840_port->dr); | ||
2627 | kfree(mos7840_port); | ||
2628 | } | ||
2629 | } | ||
2630 | } | 2590 | } |
2631 | 2591 | ||
2632 | static struct usb_serial_driver moschip7840_4port_device = { | 2592 | static struct usb_serial_driver moschip7840_4port_device = { |
@@ -2654,9 +2614,8 @@ static struct usb_serial_driver moschip7840_4port_device = { | |||
2654 | .tiocmget = mos7840_tiocmget, | 2614 | .tiocmget = mos7840_tiocmget, |
2655 | .tiocmset = mos7840_tiocmset, | 2615 | .tiocmset = mos7840_tiocmset, |
2656 | .get_icount = mos7840_get_icount, | 2616 | .get_icount = mos7840_get_icount, |
2657 | .attach = mos7840_startup, | 2617 | .port_probe = mos7840_port_probe, |
2658 | .disconnect = mos7840_disconnect, | 2618 | .port_remove = mos7840_port_remove, |
2659 | .release = mos7840_release, | ||
2660 | .read_bulk_callback = mos7840_bulk_in_callback, | 2619 | .read_bulk_callback = mos7840_bulk_in_callback, |
2661 | .read_int_callback = mos7840_interrupt_callback, | 2620 | .read_int_callback = mos7840_interrupt_callback, |
2662 | }; | 2621 | }; |