diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-03-09 07:59:16 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-24 11:41:27 -0400 |
commit | 9b6ebf3309d1b2e62727133b446397a783813331 (patch) | |
tree | 31d5d570c5d117fdbbcf5a2d64e7e708bef267d4 | |
parent | fabfd71153c7e98aca77c8069a633f3a25bcdaf7 (diff) |
[media] go7007: fix DMA related errors
- Don't pass data allocated on the stack to usb_control_msg.
- Use dma_mapping_error after calling dma_map_page().
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/staging/media/go7007/go7007-priv.h | 1 | ||||
-rw-r--r-- | drivers/staging/media/go7007/go7007-usb.c | 36 | ||||
-rw-r--r-- | drivers/staging/media/go7007/s2250-board.c | 2 | ||||
-rw-r--r-- | drivers/staging/media/go7007/saa7134-go7007.c | 4 |
4 files changed, 20 insertions, 23 deletions
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index 1c4b049bd551..daae6ddc4689 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h | |||
@@ -188,6 +188,7 @@ struct go7007 { | |||
188 | int audio_enabled; | 188 | int audio_enabled; |
189 | struct v4l2_subdev *sd_video; | 189 | struct v4l2_subdev *sd_video; |
190 | struct v4l2_subdev *sd_audio; | 190 | struct v4l2_subdev *sd_audio; |
191 | u8 usb_buf[16]; | ||
191 | 192 | ||
192 | /* Video input */ | 193 | /* Video input */ |
193 | int input; | 194 | int input; |
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index 0b1af508cd2b..f49672064c06 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c | |||
@@ -652,7 +652,7 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go, | |||
652 | { | 652 | { |
653 | struct go7007_usb *usb = go->hpi_context; | 653 | struct go7007_usb *usb = go->hpi_context; |
654 | int i, r; | 654 | int i, r; |
655 | u16 status_reg; | 655 | u16 status_reg = 0; |
656 | int timeout = 500; | 656 | int timeout = 500; |
657 | 657 | ||
658 | #ifdef GO7007_USB_DEBUG | 658 | #ifdef GO7007_USB_DEBUG |
@@ -664,15 +664,17 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go, | |||
664 | r = usb_control_msg(usb->usbdev, | 664 | r = usb_control_msg(usb->usbdev, |
665 | usb_rcvctrlpipe(usb->usbdev, 0), 0x14, | 665 | usb_rcvctrlpipe(usb->usbdev, 0), 0x14, |
666 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, | 666 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
667 | 0, HPI_STATUS_ADDR, &status_reg, | 667 | 0, HPI_STATUS_ADDR, go->usb_buf, |
668 | sizeof(status_reg), timeout); | 668 | sizeof(status_reg), timeout); |
669 | if (r < 0) | 669 | if (r < 0) |
670 | goto write_int_error; | 670 | break; |
671 | __le16_to_cpus(&status_reg); | 671 | status_reg = le16_to_cpu(*((u16 *)go->usb_buf)); |
672 | if (!(status_reg & 0x0010)) | 672 | if (!(status_reg & 0x0010)) |
673 | break; | 673 | break; |
674 | msleep(10); | 674 | msleep(10); |
675 | } | 675 | } |
676 | if (r < 0) | ||
677 | goto write_int_error; | ||
676 | if (i == 100) { | 678 | if (i == 100) { |
677 | printk(KERN_ERR | 679 | printk(KERN_ERR |
678 | "go7007-usb: device is hung, status reg = 0x%04x\n", | 680 | "go7007-usb: device is hung, status reg = 0x%04x\n", |
@@ -700,7 +702,6 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go, | |||
700 | int addr, int data) | 702 | int addr, int data) |
701 | { | 703 | { |
702 | struct go7007_usb *usb = go->hpi_context; | 704 | struct go7007_usb *usb = go->hpi_context; |
703 | u8 *tbuf; | ||
704 | int r; | 705 | int r; |
705 | int timeout = 500; | 706 | int timeout = 500; |
706 | 707 | ||
@@ -709,17 +710,14 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go, | |||
709 | "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data); | 710 | "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data); |
710 | #endif | 711 | #endif |
711 | 712 | ||
712 | tbuf = kzalloc(8, GFP_KERNEL); | 713 | go->usb_buf[0] = data & 0xff; |
713 | if (tbuf == NULL) | 714 | go->usb_buf[1] = data >> 8; |
714 | return -ENOMEM; | 715 | go->usb_buf[2] = addr & 0xff; |
715 | tbuf[0] = data & 0xff; | 716 | go->usb_buf[3] = addr >> 8; |
716 | tbuf[1] = data >> 8; | 717 | go->usb_buf[4] = go->usb_buf[5] = go->usb_buf[6] = go->usb_buf[7] = 0; |
717 | tbuf[2] = addr & 0xff; | ||
718 | tbuf[3] = addr >> 8; | ||
719 | r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 2), 0x00, | 718 | r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 2), 0x00, |
720 | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa, | 719 | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa, |
721 | 0xf0f0, tbuf, 8, timeout); | 720 | 0xf0f0, go->usb_buf, 8, timeout); |
722 | kfree(tbuf); | ||
723 | if (r < 0) { | 721 | if (r < 0) { |
724 | printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r); | 722 | printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r); |
725 | return r; | 723 | return r; |
@@ -913,7 +911,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter, | |||
913 | { | 911 | { |
914 | struct go7007 *go = i2c_get_adapdata(adapter); | 912 | struct go7007 *go = i2c_get_adapdata(adapter); |
915 | struct go7007_usb *usb = go->hpi_context; | 913 | struct go7007_usb *usb = go->hpi_context; |
916 | u8 buf[16]; | 914 | u8 *buf = go->usb_buf; |
917 | int buf_len, i; | 915 | int buf_len, i; |
918 | int ret = -EIO; | 916 | int ret = -EIO; |
919 | 917 | ||
@@ -1169,14 +1167,12 @@ static int go7007_usb_probe(struct usb_interface *intf, | |||
1169 | 1167 | ||
1170 | /* Probe the tuner model on the TV402U */ | 1168 | /* Probe the tuner model on the TV402U */ |
1171 | if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) { | 1169 | if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) { |
1172 | u8 data[3]; | ||
1173 | |||
1174 | /* Board strapping indicates tuner model */ | 1170 | /* Board strapping indicates tuner model */ |
1175 | if (go7007_usb_vendor_request(go, 0x41, 0, 0, data, 3, 1) < 0) { | 1171 | if (go7007_usb_vendor_request(go, 0x41, 0, 0, go->usb_buf, 3, 1) < 0) { |
1176 | printk(KERN_ERR "go7007-usb: GPIO read failed!\n"); | 1172 | printk(KERN_ERR "go7007-usb: GPIO read failed!\n"); |
1177 | goto initfail; | 1173 | goto initfail; |
1178 | } | 1174 | } |
1179 | switch (data[0] >> 6) { | 1175 | switch (go->usb_buf[0] >> 6) { |
1180 | case 1: | 1176 | case 1: |
1181 | go->board_id = GO7007_BOARDID_PX_TV402U_EU; | 1177 | go->board_id = GO7007_BOARDID_PX_TV402U_EU; |
1182 | go->tuner_type = TUNER_SONY_BTF_PG472Z; | 1178 | go->tuner_type = TUNER_SONY_BTF_PG472Z; |
@@ -1309,8 +1305,8 @@ static void go7007_usb_disconnect(struct usb_interface *intf) | |||
1309 | 1305 | ||
1310 | kfree(go->hpi_context); | 1306 | kfree(go->hpi_context); |
1311 | 1307 | ||
1312 | go7007_remove(go); | ||
1313 | go->status = STATUS_SHUTDOWN; | 1308 | go->status = STATUS_SHUTDOWN; |
1309 | go7007_remove(go); | ||
1314 | } | 1310 | } |
1315 | 1311 | ||
1316 | static struct usb_driver go7007_usb_driver = { | 1312 | static struct usb_driver go7007_usb_driver = { |
diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c index 37400bfa6ccb..2266e1b197cd 100644 --- a/drivers/staging/media/go7007/s2250-board.c +++ b/drivers/staging/media/go7007/s2250-board.c | |||
@@ -584,7 +584,7 @@ static int s2250_probe(struct i2c_client *client, | |||
584 | if (audio == NULL) | 584 | if (audio == NULL) |
585 | return -ENOMEM; | 585 | return -ENOMEM; |
586 | 586 | ||
587 | state = kmalloc(sizeof(struct s2250), GFP_KERNEL); | 587 | state = kzalloc(sizeof(struct s2250), GFP_KERNEL); |
588 | if (state == NULL) { | 588 | if (state == NULL) { |
589 | i2c_unregister_device(audio); | 589 | i2c_unregister_device(audio); |
590 | return -ENOMEM; | 590 | return -ENOMEM; |
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c index d65e17ace495..afe21f3f0959 100644 --- a/drivers/staging/media/go7007/saa7134-go7007.c +++ b/drivers/staging/media/go7007/saa7134-go7007.c | |||
@@ -261,12 +261,12 @@ static int saa7134_go7007_stream_start(struct go7007 *go) | |||
261 | 261 | ||
262 | saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top), | 262 | saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top), |
263 | 0, PAGE_SIZE, DMA_FROM_DEVICE); | 263 | 0, PAGE_SIZE, DMA_FROM_DEVICE); |
264 | if (!saa->top_dma) | 264 | if (dma_mapping_error(&dev->pci->dev, saa->top_dma)) |
265 | return -ENOMEM; | 265 | return -ENOMEM; |
266 | saa->bottom_dma = dma_map_page(&dev->pci->dev, | 266 | saa->bottom_dma = dma_map_page(&dev->pci->dev, |
267 | virt_to_page(saa->bottom), | 267 | virt_to_page(saa->bottom), |
268 | 0, PAGE_SIZE, DMA_FROM_DEVICE); | 268 | 0, PAGE_SIZE, DMA_FROM_DEVICE); |
269 | if (!saa->bottom_dma) { | 269 | if (dma_mapping_error(&dev->pci->dev, saa->bottom_dma)) { |
270 | dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE, | 270 | dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE, |
271 | DMA_FROM_DEVICE); | 271 | DMA_FROM_DEVICE); |
272 | return -ENOMEM; | 272 | return -ENOMEM; |