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