Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 173940
b: refs/heads/master
c: 8519110
h: refs/heads/master
v: v3
  • Loading branch information
Hans de Goede authored and Mauro Carvalho Chehab committed Dec 5, 2009
1 parent 66fa373 commit c93e6a9
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 31 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 930bf78c20187f3cbbf0775cd317616c6b681a8a
refs/heads/master: 8519110040ca98dfbc89c473921cca390c81460c
56 changes: 26 additions & 30 deletions trunk/drivers/media/video/gspca/sq905.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,22 @@ static int sq905_ack_frame(struct gspca_dev *gspca_dev)
* request and read a block of data - see warning on sq905_command.
*/
static int
sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size)
sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock)
{
int ret;
int act_len;

gspca_dev->usb_buf[0] = '\0';
if (need_lock)
mutex_lock(&gspca_dev->usb_lock);
ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
USB_REQ_SYNCH_FRAME, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
SQ905_BULK_READ, size, gspca_dev->usb_buf,
1, SQ905_CMD_TIMEOUT);
if (need_lock)
mutex_unlock(&gspca_dev->usb_lock);
if (ret < 0) {
PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
return ret;
Expand Down Expand Up @@ -214,15 +218,13 @@ static void sq905_dostream(struct work_struct *work)
int bytes_left; /* bytes remaining in current frame. */
int data_len; /* size to use for the next read. */
int header_read; /* true if we have already read the frame header. */
int discarding; /* true if we failed to get space for frame. */
int packet_type;
int frame_sz;
int ret;
u8 *data;
u8 *buffer;

buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
mutex_lock(&gspca_dev->usb_lock);
if (!buffer) {
PDEBUG(D_ERR, "Couldn't allocate USB buffer");
goto quit_stream;
Expand All @@ -232,28 +234,22 @@ static void sq905_dostream(struct work_struct *work)
+ FRAME_HEADER_LEN;

while (gspca_dev->present && gspca_dev->streaming) {
/* Need a short delay to ensure streaming flag was set by
* gspca and to make sure gspca can grab the mutex. */
mutex_unlock(&gspca_dev->usb_lock);
msleep(1);

/* request some data and then read it until we have
* a complete frame. */
bytes_left = frame_sz;
header_read = 0;
discarding = 0;

while (bytes_left > 0) {
/* Note we do not check for gspca_dev->streaming here, as
we must finish reading an entire frame, otherwise the
next time we stream we start reading in the middle of a
frame. */
while (bytes_left > 0 && gspca_dev->present) {
data_len = bytes_left > SQ905_MAX_TRANSFER ?
SQ905_MAX_TRANSFER : bytes_left;
mutex_lock(&gspca_dev->usb_lock);
if (!gspca_dev->present)
goto quit_stream;
ret = sq905_read_data(gspca_dev, buffer, data_len);
ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
if (ret < 0)
goto quit_stream;
mutex_unlock(&gspca_dev->usb_lock);
PDEBUG(D_STREAM,
PDEBUG(D_PACK,
"Got %d bytes out of %d for frame",
data_len, bytes_left);
bytes_left -= data_len;
Expand All @@ -271,7 +267,7 @@ static void sq905_dostream(struct work_struct *work)
packet_type = INTER_PACKET;
}
frame = gspca_get_i_frame(gspca_dev);
if (frame && !discarding) {
if (frame) {
frame = gspca_frame_add(gspca_dev, packet_type,
frame, data, data_len);
/* If entire frame fits in one packet we still
Expand All @@ -281,23 +277,23 @@ static void sq905_dostream(struct work_struct *work)
frame = gspca_frame_add(gspca_dev,
LAST_PACKET,
frame, data, 0);
} else {
discarding = 1;
}
}
/* acknowledge the frame */
mutex_lock(&gspca_dev->usb_lock);
if (!gspca_dev->present)
goto quit_stream;
ret = sq905_ack_frame(gspca_dev);
if (ret < 0)
goto quit_stream;
if (gspca_dev->present) {
/* acknowledge the frame */
mutex_lock(&gspca_dev->usb_lock);
ret = sq905_ack_frame(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
if (ret < 0)
goto quit_stream;
}
}
quit_stream:
/* the usb_lock is already acquired */
if (gspca_dev->present)
if (gspca_dev->present) {
mutex_lock(&gspca_dev->usb_lock);
sq905_command(gspca_dev, SQ905_CLEAR);
mutex_unlock(&gspca_dev->usb_lock);
mutex_unlock(&gspca_dev->usb_lock);
}
kfree(buffer);
}

Expand Down Expand Up @@ -346,7 +342,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
ret = sq905_command(gspca_dev, SQ905_ID);
if (ret < 0)
return ret;
ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4);
ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4, 0);
if (ret < 0)
return ret;
/* usb_buf is allocated with kmalloc so is aligned.
Expand Down

0 comments on commit c93e6a9

Please sign in to comment.