Commit a60387ba authored by Linus Torvalds's avatar Linus Torvalds

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: (40 commits)
  USB: open disconnect race in usblcd
  USB: disconnect open race in legousbtower
  USB: open disconnect race in iowarrior
  USB: missing error check in emi62
  USB: missing error check in emi26
  USB: usb_serial_resume bug fix
  USB: remove new OHCI build warnings
  USB: amd5536udc - remove set_mwi() compiler warning
  USB: usbserial - fix potential deadlock between write() and IRQ
  usb: serial/pl2303: support for IO Data Device RSAQ5
  USB: fix read vs. disconnect race in cytherm driver
  USB: fix locking in idmouse
  USB: fix interface sysfs file-creation bug
  USB: fix ssb_ohci_probe() build bug
  USB: pl2303: remove can't happen checks, set speed properly and report baud rate
  USB: mos7840: Clean up old checks and stuff
  USB rio500.c: fix check-after-use
  USB iowarrior.c: fix check-after-use
  USB: add URB_FREE_BUFFER to permissible flags
  USB: isd200: sort out USB/IDE dependancy mess
  ...
parents 0e81bef0 d5d1ceac
......@@ -1875,6 +1875,7 @@ uart_set_options(struct uart_port *port, struct console *co,
int baud, int parity, int bits, int flow)
{
struct ktermios termios;
static struct ktermios dummy;
int i;
/*
......@@ -1920,7 +1921,7 @@ uart_set_options(struct uart_port *port, struct console *co,
*/
port->mctrl |= TIOCM_DTR;
port->ops->set_termios(port, &termios, NULL);
port->ops->set_termios(port, &termios, &dummy);
co->cflag = termios.c_cflag;
return 0;
......
......@@ -1641,7 +1641,13 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
intf->dev.bus_id, ret);
continue;
}
usb_create_sysfs_intf_files (intf);
/* The driver's probe method can call usb_set_interface(),
* which would mean the interface's sysfs files are already
* created. Just in case, we'll remove them first.
*/
usb_remove_sysfs_intf_files(intf);
usb_create_sysfs_intf_files(intf);
}
usb_autosuspend_device(dev);
......
......@@ -372,7 +372,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
/* enforce simple/standard policy */
allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |
URB_NO_INTERRUPT | URB_DIR_MASK);
URB_NO_INTERRUPT | URB_DIR_MASK | URB_FREE_BUFFER);
switch (xfertype) {
case USB_ENDPOINT_XFER_BULK:
if (is_out)
......
......@@ -3289,7 +3289,7 @@ static int udc_pci_probe(
dev->chiprev = pdev->revision;
pci_set_master(pdev);
pci_set_mwi(pdev);
pci_try_set_mwi(pdev);
/* init dma pools */
if (use_dma) {
......
......@@ -156,7 +156,7 @@ config USB_OHCI_HCD_PCI
config USB_OHCI_HCD_SSB
bool "OHCI support for Broadcom SSB OHCI core"
depends on USB_OHCI_HCD && SSB && EXPERIMENTAL
depends on USB_OHCI_HCD && (SSB = y || SSB = CONFIG_USB_OHCI_HCD) && EXPERIMENTAL
default n
---help---
Support for the Sonics Silicon Backplane (SSB) attached
......
......@@ -80,7 +80,10 @@ static const char hcd_name [] = "ohci_hcd";
static void ohci_dump (struct ohci_hcd *ohci, int verbose);
static int ohci_init (struct ohci_hcd *ohci);
static void ohci_stop (struct usb_hcd *hcd);
#if defined(CONFIG_PM) || defined(CONFIG_PCI)
static int ohci_restart (struct ohci_hcd *ohci);
#endif
#include "ohci-hub.c"
#include "ohci-dbg.c"
......@@ -396,7 +399,7 @@ static int check_ed(struct ohci_hcd *ohci, struct ed *ed)
*/
static void unlink_watchdog_func(unsigned long _ohci)
{
long flags;
unsigned long flags;
unsigned max;
unsigned seen_count = 0;
unsigned i;
......@@ -893,6 +896,8 @@ static void ohci_stop (struct usb_hcd *hcd)
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_PM) || defined(CONFIG_PCI)
/* must not be called from interrupt context */
static int ohci_restart (struct ohci_hcd *ohci)
{
......@@ -954,6 +959,8 @@ static int ohci_restart (struct ohci_hcd *ohci)
return 0;
}
#endif
/*-------------------------------------------------------------------------*/
#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
......
......@@ -1271,7 +1271,8 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
} else if (qh->period != urb->interval) {
return -EINVAL; /* Can't change the period */
} else { /* Pick up where the last URB leaves off */
} else {
/* Find the next unused frame */
if (list_empty(&qh->queue)) {
frame = qh->iso_frame;
} else {
......@@ -1283,10 +1284,18 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
lurb->number_of_packets *
lurb->interval;
}
if (urb->transfer_flags & URB_ISO_ASAP)
urb->start_frame = frame;
else if (urb->start_frame != frame)
return -EINVAL;
if (urb->transfer_flags & URB_ISO_ASAP) {
/* Skip some frames if necessary to insure
* the start frame is in the future.
*/
uhci_get_current_frame_number(uhci);
if (uhci_frame_before_eq(frame, uhci->frame_number)) {
frame = uhci->frame_number + 1;
frame += ((qh->phase - frame) &
(qh->period - 1));
}
} /* Otherwise pick up where the last URB leaves off */
urb->start_frame = frame;
}
/* Make sure we won't have to go too far into the future */
......
......@@ -399,7 +399,6 @@ static void cytherm_disconnect(struct usb_interface *interface)
struct usb_cytherm *dev;
dev = usb_get_intfdata (interface);
usb_set_intfdata (interface, NULL);
device_remove_file(&interface->dev, &dev_attr_brightness);
device_remove_file(&interface->dev, &dev_attr_temp);
......@@ -407,6 +406,9 @@ static void cytherm_disconnect(struct usb_interface *interface)
device_remove_file(&interface->dev, &dev_attr_port0);
device_remove_file(&interface->dev, &dev_attr_port1);
/* first remove the files, then NULL the pointer */
usb_set_intfdata (interface, NULL);
usb_put_dev(dev->udev);
kfree(dev);
......
......@@ -114,6 +114,10 @@ static int emi26_load_firmware (struct usb_device *dev)
/* De-assert reset (let the CPU run) */
err = emi26_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
goto wraperr;
}
msleep(250); /* let device settle */
/* 2. We upload the FPGA firmware into the EMI
......
......@@ -123,6 +123,10 @@ static int emi62_load_firmware (struct usb_device *dev)
/* De-assert reset (let the CPU run) */
err = emi62_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
goto wraperr;
}
msleep(250); /* let device settle */
/* 2. We upload the FPGA firmware into the EMI
......
......@@ -147,7 +147,7 @@ struct u132_target {
/* Structure to hold all of our device specific stuff*/
struct usb_ftdi {
struct list_head ftdi_list;
struct semaphore u132_lock;
struct mutex u132_lock;
int command_next;
int command_head;
struct u132_command command[COMMAND_SIZE];
......@@ -330,39 +330,39 @@ static int ftdi_elan_hcd_init(struct usb_ftdi *ftdi)
static void ftdi_elan_abandon_completions(struct usb_ftdi *ftdi)
{
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
while (ftdi->respond_next > ftdi->respond_head) {
struct u132_respond *respond = &ftdi->respond[RESPOND_MASK &
ftdi->respond_head++];
*respond->result = -ESHUTDOWN;
*respond->value = 0;
complete(&respond->wait_completion);
} up(&ftdi->u132_lock);
} mutex_unlock(&ftdi->u132_lock);
}
static void ftdi_elan_abandon_targets(struct usb_ftdi *ftdi)
{
int ed_number = 4;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
while (ed_number-- > 0) {
struct u132_target *target = &ftdi->target[ed_number];
if (target->active == 1) {
target->condition_code = TD_DEVNOTRESP;
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
ftdi_elan_do_callback(ftdi, target, NULL, 0);
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
}
}
ftdi->recieved = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
}
static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
{
int ed_number = 4;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
while (ed_number-- > 0) {
struct u132_target *target = &ftdi->target[ed_number];
target->abandoning = 1;
......@@ -382,9 +382,9 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
goto wait_1;
}
}
......@@ -404,9 +404,9 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
goto wait_2;
}
}
......@@ -414,13 +414,13 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
ftdi->recieved = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
}
static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
{
int ed_number = 4;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
while (ed_number-- > 0) {
struct u132_target *target = &ftdi->target[ed_number];
target->abandoning = 1;
......@@ -440,9 +440,9 @@ static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
goto wait;
}
}
......@@ -450,7 +450,7 @@ static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
ftdi->recieved = 0;
ftdi->expected = 4;
ftdi->ed_found = 0;
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
}
static void ftdi_elan_kick_command_queue(struct usb_ftdi *ftdi)
......@@ -886,14 +886,14 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
char *b)
{
int payload = (ed_length >> 0) & 0x07FF;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
target->actual = 0;
target->non_null = (ed_length >> 15) & 0x0001;
target->repeat_number = (ed_length >> 11) & 0x000F;
if (ed_type == 0x02) {
if (payload == 0 || target->abandoning > 0) {
target->abandoning = 0;
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
payload);
ftdi->recieved = 0;
......@@ -903,13 +903,13 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
} else {
ftdi->expected = 4 + payload;
ftdi->ed_found = 1;
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return b;
}
} else if (ed_type == 0x03) {
if (payload == 0 || target->abandoning > 0) {
target->abandoning = 0;
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
payload);
ftdi->recieved = 0;
......@@ -919,12 +919,12 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
} else {
ftdi->expected = 4 + payload;
ftdi->ed_found = 1;
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return b;
}
} else if (ed_type == 0x01) {
target->abandoning = 0;
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
payload);
ftdi->recieved = 0;
......@@ -933,7 +933,7 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
return ftdi->response;
} else {
target->abandoning = 0;
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
payload);
ftdi->recieved = 0;
......@@ -947,12 +947,12 @@ static char *have_ed_get_response(struct usb_ftdi *ftdi,
struct u132_target *target, u16 ed_length, int ed_number, int ed_type,
char *b)
{
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
target->condition_code = TD_DEVNOTRESP;
target->actual = (ed_length >> 0) & 0x01FF;
target->non_null = (ed_length >> 15) & 0x0001;
target->repeat_number = (ed_length >> 11) & 0x000F;
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
if (target->active)
ftdi_elan_do_callback(ftdi, target, NULL, 0);
target->abandoning = 0;
......@@ -1278,7 +1278,7 @@ static int ftdi_elan_write_reg(struct usb_ftdi *ftdi, u32 data)
return -ENODEV;
} else {
int command_size;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
if (command_size < COMMAND_SIZE) {
struct u132_command *command = &ftdi->command[
......@@ -1292,10 +1292,10 @@ static int ftdi_elan_write_reg(struct usb_ftdi *ftdi, u32 data)
command->buffer = &command->value;
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return 0;
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
goto wait;
}
......@@ -1310,7 +1310,7 @@ static int ftdi_elan_write_config(struct usb_ftdi *ftdi, int config_offset,
return -ENODEV;
} else {
int command_size;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
if (command_size < COMMAND_SIZE) {
struct u132_command *command = &ftdi->command[
......@@ -1324,10 +1324,10 @@ static int ftdi_elan_write_config(struct usb_ftdi *ftdi, int config_offset,
command->buffer = &command->value;
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return 0;
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
goto wait;
}
......@@ -1342,7 +1342,7 @@ static int ftdi_elan_write_pcimem(struct usb_ftdi *ftdi, int mem_offset,
return -ENODEV;
} else {
int command_size;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
if (command_size < COMMAND_SIZE) {
struct u132_command *command = &ftdi->command[
......@@ -1356,10 +1356,10 @@ static int ftdi_elan_write_pcimem(struct usb_ftdi *ftdi, int mem_offset,
command->buffer = &command->value;
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return 0;
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
goto wait;
}
......@@ -1382,7 +1382,7 @@ static int ftdi_elan_read_reg(struct usb_ftdi *ftdi, u32 *data)
} else {
int command_size;
int respond_size;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
respond_size = ftdi->respond_next - ftdi->respond_head;
if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE)
......@@ -1405,11 +1405,11 @@ static int ftdi_elan_read_reg(struct usb_ftdi *ftdi, u32 *data)
ftdi->command_next += 1;
ftdi->respond_next += 1;
ftdi_elan_kick_command_queue(ftdi);
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
wait_for_completion(&respond->wait_completion);
return result;
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
goto wait;
}
......@@ -1425,7 +1425,7 @@ static int ftdi_elan_read_config(struct usb_ftdi *ftdi, int config_offset,
} else {
int command_size;
int respond_size;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
respond_size = ftdi->respond_next - ftdi->respond_head;
if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE)
......@@ -1449,11 +1449,11 @@ static int ftdi_elan_read_config(struct usb_ftdi *ftdi, int config_offset,
ftdi->command_next += 1;
ftdi->respond_next += 1;
ftdi_elan_kick_command_queue(ftdi);
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
wait_for_completion(&respond->wait_completion);
return result;
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
goto wait;
}
......@@ -1469,7 +1469,7 @@ static int ftdi_elan_read_pcimem(struct usb_ftdi *ftdi, int mem_offset,
} else {
int command_size;
int respond_size;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
respond_size = ftdi->respond_next - ftdi->respond_head;
if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE)
......@@ -1493,11 +1493,11 @@ static int ftdi_elan_read_pcimem(struct usb_ftdi *ftdi, int mem_offset,
ftdi->command_next += 1;
ftdi->respond_next += 1;
ftdi_elan_kick_command_queue(ftdi);
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
wait_for_completion(&respond->wait_completion);
return result;
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
goto wait;
}
......@@ -1529,7 +1529,7 @@ static int ftdi_elan_edset_setup(struct usb_ftdi *ftdi, u8 ed_number,
return -ENODEV;
} else {
int command_size;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
if (command_size < COMMAND_SIZE) {
struct u132_target *target = &ftdi->target[ed];
......@@ -1550,10 +1550,10 @@ static int ftdi_elan_edset_setup(struct usb_ftdi *ftdi, u8 ed_number,
target->active = 1;
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return 0;
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
goto wait;
}
......@@ -1586,7 +1586,7 @@ static int ftdi_elan_edset_input(struct usb_ftdi *ftdi, u8 ed_number,
return -ENODEV;
} else {
int command_size;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
if (command_size < COMMAND_SIZE) {
struct u132_target *target = &ftdi->target[ed];
......@@ -1615,10 +1615,10 @@ static int ftdi_elan_edset_input(struct usb_ftdi *ftdi, u8 ed_number,
target->active = 1;
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return 0;
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
goto wait;
}
......@@ -1651,7 +1651,7 @@ static int ftdi_elan_edset_empty(struct usb_ftdi *ftdi, u8 ed_number,
return -ENODEV;
} else {
int command_size;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
if (command_size < COMMAND_SIZE) {
struct u132_target *target = &ftdi->target[ed];
......@@ -1672,10 +1672,10 @@ static int ftdi_elan_edset_empty(struct usb_ftdi *ftdi, u8 ed_number,
target->active = 1;
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return 0;
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
goto wait;
}
......@@ -1708,7 +1708,7 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number,
return -ENODEV;
} else {
int command_size;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
if (command_size < COMMAND_SIZE) {
u8 *b;
......@@ -1751,10 +1751,10 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number,
target->active = 1;
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return 0;
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
goto wait;
}
......@@ -1787,7 +1787,7 @@ static int ftdi_elan_edset_single(struct usb_ftdi *ftdi, u8 ed_number,
return -ENODEV;
} else {
int command_size;
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
if (command_size < COMMAND_SIZE) {
int remaining_length = urb->transfer_buffer_length -
......@@ -1816,10 +1816,10 @@ static int ftdi_elan_edset_single(struct usb_ftdi *ftdi, u8 ed_number,
target->active = 1;
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return 0;
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
goto wait;
}
......@@ -1849,9 +1849,9 @@ static int ftdi_elan_edset_flush(struct usb_ftdi *ftdi, u8 ed_number,
return -ENODEV;
} else {
struct u132_target *target = &ftdi->target[ed];
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
if (target->abandoning > 0) {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return 0;
} else {
target->abandoning = 1;
......@@ -1873,13 +1873,13 @@ static int ftdi_elan_edset_flush(struct usb_ftdi *ftdi, u8 ed_number,
ftdi->command_next += 1;
ftdi_elan_kick_command_queue(ftdi);
} else {
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
msleep(100);
down(&ftdi->u132_lock);
mutex_lock(&ftdi->u132_lock);
goto wait_1;
}
}
up(&ftdi->u132_lock);
mutex_unlock(&ftdi->u132_lock);
return 0;
}
}
......@@ -2793,7 +2793,7 @@ static int ftdi_elan_probe(struct usb_interface *interface,
init_MUTEX(&ftdi->sw_lock);
ftdi->udev = usb_get_dev(interface_to_usbdev(interface));
ftdi->interface = interface;
init_MUTEX(&ftdi->u132_lock);
mutex_init(&ftdi->u132_lock);
ftdi->expected = 4;
iface_desc = interface->cur_altsetting;
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
......
......@@ -66,6 +66,7 @@ static struct usb_device_id idmouse_table[] = {
USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000)
MODULE_DEVICE_TABLE(usb, idmouse_table);
static DEFINE_MUTEX(open_disc_mutex);
/* structure to hold all of our device specific stuff */
struct usb_idmouse {
......@@ -80,7 +81,7 @@ struct usb_idmouse {
int open; /* if the port is open or not */
int present; /* if the device is not disconnected */
struct semaphore sem; /* locks this structure */
struct mutex lock; /* locks this structure */
};
......@@ -213,13 +214,17 @@ static int idmouse_open(struct inode *inode, struct file *file)
if (!interface)
return -ENODEV;
mutex_lock(&open_disc_mutex);
/* get the device information block from the interface */
dev = usb_get_intfdata(interface);
if (!dev)
if (!dev) {
mutex_unlock(&open_disc_mutex);
return -ENODEV;
}
/* lock this device */
down(&dev->sem);
mutex_lock(&dev->lock);
mutex_unlock(&open_disc_mutex);
/* check if already open */
if (dev->open) {
......@@ -245,7 +250,7 @@ static int idmouse_open(struct inode *inode, struct file *file)
error:
/* unlock this device */
up(&dev->sem);
mutex_unlock(&dev->lock);
return result;
}
......@@ -258,12 +263,14 @@ static int idmouse_release(struct inode *inode, struct file *file)
if (dev == NULL)
return -ENODEV;
mutex_lock(&open_disc_mutex);
/* lock our device */
down(&dev->sem);
mutex_lock(&dev->lock);
/* are we really open? */
if (dev->open <= 0) {
up(&dev->sem);
mutex_unlock(&dev->lock);
mutex_unlock(&open_disc_mutex);
return -ENODEV;
}
......@@ -271,10 +278,12 @@ static int idmouse_release(struct inode *inode, struct file *file)
if (!dev->present) {
/* the device was unplugged before the file was released */
up(&dev->sem);
mutex_unlock(&dev->lock);
mutex_unlock(&open_disc_mutex);
idmouse_delete(dev);
} else {
up(&dev->sem);
mutex_unlock(&dev->lock);
mutex_unlock(&open_disc_mutex);
}
return 0;
}
......@@ -286,18 +295,18 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count
int result;
/* lock this object */
down(&dev->sem);
mutex_lock(&dev->lock);
/* verify that the device wasn't unplugged */
if (!dev->present) {
up(&dev->sem);
mutex_unlock(&dev->lock);
return -ENODEV;
}
result = simple_read_from_buffer(buffer, count, ppos,
dev->bulk_in_buffer, IMGSIZE);
/* unlock the device */
up(&dev->sem);
mutex_unlock(&dev->lock);
return result;
}
......@@ -320,7 +329,7 @@ static int idmouse_probe(struct usb_interface *interface,
if (dev == NULL)
return -ENOMEM;
init_MUTEX(&dev->sem);
mutex_init(&dev->lock);
dev->udev = udev;
dev->interface = interface;
......@@ -372,24 +381,26 @@ static void idmouse_disconnect(struct usb_interface *interface)
/* get device structure */
dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
/* give back our minor */
usb_deregister_dev(interface, &idmouse_class);
/* lock it */
down(&dev->sem);
mutex_lock(&open_disc_mutex);
usb_set_intfdata(interface, NULL);
/* lock the device */
mutex_lock(&dev->lock);
mutex_unlock(&open_disc_mutex);
/* prevent device read, write and ioctl */
dev->present = 0;
/* if the device is opened, idmouse_release will clean this up */
if (!dev->open) {
up(&dev->sem);
mutex_unlock(&dev->lock);
idmouse_delete(dev);
} else {
/* unlock */
up(&dev->sem);
mutex_unlock(&dev->lock);
}
info("%s disconnected", DRIVER_DESC);
......
......@@ -66,6 +66,7 @@ module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
static struct usb_driver iowarrior_driver;
static DEFINE_MUTEX(iowarrior_open_disc_lock);
/*--------------*/
/* data */
......@@ -351,7 +352,7 @@ static ssize_t iowarrior_write(struct file *file,
mutex_lock(&dev->mutex);
/* verify that the device wasn't unplugged */
if (dev == NULL || !dev->present) {
if (!dev->present) {
retval = -ENODEV;
goto exit;
}
......@@ -608,11 +609,15 @@ static int iowarrior_open(struct inode *inode, struct file *file)
return -ENODEV;
}
mutex_lock(&iowarrior_open_disc_lock);
dev = usb_get_intfdata(interface);
if (!dev)
if (!dev) {
mutex_unlock(&iowarrior_open_disc_lock);
return -ENODEV;
}
mutex_lock(&dev->mutex);
mutex_unlock(&iowarrior_open_disc_lock);
/* Only one process can open each device, no sharing. */
if (dev->opened) {
......@@ -866,6 +871,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
int minor;
dev = usb_get_intfdata(interface);
mutex_lock(&iowarrior_open_disc_lock);
usb_set_intfdata(interface, NULL);
minor = dev->minor;
......@@ -879,6 +885,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
dev->present = 0;
mutex_unlock(&dev->mutex);
mutex_unlock(&iowarrior_open_disc_lock);
if (dev->opened) {
/* There is a process that holds a filedescriptor to the device ,
......
......@@ -198,6 +198,7 @@ static struct usb_device_id tower_table [] = {
};
MODULE_DEVICE_TABLE (usb, tower_table);
static DEFINE_MUTEX(open_disc_mutex);
#define LEGO_USB_TOWER_MINOR_BASE 160
......@@ -350,25 +351,31 @@ static int tower_open (struct inode *inode, struct file *file)
goto exit;
}
mutex_lock(&open_disc_mutex);
dev = usb_get_intfdata(interface);
if (!dev) {
mutex_unlock(&open_disc_mutex);
retval = -ENODEV;
goto exit;
}
/* lock this device */
if (down_interruptible (&dev->sem)) {
mutex_unlock(&open_disc_mutex);
retval = -ERESTARTSYS;
goto exit;
}
/* allow opening only once */
if (dev->open_count) {
mutex_unlock(&open_disc_mutex);
retval = -EBUSY;
goto unlock_exit;
}
dev->open_count = 1;
mutex_unlock(&open_disc_mutex);
/* reset the tower */
result = usb_control_msg (dev->udev,
......@@ -437,9 +444,10 @@ static int tower_release (struct inode *inode, struct file *file)
if (dev == NULL) {
dbg(1, "%s: object is NULL", __FUNCTION__);
retval = -ENODEV;
goto exit;
goto exit_nolock;
}
mutex_lock(&open_disc_mutex);
if (down_interruptible (&dev->sem)) {
retval = -ERESTARTSYS;
goto exit;
......@@ -468,6 +476,8 @@ static int tower_release (struct inode *inode, struct file *file)
up (&dev->sem);
exit:
mutex_unlock(&open_disc_mutex);
exit_nolock:
dbg(2, "%s: leave, return value %d", __FUNCTION__, retval);
return retval;
}
......@@ -989,6 +999,7 @@ static void tower_disconnect (struct usb_interface *interface)
dbg(2, "%s: enter", __FUNCTION__);
dev = usb_get_intfdata (interface);
mutex_lock(&open_disc_mutex);
usb_set_intfdata (interface, NULL);
minor = dev->minor;
......@@ -997,6 +1008,7 @@ static void tower_disconnect (struct usb_interface *interface)
usb_deregister_dev (interface, &tower_class);
down (&dev->sem);
mutex_unlock(&open_disc_mutex);
/* if the device is not opened, then we clean up right now */
if (!dev->open_count) {
......
......@@ -118,10 +118,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
mutex_lock(&(rio->lock));
/* Sanity check to make sure rio is connected, powered, etc */
if ( rio == NULL ||
rio->present == 0 ||
rio->rio_dev == NULL )
{
if (rio->present == 0 || rio->rio_dev == NULL) {
retval = -ENODEV;
goto err_out;
}
......@@ -280,10 +277,7 @@ write_rio(struct file *file, const char __user *buffer,
if (intr)
return -EINTR;
/* Sanity check to make sure rio is connected, powered, etc */
if ( rio == NULL ||
rio->present == 0 ||
rio->rio_dev == NULL )
{
if (rio->present == 0 || rio->rio_dev == NULL) {
mutex_unlock(&(rio->lock));
return -ENODEV;
}
......@@ -369,10 +363,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
if (intr)
return -EINTR;
/* Sanity check to make sure rio is connected, powered, etc */
if ( rio == NULL ||
rio->present == 0 ||
rio->rio_dev == NULL )
{
if (rio->present == 0 || rio->rio_dev == NULL) {
mutex_unlock(&(rio->lock));
return -ENODEV;
}
......
......@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
......@@ -34,6 +35,8 @@ static struct usb_device_id id_table [] = {
};
MODULE_DEVICE_TABLE (usb, id_table);
static DEFINE_MUTEX(open_disc_mutex);
struct usb_lcd {
struct usb_device * udev; /* init: probe_lcd */
......@@ -79,12 +82,16 @@ static int lcd_open(struct inode *inode, struct file *file)
return -ENODEV;
}
mutex_lock(&open_disc_mutex);
dev = usb_get_intfdata(interface);
if (!dev)
if (!dev) {
mutex_unlock(&open_disc_mutex);
return -ENODEV;
}
/* increment our usage count for the device */
kref_get(&dev->kref);
mutex_unlock(&open_disc_mutex);
/* grab a power reference */
r = usb_autopm_get_interface(interface);
......@@ -393,8 +400,10 @@ static void lcd_disconnect(struct usb_interface *interface)
struct usb_lcd *dev;
int minor = interface->minor;
mutex_lock(&open_disc_mutex);
dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
mutex_unlock(&open_disc_mutex);
/* give back our minor */
usb_deregister_dev(interface, &lcd_class);
......
......@@ -161,7 +161,8 @@ static void ark3116_set_termios(struct usb_serial_port *port,
{
struct usb_serial *serial = port->serial;
struct ark3116_private *priv = usb_get_serial_port_data(port);
unsigned int cflag = port->tty->termios->c_cflag;
struct ktermios *termios = port->tty->termios;
unsigned int cflag = termios->c_cflag;
unsigned long flags;
int baud;
int ark3116_baud;
......@@ -177,11 +178,14 @@ static void ark3116_set_termios(struct usb_serial_port *port,
*(port->tty->termios) = tty_std_termios;
port->tty->termios->c_cflag = B9600 | CS8
| CREAD | HUPCL | CLOCAL;
termios->c_ispeed = 9600;
termios->c_ospeed = 9600;
priv->termios_initialized = 1;
}
spin_unlock_irqrestore(&priv->lock, flags);
cflag = port->tty->termios->c_cflag;
cflag = termios->c_cflag;
termios->c_cflag &= ~(CMSPAR|CRTSCTS);
buf = kmalloc(1, GFP_KERNEL);
if (!buf) {
......@@ -254,9 +258,13 @@ static void ark3116_set_termios(struct usb_serial_port *port,
case 115200:
case 230400:
case 460800:
/* Report the resulting rate back to the caller */
tty_encode_baud_rate(port->tty, baud, baud);
break;
/* set 9600 as default (if given baudrate is invalid for example) */
default:
tty_encode_baud_rate(port->tty, 9600, 9600);
case 0:
baud = 9600;
}
......@@ -302,6 +310,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
/* TEST ARK3116_SND(154, 0xFE, 0x40, 0xFFFF, 0x0006); */
kfree(buf);
return;
}
......
......@@ -272,9 +272,6 @@ static void ch341_set_termios(struct usb_serial_port *port,
dbg("ch341_set_termios()");
if (!tty || !tty->termios)
return;
baud_rate = tty_get_baud_rate(tty);
switch (baud_rate) {
......@@ -299,6 +296,11 @@ static void ch341_set_termios(struct usb_serial_port *port,
* (cflag & PARENB) : parity {NONE, EVEN, ODD}
* (cflag & CSTOPB) : stop bits [1, 2]
*/
/* Copy back the old hardware settings */
tty_termios_copy_hw(tty->termios, old_termios);
/* And re-encode with the new baud */
tty_encode_baud_rate(tty, baud_rate, baud_rate);
}
static struct usb_driver ch341_driver = {
......
......@@ -164,6 +164,7 @@ static int usb_console_setup(struct console *co, char *options)
}
if (serial->type->set_termios) {
struct ktermios dummy;
/* build up a fake tty structure so that the open call has something
* to look at to get the cflag value */
tty = kzalloc(sizeof(*tty), GFP_KERNEL);
......@@ -177,12 +178,13 @@ static int usb_console_setup(struct console *co, char *options)
kfree (tty);
return -ENOMEM;
}
memset(&dummy, 0, sizeof(struct ktermios));
termios->c_cflag = cflag;
tty->termios = termios;
port->tty = tty;
/* set up the initial termios settings */
serial->type->set_termios(port, NULL);
serial->type->set_termios(port, &dummy);
port->tty = NULL;
kfree (termios);
kfree (tty);
......
......@@ -361,7 +361,6 @@ static void cp2101_get_termios (struct usb_serial_port *port)
dbg("%s - no tty structures", __FUNCTION__);
return;
}
cflag = port->tty->termios->c_cflag;
cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
/* Convert to baudrate */
......@@ -369,40 +368,9 @@ static void cp2101_get_termios (struct usb_serial_port *port)
baud = BAUD_RATE_GEN_FREQ / baud;
dbg("%s - baud rate = %d", __FUNCTION__, baud);
cflag &= ~CBAUD;
switch (baud) {
/*
* The baud rates which are commented out below
* appear to be supported by the device
* but are non-standard
*/
case 600: cflag |= B600; break;
case 1200: cflag |= B1200; break;
case 1800: cflag |= B1800; break;
case 2400: cflag |= B2400; break;
case 4800: cflag |= B4800; break;
/*case 7200: cflag |= B7200; break;*/
case 9600: cflag |= B9600; break;
/*case 14400: cflag |= B14400; break;*/
case 19200: cflag |= B19200; break;
/*case 28800: cflag |= B28800; break;*/
case 38400: cflag |= B38400; break;
/*case 55854: cflag |= B55054; break;*/
case 57600: cflag |= B57600; break;
case 115200: cflag |= B115200; break;
/*case 127117: cflag |= B127117; break;*/
case 230400: cflag |= B230400; break;
case 460800: cflag |= B460800; break;
case 921600: cflag |= B921600; break;
/*case 3686400: cflag |= B3686400; break;*/
default:
dbg("%s - Baud rate is not supported, "
"using 9600 baud", __FUNCTION__);
cflag |= B9600;
cp2101_set_config_single(port, CP2101_BAUDRATE,
(BAUD_RATE_GEN_FREQ/9600));
break;
}
tty_encode_baud_rate(port->tty, baud, baud);
cflag = port->tty->termios->c_cflag;
cp2101_get_config(port, CP2101_BITS, &bits, 2);
cflag &= ~CSIZE;
......@@ -516,7 +484,7 @@ static void cp2101_get_termios (struct usb_serial_port *port)
static void cp2101_set_termios (struct usb_serial_port *port,
struct ktermios *old_termios)
{
unsigned int cflag, old_cflag=0;
unsigned int cflag, old_cflag;
int baud=0, bits;
unsigned int modem_ctl[4];
......@@ -526,6 +494,8 @@ static void cp2101_set_termios (struct usb_serial_port *port,
dbg("%s - no tty structures", __FUNCTION__);
return;
}
port->tty->termios->c_cflag &= ~CMSPAR;
cflag = port->tty->termios->c_cflag;
old_cflag = old_termios->c_cflag;
baud = tty_get_baud_rate(port->tty);
......@@ -563,11 +533,15 @@ static void cp2101_set_termios (struct usb_serial_port *port,
dbg("%s - Setting baud rate to %d baud", __FUNCTION__,
baud);
if (cp2101_set_config_single(port, CP2101_BAUDRATE,
(BAUD_RATE_GEN_FREQ / baud)))
(BAUD_RATE_GEN_FREQ / baud))) {
dev_err(&port->dev, "Baud rate requested not "
"supported by device\n");
baud = tty_termios_baud_rate(old_termios);
}
}
}
/* Report back the resulting baud rate */
tty_encode_baud_rate(port->tty, baud, baud);
/* If the number of data bits is to be updated */
if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
......
......@@ -973,6 +973,8 @@ static void digi_set_termios(struct usb_serial_port *port,
}
}
/* set parity */
tty->termios->c_cflag &= ~CMSPAR;
if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) {
if (cflag&PARENB) {
if (cflag&PARODD)
......@@ -1054,15 +1056,15 @@ static void digi_set_termios(struct usb_serial_port *port,
}
/* set output flow control */
if ((iflag&IXON) != (old_iflag&IXON)
|| (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) {
if ((iflag & IXON) != (old_iflag & IXON)
|| (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
arg = 0;
if (iflag&IXON)
if (iflag & IXON)
arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
else
arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
if (cflag&CRTSCTS) {
if (cflag & CRTSCTS) {
arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS;
} else {
arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS;
......@@ -1076,8 +1078,8 @@ static void digi_set_termios(struct usb_serial_port *port,
}
/* set receive enable/disable */
if ((cflag&CREAD) != (old_cflag&CREAD)) {
if (cflag&CREAD)
if ((cflag & CREAD) != (old_cflag & CREAD)) {
if (cflag & CREAD)
arg = DIGI_ENABLE;
else
arg = DIGI_DISABLE;
......@@ -1089,7 +1091,7 @@ static void digi_set_termios(struct usb_serial_port *port,
}
if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0)
dbg("digi_set_termios: write oob failed, ret=%d", ret);
tty_encode_baud_rate(tty, baud, baud);
}
......
......@@ -449,14 +449,9 @@ static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsign
static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
{
struct ktermios *termios = port->tty->termios;
dbg("%s - port %d", __FUNCTION__, port->number);
if ((!port->tty) || (!port->tty->termios)) {
dbg("%s - no tty structures", __FUNCTION__);
return;
}
/*
* The empeg-car player wants these particular tty settings.
* You could, for example, change the baud rate, however the
......@@ -466,7 +461,7 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol
*
* The default requirements for this device are:
*/
port->tty->termios->c_iflag
termios->c_iflag
&= ~(IGNBRK /* disable ignore break */
| BRKINT /* disable break causes interrupt */
| PARMRK /* disable mark parity errors */
......@@ -476,24 +471,23 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol
| ICRNL /* disable translate CR to NL */
| IXON); /* disable enable XON/XOFF flow control */
port->tty->termios->c_oflag
termios->c_oflag
&= ~OPOST; /* disable postprocess output characters */
port->tty->termios->c_lflag
termios->c_lflag
&= ~(ECHO /* disable echo input characters */
| ECHONL /* disable echo new line */
| ICANON /* disable erase, kill, werase, and rprnt special characters */
| ISIG /* disable interrupt, quit, and suspend special characters */
| IEXTEN); /* disable non-POSIX special characters */
port->tty->termios->c_cflag
termios->c_cflag
&= ~(CSIZE /* no size */
| PARENB /* disable parity bit */
| CBAUD); /* clear current baud rate */
port->tty->termios->c_cflag
|= (CS8 /* character size 8 bits */
| B115200); /* baud rate 115200 */
termios->c_cflag
|= CS8; /* character size 8 bits */
/*
* Force low_latency on; otherwise the pushes are scheduled;
......@@ -501,8 +495,7 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol
* on the floor. We don't want to drop bytes on the floor. :)
*/
port->tty->low_latency = 1;
return;
tty_encode_baud_rate(port->tty, 115200, 115200);
}
......
......@@ -294,7 +294,7 @@ struct ftdi_private {
__u16 interface; /* FT2232C port interface (0 for FT232/245) */
int force_baud; /* if non-zero, force the baud rate to this value */
speed_t force_baud; /* if non-zero, force the baud rate to this value */
int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
spinlock_t tx_lock; /* spinlock for transmit state */
......@@ -878,6 +878,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
if (div_value == 0) {
dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__, baud);
div_value = ftdi_sio_b9600;
baud = 9600;
div_okay = 0;
}
break;
......@@ -886,6 +887,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
div_value = ftdi_232am_baud_to_divisor(baud);
} else {
dbg("%s - Baud rate too high!", __FUNCTION__);
baud = 9600;
div_value = ftdi_232am_baud_to_divisor(9600);
div_okay = 0;
}
......@@ -899,6 +901,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
dbg("%s - Baud rate too high!", __FUNCTION__);
div_value = ftdi_232bm_baud_to_divisor(9600);
div_okay = 0;
baud = 9600;
}
break;
} /* priv->chip_type */
......@@ -909,6 +912,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
ftdi_chip_name[priv->chip_type]);
}
tty_encode_baud_rate(port->tty, baud, baud);
return(div_value);
}
......@@ -1263,7 +1267,7 @@ static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
priv->flags |= ASYNC_SPD_CUST;
priv->custom_divisor = 77;
priv->force_baud = B38400;
priv->force_baud = 38400;
} /* ftdi_USB_UIRT_setup */
/* Setup for the HE-TIRA1 device, which requires hardwired
......@@ -1274,7 +1278,7 @@ static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv)
priv->flags |= ASYNC_SPD_CUST;
priv->custom_divisor = 240;
priv->force_baud = B38400;
priv->force_baud = 38400;
priv->force_rtscts = 1;
} /* ftdi_HE_TIRA1_setup */
......@@ -1363,7 +1367,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp)
/* ftdi_set_termios will send usb control messages */
if (port->tty)
ftdi_set_termios(port, NULL);
ftdi_set_termios(port, port->tty->termios);
/* FIXME: Flow control might be enabled, so it should be checked -
we have no control of defaults! */
......@@ -1933,32 +1937,33 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state )
static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
{ /* ftdi_termios */
struct usb_device *dev = port->serial->dev;
unsigned int cflag = port->tty->termios->c_cflag;
struct ftdi_private *priv = usb_get_serial_port_data(port);
struct ktermios *termios = port->tty->termios;
unsigned int cflag = termios->c_cflag;
__u16 urb_value; /* will hold the new flags */
char buf[1]; /* Perhaps I should dynamically alloc this? */
// Added for xon/xoff support
unsigned int iflag = port->tty->termios->c_iflag;
unsigned int iflag = termios->c_iflag;
unsigned char vstop;
unsigned char vstart;
dbg("%s", __FUNCTION__);
/* Force baud rate if this device requires it, unless it is set to B0. */
if (priv->force_baud && ((port->tty->termios->c_cflag & CBAUD) != B0)) {
if (priv->force_baud && ((termios->c_cflag & CBAUD) != B0)) {
dbg("%s: forcing baud rate for this device", __FUNCTION__);
port->tty->termios->c_cflag &= ~CBAUD;
port->tty->termios->c_cflag |= priv->force_baud;
tty_encode_baud_rate(port->tty, priv->force_baud,
priv->force_baud);
}
/* Force RTS-CTS if this device requires it. */
if (priv->force_rtscts) {
dbg("%s: forcing rtscts for this device", __FUNCTION__);
port->tty->termios->c_cflag |= CRTSCTS;
termios->c_cflag |= CRTSCTS;
}
cflag = port->tty->termios->c_cflag;
cflag = termios->c_cflag;
/* FIXME -For this cut I don't care if the line is really changing or
not - so just do the change regardless - should be able to
......@@ -1969,6 +1974,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
/* Set number of data bits, parity, stop bits */
termios->c_cflag &= ~CMSPAR;
urb_value = 0;
urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 :
FTDI_SIO_SET_DATA_STOP_BITS_1);
......@@ -2048,8 +2055,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
// Set the vstart and vstop -- could have been done up above where
// a lot of other dereferencing is done but that would be very
// inefficient as vstart and vstop are not always needed
vstart=port->tty->termios->c_cc[VSTART];
vstop=port->tty->termios->c_cc[VSTOP];
vstart = termios->c_cc[VSTART];
vstop = termios->c_cc[VSTOP];
urb_value=(vstop << 8) | (vstart);
if (usb_control_msg(dev,
......
......@@ -208,14 +208,15 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *
/* only do something if we have a bulk out endpoint */
if (serial->num_bulk_out) {
spin_lock_bh(&port->lock);
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
if (port->write_urb_busy) {
spin_unlock_bh(&port->lock);
spin_unlock_irqrestore(&port->lock, flags);
dbg("%s - already writing", __FUNCTION__);
return 0;
}
port->write_urb_busy = 1;
spin_unlock_bh(&port->lock);
spin_unlock_irqrestore(&port->lock, flags);
count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
......
......@@ -1503,22 +1503,16 @@ static void edge_unthrottle (struct usb_serial_port *port)
*****************************************************************************/
static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
{
/* FIXME: This function appears unused ?? */
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
struct tty_struct *tty = port->tty;
unsigned int cflag;
if (!port->tty || !port->tty->termios) {
dbg ("%s - no tty or termios", __FUNCTION__);
return;
}
cflag = tty->termios->c_cflag;
dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
tty->termios->c_cflag, tty->termios->c_iflag);
if (old_termios) {
dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
old_termios->c_cflag, old_termios->c_iflag);
}
dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
old_termios->c_cflag, old_termios->c_iflag);
dbg("%s - port %d", __FUNCTION__, port->number);
......@@ -2653,7 +2647,11 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
dbg("%s - baud rate = %d", __FUNCTION__, baud);
status = send_cmd_write_baud_rate (edge_port, baud);
if (status == -1) {
/* Speed change was not possible - put back the old speed */
baud = tty_termios_baud_rate(old_termios);
tty_encode_baud_rate(tty, baud, baud);
}
return;
}
......
......@@ -504,11 +504,6 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
dbg("%s - port %d", __FUNCTION__, port->number);
if ((!port->tty) || (!port->tty->termios)) {
dbg("%s - no tty structures", __FUNCTION__);
return;
}
baud = tty_get_baud_rate(port->tty);
/*
......@@ -531,8 +526,6 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
default:
ir_baud = SPEED_9600;
baud = 9600;
/* And once the new tty stuff is all done we need to
call back to correct the baud bits */
}
if (xbof == -1)
......@@ -562,6 +555,10 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
result = usb_submit_urb (port->write_urb, GFP_KERNEL);
if (result)
dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
/* Only speed changes are supported */
tty_termios_copy_hw(port->tty->termios, old_termios);
tty_encode_baud_rate(port->tty, baud, baud);
}
......
......@@ -278,29 +278,35 @@ static void keyspan_set_termios (struct usb_serial_port *port,
struct keyspan_port_private *p_priv;
const struct keyspan_device_details *d_details;
unsigned int cflag;
struct tty_struct *tty = port->tty;
dbg("%s", __FUNCTION__);
p_priv = usb_get_serial_port_data(port);
d_details = p_priv->device_details;
cflag = port->tty->termios->c_cflag;
cflag = tty->termios->c_cflag;
device_port = port->number - port->serial->minor;
/* Baud rate calculation takes baud rate as an integer
so other rates can be generated if desired. */
baud_rate = tty_get_baud_rate(port->tty);
baud_rate = tty_get_baud_rate(tty);
/* If no match or invalid, don't change */
if (baud_rate >= 0
&& d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
if (d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
/* FIXME - more to do here to ensure rate changes cleanly */
/* FIXME - calcuate exact rate from divisor ? */
p_priv->baud = baud_rate;
}
} else
baud_rate = tty_termios_baud_rate(old_termios);
tty_encode_baud_rate(tty, baud_rate, baud_rate);
/* set CTS/RTS handshake etc. */
p_priv->cflag = cflag;
p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
/* Mark/Space not supported */
tty->termios->c_cflag &= ~CMSPAR;
keyspan_send_setup(port, 0);
}
......
......@@ -616,8 +616,9 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old
case 1200:
urb_val = SUSBCR_SBR_1200;
break;
case 9600:
default:
speed = 9600;
case 9600:
urb_val = SUSBCR_SBR_9600;
break;
}
......@@ -641,6 +642,8 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old
urb_val |= SUSBCR_SPASB_NoParity;
strcat(settings, "No Parity");
}
port->tty->termios->c_cflag &= ~CMSPAR;
tty_encode_baud_rate(port->tty, speed, speed);
result = usb_control_msg( port->serial->dev,
usb_rcvctrlpipe(port->serial->dev, 0 ),
......
......@@ -1977,11 +1977,6 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
tty = mos7840_port->port->tty;
if ((!tty) || (!tty->termios)) {
dbg("%s - no tty structures", __FUNCTION__);
return;
}
dbg("%s", "Entering .......... \n");
lData = LCR_BITS_8;
......@@ -2151,11 +2146,6 @@ static void mos7840_set_termios(struct usb_serial_port *port,
tty = port->tty;
if (!port->tty || !port->tty->termios) {
dbg("%s - no tty or termios", __FUNCTION__);
return;
}
if (!mos7840_port->open) {
dbg("%s - port not opened", __FUNCTION__);
return;
......@@ -2165,19 +2155,10 @@ static void mos7840_set_termios(struct usb_serial_port *port,
cflag = tty->termios->c_cflag;
if (!cflag) {
dbg("%s %s\n", __FUNCTION__, "cflag is NULL");
return;
}
dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
if (old_termios) {
dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
}
dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
dbg("%s - port %d", __FUNCTION__, port->number);
/* change the port settings to the new ones specified */
......
......@@ -172,6 +172,8 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4100) }, /* Novatel U727 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4400) }, /* Novatel MC950 */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
......@@ -311,7 +313,8 @@ static void option_set_termios(struct usb_serial_port *port,
struct ktermios *old_termios)
{
dbg("%s", __FUNCTION__);
/* Doesn't support option setting */
tty_termios_copy_hw(port->tty->termios, old_termios);
option_send_setup(port);
}
......
......@@ -56,6 +56,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
{ USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
......@@ -470,16 +471,13 @@ static void pl2303_set_termios(struct usb_serial_port *port,
dbg("%s - port %d", __FUNCTION__, port->number);
if ((!port->tty) || (!port->tty->termios)) {
dbg("%s - no tty structures", __FUNCTION__);
return;
}
spin_lock_irqsave(&priv->lock, flags);
if (!priv->termios_initialized) {
*(port->tty->termios) = tty_std_termios;
port->tty->termios->c_cflag = B9600 | CS8 | CREAD |
HUPCL | CLOCAL;
port->tty->termios->c_ispeed = 9600;
port->tty->termios->c_ospeed = 9600;
priv->termios_initialized = 1;
}
spin_unlock_irqrestore(&priv->lock, flags);
......@@ -596,6 +594,10 @@ static void pl2303_set_termios(struct usb_serial_port *port,
dbg ("0x40:0x1:0x0:0x0 %d", i);
}
/* FIXME: Need to read back resulting baud rate */
if (baud)
tty_encode_baud_rate(port->tty, baud, baud);
kfree(buf);
}
......
......@@ -20,6 +20,7 @@
#define IODATA_VENDOR_ID 0x04bb
#define IODATA_PRODUCT_ID 0x0a03
#define IODATA_PRODUCT_ID_RSAQ5 0x0a0e
#define ELCOM_VENDOR_ID 0x056e
#define ELCOM_PRODUCT_ID 0x5003
......
......@@ -224,7 +224,7 @@ static void sierra_set_termios(struct usb_serial_port *port,
struct ktermios *old_termios)
{
dbg("%s", __FUNCTION__);
tty_termios_copy_hw(port->tty->termios, old_termios);
sierra_send_setup(port);
}
......
......@@ -429,6 +429,8 @@ static void serial_set_termios (struct tty_struct *tty, struct ktermios * old)
/* pass on to the driver specific version of this function if it is available */
if (port->serial->type->set_termios)
port->serial->type->set_termios(port, old);
else
tty_termios_copy_hw(tty->termios, old);
}
static void serial_break (struct tty_struct *tty, int break_state)
......@@ -1121,7 +1123,9 @@ int usb_serial_resume(struct usb_interface *intf)
{
struct usb_serial *serial = usb_get_intfdata(intf);
return serial->type->resume(serial);
if (serial->type->resume)
return serial->type->resume(serial);
return 0;
}
EXPORT_SYMBOL(usb_serial_resume);
......
......@@ -885,16 +885,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un
static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios)
{
dbg("%s -port %d", __FUNCTION__, port->number);
if ((!port->tty) || (!port->tty->termios)) {
dbg("%s - no tty structures", __FUNCTION__);
goto exit;
}
firm_setup_port(port);
exit:
return;
}
......@@ -1244,6 +1235,8 @@ static int firm_setup_port(struct usb_serial_port *port) {
port_settings.baud = tty_get_baud_rate(port->tty);
dbg("%s - baud rate = %d", __FUNCTION__, port_settings.baud);
/* fixme: should set validated settings */
tty_encode_baud_rate(port->tty, port_settings.baud, port_settings.baud);
/* handle any settings that aren't specified in the tty structure */
port_settings.lloop = 0;
......
......@@ -48,7 +48,6 @@ config USB_STORAGE_FREECOM
config USB_STORAGE_ISD200
bool "ISD-200 USB/ATA Bridge support"
depends on USB_STORAGE
depends on BLK_DEV_IDE=y || BLK_DEV_IDE=USB_STORAGE
---help---
Say Y here if you want to use USB Mass Store devices based
on the In-Systems Design ISD-200 USB/ATA bridge.
......
......@@ -977,6 +977,109 @@ static int isd200_manual_enum(struct us_data *us)
return(retStatus);
}
/*
* We are the last non IDE user of the legacy IDE ident structures
* and we thus want to keep a private copy of this function so the
* driver can be used without the obsolete drivers/ide layer
*/
static void isd200_fix_driveid (struct hd_driveid *id)
{
#ifndef __LITTLE_ENDIAN
# ifdef __BIG_ENDIAN
int i;
u16 *stringcast;
id->config = __le16_to_cpu(id->config);
id->cyls = __le16_to_cpu(id->cyls);
id->reserved2 = __le16_to_cpu(id->reserved2);
id->heads = __le16_to_cpu(id->heads);
id->track_bytes = __le16_to_cpu(id->track_bytes);
id->sector_bytes = __le16_to_cpu(id->sector_bytes);
id->sectors = __le16_to_cpu(id->sectors);
id->vendor0 = __le16_to_cpu(id->vendor0);
id->vendor1 = __le16_to_cpu(id->vendor1);
id->vendor2 = __le16_to_cpu(id->vendor2);
stringcast = (u16 *)&id->serial_no[0];
for (i = 0; i < (20/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
id->buf_type = __le16_to_cpu(id->buf_type);
id->buf_size = __le16_to_cpu(id->buf_size);
id->ecc_bytes = __le16_to_cpu(id->ecc_bytes);
stringcast = (u16 *)&id->fw_rev[0];
for (i = 0; i < (8/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
stringcast = (u16 *)&id->model[0];
for (i = 0; i < (40/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
id->dword_io = __le16_to_cpu(id->dword_io);
id->reserved50 = __le16_to_cpu(id->reserved50);
id->field_valid = __le16_to_cpu(id->field_valid);
id->cur_cyls = __le16_to_cpu(id->cur_cyls);
id->cur_heads = __le16_to_cpu(id->cur_heads);
id->cur_sectors = __le16_to_cpu(id->cur_sectors);
id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0);
id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1);
id->lba_capacity = __le32_to_cpu(id->lba_capacity);
id->dma_1word = __le16_to_cpu(id->dma_1word);
id->dma_mword = __le16_to_cpu(id->dma_mword);
id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
id->eide_dma_min = __le16_to_cpu(id->eide_dma_min);
id->eide_dma_time = __le16_to_cpu(id->eide_dma_time);
id->eide_pio = __le16_to_cpu(id->eide_pio);
id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
for (i = 0; i < 2; ++i)
id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
for (i = 0; i < 4; ++i)
id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
id->queue_depth = __le16_to_cpu(id->queue_depth);
for (i = 0; i < 4; ++i)
id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
id->major_rev_num = __le16_to_cpu(id->major_rev_num);
id->minor_rev_num = __le16_to_cpu(id->minor_rev_num);
id->command_set_1 = __le16_to_cpu(id->command_set_1);
id->command_set_2 = __le16_to_cpu(id->command_set_2);
id->cfsse = __le16_to_cpu(id->cfsse);
id->cfs_enable_1 = __le16_to_cpu(id->cfs_enable_1);
id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2);
id->csf_default = __le16_to_cpu(id->csf_default);
id->dma_ultra = __le16_to_cpu(id->dma_ultra);
id->trseuc = __le16_to_cpu(id->trseuc);
id->trsEuc = __le16_to_cpu(id->trsEuc);
id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues);
id->mprc = __le16_to_cpu(id->mprc);
id->hw_config = __le16_to_cpu(id->hw_config);
id->acoustic = __le16_to_cpu(id->acoustic);
id->msrqs = __le16_to_cpu(id->msrqs);
id->sxfert = __le16_to_cpu(id->sxfert);
id->sal = __le16_to_cpu(id->sal);
id->spg = __le32_to_cpu(id->spg);
id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
for (i = 0; i < 22; i++)
id->words104_125[i] = __le16_to_cpu(id->words104_125[i]);
id->last_lun = __le16_to_cpu(id->last_lun);
id->word127 = __le16_to_cpu(id->word127);
id->dlf = __le16_to_cpu(id->dlf);
id->csfo = __le16_to_cpu(id->csfo);
for (i = 0; i < 26; i++)
id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
id->word156 = __le16_to_cpu(id->word156);
for (i = 0; i < 3; i++)
id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
id->cfa_power = __le16_to_cpu(id->cfa_power);
for (i = 0; i < 14; i++)
id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
for (i = 0; i < 31; i++)
id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
for (i = 0; i < 48; i++)
id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
id->integrity_word = __le16_to_cpu(id->integrity_word);
# else
# error "Please fix <asm/byteorder.h>"
# endif
#endif
}
/**************************************************************************
* isd200_get_inquiry_data
......@@ -1018,7 +1121,7 @@ static int isd200_get_inquiry_data( struct us_data *us )
int i;
__be16 *src;
__u16 *dest;
ide_fix_driveid(id);
isd200_fix_driveid(id);
US_DEBUGP(" Identify Data Structure:\n");
US_DEBUGP(" config = 0x%x\n", id->config);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment