forked from luck/tmp_suning_uos_patched
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: USB: pwc : do not pass stack allocated buffers to USB core. USB: otg: Fix bug on remove path without transceiver USB: correct error handling in cdc-wdm USB: removal of tty->low_latency hack dating back to the old serial code USB: serial: sierra driver bug fix for composite interface USB: gadget: omap_udc uses platform_driver_probe() USB: ci13xxx_udc: fix build error USB: musb: Prevent multiple includes of musb.h USB: pass mem_flags to dma_alloc_coherent USB: g_file_storage: fix use-after-free bug when closing files USB: ehci-sched.c: EHCI SITD scheduling bugfix USB: fix mos7840 problem with minor numbers USB: mos7840: add new device id USB: musb: fix build when !CONFIG_PM USB: musb: Remove my email address from few musb related drivers USB: Gadget: MIPS CI13xxx UDC bugfixes USB: Unusual Device support for Gold MP3 Player Energy USB: serial: fix lifetime and locking problems
This commit is contained in:
commit
d72cd3a90e
|
@ -159,35 +159,67 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev);
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
#define SendControlMsg(request, value, buflen) \
|
||||
usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), \
|
||||
request, \
|
||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
|
||||
value, \
|
||||
pdev->vcinterface, \
|
||||
&buf, buflen, 500)
|
||||
|
||||
#define RecvControlMsg(request, value, buflen) \
|
||||
usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), \
|
||||
request, \
|
||||
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
|
||||
value, \
|
||||
pdev->vcinterface, \
|
||||
&buf, buflen, 500)
|
||||
|
||||
|
||||
static int send_video_command(struct usb_device *udev, int index, void *buf, int buflen)
|
||||
static int _send_control_msg(struct pwc_device *pdev,
|
||||
u8 request, u16 value, int index, void *buf, int buflen, int timeout)
|
||||
{
|
||||
return usb_control_msg(udev,
|
||||
usb_sndctrlpipe(udev, 0),
|
||||
SET_EP_STREAM_CTL,
|
||||
int rc;
|
||||
void *kbuf = NULL;
|
||||
|
||||
if (buflen) {
|
||||
kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
|
||||
if (kbuf == NULL)
|
||||
return -ENOMEM;
|
||||
memcpy(kbuf, buf, buflen);
|
||||
}
|
||||
|
||||
rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
|
||||
request,
|
||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
value,
|
||||
index,
|
||||
kbuf, buflen, timeout);
|
||||
|
||||
kfree(kbuf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int recv_control_msg(struct pwc_device *pdev,
|
||||
u8 request, u16 value, void *buf, int buflen)
|
||||
{
|
||||
int rc;
|
||||
void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
|
||||
|
||||
if (kbuf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
|
||||
request,
|
||||
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
value,
|
||||
pdev->vcinterface,
|
||||
kbuf, buflen, 500);
|
||||
memcpy(buf, kbuf, buflen);
|
||||
kfree(kbuf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int send_video_command(struct pwc_device *pdev,
|
||||
int index, void *buf, int buflen)
|
||||
{
|
||||
return _send_control_msg(pdev,
|
||||
SET_EP_STREAM_CTL,
|
||||
VIDEO_OUTPUT_CONTROL_FORMATTER,
|
||||
index,
|
||||
buf, buflen, 1000);
|
||||
}
|
||||
|
||||
static inline int send_control_msg(struct pwc_device *pdev,
|
||||
u8 request, u16 value, void *buf, int buflen)
|
||||
{
|
||||
return _send_control_msg(pdev,
|
||||
request, value, pdev->vcinterface, buf, buflen, 500);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
|
||||
|
@ -224,7 +256,7 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
|
|||
return -EINVAL;
|
||||
|
||||
memcpy(buf, pEntry->mode, 3);
|
||||
ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
|
||||
ret = send_video_command(pdev, pdev->vendpoint, buf, 3);
|
||||
if (ret < 0) {
|
||||
PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
|
||||
return ret;
|
||||
|
@ -285,7 +317,7 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, i
|
|||
memcpy(buf, pChoose->mode, 13);
|
||||
if (snapshot)
|
||||
buf[0] |= 0x80;
|
||||
ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 13);
|
||||
ret = send_video_command(pdev, pdev->vendpoint, buf, 13);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -358,7 +390,7 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i
|
|||
buf[0] |= 0x80;
|
||||
|
||||
/* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
|
||||
ret = send_video_command(pdev->udev, 4 /* pdev->vendpoint */, buf, 12);
|
||||
ret = send_video_command(pdev, 4 /* pdev->vendpoint */, buf, 12);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -530,7 +562,8 @@ int pwc_get_brightness(struct pwc_device *pdev)
|
|||
char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return buf;
|
||||
|
@ -545,7 +578,8 @@ int pwc_set_brightness(struct pwc_device *pdev, int value)
|
|||
if (value > 0xffff)
|
||||
value = 0xffff;
|
||||
buf = (value >> 9) & 0x7f;
|
||||
return SendControlMsg(SET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/* CONTRAST */
|
||||
|
@ -555,7 +589,8 @@ int pwc_get_contrast(struct pwc_device *pdev)
|
|||
char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return buf;
|
||||
|
@ -570,7 +605,8 @@ int pwc_set_contrast(struct pwc_device *pdev, int value)
|
|||
if (value > 0xffff)
|
||||
value = 0xffff;
|
||||
buf = (value >> 10) & 0x3f;
|
||||
return SendControlMsg(SET_LUM_CTL, CONTRAST_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/* GAMMA */
|
||||
|
@ -580,7 +616,8 @@ int pwc_get_gamma(struct pwc_device *pdev)
|
|||
char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return buf;
|
||||
|
@ -595,7 +632,8 @@ int pwc_set_gamma(struct pwc_device *pdev, int value)
|
|||
if (value > 0xffff)
|
||||
value = 0xffff;
|
||||
buf = (value >> 11) & 0x1f;
|
||||
return SendControlMsg(SET_LUM_CTL, GAMMA_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
|
||||
|
@ -613,7 +651,8 @@ int pwc_get_saturation(struct pwc_device *pdev, int *value)
|
|||
saturation_register = SATURATION_MODE_FORMATTER2;
|
||||
else
|
||||
saturation_register = SATURATION_MODE_FORMATTER1;
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, saturation_register, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_CHROM_CTL, saturation_register, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*value = (signed)buf;
|
||||
|
@ -636,7 +675,8 @@ int pwc_set_saturation(struct pwc_device *pdev, int value)
|
|||
saturation_register = SATURATION_MODE_FORMATTER2;
|
||||
else
|
||||
saturation_register = SATURATION_MODE_FORMATTER1;
|
||||
return SendControlMsg(SET_CHROM_CTL, saturation_register, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_CHROM_CTL, saturation_register, &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/* AGC */
|
||||
|
@ -651,7 +691,8 @@ int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
|
|||
else
|
||||
buf = 0xff; /* fixed */
|
||||
|
||||
ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1);
|
||||
ret = send_control_msg(pdev,
|
||||
SET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf));
|
||||
|
||||
if (!mode && ret >= 0) {
|
||||
if (value < 0)
|
||||
|
@ -659,7 +700,8 @@ int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
|
|||
if (value > 0xffff)
|
||||
value = 0xffff;
|
||||
buf = (value >> 10) & 0x3F;
|
||||
ret = SendControlMsg(SET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
|
||||
ret = send_control_msg(pdev,
|
||||
SET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf));
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -671,12 +713,14 @@ int pwc_get_agc(struct pwc_device *pdev, int *value)
|
|||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (buf != 0) { /* fixed */
|
||||
ret = RecvControlMsg(GET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (buf > 0x3F)
|
||||
|
@ -684,7 +728,8 @@ int pwc_get_agc(struct pwc_device *pdev, int *value)
|
|||
*value = (buf << 10);
|
||||
}
|
||||
else { /* auto */
|
||||
ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_STATUS_CTL, READ_AGC_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* Gah... this value ranges from 0x00 ... 0x9F */
|
||||
|
@ -707,7 +752,8 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
|
|||
else
|
||||
buf[0] = 0xff; /* fixed */
|
||||
|
||||
ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1);
|
||||
ret = send_control_msg(pdev,
|
||||
SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, sizeof(buf));
|
||||
|
||||
if (!mode && ret >= 0) {
|
||||
if (value < 0)
|
||||
|
@ -726,7 +772,9 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
|
|||
buf[0] = value >> 8;
|
||||
}
|
||||
|
||||
ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
|
||||
ret = send_control_msg(pdev,
|
||||
SET_LUM_CTL, PRESET_SHUTTER_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -737,7 +785,8 @@ int pwc_get_shutter_speed(struct pwc_device *pdev, int *value)
|
|||
unsigned char buf[2];
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_STATUS_CTL, READ_SHUTTER_FORMATTER, 2);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_STATUS_CTL, READ_SHUTTER_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*value = buf[0] + (buf[1] << 8);
|
||||
|
@ -764,7 +813,9 @@ int pwc_camera_power(struct pwc_device *pdev, int power)
|
|||
buf = 0x00; /* active */
|
||||
else
|
||||
buf = 0xFF; /* power save */
|
||||
return SendControlMsg(SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
}
|
||||
|
||||
|
||||
|
@ -773,20 +824,20 @@ int pwc_camera_power(struct pwc_device *pdev, int power)
|
|||
|
||||
int pwc_restore_user(struct pwc_device *pdev)
|
||||
{
|
||||
char buf; /* dummy */
|
||||
return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0);
|
||||
return send_control_msg(pdev,
|
||||
SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, NULL, 0);
|
||||
}
|
||||
|
||||
int pwc_save_user(struct pwc_device *pdev)
|
||||
{
|
||||
char buf; /* dummy */
|
||||
return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0);
|
||||
return send_control_msg(pdev,
|
||||
SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, NULL, 0);
|
||||
}
|
||||
|
||||
int pwc_restore_factory(struct pwc_device *pdev)
|
||||
{
|
||||
char buf; /* dummy */
|
||||
return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0);
|
||||
return send_control_msg(pdev,
|
||||
SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, NULL, 0);
|
||||
}
|
||||
|
||||
/* ************************************************* */
|
||||
|
@ -814,7 +865,8 @@ int pwc_set_awb(struct pwc_device *pdev, int mode)
|
|||
|
||||
buf = mode & 0x07; /* just the lowest three bits */
|
||||
|
||||
ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1);
|
||||
ret = send_control_msg(pdev,
|
||||
SET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf));
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -826,7 +878,8 @@ int pwc_get_awb(struct pwc_device *pdev)
|
|||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf));
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -843,7 +896,9 @@ int pwc_set_red_gain(struct pwc_device *pdev, int value)
|
|||
value = 0xffff;
|
||||
/* only the msb is considered */
|
||||
buf = value >> 8;
|
||||
return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
}
|
||||
|
||||
int pwc_get_red_gain(struct pwc_device *pdev, int *value)
|
||||
|
@ -851,7 +906,9 @@ int pwc_get_red_gain(struct pwc_device *pdev, int *value)
|
|||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*value = buf << 8;
|
||||
|
@ -869,7 +926,9 @@ int pwc_set_blue_gain(struct pwc_device *pdev, int value)
|
|||
value = 0xffff;
|
||||
/* only the msb is considered */
|
||||
buf = value >> 8;
|
||||
return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
}
|
||||
|
||||
int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
|
||||
|
@ -877,7 +936,9 @@ int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
|
|||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*value = buf << 8;
|
||||
|
@ -894,7 +955,8 @@ static int pwc_read_red_gain(struct pwc_device *pdev, int *value)
|
|||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*value = buf << 8;
|
||||
|
@ -906,7 +968,8 @@ static int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
|
|||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*value = buf << 8;
|
||||
|
@ -920,7 +983,8 @@ static int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
|
|||
|
||||
/* useful range is 0x01..0x20 */
|
||||
buf = speed / 0x7f0;
|
||||
return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
|
||||
|
@ -928,7 +992,8 @@ static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
|
|||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*value = buf * 0x7f0;
|
||||
|
@ -942,7 +1007,8 @@ static int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
|
|||
|
||||
/* useful range is 0x01..0x3F */
|
||||
buf = (delay >> 10);
|
||||
return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
|
||||
|
@ -950,7 +1016,8 @@ static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
|
|||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*value = buf << 10;
|
||||
|
@ -978,7 +1045,8 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
|
|||
buf[0] = on_value;
|
||||
buf[1] = off_value;
|
||||
|
||||
return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2);
|
||||
return send_control_msg(pdev,
|
||||
SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
|
||||
|
@ -992,7 +1060,8 @@ static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ret = RecvControlMsg(GET_STATUS_CTL, LED_FORMATTER, 2);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*on_value = buf[0] * 100;
|
||||
|
@ -1009,7 +1078,8 @@ int pwc_set_contour(struct pwc_device *pdev, int contour)
|
|||
buf = 0xff; /* auto contour on */
|
||||
else
|
||||
buf = 0x0; /* auto contour off */
|
||||
ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
|
||||
ret = send_control_msg(pdev,
|
||||
SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -1019,7 +1089,8 @@ int pwc_set_contour(struct pwc_device *pdev, int contour)
|
|||
contour = 0xffff;
|
||||
|
||||
buf = (contour >> 10); /* contour preset is [0..3f] */
|
||||
ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
|
||||
ret = send_control_msg(pdev,
|
||||
SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
|
@ -1030,13 +1101,16 @@ int pwc_get_contour(struct pwc_device *pdev, int *contour)
|
|||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (buf == 0) {
|
||||
/* auto mode off, query current preset value */
|
||||
ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_LUM_CTL, PRESET_CONTOUR_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*contour = buf << 10;
|
||||
|
@ -1055,7 +1129,9 @@ int pwc_set_backlight(struct pwc_device *pdev, int backlight)
|
|||
buf = 0xff;
|
||||
else
|
||||
buf = 0x0;
|
||||
return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
}
|
||||
|
||||
int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
|
||||
|
@ -1063,7 +1139,9 @@ int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
|
|||
int ret;
|
||||
unsigned char buf;
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*backlight = !!buf;
|
||||
|
@ -1078,7 +1156,8 @@ int pwc_set_colour_mode(struct pwc_device *pdev, int colour)
|
|||
buf = 0xff;
|
||||
else
|
||||
buf = 0x0;
|
||||
return SendControlMsg(SET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
int pwc_get_colour_mode(struct pwc_device *pdev, int *colour)
|
||||
|
@ -1086,7 +1165,8 @@ int pwc_get_colour_mode(struct pwc_device *pdev, int *colour)
|
|||
int ret;
|
||||
unsigned char buf;
|
||||
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*colour = !!buf;
|
||||
|
@ -1102,7 +1182,8 @@ int pwc_set_flicker(struct pwc_device *pdev, int flicker)
|
|||
buf = 0xff;
|
||||
else
|
||||
buf = 0x0;
|
||||
return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
|
||||
|
@ -1110,7 +1191,8 @@ int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
|
|||
int ret;
|
||||
unsigned char buf;
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*flicker = !!buf;
|
||||
|
@ -1126,7 +1208,9 @@ int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
|
|||
if (noise > 3)
|
||||
noise = 3;
|
||||
buf = noise;
|
||||
return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
}
|
||||
|
||||
int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
|
||||
|
@ -1134,7 +1218,9 @@ int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
|
|||
int ret;
|
||||
unsigned char buf;
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*noise = buf;
|
||||
|
@ -1146,7 +1232,8 @@ static int _pwc_mpt_reset(struct pwc_device *pdev, int flags)
|
|||
unsigned char buf;
|
||||
|
||||
buf = flags & 0x03; // only lower two bits are currently used
|
||||
return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);
|
||||
return send_control_msg(pdev,
|
||||
SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
int pwc_mpt_reset(struct pwc_device *pdev, int flags)
|
||||
|
@ -1175,7 +1262,8 @@ static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
|
|||
buf[1] = (pan >> 8) & 0xFF;
|
||||
buf[2] = tilt & 0xFF;
|
||||
buf[3] = (tilt >> 8) & 0xFF;
|
||||
return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4);
|
||||
return send_control_msg(pdev,
|
||||
SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, &buf, sizeof(buf));
|
||||
}
|
||||
|
||||
int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
|
||||
|
@ -1211,7 +1299,8 @@ static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *st
|
|||
int ret;
|
||||
unsigned char buf[5];
|
||||
|
||||
ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_MPT_CTL, PT_STATUS_FORMATTER, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
status->status = buf[0] & 0x7; // 3 bits are used for reporting
|
||||
|
@ -1233,7 +1322,8 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
|
|||
else
|
||||
request = SENSOR_TYPE_FORMATTER2;
|
||||
|
||||
ret = RecvControlMsg(GET_STATUS_CTL, request, 1);
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_STATUS_CTL, request, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (pdev->type < 675)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* This driver supports USB CDC WCM Device Management.
|
||||
*
|
||||
* Copyright (c) 2007-2008 Oliver Neukum
|
||||
* Copyright (c) 2007-2009 Oliver Neukum
|
||||
*
|
||||
* Some code taken from cdc-acm.c
|
||||
*
|
||||
|
@ -610,7 +610,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
if (!buffer)
|
||||
goto out;
|
||||
|
||||
while (buflen > 0) {
|
||||
while (buflen > 2) {
|
||||
if (buffer [1] != USB_DT_CS_INTERFACE) {
|
||||
dev_err(&intf->dev, "skipping garbage\n");
|
||||
goto next_desc;
|
||||
|
@ -646,16 +646,18 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
spin_lock_init(&desc->iuspin);
|
||||
init_waitqueue_head(&desc->wait);
|
||||
desc->wMaxCommand = maxcom;
|
||||
/* this will be expanded and needed in hardware endianness */
|
||||
desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
|
||||
desc->intf = intf;
|
||||
INIT_WORK(&desc->rxwork, wdm_rxwork);
|
||||
|
||||
iface = &intf->altsetting[0];
|
||||
ep = &iface->endpoint[0].desc;
|
||||
if (!ep || !usb_endpoint_is_int_in(ep)) {
|
||||
rv = -EINVAL;
|
||||
rv = -EINVAL;
|
||||
iface = intf->cur_altsetting;
|
||||
if (iface->desc.bNumEndpoints != 1)
|
||||
goto err;
|
||||
ep = &iface->endpoint[0].desc;
|
||||
if (!ep || !usb_endpoint_is_int_in(ep))
|
||||
goto err;
|
||||
}
|
||||
|
||||
desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize);
|
||||
desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0;
|
||||
|
@ -711,12 +713,19 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
|
||||
usb_set_intfdata(intf, desc);
|
||||
rv = usb_register_dev(intf, &wdm_class);
|
||||
dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
|
||||
intf->minor - WDM_MINOR_BASE);
|
||||
if (rv < 0)
|
||||
goto err;
|
||||
goto err3;
|
||||
else
|
||||
dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
|
||||
intf->minor - WDM_MINOR_BASE);
|
||||
out:
|
||||
return rv;
|
||||
err3:
|
||||
usb_set_intfdata(intf, NULL);
|
||||
usb_buffer_free(interface_to_usbdev(desc->intf),
|
||||
desc->bMaxPacketSize0,
|
||||
desc->inbuf,
|
||||
desc->response->transfer_dma);
|
||||
err2:
|
||||
usb_buffer_free(interface_to_usbdev(desc->intf),
|
||||
desc->wMaxPacketSize,
|
||||
|
|
|
@ -119,7 +119,7 @@ void *hcd_buffer_alloc(
|
|||
if (size <= pool_max [i])
|
||||
return dma_pool_alloc(hcd->pool [i], mem_flags, dma);
|
||||
}
|
||||
return dma_alloc_coherent(hcd->self.controller, size, dma, 0);
|
||||
return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
|
||||
}
|
||||
|
||||
void hcd_buffer_free(
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
* - Gadget API (majority of optional features)
|
||||
* - Suspend & Remote Wakeup
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dmapool.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
@ -142,7 +143,7 @@ static struct {
|
|||
#define CAP_DEVICEADDR (0x014UL)
|
||||
#define CAP_ENDPTLISTADDR (0x018UL)
|
||||
#define CAP_PORTSC (0x044UL)
|
||||
#define CAP_DEVLC (0x0B4UL)
|
||||
#define CAP_DEVLC (0x084UL)
|
||||
#define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL)
|
||||
#define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL)
|
||||
#define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL)
|
||||
|
@ -1986,6 +1987,8 @@ static int ep_enable(struct usb_ep *ep,
|
|||
do {
|
||||
dbg_event(_usb_addr(mEp), "ENABLE", 0);
|
||||
|
||||
mEp->qh[mEp->dir].ptr->cap = 0;
|
||||
|
||||
if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
|
||||
mEp->qh[mEp->dir].ptr->cap |= QH_IOS;
|
||||
else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
|
||||
|
|
|
@ -738,7 +738,6 @@ static struct fsg_dev *the_fsg;
|
|||
static struct usb_gadget_driver fsg_driver;
|
||||
|
||||
static void close_backing_file(struct lun *curlun);
|
||||
static void close_all_backing_files(struct fsg_dev *fsg);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -3593,12 +3592,10 @@ static int fsg_main_thread(void *fsg_)
|
|||
fsg->thread_task = NULL;
|
||||
spin_unlock_irq(&fsg->lock);
|
||||
|
||||
/* In case we are exiting because of a signal, unregister the
|
||||
* gadget driver and close the backing file. */
|
||||
if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) {
|
||||
/* If we are exiting because of a signal, unregister the
|
||||
* gadget driver. */
|
||||
if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags))
|
||||
usb_gadget_unregister_driver(&fsg_driver);
|
||||
close_all_backing_files(fsg);
|
||||
}
|
||||
|
||||
/* Let the unbind and cleanup routines know the thread has exited */
|
||||
complete_and_exit(&fsg->thread_notifier, 0);
|
||||
|
@ -3703,14 +3700,6 @@ static void close_backing_file(struct lun *curlun)
|
|||
}
|
||||
}
|
||||
|
||||
static void close_all_backing_files(struct fsg_dev *fsg)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fsg->nluns; ++i)
|
||||
close_backing_file(&fsg->luns[i]);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
@ -3845,6 +3834,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
|
|||
if (curlun->registered) {
|
||||
device_remove_file(&curlun->dev, &dev_attr_ro);
|
||||
device_remove_file(&curlun->dev, &dev_attr_file);
|
||||
close_backing_file(curlun);
|
||||
device_unregister(&curlun->dev);
|
||||
curlun->registered = 0;
|
||||
}
|
||||
|
@ -4190,7 +4180,6 @@ static int __init fsg_bind(struct usb_gadget *gadget)
|
|||
out:
|
||||
fsg->state = FSG_STATE_TERMINATED; // The thread is dead
|
||||
fsg_unbind(gadget);
|
||||
close_all_backing_files(fsg);
|
||||
complete(&fsg->thread_notifier);
|
||||
return rc;
|
||||
}
|
||||
|
@ -4284,7 +4273,6 @@ static void __exit fsg_cleanup(void)
|
|||
/* Wait for the thread to finish up */
|
||||
wait_for_completion(&fsg->thread_notifier);
|
||||
|
||||
close_all_backing_files(fsg);
|
||||
kref_put(&fsg->ref, fsg_release);
|
||||
}
|
||||
module_exit(fsg_cleanup);
|
||||
|
|
|
@ -3104,7 +3104,6 @@ static int omap_udc_resume(struct platform_device *dev)
|
|||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct platform_driver udc_driver = {
|
||||
.probe = omap_udc_probe,
|
||||
.remove = __exit_p(omap_udc_remove),
|
||||
.suspend = omap_udc_suspend,
|
||||
.resume = omap_udc_resume,
|
||||
|
@ -3122,7 +3121,7 @@ static int __init udc_init(void)
|
|||
#endif
|
||||
"%s\n", driver_desc,
|
||||
use_dma ? " (dma)" : "");
|
||||
return platform_driver_register(&udc_driver);
|
||||
return platform_driver_probe(&udc_driver, omap_udc_probe);
|
||||
}
|
||||
module_init(udc_init);
|
||||
|
||||
|
|
|
@ -323,7 +323,7 @@ static int tt_available (
|
|||
* already scheduled transactions
|
||||
*/
|
||||
if (125 < usecs) {
|
||||
int ufs = (usecs / 125) - 1;
|
||||
int ufs = (usecs / 125);
|
||||
int i;
|
||||
for (i = uframe; i < (uframe + ufs) && i < 8; i++)
|
||||
if (0 < tt_usecs[i]) {
|
||||
|
|
|
@ -2191,7 +2191,7 @@ static int musb_resume_early(struct platform_device *pdev)
|
|||
|
||||
#else
|
||||
#define musb_suspend NULL
|
||||
#define musb_resume NULL
|
||||
#define musb_resume_early NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver musb_driver = {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* Some code has been taken from tusb6010.c
|
||||
* Copyrights for that are attributable to:
|
||||
* Copyright (C) 2006 Nokia Corporation
|
||||
* Jarkko Nikula <jarkko.nikula@nokia.com>
|
||||
* Tony Lindgren <tony@atomide.com>
|
||||
*
|
||||
* This file is part of the Inventra Controller Driver for Linux.
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* TUSB6010 USB 2.0 OTG Dual Role controller
|
||||
*
|
||||
* Copyright (C) 2006 Nokia Corporation
|
||||
* Jarkko Nikula <jarkko.nikula@nokia.com>
|
||||
* Tony Lindgren <tony@atomide.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* Definitions for TUSB6010 USB 2.0 OTG Dual Role controller
|
||||
*
|
||||
* Copyright (C) 2006 Nokia Corporation
|
||||
* Jarkko Nikula <jarkko.nikula@nokia.com>
|
||||
* Tony Lindgren <tony@atomide.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
|
@ -43,7 +43,8 @@ EXPORT_SYMBOL(otg_get_transceiver);
|
|||
*/
|
||||
void otg_put_transceiver(struct otg_transceiver *x)
|
||||
{
|
||||
put_device(x->dev);
|
||||
if (x)
|
||||
put_device(x->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(otg_put_transceiver);
|
||||
|
||||
|
|
|
@ -175,13 +175,6 @@ static int cyberjack_open(struct tty_struct *tty,
|
|||
dbg("%s - usb_clear_halt", __func__);
|
||||
usb_clear_halt(port->serial->dev, port->write_urb->pipe);
|
||||
|
||||
/* force low_latency on so that our tty_push actually forces
|
||||
* the data through, otherwise it is scheduled, and with high
|
||||
* data rates (like with OHCI) data can get lost.
|
||||
*/
|
||||
if (tty)
|
||||
tty->low_latency = 1;
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
priv->rdtodo = 0;
|
||||
|
|
|
@ -656,10 +656,6 @@ static int cypress_open(struct tty_struct *tty,
|
|||
priv->rx_flags = 0;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
/* setting to zero could cause data loss */
|
||||
if (tty)
|
||||
tty->low_latency = 1;
|
||||
|
||||
/* raise both lines and set termios */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
priv->line_control = CONTROL_DTR | CONTROL_RTS;
|
||||
|
|
|
@ -478,12 +478,6 @@ static void empeg_set_termios(struct tty_struct *tty,
|
|||
termios->c_cflag
|
||||
|= CS8; /* character size 8 bits */
|
||||
|
||||
/*
|
||||
* Force low_latency on; otherwise the pushes are scheduled;
|
||||
* this is bad as it opens up the possibility of dropping bytes
|
||||
* on the floor. We don't want to drop bytes on the floor. :)
|
||||
*/
|
||||
tty->low_latency = 1;
|
||||
tty_encode_baud_rate(tty, 115200, 115200);
|
||||
}
|
||||
|
||||
|
|
|
@ -973,14 +973,6 @@ static int garmin_open(struct tty_struct *tty,
|
|||
|
||||
dbg("%s - port %d", __func__, port->number);
|
||||
|
||||
/*
|
||||
* Force low_latency on so that our tty_push actually forces the data
|
||||
* through, otherwise it is scheduled, and with high data rates (like
|
||||
* with OHCI) data can get lost.
|
||||
*/
|
||||
if (tty)
|
||||
tty->low_latency = 1;
|
||||
|
||||
spin_lock_irqsave(&garmin_data_p->lock, flags);
|
||||
garmin_data_p->mode = initial_mode;
|
||||
garmin_data_p->count = 0;
|
||||
|
|
|
@ -122,12 +122,6 @@ int usb_serial_generic_open(struct tty_struct *tty,
|
|||
|
||||
dbg("%s - port %d", __func__, port->number);
|
||||
|
||||
/* force low_latency on so that our tty_push actually forces the data
|
||||
through, otherwise it is scheduled, and with high data rates (like
|
||||
with OHCI) data can get lost. */
|
||||
if (tty)
|
||||
tty->low_latency = 1;
|
||||
|
||||
/* clear the throttle flags */
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
port->throttled = 0;
|
||||
|
|
|
@ -193,8 +193,6 @@ static const struct divisor_table_entry divisor_table[] = {
|
|||
/* local variables */
|
||||
static int debug;
|
||||
|
||||
static int low_latency = 1; /* tty low latency flag, on by default */
|
||||
|
||||
static atomic_t CmdUrbs; /* Number of outstanding Command Write Urbs */
|
||||
|
||||
|
||||
|
@ -867,9 +865,6 @@ static int edge_open(struct tty_struct *tty,
|
|||
if (edge_port == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
if (tty)
|
||||
tty->low_latency = low_latency;
|
||||
|
||||
/* see if we've set up our endpoint info yet (can't set it up
|
||||
in edge_startup as the structures were not set up at that time.) */
|
||||
serial = port->serial;
|
||||
|
@ -3299,6 +3294,3 @@ MODULE_FIRMWARE("edgeport/down2.fw");
|
|||
|
||||
module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(debug, "Debug enabled or not");
|
||||
|
||||
module_param(low_latency, bool, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(low_latency, "Low latency enabled or not");
|
||||
|
|
|
@ -76,7 +76,6 @@ struct edgeport_uart_buf_desc {
|
|||
#define EDGE_READ_URB_STOPPING 1
|
||||
#define EDGE_READ_URB_STOPPED 2
|
||||
|
||||
#define EDGE_LOW_LATENCY 1
|
||||
#define EDGE_CLOSING_WAIT 4000 /* in .01 sec */
|
||||
|
||||
#define EDGE_OUT_BUF_SIZE 1024
|
||||
|
@ -232,7 +231,6 @@ static unsigned short OperationalBuildNumber;
|
|||
|
||||
static int debug;
|
||||
|
||||
static int low_latency = EDGE_LOW_LATENCY;
|
||||
static int closing_wait = EDGE_CLOSING_WAIT;
|
||||
static int ignore_cpu_rev;
|
||||
static int default_uart_mode; /* RS232 */
|
||||
|
@ -1850,9 +1848,6 @@ static int edge_open(struct tty_struct *tty,
|
|||
if (edge_port == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
if (tty)
|
||||
tty->low_latency = low_latency;
|
||||
|
||||
port_number = port->number - port->serial->minor;
|
||||
switch (port_number) {
|
||||
case 0:
|
||||
|
@ -3008,9 +3003,6 @@ MODULE_FIRMWARE("edgeport/down3.bin");
|
|||
module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(debug, "Debug enabled or not");
|
||||
|
||||
module_param(low_latency, bool, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(low_latency, "Low latency enabled or not");
|
||||
|
||||
module_param(closing_wait, int, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain, in .01 secs");
|
||||
|
||||
|
|
|
@ -631,13 +631,7 @@ static int ipaq_open(struct tty_struct *tty,
|
|||
priv->free_len += PACKET_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Force low latency on. This will immediately push data to the line
|
||||
* discipline instead of queueing.
|
||||
*/
|
||||
|
||||
if (tty) {
|
||||
tty->low_latency = 1;
|
||||
/* FIXME: These two are bogus */
|
||||
tty->raw = 1;
|
||||
tty->real_raw = 1;
|
||||
|
|
|
@ -207,9 +207,6 @@ static int ipw_open(struct tty_struct *tty,
|
|||
if (!buf_flow_init)
|
||||
return -ENOMEM;
|
||||
|
||||
if (tty)
|
||||
tty->low_latency = 1;
|
||||
|
||||
/* --1: Tell the modem to initialize (we think) From sniffs this is
|
||||
* always the first thing that gets sent to the modem during
|
||||
* opening of the device */
|
||||
|
|
|
@ -1051,7 +1051,6 @@ static int iuu_open(struct tty_struct *tty,
|
|||
tty->termios->c_oflag = 0;
|
||||
tty->termios->c_iflag = 0;
|
||||
priv->termios_initialized = 1;
|
||||
tty->low_latency = 1;
|
||||
priv->poll = 0;
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
|
|
@ -231,13 +231,7 @@ static int kobil_open(struct tty_struct *tty,
|
|||
/* someone sets the dev to 0 if the close method has been called */
|
||||
port->interrupt_in_urb->dev = port->serial->dev;
|
||||
|
||||
|
||||
/* force low_latency on so that our tty_push actually forces
|
||||
* the data through, otherwise it is scheduled, and with high
|
||||
* data rates (like with OHCI) data can get lost.
|
||||
*/
|
||||
if (tty) {
|
||||
tty->low_latency = 1;
|
||||
|
||||
/* Default to echo off and other sane device settings */
|
||||
tty->termios->c_lflag = 0;
|
||||
|
|
|
@ -446,13 +446,6 @@ static int mos7720_open(struct tty_struct *tty,
|
|||
data = 0x0c;
|
||||
send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
|
||||
|
||||
/* force low_latency on so that our tty_push actually forces *
|
||||
* the data through,otherwise it is scheduled, and with *
|
||||
* high data rates (like with OHCI) data can get lost. */
|
||||
|
||||
if (tty)
|
||||
tty->low_latency = 1;
|
||||
|
||||
/* see if we've set up our endpoint info yet *
|
||||
* (can't set it up in mos7720_startup as the *
|
||||
* structures were not set up at that time.) */
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
/*
|
||||
* Version Information
|
||||
*/
|
||||
#define DRIVER_VERSION "1.3.1"
|
||||
#define DRIVER_VERSION "1.3.2"
|
||||
#define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver"
|
||||
|
||||
/*
|
||||
|
@ -123,6 +123,11 @@
|
|||
#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44
|
||||
#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42
|
||||
|
||||
/* This driver also supports the ATEN UC2324 device since it is mos7840 based
|
||||
* - if I knew the device id it would also support the ATEN UC2322 */
|
||||
#define USB_VENDOR_ID_ATENINTL 0x0557
|
||||
#define ATENINTL_DEVICE_ID_UC2324 0x2011
|
||||
|
||||
/* Interrupt Routine Defines */
|
||||
|
||||
#define SERIAL_IIR_RLS 0x06
|
||||
|
@ -170,6 +175,7 @@ static struct usb_device_id moschip_port_id_table[] = {
|
|||
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
|
||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
|
||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
|
||||
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
|
||||
{} /* terminating entry */
|
||||
};
|
||||
|
||||
|
@ -178,6 +184,7 @@ static __devinitdata struct usb_device_id moschip_id_table_combined[] = {
|
|||
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
|
||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
|
||||
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
|
||||
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
|
||||
{} /* terminating entry */
|
||||
};
|
||||
|
||||
|
@ -1000,12 +1007,6 @@ static int mos7840_open(struct tty_struct *tty,
|
|||
status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
|
||||
Data);
|
||||
|
||||
/* force low_latency on so that our tty_push actually forces *
|
||||
* the data through,otherwise it is scheduled, and with *
|
||||
* high data rates (like with OHCI) data can get lost. */
|
||||
if (tty)
|
||||
tty->low_latency = 1;
|
||||
|
||||
/* Check to see if we've set up our endpoint info yet *
|
||||
* (can't set it up in mos7840_startup as the structures *
|
||||
* were not set up at that time.) */
|
||||
|
@ -2477,9 +2478,14 @@ static int mos7840_startup(struct usb_serial *serial)
|
|||
mos7840_set_port_private(serial->port[i], mos7840_port);
|
||||
spin_lock_init(&mos7840_port->pool_lock);
|
||||
|
||||
mos7840_port->port_num = ((serial->port[i]->number -
|
||||
(serial->port[i]->serial->minor)) +
|
||||
1);
|
||||
/* minor is not initialised until later by
|
||||
* usb-serial.c:get_free_serial() and cannot therefore be used
|
||||
* to index device instances */
|
||||
mos7840_port->port_num = i + 1;
|
||||
dbg ("serial->port[i]->number = %d", serial->port[i]->number);
|
||||
dbg ("serial->port[i]->serial->minor = %d", serial->port[i]->serial->minor);
|
||||
dbg ("mos7840_port->port_num = %d", mos7840_port->port_num);
|
||||
dbg ("serial->minor = %d", serial->minor);
|
||||
|
||||
if (mos7840_port->port_num == 1) {
|
||||
mos7840_port->SpRegOffset = 0x0;
|
||||
|
@ -2690,13 +2696,16 @@ static void mos7840_shutdown(struct usb_serial *serial)
|
|||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
mos7840_port = mos7840_get_port_private(serial->port[i]);
|
||||
spin_lock_irqsave(&mos7840_port->pool_lock, flags);
|
||||
mos7840_port->zombie = 1;
|
||||
spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
|
||||
usb_kill_urb(mos7840_port->control_urb);
|
||||
kfree(mos7840_port->ctrl_buf);
|
||||
kfree(mos7840_port->dr);
|
||||
kfree(mos7840_port);
|
||||
dbg ("mos7840_port %d = %p", i, mos7840_port);
|
||||
if (mos7840_port) {
|
||||
spin_lock_irqsave(&mos7840_port->pool_lock, flags);
|
||||
mos7840_port->zombie = 1;
|
||||
spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
|
||||
usb_kill_urb(mos7840_port->control_urb);
|
||||
kfree(mos7840_port->ctrl_buf);
|
||||
kfree(mos7840_port->dr);
|
||||
kfree(mos7840_port);
|
||||
}
|
||||
mos7840_set_port_private(serial->port[i], NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -159,14 +159,6 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port,
|
|||
priv->port = port;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
/*
|
||||
* Force low_latency on so that our tty_push actually forces the data
|
||||
* through, otherwise it is scheduled, and with high data rates (like
|
||||
* with OHCI) data can get lost.
|
||||
*/
|
||||
if (tty)
|
||||
tty->low_latency = 1;
|
||||
|
||||
/* Start reading from the device */
|
||||
usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev,
|
||||
usb_rcvbulkpipe(priv->udev,
|
||||
|
|
|
@ -936,9 +936,6 @@ static int option_open(struct tty_struct *tty,
|
|||
usb_pipeout(urb->pipe), 0); */
|
||||
}
|
||||
|
||||
if (tty)
|
||||
tty->low_latency = 1;
|
||||
|
||||
option_send_setup(tty, port);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
|
||||
*/
|
||||
|
||||
#define DRIVER_VERSION "v.1.3.2"
|
||||
#define DRIVER_VERSION "v.1.3.3"
|
||||
#define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>"
|
||||
#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
|
||||
|
||||
|
@ -259,9 +259,21 @@ static int sierra_send_setup(struct tty_struct *tty,
|
|||
val |= 0x02;
|
||||
|
||||
/* If composite device then properly report interface */
|
||||
if (serial->num_ports == 1)
|
||||
if (serial->num_ports == 1) {
|
||||
interface = sierra_calc_interface(serial);
|
||||
|
||||
/* Control message is sent only to interfaces with
|
||||
* interrupt_in endpoints
|
||||
*/
|
||||
if (port->interrupt_in_urb) {
|
||||
/* send control message */
|
||||
return usb_control_msg(serial->dev,
|
||||
usb_rcvctrlpipe(serial->dev, 0),
|
||||
0x22, 0x21, val, interface,
|
||||
NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise the need to do non-composite mapping */
|
||||
else {
|
||||
if (port->bulk_out_endpointAddress == 2)
|
||||
|
@ -270,12 +282,13 @@ static int sierra_send_setup(struct tty_struct *tty,
|
|||
interface = 1;
|
||||
else if (port->bulk_out_endpointAddress == 5)
|
||||
interface = 2;
|
||||
}
|
||||
|
||||
return usb_control_msg(serial->dev,
|
||||
return usb_control_msg(serial->dev,
|
||||
usb_rcvctrlpipe(serial->dev, 0),
|
||||
0x22, 0x21, val, interface,
|
||||
NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -585,9 +598,6 @@ static int sierra_open(struct tty_struct *tty,
|
|||
}
|
||||
}
|
||||
|
||||
if (tty)
|
||||
tty->low_latency = 1;
|
||||
|
||||
sierra_send_setup(tty, port);
|
||||
|
||||
/* start up the interrupt endpoint if we have one */
|
||||
|
|
|
@ -50,11 +50,10 @@
|
|||
|
||||
#define TI_TRANSFER_TIMEOUT 2
|
||||
|
||||
#define TI_DEFAULT_LOW_LATENCY 0
|
||||
#define TI_DEFAULT_CLOSING_WAIT 4000 /* in .01 secs */
|
||||
|
||||
/* supported setserial flags */
|
||||
#define TI_SET_SERIAL_FLAGS (ASYNC_LOW_LATENCY)
|
||||
#define TI_SET_SERIAL_FLAGS 0
|
||||
|
||||
/* read urb states */
|
||||
#define TI_READ_URB_RUNNING 0
|
||||
|
@ -161,7 +160,6 @@ static int ti_buf_get(struct circ_buf *cb, char *buf, int count);
|
|||
|
||||
/* module parameters */
|
||||
static int debug;
|
||||
static int low_latency = TI_DEFAULT_LOW_LATENCY;
|
||||
static int closing_wait = TI_DEFAULT_CLOSING_WAIT;
|
||||
static ushort vendor_3410[TI_EXTRA_VID_PID_COUNT];
|
||||
static unsigned int vendor_3410_count;
|
||||
|
@ -296,10 +294,6 @@ MODULE_FIRMWARE("mts_edge.fw");
|
|||
module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
|
||||
|
||||
module_param(low_latency, bool, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(low_latency,
|
||||
"TTY low_latency flag, 0=off, 1=on, default is off");
|
||||
|
||||
module_param(closing_wait, int, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(closing_wait,
|
||||
"Maximum wait for data to drain in close, in .01 secs, default is 4000");
|
||||
|
@ -448,7 +442,6 @@ static int ti_startup(struct usb_serial *serial)
|
|||
spin_lock_init(&tport->tp_lock);
|
||||
tport->tp_uart_base_addr = (i == 0 ?
|
||||
TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
|
||||
tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0;
|
||||
tport->tp_closing_wait = closing_wait;
|
||||
init_waitqueue_head(&tport->tp_msr_wait);
|
||||
init_waitqueue_head(&tport->tp_write_wait);
|
||||
|
@ -528,10 +521,6 @@ static int ti_open(struct tty_struct *tty,
|
|||
if (mutex_lock_interruptible(&tdev->td_open_close_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (tty)
|
||||
tty->low_latency =
|
||||
(tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
|
||||
|
||||
port_number = port->number - port->serial->minor;
|
||||
|
||||
memset(&(tport->tp_icount), 0x00, sizeof(tport->tp_icount));
|
||||
|
@ -1454,7 +1443,6 @@ static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport,
|
|||
return -EFAULT;
|
||||
|
||||
tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;
|
||||
tty->low_latency = (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
|
||||
tport->tp_closing_wait = new_serial.closing_wait;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -137,22 +137,10 @@ static void destroy_serial(struct kref *kref)
|
|||
|
||||
dbg("%s - %s", __func__, serial->type->description);
|
||||
|
||||
serial->type->shutdown(serial);
|
||||
|
||||
/* return the minor range that this device had */
|
||||
if (serial->minor != SERIAL_TTY_NO_MINOR)
|
||||
return_serial(serial);
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i)
|
||||
serial->port[i]->port.count = 0;
|
||||
|
||||
/* the ports are cleaned up and released in port_release() */
|
||||
for (i = 0; i < serial->num_ports; ++i)
|
||||
if (serial->port[i]->dev.parent != NULL) {
|
||||
device_unregister(&serial->port[i]->dev);
|
||||
serial->port[i] = NULL;
|
||||
}
|
||||
|
||||
/* If this is a "fake" port, we have to clean it up here, as it will
|
||||
* not get cleaned up in port_release() as it was never registered with
|
||||
* the driver core */
|
||||
|
@ -187,7 +175,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
|
|||
struct usb_serial *serial;
|
||||
struct usb_serial_port *port;
|
||||
unsigned int portNumber;
|
||||
int retval;
|
||||
int retval = 0;
|
||||
|
||||
dbg("%s", __func__);
|
||||
|
||||
|
@ -198,21 +186,24 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
mutex_lock(&serial->disc_mutex);
|
||||
portNumber = tty->index - serial->minor;
|
||||
port = serial->port[portNumber];
|
||||
if (!port) {
|
||||
if (!port || serial->disconnected)
|
||||
retval = -ENODEV;
|
||||
goto bailout_kref_put;
|
||||
}
|
||||
|
||||
if (port->serial->disconnected) {
|
||||
retval = -ENODEV;
|
||||
goto bailout_kref_put;
|
||||
}
|
||||
else
|
||||
get_device(&port->dev);
|
||||
/*
|
||||
* Note: Our locking order requirement does not allow port->mutex
|
||||
* to be acquired while serial->disc_mutex is held.
|
||||
*/
|
||||
mutex_unlock(&serial->disc_mutex);
|
||||
if (retval)
|
||||
goto bailout_serial_put;
|
||||
|
||||
if (mutex_lock_interruptible(&port->mutex)) {
|
||||
retval = -ERESTARTSYS;
|
||||
goto bailout_kref_put;
|
||||
goto bailout_port_put;
|
||||
}
|
||||
|
||||
++port->port.count;
|
||||
|
@ -232,14 +223,20 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
|
|||
goto bailout_mutex_unlock;
|
||||
}
|
||||
|
||||
retval = usb_autopm_get_interface(serial->interface);
|
||||
mutex_lock(&serial->disc_mutex);
|
||||
if (serial->disconnected)
|
||||
retval = -ENODEV;
|
||||
else
|
||||
retval = usb_autopm_get_interface(serial->interface);
|
||||
if (retval)
|
||||
goto bailout_module_put;
|
||||
|
||||
/* only call the device specific open if this
|
||||
* is the first time the port is opened */
|
||||
retval = serial->type->open(tty, port, filp);
|
||||
if (retval)
|
||||
goto bailout_interface_put;
|
||||
mutex_unlock(&serial->disc_mutex);
|
||||
}
|
||||
|
||||
mutex_unlock(&port->mutex);
|
||||
|
@ -248,13 +245,16 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
|
|||
bailout_interface_put:
|
||||
usb_autopm_put_interface(serial->interface);
|
||||
bailout_module_put:
|
||||
mutex_unlock(&serial->disc_mutex);
|
||||
module_put(serial->type->driver.owner);
|
||||
bailout_mutex_unlock:
|
||||
port->port.count = 0;
|
||||
tty->driver_data = NULL;
|
||||
tty_port_tty_set(&port->port, NULL);
|
||||
mutex_unlock(&port->mutex);
|
||||
bailout_kref_put:
|
||||
bailout_port_put:
|
||||
put_device(&port->dev);
|
||||
bailout_serial_put:
|
||||
usb_serial_put(serial);
|
||||
return retval;
|
||||
}
|
||||
|
@ -262,6 +262,9 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
|
|||
static void serial_close(struct tty_struct *tty, struct file *filp)
|
||||
{
|
||||
struct usb_serial_port *port = tty->driver_data;
|
||||
struct usb_serial *serial;
|
||||
struct module *owner;
|
||||
int count;
|
||||
|
||||
if (!port)
|
||||
return;
|
||||
|
@ -269,6 +272,8 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
|
|||
dbg("%s - port %d", __func__, port->number);
|
||||
|
||||
mutex_lock(&port->mutex);
|
||||
serial = port->serial;
|
||||
owner = serial->type->driver.owner;
|
||||
|
||||
if (port->port.count == 0) {
|
||||
mutex_unlock(&port->mutex);
|
||||
|
@ -281,7 +286,7 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
|
|||
* this before we drop the port count. The call is protected
|
||||
* by the port mutex
|
||||
*/
|
||||
port->serial->type->close(tty, port, filp);
|
||||
serial->type->close(tty, port, filp);
|
||||
|
||||
if (port->port.count == (port->console ? 2 : 1)) {
|
||||
struct tty_struct *tty = tty_port_tty_get(&port->port);
|
||||
|
@ -295,17 +300,23 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
|
|||
}
|
||||
}
|
||||
|
||||
if (port->port.count == 1) {
|
||||
mutex_lock(&port->serial->disc_mutex);
|
||||
if (!port->serial->disconnected)
|
||||
usb_autopm_put_interface(port->serial->interface);
|
||||
mutex_unlock(&port->serial->disc_mutex);
|
||||
module_put(port->serial->type->driver.owner);
|
||||
}
|
||||
--port->port.count;
|
||||
|
||||
count = port->port.count;
|
||||
mutex_unlock(&port->mutex);
|
||||
usb_serial_put(port->serial);
|
||||
put_device(&port->dev);
|
||||
|
||||
/* Mustn't dereference port any more */
|
||||
if (count == 0) {
|
||||
mutex_lock(&serial->disc_mutex);
|
||||
if (!serial->disconnected)
|
||||
usb_autopm_put_interface(serial->interface);
|
||||
mutex_unlock(&serial->disc_mutex);
|
||||
}
|
||||
usb_serial_put(serial);
|
||||
|
||||
/* Mustn't dereference serial any more */
|
||||
if (count == 0)
|
||||
module_put(owner);
|
||||
}
|
||||
|
||||
static int serial_write(struct tty_struct *tty, const unsigned char *buf,
|
||||
|
@ -549,7 +560,13 @@ static void kill_traffic(struct usb_serial_port *port)
|
|||
|
||||
static void port_free(struct usb_serial_port *port)
|
||||
{
|
||||
/*
|
||||
* Stop all the traffic before cancelling the work, so that
|
||||
* nobody will restart it by calling usb_serial_port_softint.
|
||||
*/
|
||||
kill_traffic(port);
|
||||
cancel_work_sync(&port->work);
|
||||
|
||||
usb_free_urb(port->read_urb);
|
||||
usb_free_urb(port->write_urb);
|
||||
usb_free_urb(port->interrupt_in_urb);
|
||||
|
@ -558,7 +575,6 @@ static void port_free(struct usb_serial_port *port)
|
|||
kfree(port->bulk_out_buffer);
|
||||
kfree(port->interrupt_in_buffer);
|
||||
kfree(port->interrupt_out_buffer);
|
||||
flush_scheduled_work(); /* port->work */
|
||||
kfree(port);
|
||||
}
|
||||
|
||||
|
@ -1043,6 +1059,12 @@ void usb_serial_disconnect(struct usb_interface *interface)
|
|||
usb_set_intfdata(interface, NULL);
|
||||
/* must set a flag, to signal subdrivers */
|
||||
serial->disconnected = 1;
|
||||
mutex_unlock(&serial->disc_mutex);
|
||||
|
||||
/* Unfortunately, many of the sub-drivers expect the port structures
|
||||
* to exist when their shutdown method is called, so we have to go
|
||||
* through this awkward two-step unregistration procedure.
|
||||
*/
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
port = serial->port[i];
|
||||
if (port) {
|
||||
|
@ -1052,11 +1074,21 @@ void usb_serial_disconnect(struct usb_interface *interface)
|
|||
tty_kref_put(tty);
|
||||
}
|
||||
kill_traffic(port);
|
||||
cancel_work_sync(&port->work);
|
||||
device_del(&port->dev);
|
||||
}
|
||||
}
|
||||
serial->type->shutdown(serial);
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
port = serial->port[i];
|
||||
if (port) {
|
||||
put_device(&port->dev);
|
||||
serial->port[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* let the last holder of this object
|
||||
* cause it to be cleaned up */
|
||||
mutex_unlock(&serial->disc_mutex);
|
||||
usb_serial_put(serial);
|
||||
dev_info(dev, "device disconnected\n");
|
||||
}
|
||||
|
|
|
@ -296,14 +296,6 @@ static int visor_open(struct tty_struct *tty, struct usb_serial_port *port,
|
|||
priv->throttled = 0;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
/*
|
||||
* Force low_latency on so that our tty_push actually forces the data
|
||||
* through, otherwise it is scheduled, and with high data rates (like
|
||||
* with OHCI) data can get lost.
|
||||
*/
|
||||
if (tty)
|
||||
tty->low_latency = 1;
|
||||
|
||||
/* Start reading from the device */
|
||||
usb_fill_bulk_urb(port->read_urb, serial->dev,
|
||||
usb_rcvbulkpipe(serial->dev,
|
||||
|
|
|
@ -1851,6 +1851,12 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001,
|
|||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_CAPACITY_HEURISTICS),
|
||||
|
||||
/* Reported by Alessio Treglia <quadrispro@ubuntu.com> */
|
||||
UNUSUAL_DEV( 0xed10, 0x7636, 0x0001, 0x0001,
|
||||
"TGE",
|
||||
"Digital MP3 Audio Player",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
|
||||
|
||||
/* Control/Bulk transport for all SubClass values */
|
||||
USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
|
||||
USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
* key configuration differences between boards.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_MUSB_H
|
||||
#define __LINUX_USB_MUSB_H
|
||||
|
||||
/* The USB role is defined by the connector used on the board, so long as
|
||||
* standards are being followed. (Developer boards sometimes won't.)
|
||||
*/
|
||||
|
@ -101,3 +104,5 @@ extern int __init tusb6010_setup_interface(
|
|||
extern int tusb6010_platform_retime(unsigned is_refclk);
|
||||
|
||||
#endif /* OMAP2 */
|
||||
|
||||
#endif /* __LINUX_USB_MUSB_H */
|
||||
|
|
Loading…
Reference in New Issue
Block a user