Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (25 commits)
  em28xx: remove backward compat macro added on a previous fix
  V4L/DVB (9748): em28xx: fix compile warning
  V4L/DVB (9743): em28xx: fix oops audio
  V4L/DVB (9742): em28xx-alsa: implement another locking schema
  V4L/DVB (9732): sms1xxx: use new firmware for Hauppauge WinTV MiniStick
  V4L/DVB (9691): gspca: Move the video device to a separate area.
  V4L/DVB (9690): gspca: Lock the subdrivers via module_get/put.
  V4L/DVB (9689): gspca: Memory leak when disconnect while streaming.
  V4L/DVB (9668): em28xx: fix a race condition with hald
  V4L/DVB (9664): af9015: don't reconnect device in USB-bus
  V4L/DVB (9647): em28xx: void having two concurrent control URB's
  V4L/DVB (9646): em28xx: avoid allocating/dealocating memory on every control urb
  V4L/DVB (9645): em28xx: Avoid memory leaks if registration fails
  V4L/DVB (9639): Make dib0700 remote control support work with firmware v1.20
  V4L/DVB (9635): v4l: s2255drv fix firmware test on big-endian
  V4L/DVB (9634): Make sure the i2c gate is open before powering down tuner
  V4L/DVB (9632): make em28xx aux audio input work
  V4L/DVB (9631): Make s2api work for ATSC support
  V4L/DVB (9627): em28xx: Avoid i2c register error for boards without eeprom
  V4L/DVB (9608): Fix section mismatch warning for dm1105 during make
  ...
This commit is contained in:
Linus Torvalds 2008-12-01 19:56:34 -08:00
commit 0d815142d1
26 changed files with 410 additions and 149 deletions

View File

@ -376,7 +376,7 @@ static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb)
pci_free_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, dm1105dvb->ts_buf, dm1105dvb->dma_addr);
}
static void __devinit dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb)
static void dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb)
{
outb(INTMAK_ALLMASK, dm_io_mem(DM1105_INTMAK));
outb(1, dm_io_mem(DM1105_CR));

View File

@ -585,6 +585,8 @@ restart:
if (fe->ops.set_voltage)
fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
if (fe->ops.tuner_ops.sleep) {
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
fe->ops.tuner_ops.sleep(fe);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@ -934,7 +936,8 @@ void dtv_property_dump(struct dtv_property *tvp)
int is_legacy_delivery_system(fe_delivery_system_t s)
{
if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) ||
(s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS))
(s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS) ||
(s == SYS_ATSC))
return 1;
return 0;

View File

@ -681,12 +681,6 @@ static int af9015_download_firmware(struct usb_device *udev,
goto error;
}
/* firmware is running, reconnect device in the usb bus */
req.cmd = RECONNECT_USB;
ret = af9015_rw_udev(udev, &req);
if (ret)
err("reconnect failed: %d", ret);
error:
return ret;
}
@ -1208,6 +1202,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.usb_ctrl = DEVICE_SPECIFIC,
.download_firmware = af9015_download_firmware,
.firmware = "dvb-usb-af9015.fw",
.no_reconnect = 1,
.size_of_priv = sizeof(struct af9015_state), \
@ -1306,6 +1301,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.usb_ctrl = DEVICE_SPECIFIC,
.download_firmware = af9015_download_firmware,
.firmware = "dvb-usb-af9015.fw",
.no_reconnect = 1,
.size_of_priv = sizeof(struct af9015_state), \

View File

@ -22,7 +22,7 @@ extern int dvb_usb_dib0700_debug;
#define REQUEST_I2C_READ 0x2
#define REQUEST_I2C_WRITE 0x3
#define REQUEST_POLL_RC 0x4
#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
#define REQUEST_JUMPRAM 0x8
#define REQUEST_SET_CLOCK 0xB
#define REQUEST_SET_GPIO 0xC
@ -40,11 +40,14 @@ struct dib0700_state {
u16 mt2060_if1[2];
u8 rc_toggle;
u8 rc_counter;
u8 rc_func_version;
u8 is_dib7000pc;
u8 fw_use_new_i2c_api;
u8 disable_streaming_master_mode;
};
extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
u32 *romversion, u32 *ramversion, u32 *fwtype);
extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3);
extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen);

View File

@ -19,6 +19,22 @@ MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (defau
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
u32 *romversion, u32 *ramversion, u32 *fwtype)
{
u8 b[16];
int ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
REQUEST_GET_VERSION,
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
b, sizeof(b), USB_CTRL_GET_TIMEOUT);
*hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
*romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7];
*ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
*fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
return ret;
}
/* expecting rx buffer: request data[0] data[1] ... data[2] */
static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
{

View File

@ -38,6 +38,7 @@ static struct mt2060_config bristol_mt2060_config[2] = {
}
};
static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
.band_caps = BAND_VHF | BAND_UHF,
.setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
@ -451,8 +452,13 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
/* Number of keypresses to ignore before start repeating */
#define RC_REPEAT_DELAY 2
#define RC_REPEAT_DELAY_V1_20 5
static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
/* Used by firmware versions < 1.20 (deprecated) */
static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
int *state)
{
u8 key[4];
int i;
@ -529,6 +535,137 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
return 0;
}
/* This is the structure of the RC response packet starting in firmware 1.20 */
struct dib0700_rc_response {
u8 report_id;
u8 data_state;
u8 system_msb;
u8 system_lsb;
u8 data;
u8 not_data;
};
/* This supports the new IR response format for firmware v1.20 */
static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
int *state)
{
struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
struct dib0700_state *st = d->priv;
struct dib0700_rc_response poll_reply;
u8 buf[6];
int i;
int status;
int actlen;
int found = 0;
/* Set initial results in case we exit the function early */
*event = 0;
*state = REMOTE_NO_KEY_PRESSED;
/* Firmware v1.20 provides RC data via bulk endpoint 1 */
status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf,
sizeof(buf), &actlen, 50);
if (status < 0) {
/* No data available (meaning no key press) */
return 0;
}
if (actlen != sizeof(buf)) {
/* We didn't get back the 6 byte message we expected */
err("Unexpected RC response size [%d]", actlen);
return -1;
}
poll_reply.report_id = buf[0];
poll_reply.data_state = buf[1];
poll_reply.system_msb = buf[2];
poll_reply.system_lsb = buf[3];
poll_reply.data = buf[4];
poll_reply.not_data = buf[5];
/*
info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n",
poll_reply.report_id, poll_reply.data_state,
poll_reply.system_msb, poll_reply.system_lsb,
poll_reply.data, poll_reply.not_data);
*/
if ((poll_reply.data + poll_reply.not_data) != 0xff) {
/* Key failed integrity check */
err("key failed integrity check: %02x %02x %02x %02x",
poll_reply.system_msb, poll_reply.system_lsb,
poll_reply.data, poll_reply.not_data);
return -1;
}
/* Find the key in the map */
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (keymap[i].custom == poll_reply.system_lsb &&
keymap[i].data == poll_reply.data) {
*event = keymap[i].event;
found = 1;
break;
}
}
if (found == 0) {
err("Unknown remote controller key: %02x %02x %02x %02x",
poll_reply.system_msb, poll_reply.system_lsb,
poll_reply.data, poll_reply.not_data);
d->last_event = 0;
return 0;
}
if (poll_reply.data_state == 1) {
/* New key hit */
st->rc_counter = 0;
*event = keymap[i].event;
*state = REMOTE_KEY_PRESSED;
d->last_event = keymap[i].event;
} else if (poll_reply.data_state == 2) {
/* Key repeated */
st->rc_counter++;
/* prevents unwanted double hits */
if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
*event = d->last_event;
*state = REMOTE_KEY_PRESSED;
st->rc_counter = RC_REPEAT_DELAY_V1_20;
}
} else {
err("Unknown data state [%d]", poll_reply.data_state);
}
return 0;
}
static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
struct dib0700_state *st = d->priv;
/* Because some people may have improperly named firmware files,
let's figure out whether to use the new firmware call or the legacy
call based on the firmware version embedded in the file */
if (st->rc_func_version == 0) {
u32 hwver, romver, ramver, fwtype;
int ret = dib0700_get_version(d, &hwver, &romver, &ramver,
&fwtype);
if (ret < 0) {
err("Could not determine version info");
return -1;
}
if (ramver < 0x10200)
st->rc_func_version = 1;
else
st->rc_func_version = 2;
}
if (st->rc_func_version == 2)
return dib0700_rc_query_v1_20(d, event, state);
else
return dib0700_rc_query_legacy(d, event, state);
}
static struct dvb_usb_rc_key dib0700_rc_keys[] = {
/* Key codes for the tiny Pinnacle remote*/
{ 0x07, 0x00, KEY_MUTE },

View File

@ -135,7 +135,7 @@ stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num])
static int usb_bulk_urb_init(struct usb_data_stream *stream)
{
int i;
int i, j;
if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
stream->props.u.bulk.buffersize)) < 0)
@ -143,9 +143,13 @@ static int usb_bulk_urb_init(struct usb_data_stream *stream)
/* allocate the URBs */
for (i = 0; i < stream->props.count; i++) {
if ((stream->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
if (!stream->urb_list[i]) {
deb_mem("not enough memory for urb_alloc_urb!.\n");
for (j = 0; j < i; j++)
usb_free_urb(stream->urb_list[i]);
return -ENOMEM;
}
usb_fill_bulk_urb( stream->urb_list[i], stream->udev,
usb_rcvbulkpipe(stream->udev,stream->props.endpoint),
stream->buf_list[i],
@ -170,9 +174,14 @@ static int usb_isoc_urb_init(struct usb_data_stream *stream)
for (i = 0; i < stream->props.count; i++) {
struct urb *urb;
int frame_offset = 0;
if ((stream->urb_list[i] =
usb_alloc_urb(stream->props.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_ATOMIC);
if (!stream->urb_list[i]) {
deb_mem("not enough memory for urb_alloc_urb!\n");
for (j = 0; j < i; j++)
usb_free_urb(stream->urb_list[i]);
return -ENOMEM;
}
urb = stream->urb_list[i];

View File

@ -95,7 +95,7 @@ static struct sms_board sms_boards[] = {
[SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
.name = "Hauppauge WinTV MiniStick",
.type = SMS_NOVA_B0,
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-01.fw",
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
},
};

View File

@ -808,6 +808,12 @@ static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
ISO_BUF_COUNT,
&ttusb->iso_dma_handle);
if (!ttusb->iso_buffer) {
dprintk("%s: pci_alloc_consistent - not enough memory\n",
__func__);
return -ENOMEM;
}
memset(ttusb->iso_buffer, 0,
ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
@ -1659,7 +1665,14 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
ttusb_setup_interfaces(ttusb);
ttusb_alloc_iso_urbs(ttusb);
result = ttusb_alloc_iso_urbs(ttusb);
if (result < 0) {
dprintk("%s: ttusb_alloc_iso_urbs - failed\n", __func__);
mutex_unlock(&ttusb->semi2c);
kfree(ttusb);
return result;
}
if (ttusb_init_controller(ttusb))
printk("ttusb_init_controller: error\n");

View File

@ -1157,6 +1157,12 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
ISO_BUF_COUNT),
&dec->iso_dma_handle);
if (!dec->iso_buffer) {
dprintk("%s: pci_alloc_consistent - not enough memory\n",
__func__);
return -ENOMEM;
}
memset(dec->iso_buffer, 0,
ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT));
@ -1254,6 +1260,7 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec)
dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE,
GFP_ATOMIC, &dec->irq_dma_handle);
if(!dec->irq_buffer) {
usb_free_urb(dec->irq_urb);
return -ENOMEM;
}
usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,

View File

@ -62,7 +62,7 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev)
dprintk("Stopping isoc\n");
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
usb_kill_urb(dev->adev->urb[i]);
usb_unlink_urb(dev->adev->urb[i]);
usb_free_urb(dev->adev->urb[i]);
dev->adev->urb[i] = NULL;
}
@ -75,7 +75,6 @@ static void em28xx_audio_isocirq(struct urb *urb)
struct em28xx *dev = urb->context;
int i;
unsigned int oldptr;
unsigned long flags;
int period_elapsed = 0;
int status;
unsigned char *cp;
@ -96,9 +95,21 @@ static void em28xx_audio_isocirq(struct urb *urb)
if (!length)
continue;
spin_lock_irqsave(&dev->adev->slock, flags);
oldptr = dev->adev->hwptr_done_capture;
if (oldptr + length >= runtime->buffer_size) {
unsigned int cnt =
runtime->buffer_size - oldptr;
memcpy(runtime->dma_area + oldptr * stride, cp,
cnt * stride);
memcpy(runtime->dma_area, cp + cnt * stride,
length * stride - cnt * stride);
} else {
memcpy(runtime->dma_area + oldptr * stride, cp,
length * stride);
}
snd_pcm_stream_lock(substream);
dev->adev->hwptr_done_capture += length;
if (dev->adev->hwptr_done_capture >=
runtime->buffer_size)
@ -113,19 +124,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
period_elapsed = 1;
}
spin_unlock_irqrestore(&dev->adev->slock, flags);
if (oldptr + length >= runtime->buffer_size) {
unsigned int cnt =
runtime->buffer_size - oldptr;
memcpy(runtime->dma_area + oldptr * stride, cp,
cnt * stride);
memcpy(runtime->dma_area, cp + cnt * stride,
length * stride - cnt * stride);
} else {
memcpy(runtime->dma_area + oldptr * stride, cp,
length * stride);
}
snd_pcm_stream_unlock(substream);
}
if (period_elapsed)
snd_pcm_period_elapsed(substream);

View File

@ -69,19 +69,33 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
int ret, byte;
if (dev->state & DEV_DISCONNECTED)
return(-ENODEV);
return -ENODEV;
if (len > URB_MAX_CTRL_SIZE)
return -EINVAL;
em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
mutex_lock(&dev->ctrl_urb_lock);
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x0000, reg, buf, len, HZ);
0x0000, reg, dev->urb_buf, len, HZ);
if (ret < 0) {
if (reg_debug)
printk(" failed!\n");
mutex_unlock(&dev->ctrl_urb_lock);
return ret;
}
if (len)
memcpy(buf, dev->urb_buf, len);
mutex_unlock(&dev->ctrl_urb_lock);
if (reg_debug) {
printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
printk("%02x values: ", ret);
for (byte = 0; byte < len; byte++)
printk(" %02x", (unsigned char)buf[byte]);
printk("\n");
}
@ -102,16 +116,20 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
mutex_lock(&dev->ctrl_urb_lock);
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x0000, reg, &val, 1, HZ);
0x0000, reg, dev->urb_buf, 1, HZ);
val = dev->urb_buf[0];
mutex_unlock(&dev->ctrl_urb_lock);
if (ret < 0) {
printk(" failed!\n");
return ret;
}
if (reg_debug)
printk(ret < 0 ? " failed!\n" :
"%02x\n", (unsigned char) val);
if (ret < 0)
return ret;
printk("%02x\n", (unsigned char) val);
return val;
}
@ -130,19 +148,13 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
{
int ret;
/*usb_control_msg seems to expect a kmalloced buffer */
unsigned char *bufs;
if (dev->state & DEV_DISCONNECTED)
return -ENODEV;
if (len < 1)
if ((len < 1) || (len > URB_MAX_CTRL_SIZE))
return -EINVAL;
bufs = kmalloc(len, GFP_KERNEL);
em28xx_regdbg("req=%02x reg=%02x:", req, reg);
if (reg_debug) {
int i;
for (i = 0; i < len; ++i)
@ -150,16 +162,16 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
printk("\n");
}
if (!bufs)
return -ENOMEM;
memcpy(bufs, buf, len);
mutex_lock(&dev->ctrl_urb_lock);
memcpy(dev->urb_buf, buf, len);
ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x0000, reg, bufs, len, HZ);
0x0000, reg, dev->urb_buf, len, HZ);
mutex_unlock(&dev->ctrl_urb_lock);
if (dev->wait_after_write)
msleep(dev->wait_after_write);
kfree(bufs);
return ret;
}
@ -270,6 +282,8 @@ static int em28xx_set_audio_source(struct em28xx *dev)
break;
case EM28XX_AMUX_LINE_IN:
input = EM28XX_AUDIO_SRC_LINE;
video = disable;
line = enable;
break;
case EM28XX_AMUX_AC97_VIDEO:
input = EM28XX_AUDIO_SRC_LINE;

View File

@ -337,9 +337,9 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
/* Check if board has eeprom */
err = i2c_master_recv(&dev->i2c_client, &buf, 0);
if (err < 0) {
em28xx_errdev("%s: i2c_master_recv failed! err [%d]\n",
__func__, err);
return err;
em28xx_errdev("board has no eeprom\n");
memset(eedata, 0, len);
return -ENODEV;
}
buf = 0;
@ -609,14 +609,16 @@ int em28xx_i2c_register(struct em28xx *dev)
dev->i2c_client.adapter = &dev->i2c_adap;
retval = em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata));
if (retval < 0) {
if ((retval < 0) && (retval != -ENODEV)) {
em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n",
__func__, retval);
return retval;
}
if (i2c_scan)
em28xx_do_i2c_scan(dev);
return 0;
}

View File

@ -73,6 +73,7 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
static LIST_HEAD(em28xx_devlist);
static DEFINE_MUTEX(em28xx_devlist_mutex);
static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
@ -1519,7 +1520,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
struct em28xx_fh *fh;
enum v4l2_buf_type fh_type = 0;
lock_kernel();
mutex_lock(&em28xx_devlist_mutex);
list_for_each_entry(h, &em28xx_devlist, devlist) {
if (h->vdev->minor == minor) {
dev = h;
@ -1535,10 +1536,11 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
dev = h;
}
}
if (NULL == dev) {
unlock_kernel();
mutex_unlock(&em28xx_devlist_mutex);
if (NULL == dev)
return -ENODEV;
}
mutex_lock(&dev->lock);
em28xx_videodbg("open minor=%d type=%s users=%d\n",
minor, v4l2_type_names[fh_type], dev->users);
@ -1547,10 +1549,9 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
if (!fh) {
em28xx_errdev("em28xx-video.c: Out of memory?!\n");
unlock_kernel();
mutex_unlock(&dev->lock);
return -ENOMEM;
}
mutex_lock(&dev->lock);
fh->dev = dev;
fh->radio = radio;
fh->type = fh_type;
@ -1584,7 +1585,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
sizeof(struct em28xx_buffer), fh);
mutex_unlock(&dev->lock);
unlock_kernel();
return errCode;
}
@ -1871,6 +1871,7 @@ int em28xx_register_extension(struct em28xx_ops *ops)
{
struct em28xx *dev = NULL;
mutex_lock(&em28xx_devlist_mutex);
mutex_lock(&em28xx_extension_devlist_lock);
list_add_tail(&ops->next, &em28xx_extension_devlist);
list_for_each_entry(dev, &em28xx_devlist, devlist) {
@ -1879,6 +1880,7 @@ int em28xx_register_extension(struct em28xx_ops *ops)
}
printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
mutex_unlock(&em28xx_extension_devlist_lock);
mutex_unlock(&em28xx_devlist_mutex);
return 0;
}
EXPORT_SYMBOL(em28xx_register_extension);
@ -1887,6 +1889,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
{
struct em28xx *dev = NULL;
mutex_lock(&em28xx_devlist_mutex);
list_for_each_entry(dev, &em28xx_devlist, devlist) {
if (dev)
ops->fini(dev);
@ -1896,6 +1899,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
list_del(&ops->next);
mutex_unlock(&em28xx_extension_devlist_lock);
mutex_unlock(&em28xx_devlist_mutex);
}
EXPORT_SYMBOL(em28xx_unregister_extension);
@ -1921,6 +1925,60 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
}
static int register_analog_devices(struct em28xx *dev)
{
int ret;
/* allocate and fill video video_device struct */
dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
if (!dev->vdev) {
em28xx_errdev("cannot allocate video_device.\n");
return -ENODEV;
}
/* register v4l2 video video_device */
ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
video_nr[dev->devno]);
if (ret) {
em28xx_errdev("unable to register video device (error=%i).\n",
ret);
return ret;
}
/* Allocate and fill vbi video_device struct */
dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi");
/* register v4l2 vbi video_device */
ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
vbi_nr[dev->devno]);
if (ret < 0) {
em28xx_errdev("unable to register vbi device\n");
return ret;
}
if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
if (!dev->radio_dev) {
em28xx_errdev("cannot allocate video_device.\n");
return -ENODEV;
}
ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
radio_nr[dev->devno]);
if (ret < 0) {
em28xx_errdev("can't register radio device\n");
return ret;
}
em28xx_info("Registered radio device as /dev/radio%d\n",
dev->radio_dev->num);
}
em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
dev->vdev->num, dev->vbi_dev->num);
return 0;
}
/*
* em28xx_init_dev()
* allocates and inits the device structs, registers i2c bus and v4l device
@ -1936,6 +1994,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
dev->udev = udev;
mutex_init(&dev->lock);
mutex_init(&dev->ctrl_urb_lock);
spin_lock_init(&dev->slock);
init_waitqueue_head(&dev->open);
init_waitqueue_head(&dev->wait_frame);
@ -1953,8 +2012,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
errCode = em28xx_config(dev);
if (errCode) {
em28xx_errdev("error configuring device\n");
em28xx_devused &= ~(1<<dev->devno);
kfree(dev);
return -ENOMEM;
}
@ -2001,50 +2058,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
return errCode;
}
list_add_tail(&dev->devlist, &em28xx_devlist);
/* allocate and fill video video_device struct */
dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
if (NULL == dev->vdev) {
em28xx_errdev("cannot allocate video_device.\n");
goto fail_unreg;
}
/* register v4l2 video video_device */
retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
video_nr[dev->devno]);
if (retval) {
em28xx_errdev("unable to register video device (error=%i).\n",
retval);
goto fail_unreg;
}
/* Allocate and fill vbi video_device struct */
dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi");
/* register v4l2 vbi video_device */
if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
vbi_nr[dev->devno]) < 0) {
em28xx_errdev("unable to register vbi device\n");
retval = -ENODEV;
goto fail_unreg;
}
if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
if (NULL == dev->radio_dev) {
em28xx_errdev("cannot allocate video_device.\n");
goto fail_unreg;
}
retval = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
radio_nr[dev->devno]);
if (retval < 0) {
em28xx_errdev("can't register radio device\n");
goto fail_unreg;
}
em28xx_info("Registered radio device as /dev/radio%d\n",
dev->radio_dev->num);
}
/* init video dma queues */
INIT_LIST_HEAD(&dev->vidq.active);
INIT_LIST_HEAD(&dev->vidq.queued);
@ -2071,8 +2084,14 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
video_mux(dev, 0);
em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
dev->vdev->num, dev->vbi_dev->num);
mutex_lock(&em28xx_devlist_mutex);
list_add_tail(&dev->devlist, &em28xx_devlist);
retval = register_analog_devices(dev);
if (retval < 0) {
em28xx_release_resources(dev);
mutex_unlock(&em28xx_devlist_mutex);
goto fail_reg_devices;
}
mutex_lock(&em28xx_extension_devlist_lock);
if (!list_empty(&em28xx_extension_devlist)) {
@ -2082,13 +2101,12 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
}
}
mutex_unlock(&em28xx_extension_devlist_lock);
mutex_unlock(&em28xx_devlist_mutex);
return 0;
fail_unreg:
em28xx_release_resources(dev);
fail_reg_devices:
mutex_unlock(&dev->lock);
kfree(dev);
return retval;
}
@ -2231,8 +2249,12 @@ static int em28xx_usb_probe(struct usb_interface *interface,
/* allocate device struct */
retval = em28xx_init_dev(&dev, udev, nr);
if (retval)
if (retval) {
em28xx_devused &= ~(1<<dev->devno);
kfree(dev);
return retval;
}
em28xx_info("Found %s\n", em28xx_boards[dev->model].name);

View File

@ -102,6 +102,9 @@
#define EM28XX_MIN_BUF 4
#define EM28XX_DEF_BUF 8
/*Limits the max URB message size */
#define URB_MAX_CTRL_SIZE 80
/* Params for validated field */
#define EM28XX_BOARD_NOT_VALIDATED 1
#define EM28XX_BOARD_VALIDATED 0
@ -430,6 +433,7 @@ struct em28xx {
/* locks */
struct mutex lock;
struct mutex ctrl_urb_lock; /* protects urb_buf */
/* spinlock_t queue_lock; */
struct list_head inqueue, outqueue;
wait_queue_head_t open, wait_frame, wait_stream;
@ -451,6 +455,8 @@ struct em28xx {
unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */
char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */
/* helper funcs that call usb_control_msg */
int (*em28xx_write_regs) (struct em28xx *dev, u16 reg,
char *buf, int len);

View File

@ -846,10 +846,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
return 0;
}
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
int retry = 50;
if (!gspca_dev->present)
return;
reg_w_val(gspca_dev, 0x0000, 0x00);
reg_r(gspca_dev, 0x0002, 1);
reg_w_val(gspca_dev, 0x0053, 0x00);

View File

@ -276,6 +276,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
/* Stop the state machine */
if (dev->state != FPIX_NOP)
wait_for_completion(&dev->can_close);
}
/* called on streamoff with alt 0 and disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
usb_free_urb(dev->control_urb);
dev->control_urb = NULL;
@ -385,6 +391,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
error:
/* Free the ressources */
sd_stopN(gspca_dev);
sd_stop0(gspca_dev);
return ret;
}
@ -425,6 +432,7 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
.stop0 = sd_stop0,
};
/* -- device connect -- */

View File

@ -646,15 +646,14 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
{
gspca_dev->streaming = 0;
atomic_set(&gspca_dev->nevent, 0);
if (gspca_dev->present) {
if (gspca_dev->sd_desc->stopN)
gspca_dev->sd_desc->stopN(gspca_dev);
destroy_urbs(gspca_dev);
gspca_set_alt0(gspca_dev);
if (gspca_dev->sd_desc->stop0)
gspca_dev->sd_desc->stop0(gspca_dev);
PDEBUG(D_STREAM, "stream off OK");
}
if (gspca_dev->present
&& gspca_dev->sd_desc->stopN)
gspca_dev->sd_desc->stopN(gspca_dev);
destroy_urbs(gspca_dev);
gspca_set_alt0(gspca_dev);
if (gspca_dev->sd_desc->stop0)
gspca_dev->sd_desc->stop0(gspca_dev);
PDEBUG(D_STREAM, "stream off OK");
}
static void gspca_set_default_mode(struct gspca_dev *gspca_dev)
@ -863,7 +862,7 @@ static int dev_open(struct inode *inode, struct file *file)
int ret;
PDEBUG(D_STREAM, "%s open", current->comm);
gspca_dev = (struct gspca_dev *) video_devdata(file);
gspca_dev = video_drvdata(file);
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
if (!gspca_dev->present) {
@ -875,6 +874,13 @@ static int dev_open(struct inode *inode, struct file *file)
ret = -EBUSY;
goto out;
}
/* protect the subdriver against rmmod */
if (!try_module_get(gspca_dev->module)) {
ret = -ENODEV;
goto out;
}
gspca_dev->users++;
/* one more user */
@ -884,10 +890,10 @@ static int dev_open(struct inode *inode, struct file *file)
#ifdef GSPCA_DEBUG
/* activate the v4l2 debug */
if (gspca_debug & D_V4L2)
gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL
gspca_dev->vdev->debug |= V4L2_DEBUG_IOCTL
| V4L2_DEBUG_IOCTL_ARG;
else
gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
gspca_dev->vdev->debug &= ~(V4L2_DEBUG_IOCTL
| V4L2_DEBUG_IOCTL_ARG);
#endif
ret = 0;
@ -921,6 +927,7 @@ static int dev_close(struct inode *inode, struct file *file)
gspca_dev->memory = GSPCA_MEMORY_NO;
}
file->private_data = NULL;
module_put(gspca_dev->module);
mutex_unlock(&gspca_dev->queue_lock);
PDEBUG(D_STREAM, "close done");
@ -1748,11 +1755,6 @@ out:
return ret;
}
static void dev_release(struct video_device *vfd)
{
/* nothing */
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.open = dev_open,
@ -1800,7 +1802,7 @@ static struct video_device gspca_template = {
.name = "gspca main driver",
.fops = &dev_fops,
.ioctl_ops = &dev_ioctl_ops,
.release = dev_release, /* mandatory */
.release = video_device_release,
.minor = -1,
};
@ -1869,17 +1871,18 @@ int gspca_dev_probe(struct usb_interface *intf,
init_waitqueue_head(&gspca_dev->wq);
/* init video stuff */
memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
gspca_dev->vdev.parent = &dev->dev;
memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops);
gspca_dev->vdev.fops = &gspca_dev->fops;
gspca_dev->fops.owner = module; /* module protection */
gspca_dev->vdev = video_device_alloc();
memcpy(gspca_dev->vdev, &gspca_template, sizeof gspca_template);
gspca_dev->vdev->parent = &dev->dev;
gspca_dev->module = module;
gspca_dev->present = 1;
ret = video_register_device(&gspca_dev->vdev,
video_set_drvdata(gspca_dev->vdev, gspca_dev);
ret = video_register_device(gspca_dev->vdev,
VFL_TYPE_GRABBER,
video_nr);
if (ret < 0) {
err("video_register_device err %d", ret);
video_device_release(gspca_dev->vdev);
goto out;
}
@ -1887,7 +1890,8 @@ int gspca_dev_probe(struct usb_interface *intf,
PDEBUG(D_PROBE, "probe ok");
return 0;
out:
kref_put(&gspca_dev->kref, gspca_delete);
kfree(gspca_dev->usb_buf);
kfree(gspca_dev);
return ret;
}
EXPORT_SYMBOL(gspca_dev_probe);
@ -1905,7 +1909,7 @@ void gspca_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
/* We don't want people trying to open up the device */
video_unregister_device(&gspca_dev->vdev);
video_unregister_device(gspca_dev->vdev);
gspca_dev->present = 0;
gspca_dev->streaming = 0;

View File

@ -97,7 +97,7 @@ struct sd_desc {
cam_pkt_op pkt_scan;
/* optional operations */
cam_v_op stopN; /* called on stream off - main alt */
cam_v_op stop0; /* called on stream off - alt 0 */
cam_v_op stop0; /* called on stream off & disconnect - alt 0 */
cam_v_op dq_callback; /* called when a frame has been dequeued */
cam_jpg_op get_jcomp;
cam_jpg_op set_jcomp;
@ -120,8 +120,8 @@ struct gspca_frame {
};
struct gspca_dev {
struct video_device vdev; /* !! must be the first item */
struct file_operations fops;
struct video_device *vdev;
struct module *module; /* subdriver handling the device */
struct usb_device *dev;
struct kref kref;
struct file *capt_file; /* file doing video capture */

View File

@ -749,10 +749,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
}
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
if (!gspca_dev->present)
return;
if (sd->sensor == SENSOR_PAC7302) {
reg_w(gspca_dev, 0xff, 0x01);
reg_w(gspca_dev, 0x78, 0x40);

View File

@ -2022,8 +2022,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00);
}
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
if (!gspca_dev->present)
return;
reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00);
}

View File

@ -742,8 +742,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, 0x02, 0x00, 0x00);
}
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
if (!gspca_dev->present)
return;
/* This maybe reset or power control */
reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);

View File

@ -766,10 +766,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
}
}
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
if (!gspca_dev->present)
return;
if (sd->chip_revision == Rev012A) {
reg_w_val(gspca_dev->dev, 0x8118, 0x29);
reg_w_val(gspca_dev->dev, 0x8114, 0x08);

View File

@ -1633,10 +1633,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w(dev, 0xa0, 0x09, 0xb003);
}
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
if (!gspca_dev->present)
return;
reg_w(dev, 0x89, 0xffff, 0xffff);
}

View File

@ -7336,10 +7336,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
return 0;
}
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
if (!gspca_dev->present)
return;
send_unknown(gspca_dev->dev, sd->sensor);
}

View File

@ -192,7 +192,7 @@ struct s2255_dmaqueue {
#define S2255_FW_FAILED 3
#define S2255_FW_DISCONNECTING 4
#define S2255_FW_MARKER 0x22552f2f
#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
/* 2255 read states */
#define S2255_READ_IDLE 0
#define S2255_READ_FRAME 1