V4L/DVB (9689): gspca: Memory leak when disconnect while streaming.

As a side effect, the sd routine stop0 is called on disconnect.
This permits the subdriver to free its resources.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by Jean-Francois Moine and committed by Mauro Carvalho Chehab 98522a7b 818a557e

+39 -10
+3
drivers/media/video/gspca/conex.c
··· 846 846 return 0; 847 847 } 848 848 849 + /* called on streamoff with alt 0 and on disconnect */ 849 850 static void sd_stop0(struct gspca_dev *gspca_dev) 850 851 { 851 852 int retry = 50; 852 853 854 + if (!gspca_dev->present) 855 + return; 853 856 reg_w_val(gspca_dev, 0x0000, 0x00); 854 857 reg_r(gspca_dev, 0x0002, 1); 855 858 reg_w_val(gspca_dev, 0x0053, 0x00);
+8
drivers/media/video/gspca/finepix.c
··· 276 276 /* Stop the state machine */ 277 277 if (dev->state != FPIX_NOP) 278 278 wait_for_completion(&dev->can_close); 279 + } 280 + 281 + /* called on streamoff with alt 0 and disconnect */ 282 + static void sd_stop0(struct gspca_dev *gspca_dev) 283 + { 284 + struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; 279 285 280 286 usb_free_urb(dev->control_urb); 281 287 dev->control_urb = NULL; ··· 391 385 error: 392 386 /* Free the ressources */ 393 387 sd_stopN(gspca_dev); 388 + sd_stop0(gspca_dev); 394 389 return ret; 395 390 } 396 391 ··· 432 425 .init = sd_init, 433 426 .start = sd_start, 434 427 .stopN = sd_stopN, 428 + .stop0 = sd_stop0, 435 429 }; 436 430 437 431 /* -- device connect -- */
+8 -9
drivers/media/video/gspca/gspca.c
··· 646 646 { 647 647 gspca_dev->streaming = 0; 648 648 atomic_set(&gspca_dev->nevent, 0); 649 - if (gspca_dev->present) { 650 - if (gspca_dev->sd_desc->stopN) 651 - gspca_dev->sd_desc->stopN(gspca_dev); 652 - destroy_urbs(gspca_dev); 653 - gspca_set_alt0(gspca_dev); 654 - if (gspca_dev->sd_desc->stop0) 655 - gspca_dev->sd_desc->stop0(gspca_dev); 656 - PDEBUG(D_STREAM, "stream off OK"); 657 - } 649 + if (gspca_dev->present 650 + && gspca_dev->sd_desc->stopN) 651 + gspca_dev->sd_desc->stopN(gspca_dev); 652 + destroy_urbs(gspca_dev); 653 + gspca_set_alt0(gspca_dev); 654 + if (gspca_dev->sd_desc->stop0) 655 + gspca_dev->sd_desc->stop0(gspca_dev); 656 + PDEBUG(D_STREAM, "stream off OK"); 658 657 } 659 658 660 659 static void gspca_set_default_mode(struct gspca_dev *gspca_dev)
+1 -1
drivers/media/video/gspca/gspca.h
··· 97 97 cam_pkt_op pkt_scan; 98 98 /* optional operations */ 99 99 cam_v_op stopN; /* called on stream off - main alt */ 100 - cam_v_op stop0; /* called on stream off - alt 0 */ 100 + cam_v_op stop0; /* called on stream off & disconnect - alt 0 */ 101 101 cam_v_op dq_callback; /* called when a frame has been dequeued */ 102 102 cam_jpg_op get_jcomp; 103 103 cam_jpg_op set_jcomp;
+3
drivers/media/video/gspca/pac7311.c
··· 749 749 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ 750 750 } 751 751 752 + /* called on streamoff with alt 0 and on disconnect */ 752 753 static void sd_stop0(struct gspca_dev *gspca_dev) 753 754 { 754 755 struct sd *sd = (struct sd *) gspca_dev; 755 756 757 + if (!gspca_dev->present) 758 + return; 756 759 if (sd->sensor == SENSOR_PAC7302) { 757 760 reg_w(gspca_dev, 0xff, 0x01); 758 761 reg_w(gspca_dev, 0x78, 0x40);
+3
drivers/media/video/gspca/spca501.c
··· 2022 2022 reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00); 2023 2023 } 2024 2024 2025 + /* called on streamoff with alt 0 and on disconnect */ 2025 2026 static void sd_stop0(struct gspca_dev *gspca_dev) 2026 2027 { 2028 + if (!gspca_dev->present) 2029 + return; 2027 2030 reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00); 2028 2031 } 2029 2032
+4
drivers/media/video/gspca/spca505.c
··· 742 742 reg_write(gspca_dev->dev, 0x02, 0x00, 0x00); 743 743 } 744 744 745 + /* called on streamoff with alt 0 and on disconnect */ 745 746 static void sd_stop0(struct gspca_dev *gspca_dev) 746 747 { 748 + if (!gspca_dev->present) 749 + return; 750 + 747 751 /* This maybe reset or power control */ 748 752 reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); 749 753 reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
+3
drivers/media/video/gspca/spca561.c
··· 766 766 } 767 767 } 768 768 769 + /* called on streamoff with alt 0 and on disconnect */ 769 770 static void sd_stop0(struct gspca_dev *gspca_dev) 770 771 { 771 772 struct sd *sd = (struct sd *) gspca_dev; 772 773 774 + if (!gspca_dev->present) 775 + return; 773 776 if (sd->chip_revision == Rev012A) { 774 777 reg_w_val(gspca_dev->dev, 0x8118, 0x29); 775 778 reg_w_val(gspca_dev->dev, 0x8114, 0x08);
+3
drivers/media/video/gspca/vc032x.c
··· 1633 1633 reg_w(dev, 0xa0, 0x09, 0xb003); 1634 1634 } 1635 1635 1636 + /* called on streamoff with alt 0 and on disconnect */ 1636 1637 static void sd_stop0(struct gspca_dev *gspca_dev) 1637 1638 { 1638 1639 struct usb_device *dev = gspca_dev->dev; 1639 1640 1641 + if (!gspca_dev->present) 1642 + return; 1640 1643 reg_w(dev, 0x89, 0xffff, 0xffff); 1641 1644 } 1642 1645
+3
drivers/media/video/gspca/zc3xx.c
··· 7336 7336 return 0; 7337 7337 } 7338 7338 7339 + /* called on streamoff with alt 0 and on disconnect */ 7339 7340 static void sd_stop0(struct gspca_dev *gspca_dev) 7340 7341 { 7341 7342 struct sd *sd = (struct sd *) gspca_dev; 7342 7343 7344 + if (!gspca_dev->present) 7345 + return; 7343 7346 send_unknown(gspca_dev->dev, sd->sensor); 7344 7347 } 7345 7348