diff options
author | Antti Palosaari <crope@iki.fi> | 2013-02-26 11:56:34 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-18 15:53:33 -0400 |
commit | 3484d37a66bb45dc9b4f70868b68739262bf6832 (patch) | |
tree | b47b999d6e826b941597325a3ee321823321108b | |
parent | aff8c2d475cb660ee246099dd15f269e9ebb7b1d (diff) |
[media] af9035: do not use buffers from stack for usb_bulk_msg()
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/af9035.c | 44 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/af9035.h | 2 |
2 files changed, 24 insertions, 22 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index d3cb8d55febc..66f65197c40d 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c | |||
@@ -41,43 +41,45 @@ static u16 af9035_checksum(const u8 *buf, size_t len) | |||
41 | 41 | ||
42 | static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req) | 42 | static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req) |
43 | { | 43 | { |
44 | #define BUF_LEN 64 | ||
45 | #define REQ_HDR_LEN 4 /* send header size */ | 44 | #define REQ_HDR_LEN 4 /* send header size */ |
46 | #define ACK_HDR_LEN 3 /* rece header size */ | 45 | #define ACK_HDR_LEN 3 /* rece header size */ |
47 | #define CHECKSUM_LEN 2 | 46 | #define CHECKSUM_LEN 2 |
48 | #define USB_TIMEOUT 2000 | 47 | #define USB_TIMEOUT 2000 |
49 | struct state *state = d_to_priv(d); | 48 | struct state *state = d_to_priv(d); |
50 | int ret, wlen, rlen; | 49 | int ret, wlen, rlen; |
51 | u8 buf[BUF_LEN]; | ||
52 | u16 checksum, tmp_checksum; | 50 | u16 checksum, tmp_checksum; |
53 | 51 | ||
52 | mutex_lock(&d->usb_mutex); | ||
53 | |||
54 | /* buffer overflow check */ | 54 | /* buffer overflow check */ |
55 | if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) || | 55 | if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) || |
56 | req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) { | 56 | req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) { |
57 | dev_err(&d->udev->dev, "%s: too much data wlen=%d rlen=%d\n", | 57 | dev_err(&d->udev->dev, "%s: too much data wlen=%d rlen=%d\n", |
58 | __func__, req->wlen, req->rlen); | 58 | __func__, req->wlen, req->rlen); |
59 | return -EINVAL; | 59 | ret = -EINVAL; |
60 | goto err; | ||
60 | } | 61 | } |
61 | 62 | ||
62 | buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1; | 63 | state->buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1; |
63 | buf[1] = req->mbox; | 64 | state->buf[1] = req->mbox; |
64 | buf[2] = req->cmd; | 65 | state->buf[2] = req->cmd; |
65 | buf[3] = state->seq++; | 66 | state->buf[3] = state->seq++; |
66 | memcpy(&buf[REQ_HDR_LEN], req->wbuf, req->wlen); | 67 | memcpy(&state->buf[REQ_HDR_LEN], req->wbuf, req->wlen); |
67 | 68 | ||
68 | wlen = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN; | 69 | wlen = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN; |
69 | rlen = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN; | 70 | rlen = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN; |
70 | 71 | ||
71 | /* calc and add checksum */ | 72 | /* calc and add checksum */ |
72 | checksum = af9035_checksum(buf, buf[0] - 1); | 73 | checksum = af9035_checksum(state->buf, state->buf[0] - 1); |
73 | buf[buf[0] - 1] = (checksum >> 8); | 74 | state->buf[state->buf[0] - 1] = (checksum >> 8); |
74 | buf[buf[0] - 0] = (checksum & 0xff); | 75 | state->buf[state->buf[0] - 0] = (checksum & 0xff); |
75 | 76 | ||
76 | /* no ack for these packets */ | 77 | /* no ack for these packets */ |
77 | if (req->cmd == CMD_FW_DL) | 78 | if (req->cmd == CMD_FW_DL) |
78 | rlen = 0; | 79 | rlen = 0; |
79 | 80 | ||
80 | ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen); | 81 | ret = dvb_usbv2_generic_rw_locked(d, |
82 | state->buf, wlen, state->buf, rlen); | ||
81 | if (ret) | 83 | if (ret) |
82 | goto err; | 84 | goto err; |
83 | 85 | ||
@@ -86,8 +88,8 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req) | |||
86 | goto exit; | 88 | goto exit; |
87 | 89 | ||
88 | /* verify checksum */ | 90 | /* verify checksum */ |
89 | checksum = af9035_checksum(buf, rlen - 2); | 91 | checksum = af9035_checksum(state->buf, rlen - 2); |
90 | tmp_checksum = (buf[rlen - 2] << 8) | buf[rlen - 1]; | 92 | tmp_checksum = (state->buf[rlen - 2] << 8) | state->buf[rlen - 1]; |
91 | if (tmp_checksum != checksum) { | 93 | if (tmp_checksum != checksum) { |
92 | dev_err(&d->udev->dev, "%s: command=%02x checksum mismatch " \ | 94 | dev_err(&d->udev->dev, "%s: command=%02x checksum mismatch " \ |
93 | "(%04x != %04x)\n", KBUILD_MODNAME, req->cmd, | 95 | "(%04x != %04x)\n", KBUILD_MODNAME, req->cmd, |
@@ -97,23 +99,21 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req) | |||
97 | } | 99 | } |
98 | 100 | ||
99 | /* check status */ | 101 | /* check status */ |
100 | if (buf[2]) { | 102 | if (state->buf[2]) { |
101 | dev_dbg(&d->udev->dev, "%s: command=%02x failed fw error=%d\n", | 103 | dev_dbg(&d->udev->dev, "%s: command=%02x failed fw error=%d\n", |
102 | __func__, req->cmd, buf[2]); | 104 | __func__, req->cmd, state->buf[2]); |
103 | ret = -EIO; | 105 | ret = -EIO; |
104 | goto err; | 106 | goto err; |
105 | } | 107 | } |
106 | 108 | ||
107 | /* read request, copy returned data to return buf */ | 109 | /* read request, copy returned data to return buf */ |
108 | if (req->rlen) | 110 | if (req->rlen) |
109 | memcpy(req->rbuf, &buf[ACK_HDR_LEN], req->rlen); | 111 | memcpy(req->rbuf, &state->buf[ACK_HDR_LEN], req->rlen); |
110 | |||
111 | exit: | 112 | exit: |
112 | return 0; | ||
113 | |||
114 | err: | 113 | err: |
115 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | 114 | mutex_unlock(&d->usb_mutex); |
116 | 115 | if (ret) | |
116 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | ||
117 | return ret; | 117 | return ret; |
118 | } | 118 | } |
119 | 119 | ||
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index 29f3eec22c2c..6d098a93d5ab 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h | |||
@@ -52,6 +52,8 @@ struct usb_req { | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | struct state { | 54 | struct state { |
55 | #define BUF_LEN 64 | ||
56 | u8 buf[BUF_LEN]; | ||
55 | u8 seq; /* packet sequence number */ | 57 | u8 seq; /* packet sequence number */ |
56 | bool dual_mode; | 58 | bool dual_mode; |
57 | struct af9033_config af9033_config[2]; | 59 | struct af9033_config af9033_config[2]; |