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 ...
This commit is contained in:
commit
a60387ba31
37 changed files with 397 additions and 254 deletions
|
@ -1875,6 +1875,7 @@ uart_set_options(struct uart_port *port, struct console *co,
|
||||||
int baud, int parity, int bits, int flow)
|
int baud, int parity, int bits, int flow)
|
||||||
{
|
{
|
||||||
struct ktermios termios;
|
struct ktermios termios;
|
||||||
|
static struct ktermios dummy;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1920,7 +1921,7 @@ uart_set_options(struct uart_port *port, struct console *co,
|
||||||
*/
|
*/
|
||||||
port->mctrl |= TIOCM_DTR;
|
port->mctrl |= TIOCM_DTR;
|
||||||
|
|
||||||
port->ops->set_termios(port, &termios, NULL);
|
port->ops->set_termios(port, &termios, &dummy);
|
||||||
co->cflag = termios.c_cflag;
|
co->cflag = termios.c_cflag;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1641,7 +1641,13 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
|
||||||
intf->dev.bus_id, ret);
|
intf->dev.bus_id, ret);
|
||||||
continue;
|
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);
|
usb_autosuspend_device(dev);
|
||||||
|
|
|
@ -372,7 +372,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
|
||||||
|
|
||||||
/* enforce simple/standard policy */
|
/* enforce simple/standard policy */
|
||||||
allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |
|
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) {
|
switch (xfertype) {
|
||||||
case USB_ENDPOINT_XFER_BULK:
|
case USB_ENDPOINT_XFER_BULK:
|
||||||
if (is_out)
|
if (is_out)
|
||||||
|
|
|
@ -3289,7 +3289,7 @@ static int udc_pci_probe(
|
||||||
dev->chiprev = pdev->revision;
|
dev->chiprev = pdev->revision;
|
||||||
|
|
||||||
pci_set_master(pdev);
|
pci_set_master(pdev);
|
||||||
pci_set_mwi(pdev);
|
pci_try_set_mwi(pdev);
|
||||||
|
|
||||||
/* init dma pools */
|
/* init dma pools */
|
||||||
if (use_dma) {
|
if (use_dma) {
|
||||||
|
|
|
@ -156,7 +156,7 @@ config USB_OHCI_HCD_PCI
|
||||||
|
|
||||||
config USB_OHCI_HCD_SSB
|
config USB_OHCI_HCD_SSB
|
||||||
bool "OHCI support for Broadcom SSB OHCI core"
|
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
|
default n
|
||||||
---help---
|
---help---
|
||||||
Support for the Sonics Silicon Backplane (SSB) attached
|
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 void ohci_dump (struct ohci_hcd *ohci, int verbose);
|
||||||
static int ohci_init (struct ohci_hcd *ohci);
|
static int ohci_init (struct ohci_hcd *ohci);
|
||||||
static void ohci_stop (struct usb_hcd *hcd);
|
static void ohci_stop (struct usb_hcd *hcd);
|
||||||
|
|
||||||
|
#if defined(CONFIG_PM) || defined(CONFIG_PCI)
|
||||||
static int ohci_restart (struct ohci_hcd *ohci);
|
static int ohci_restart (struct ohci_hcd *ohci);
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "ohci-hub.c"
|
#include "ohci-hub.c"
|
||||||
#include "ohci-dbg.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)
|
static void unlink_watchdog_func(unsigned long _ohci)
|
||||||
{
|
{
|
||||||
long flags;
|
unsigned long flags;
|
||||||
unsigned max;
|
unsigned max;
|
||||||
unsigned seen_count = 0;
|
unsigned seen_count = 0;
|
||||||
unsigned i;
|
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 */
|
/* must not be called from interrupt context */
|
||||||
static int ohci_restart (struct ohci_hcd *ohci)
|
static int ohci_restart (struct ohci_hcd *ohci)
|
||||||
{
|
{
|
||||||
|
@ -954,6 +959,8 @@ static int ohci_restart (struct ohci_hcd *ohci)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
|
#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) {
|
} else if (qh->period != urb->interval) {
|
||||||
return -EINVAL; /* Can't change the period */
|
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)) {
|
if (list_empty(&qh->queue)) {
|
||||||
frame = qh->iso_frame;
|
frame = qh->iso_frame;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1283,10 +1284,18 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
|
||||||
lurb->number_of_packets *
|
lurb->number_of_packets *
|
||||||
lurb->interval;
|
lurb->interval;
|
||||||
}
|
}
|
||||||
if (urb->transfer_flags & URB_ISO_ASAP)
|
if (urb->transfer_flags & URB_ISO_ASAP) {
|
||||||
urb->start_frame = frame;
|
/* Skip some frames if necessary to insure
|
||||||
else if (urb->start_frame != frame)
|
* the start frame is in the future.
|
||||||
return -EINVAL;
|
*/
|
||||||
|
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 */
|
/* 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;
|
struct usb_cytherm *dev;
|
||||||
|
|
||||||
dev = usb_get_intfdata (interface);
|
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_brightness);
|
||||||
device_remove_file(&interface->dev, &dev_attr_temp);
|
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_port0);
|
||||||
device_remove_file(&interface->dev, &dev_attr_port1);
|
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);
|
usb_put_dev(dev->udev);
|
||||||
|
|
||||||
kfree(dev);
|
kfree(dev);
|
||||||
|
|
|
@ -114,6 +114,10 @@ static int emi26_load_firmware (struct usb_device *dev)
|
||||||
|
|
||||||
/* De-assert reset (let the CPU run) */
|
/* De-assert reset (let the CPU run) */
|
||||||
err = emi26_set_reset(dev,0);
|
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 */
|
msleep(250); /* let device settle */
|
||||||
|
|
||||||
/* 2. We upload the FPGA firmware into the EMI
|
/* 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) */
|
/* De-assert reset (let the CPU run) */
|
||||||
err = emi62_set_reset(dev,0);
|
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 */
|
msleep(250); /* let device settle */
|
||||||
|
|
||||||
/* 2. We upload the FPGA firmware into the EMI
|
/* 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*/
|
/* Structure to hold all of our device specific stuff*/
|
||||||
struct usb_ftdi {
|
struct usb_ftdi {
|
||||||
struct list_head ftdi_list;
|
struct list_head ftdi_list;
|
||||||
struct semaphore u132_lock;
|
struct mutex u132_lock;
|
||||||
int command_next;
|
int command_next;
|
||||||
int command_head;
|
int command_head;
|
||||||
struct u132_command command[COMMAND_SIZE];
|
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)
|
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) {
|
while (ftdi->respond_next > ftdi->respond_head) {
|
||||||
struct u132_respond *respond = &ftdi->respond[RESPOND_MASK &
|
struct u132_respond *respond = &ftdi->respond[RESPOND_MASK &
|
||||||
ftdi->respond_head++];
|
ftdi->respond_head++];
|
||||||
*respond->result = -ESHUTDOWN;
|
*respond->result = -ESHUTDOWN;
|
||||||
*respond->value = 0;
|
*respond->value = 0;
|
||||||
complete(&respond->wait_completion);
|
complete(&respond->wait_completion);
|
||||||
} up(&ftdi->u132_lock);
|
} mutex_unlock(&ftdi->u132_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftdi_elan_abandon_targets(struct usb_ftdi *ftdi)
|
static void ftdi_elan_abandon_targets(struct usb_ftdi *ftdi)
|
||||||
{
|
{
|
||||||
int ed_number = 4;
|
int ed_number = 4;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
while (ed_number-- > 0) {
|
while (ed_number-- > 0) {
|
||||||
struct u132_target *target = &ftdi->target[ed_number];
|
struct u132_target *target = &ftdi->target[ed_number];
|
||||||
if (target->active == 1) {
|
if (target->active == 1) {
|
||||||
target->condition_code = TD_DEVNOTRESP;
|
target->condition_code = TD_DEVNOTRESP;
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
ftdi_elan_do_callback(ftdi, target, NULL, 0);
|
ftdi_elan_do_callback(ftdi, target, NULL, 0);
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ftdi->recieved = 0;
|
ftdi->recieved = 0;
|
||||||
ftdi->expected = 4;
|
ftdi->expected = 4;
|
||||||
ftdi->ed_found = 0;
|
ftdi->ed_found = 0;
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
|
static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
|
||||||
{
|
{
|
||||||
int ed_number = 4;
|
int ed_number = 4;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
while (ed_number-- > 0) {
|
while (ed_number-- > 0) {
|
||||||
struct u132_target *target = &ftdi->target[ed_number];
|
struct u132_target *target = &ftdi->target[ed_number];
|
||||||
target->abandoning = 1;
|
target->abandoning = 1;
|
||||||
|
@ -382,9 +382,9 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
|
||||||
ftdi->command_next += 1;
|
ftdi->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
goto wait_1;
|
goto wait_1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,9 +404,9 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
|
||||||
ftdi->command_next += 1;
|
ftdi->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
goto wait_2;
|
goto wait_2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -414,13 +414,13 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
|
||||||
ftdi->recieved = 0;
|
ftdi->recieved = 0;
|
||||||
ftdi->expected = 4;
|
ftdi->expected = 4;
|
||||||
ftdi->ed_found = 0;
|
ftdi->ed_found = 0;
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
|
static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
|
||||||
{
|
{
|
||||||
int ed_number = 4;
|
int ed_number = 4;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
while (ed_number-- > 0) {
|
while (ed_number-- > 0) {
|
||||||
struct u132_target *target = &ftdi->target[ed_number];
|
struct u132_target *target = &ftdi->target[ed_number];
|
||||||
target->abandoning = 1;
|
target->abandoning = 1;
|
||||||
|
@ -440,9 +440,9 @@ static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
|
||||||
ftdi->command_next += 1;
|
ftdi->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -450,7 +450,7 @@ static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
|
||||||
ftdi->recieved = 0;
|
ftdi->recieved = 0;
|
||||||
ftdi->expected = 4;
|
ftdi->expected = 4;
|
||||||
ftdi->ed_found = 0;
|
ftdi->ed_found = 0;
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftdi_elan_kick_command_queue(struct usb_ftdi *ftdi)
|
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)
|
char *b)
|
||||||
{
|
{
|
||||||
int payload = (ed_length >> 0) & 0x07FF;
|
int payload = (ed_length >> 0) & 0x07FF;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
target->actual = 0;
|
target->actual = 0;
|
||||||
target->non_null = (ed_length >> 15) & 0x0001;
|
target->non_null = (ed_length >> 15) & 0x0001;
|
||||||
target->repeat_number = (ed_length >> 11) & 0x000F;
|
target->repeat_number = (ed_length >> 11) & 0x000F;
|
||||||
if (ed_type == 0x02) {
|
if (ed_type == 0x02) {
|
||||||
if (payload == 0 || target->abandoning > 0) {
|
if (payload == 0 || target->abandoning > 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,
|
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
|
||||||
payload);
|
payload);
|
||||||
ftdi->recieved = 0;
|
ftdi->recieved = 0;
|
||||||
|
@ -903,13 +903,13 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
|
||||||
} else {
|
} else {
|
||||||
ftdi->expected = 4 + payload;
|
ftdi->expected = 4 + payload;
|
||||||
ftdi->ed_found = 1;
|
ftdi->ed_found = 1;
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
} else if (ed_type == 0x03) {
|
} else if (ed_type == 0x03) {
|
||||||
if (payload == 0 || target->abandoning > 0) {
|
if (payload == 0 || target->abandoning > 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,
|
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
|
||||||
payload);
|
payload);
|
||||||
ftdi->recieved = 0;
|
ftdi->recieved = 0;
|
||||||
|
@ -919,12 +919,12 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
|
||||||
} else {
|
} else {
|
||||||
ftdi->expected = 4 + payload;
|
ftdi->expected = 4 + payload;
|
||||||
ftdi->ed_found = 1;
|
ftdi->ed_found = 1;
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
} else if (ed_type == 0x01) {
|
} else if (ed_type == 0x01) {
|
||||||
target->abandoning = 0;
|
target->abandoning = 0;
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
|
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
|
||||||
payload);
|
payload);
|
||||||
ftdi->recieved = 0;
|
ftdi->recieved = 0;
|
||||||
|
@ -933,7 +933,7 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
|
||||||
return ftdi->response;
|
return ftdi->response;
|
||||||
} else {
|
} else {
|
||||||
target->abandoning = 0;
|
target->abandoning = 0;
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
|
ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
|
||||||
payload);
|
payload);
|
||||||
ftdi->recieved = 0;
|
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,
|
struct u132_target *target, u16 ed_length, int ed_number, int ed_type,
|
||||||
char *b)
|
char *b)
|
||||||
{
|
{
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
target->condition_code = TD_DEVNOTRESP;
|
target->condition_code = TD_DEVNOTRESP;
|
||||||
target->actual = (ed_length >> 0) & 0x01FF;
|
target->actual = (ed_length >> 0) & 0x01FF;
|
||||||
target->non_null = (ed_length >> 15) & 0x0001;
|
target->non_null = (ed_length >> 15) & 0x0001;
|
||||||
target->repeat_number = (ed_length >> 11) & 0x000F;
|
target->repeat_number = (ed_length >> 11) & 0x000F;
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
if (target->active)
|
if (target->active)
|
||||||
ftdi_elan_do_callback(ftdi, target, NULL, 0);
|
ftdi_elan_do_callback(ftdi, target, NULL, 0);
|
||||||
target->abandoning = 0;
|
target->abandoning = 0;
|
||||||
|
@ -1278,7 +1278,7 @@ static int ftdi_elan_write_reg(struct usb_ftdi *ftdi, u32 data)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
int command_size;
|
int command_size;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
command_size = ftdi->command_next - ftdi->command_head;
|
command_size = ftdi->command_next - ftdi->command_head;
|
||||||
if (command_size < COMMAND_SIZE) {
|
if (command_size < COMMAND_SIZE) {
|
||||||
struct u132_command *command = &ftdi->command[
|
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;
|
command->buffer = &command->value;
|
||||||
ftdi->command_next += 1;
|
ftdi->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
@ -1310,7 +1310,7 @@ static int ftdi_elan_write_config(struct usb_ftdi *ftdi, int config_offset,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
int command_size;
|
int command_size;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
command_size = ftdi->command_next - ftdi->command_head;
|
command_size = ftdi->command_next - ftdi->command_head;
|
||||||
if (command_size < COMMAND_SIZE) {
|
if (command_size < COMMAND_SIZE) {
|
||||||
struct u132_command *command = &ftdi->command[
|
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;
|
command->buffer = &command->value;
|
||||||
ftdi->command_next += 1;
|
ftdi->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
@ -1342,7 +1342,7 @@ static int ftdi_elan_write_pcimem(struct usb_ftdi *ftdi, int mem_offset,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
int command_size;
|
int command_size;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
command_size = ftdi->command_next - ftdi->command_head;
|
command_size = ftdi->command_next - ftdi->command_head;
|
||||||
if (command_size < COMMAND_SIZE) {
|
if (command_size < COMMAND_SIZE) {
|
||||||
struct u132_command *command = &ftdi->command[
|
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;
|
command->buffer = &command->value;
|
||||||
ftdi->command_next += 1;
|
ftdi->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
@ -1382,7 +1382,7 @@ static int ftdi_elan_read_reg(struct usb_ftdi *ftdi, u32 *data)
|
||||||
} else {
|
} else {
|
||||||
int command_size;
|
int command_size;
|
||||||
int respond_size;
|
int respond_size;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
command_size = ftdi->command_next - ftdi->command_head;
|
command_size = ftdi->command_next - ftdi->command_head;
|
||||||
respond_size = ftdi->respond_next - ftdi->respond_head;
|
respond_size = ftdi->respond_next - ftdi->respond_head;
|
||||||
if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE)
|
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->command_next += 1;
|
||||||
ftdi->respond_next += 1;
|
ftdi->respond_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
wait_for_completion(&respond->wait_completion);
|
wait_for_completion(&respond->wait_completion);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
@ -1425,7 +1425,7 @@ static int ftdi_elan_read_config(struct usb_ftdi *ftdi, int config_offset,
|
||||||
} else {
|
} else {
|
||||||
int command_size;
|
int command_size;
|
||||||
int respond_size;
|
int respond_size;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
command_size = ftdi->command_next - ftdi->command_head;
|
command_size = ftdi->command_next - ftdi->command_head;
|
||||||
respond_size = ftdi->respond_next - ftdi->respond_head;
|
respond_size = ftdi->respond_next - ftdi->respond_head;
|
||||||
if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE)
|
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->command_next += 1;
|
||||||
ftdi->respond_next += 1;
|
ftdi->respond_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
wait_for_completion(&respond->wait_completion);
|
wait_for_completion(&respond->wait_completion);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
@ -1469,7 +1469,7 @@ static int ftdi_elan_read_pcimem(struct usb_ftdi *ftdi, int mem_offset,
|
||||||
} else {
|
} else {
|
||||||
int command_size;
|
int command_size;
|
||||||
int respond_size;
|
int respond_size;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
command_size = ftdi->command_next - ftdi->command_head;
|
command_size = ftdi->command_next - ftdi->command_head;
|
||||||
respond_size = ftdi->respond_next - ftdi->respond_head;
|
respond_size = ftdi->respond_next - ftdi->respond_head;
|
||||||
if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE)
|
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->command_next += 1;
|
||||||
ftdi->respond_next += 1;
|
ftdi->respond_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
wait_for_completion(&respond->wait_completion);
|
wait_for_completion(&respond->wait_completion);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
@ -1529,7 +1529,7 @@ static int ftdi_elan_edset_setup(struct usb_ftdi *ftdi, u8 ed_number,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
int command_size;
|
int command_size;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
command_size = ftdi->command_next - ftdi->command_head;
|
command_size = ftdi->command_next - ftdi->command_head;
|
||||||
if (command_size < COMMAND_SIZE) {
|
if (command_size < COMMAND_SIZE) {
|
||||||
struct u132_target *target = &ftdi->target[ed];
|
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;
|
target->active = 1;
|
||||||
ftdi->command_next += 1;
|
ftdi->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
@ -1586,7 +1586,7 @@ static int ftdi_elan_edset_input(struct usb_ftdi *ftdi, u8 ed_number,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
int command_size;
|
int command_size;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
command_size = ftdi->command_next - ftdi->command_head;
|
command_size = ftdi->command_next - ftdi->command_head;
|
||||||
if (command_size < COMMAND_SIZE) {
|
if (command_size < COMMAND_SIZE) {
|
||||||
struct u132_target *target = &ftdi->target[ed];
|
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;
|
target->active = 1;
|
||||||
ftdi->command_next += 1;
|
ftdi->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
@ -1651,7 +1651,7 @@ static int ftdi_elan_edset_empty(struct usb_ftdi *ftdi, u8 ed_number,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
int command_size;
|
int command_size;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
command_size = ftdi->command_next - ftdi->command_head;
|
command_size = ftdi->command_next - ftdi->command_head;
|
||||||
if (command_size < COMMAND_SIZE) {
|
if (command_size < COMMAND_SIZE) {
|
||||||
struct u132_target *target = &ftdi->target[ed];
|
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;
|
target->active = 1;
|
||||||
ftdi->command_next += 1;
|
ftdi->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
@ -1708,7 +1708,7 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
int command_size;
|
int command_size;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
command_size = ftdi->command_next - ftdi->command_head;
|
command_size = ftdi->command_next - ftdi->command_head;
|
||||||
if (command_size < COMMAND_SIZE) {
|
if (command_size < COMMAND_SIZE) {
|
||||||
u8 *b;
|
u8 *b;
|
||||||
|
@ -1751,10 +1751,10 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number,
|
||||||
target->active = 1;
|
target->active = 1;
|
||||||
ftdi->command_next += 1;
|
ftdi->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
@ -1787,7 +1787,7 @@ static int ftdi_elan_edset_single(struct usb_ftdi *ftdi, u8 ed_number,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
int command_size;
|
int command_size;
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
command_size = ftdi->command_next - ftdi->command_head;
|
command_size = ftdi->command_next - ftdi->command_head;
|
||||||
if (command_size < COMMAND_SIZE) {
|
if (command_size < COMMAND_SIZE) {
|
||||||
int remaining_length = urb->transfer_buffer_length -
|
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;
|
target->active = 1;
|
||||||
ftdi->command_next += 1;
|
ftdi->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
@ -1849,9 +1849,9 @@ static int ftdi_elan_edset_flush(struct usb_ftdi *ftdi, u8 ed_number,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
struct u132_target *target = &ftdi->target[ed];
|
struct u132_target *target = &ftdi->target[ed];
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
if (target->abandoning > 0) {
|
if (target->abandoning > 0) {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
target->abandoning = 1;
|
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->command_next += 1;
|
||||||
ftdi_elan_kick_command_queue(ftdi);
|
ftdi_elan_kick_command_queue(ftdi);
|
||||||
} else {
|
} else {
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
down(&ftdi->u132_lock);
|
mutex_lock(&ftdi->u132_lock);
|
||||||
goto wait_1;
|
goto wait_1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
up(&ftdi->u132_lock);
|
mutex_unlock(&ftdi->u132_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2793,7 +2793,7 @@ static int ftdi_elan_probe(struct usb_interface *interface,
|
||||||
init_MUTEX(&ftdi->sw_lock);
|
init_MUTEX(&ftdi->sw_lock);
|
||||||
ftdi->udev = usb_get_dev(interface_to_usbdev(interface));
|
ftdi->udev = usb_get_dev(interface_to_usbdev(interface));
|
||||||
ftdi->interface = interface;
|
ftdi->interface = interface;
|
||||||
init_MUTEX(&ftdi->u132_lock);
|
mutex_init(&ftdi->u132_lock);
|
||||||
ftdi->expected = 4;
|
ftdi->expected = 4;
|
||||||
iface_desc = interface->cur_altsetting;
|
iface_desc = interface->cur_altsetting;
|
||||||
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
|
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)
|
USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000)
|
||||||
|
|
||||||
MODULE_DEVICE_TABLE(usb, idmouse_table);
|
MODULE_DEVICE_TABLE(usb, idmouse_table);
|
||||||
|
static DEFINE_MUTEX(open_disc_mutex);
|
||||||
|
|
||||||
/* structure to hold all of our device specific stuff */
|
/* structure to hold all of our device specific stuff */
|
||||||
struct usb_idmouse {
|
struct usb_idmouse {
|
||||||
|
@ -80,7 +81,7 @@ struct usb_idmouse {
|
||||||
|
|
||||||
int open; /* if the port is open or not */
|
int open; /* if the port is open or not */
|
||||||
int present; /* if the device is not disconnected */
|
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)
|
if (!interface)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
mutex_lock(&open_disc_mutex);
|
||||||
/* get the device information block from the interface */
|
/* get the device information block from the interface */
|
||||||
dev = usb_get_intfdata(interface);
|
dev = usb_get_intfdata(interface);
|
||||||
if (!dev)
|
if (!dev) {
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
/* lock this device */
|
/* lock this device */
|
||||||
down(&dev->sem);
|
mutex_lock(&dev->lock);
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
|
|
||||||
/* check if already open */
|
/* check if already open */
|
||||||
if (dev->open) {
|
if (dev->open) {
|
||||||
|
@ -245,7 +250,7 @@ static int idmouse_open(struct inode *inode, struct file *file)
|
||||||
error:
|
error:
|
||||||
|
|
||||||
/* unlock this device */
|
/* unlock this device */
|
||||||
up(&dev->sem);
|
mutex_unlock(&dev->lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,12 +263,14 @@ static int idmouse_release(struct inode *inode, struct file *file)
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
mutex_lock(&open_disc_mutex);
|
||||||
/* lock our device */
|
/* lock our device */
|
||||||
down(&dev->sem);
|
mutex_lock(&dev->lock);
|
||||||
|
|
||||||
/* are we really open? */
|
/* are we really open? */
|
||||||
if (dev->open <= 0) {
|
if (dev->open <= 0) {
|
||||||
up(&dev->sem);
|
mutex_unlock(&dev->lock);
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,10 +278,12 @@ static int idmouse_release(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
if (!dev->present) {
|
if (!dev->present) {
|
||||||
/* the device was unplugged before the file was released */
|
/* the device was unplugged before the file was released */
|
||||||
up(&dev->sem);
|
mutex_unlock(&dev->lock);
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
idmouse_delete(dev);
|
idmouse_delete(dev);
|
||||||
} else {
|
} else {
|
||||||
up(&dev->sem);
|
mutex_unlock(&dev->lock);
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -286,18 +295,18 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* lock this object */
|
/* lock this object */
|
||||||
down(&dev->sem);
|
mutex_lock(&dev->lock);
|
||||||
|
|
||||||
/* verify that the device wasn't unplugged */
|
/* verify that the device wasn't unplugged */
|
||||||
if (!dev->present) {
|
if (!dev->present) {
|
||||||
up(&dev->sem);
|
mutex_unlock(&dev->lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = simple_read_from_buffer(buffer, count, ppos,
|
result = simple_read_from_buffer(buffer, count, ppos,
|
||||||
dev->bulk_in_buffer, IMGSIZE);
|
dev->bulk_in_buffer, IMGSIZE);
|
||||||
/* unlock the device */
|
/* unlock the device */
|
||||||
up(&dev->sem);
|
mutex_unlock(&dev->lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +329,7 @@ static int idmouse_probe(struct usb_interface *interface,
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
init_MUTEX(&dev->sem);
|
mutex_init(&dev->lock);
|
||||||
dev->udev = udev;
|
dev->udev = udev;
|
||||||
dev->interface = interface;
|
dev->interface = interface;
|
||||||
|
|
||||||
|
@ -372,24 +381,26 @@ static void idmouse_disconnect(struct usb_interface *interface)
|
||||||
|
|
||||||
/* get device structure */
|
/* get device structure */
|
||||||
dev = usb_get_intfdata(interface);
|
dev = usb_get_intfdata(interface);
|
||||||
usb_set_intfdata(interface, NULL);
|
|
||||||
|
|
||||||
/* give back our minor */
|
/* give back our minor */
|
||||||
usb_deregister_dev(interface, &idmouse_class);
|
usb_deregister_dev(interface, &idmouse_class);
|
||||||
|
|
||||||
/* lock it */
|
mutex_lock(&open_disc_mutex);
|
||||||
down(&dev->sem);
|
usb_set_intfdata(interface, NULL);
|
||||||
|
/* lock the device */
|
||||||
|
mutex_lock(&dev->lock);
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
|
|
||||||
/* prevent device read, write and ioctl */
|
/* prevent device read, write and ioctl */
|
||||||
dev->present = 0;
|
dev->present = 0;
|
||||||
|
|
||||||
/* if the device is opened, idmouse_release will clean this up */
|
/* if the device is opened, idmouse_release will clean this up */
|
||||||
if (!dev->open) {
|
if (!dev->open) {
|
||||||
up(&dev->sem);
|
mutex_unlock(&dev->lock);
|
||||||
idmouse_delete(dev);
|
idmouse_delete(dev);
|
||||||
} else {
|
} else {
|
||||||
/* unlock */
|
/* unlock */
|
||||||
up(&dev->sem);
|
mutex_unlock(&dev->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
info("%s disconnected", DRIVER_DESC);
|
info("%s disconnected", DRIVER_DESC);
|
||||||
|
|
|
@ -66,6 +66,7 @@ module_param(debug, bool, 0644);
|
||||||
MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
|
MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
|
||||||
|
|
||||||
static struct usb_driver iowarrior_driver;
|
static struct usb_driver iowarrior_driver;
|
||||||
|
static DEFINE_MUTEX(iowarrior_open_disc_lock);
|
||||||
|
|
||||||
/*--------------*/
|
/*--------------*/
|
||||||
/* data */
|
/* data */
|
||||||
|
@ -351,7 +352,7 @@ static ssize_t iowarrior_write(struct file *file,
|
||||||
|
|
||||||
mutex_lock(&dev->mutex);
|
mutex_lock(&dev->mutex);
|
||||||
/* verify that the device wasn't unplugged */
|
/* verify that the device wasn't unplugged */
|
||||||
if (dev == NULL || !dev->present) {
|
if (!dev->present) {
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -608,11 +609,15 @@ static int iowarrior_open(struct inode *inode, struct file *file)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&iowarrior_open_disc_lock);
|
||||||
dev = usb_get_intfdata(interface);
|
dev = usb_get_intfdata(interface);
|
||||||
if (!dev)
|
if (!dev) {
|
||||||
|
mutex_unlock(&iowarrior_open_disc_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_lock(&dev->mutex);
|
mutex_lock(&dev->mutex);
|
||||||
|
mutex_unlock(&iowarrior_open_disc_lock);
|
||||||
|
|
||||||
/* Only one process can open each device, no sharing. */
|
/* Only one process can open each device, no sharing. */
|
||||||
if (dev->opened) {
|
if (dev->opened) {
|
||||||
|
@ -866,6 +871,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
|
||||||
int minor;
|
int minor;
|
||||||
|
|
||||||
dev = usb_get_intfdata(interface);
|
dev = usb_get_intfdata(interface);
|
||||||
|
mutex_lock(&iowarrior_open_disc_lock);
|
||||||
usb_set_intfdata(interface, NULL);
|
usb_set_intfdata(interface, NULL);
|
||||||
|
|
||||||
minor = dev->minor;
|
minor = dev->minor;
|
||||||
|
@ -879,6 +885,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
|
||||||
dev->present = 0;
|
dev->present = 0;
|
||||||
|
|
||||||
mutex_unlock(&dev->mutex);
|
mutex_unlock(&dev->mutex);
|
||||||
|
mutex_unlock(&iowarrior_open_disc_lock);
|
||||||
|
|
||||||
if (dev->opened) {
|
if (dev->opened) {
|
||||||
/* There is a process that holds a filedescriptor to the device ,
|
/* 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);
|
MODULE_DEVICE_TABLE (usb, tower_table);
|
||||||
|
static DEFINE_MUTEX(open_disc_mutex);
|
||||||
|
|
||||||
#define LEGO_USB_TOWER_MINOR_BASE 160
|
#define LEGO_USB_TOWER_MINOR_BASE 160
|
||||||
|
|
||||||
|
@ -350,25 +351,31 @@ static int tower_open (struct inode *inode, struct file *file)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&open_disc_mutex);
|
||||||
dev = usb_get_intfdata(interface);
|
dev = usb_get_intfdata(interface);
|
||||||
|
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lock this device */
|
/* lock this device */
|
||||||
if (down_interruptible (&dev->sem)) {
|
if (down_interruptible (&dev->sem)) {
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
retval = -ERESTARTSYS;
|
retval = -ERESTARTSYS;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* allow opening only once */
|
/* allow opening only once */
|
||||||
if (dev->open_count) {
|
if (dev->open_count) {
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
retval = -EBUSY;
|
retval = -EBUSY;
|
||||||
goto unlock_exit;
|
goto unlock_exit;
|
||||||
}
|
}
|
||||||
dev->open_count = 1;
|
dev->open_count = 1;
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
|
|
||||||
/* reset the tower */
|
/* reset the tower */
|
||||||
result = usb_control_msg (dev->udev,
|
result = usb_control_msg (dev->udev,
|
||||||
|
@ -437,9 +444,10 @@ static int tower_release (struct inode *inode, struct file *file)
|
||||||
if (dev == NULL) {
|
if (dev == NULL) {
|
||||||
dbg(1, "%s: object is NULL", __FUNCTION__);
|
dbg(1, "%s: object is NULL", __FUNCTION__);
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto exit;
|
goto exit_nolock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&open_disc_mutex);
|
||||||
if (down_interruptible (&dev->sem)) {
|
if (down_interruptible (&dev->sem)) {
|
||||||
retval = -ERESTARTSYS;
|
retval = -ERESTARTSYS;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -468,6 +476,8 @@ static int tower_release (struct inode *inode, struct file *file)
|
||||||
up (&dev->sem);
|
up (&dev->sem);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
|
exit_nolock:
|
||||||
dbg(2, "%s: leave, return value %d", __FUNCTION__, retval);
|
dbg(2, "%s: leave, return value %d", __FUNCTION__, retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -989,6 +999,7 @@ static void tower_disconnect (struct usb_interface *interface)
|
||||||
dbg(2, "%s: enter", __FUNCTION__);
|
dbg(2, "%s: enter", __FUNCTION__);
|
||||||
|
|
||||||
dev = usb_get_intfdata (interface);
|
dev = usb_get_intfdata (interface);
|
||||||
|
mutex_lock(&open_disc_mutex);
|
||||||
usb_set_intfdata (interface, NULL);
|
usb_set_intfdata (interface, NULL);
|
||||||
|
|
||||||
minor = dev->minor;
|
minor = dev->minor;
|
||||||
|
@ -997,6 +1008,7 @@ static void tower_disconnect (struct usb_interface *interface)
|
||||||
usb_deregister_dev (interface, &tower_class);
|
usb_deregister_dev (interface, &tower_class);
|
||||||
|
|
||||||
down (&dev->sem);
|
down (&dev->sem);
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
|
|
||||||
/* if the device is not opened, then we clean up right now */
|
/* if the device is not opened, then we clean up right now */
|
||||||
if (!dev->open_count) {
|
if (!dev->open_count) {
|
||||||
|
|
|
@ -118,10 +118,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
|
||||||
|
|
||||||
mutex_lock(&(rio->lock));
|
mutex_lock(&(rio->lock));
|
||||||
/* Sanity check to make sure rio is connected, powered, etc */
|
/* Sanity check to make sure rio is connected, powered, etc */
|
||||||
if ( rio == NULL ||
|
if (rio->present == 0 || rio->rio_dev == NULL) {
|
||||||
rio->present == 0 ||
|
|
||||||
rio->rio_dev == NULL )
|
|
||||||
{
|
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
@ -280,10 +277,7 @@ write_rio(struct file *file, const char __user *buffer,
|
||||||
if (intr)
|
if (intr)
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
/* Sanity check to make sure rio is connected, powered, etc */
|
/* Sanity check to make sure rio is connected, powered, etc */
|
||||||
if ( rio == NULL ||
|
if (rio->present == 0 || rio->rio_dev == NULL) {
|
||||||
rio->present == 0 ||
|
|
||||||
rio->rio_dev == NULL )
|
|
||||||
{
|
|
||||||
mutex_unlock(&(rio->lock));
|
mutex_unlock(&(rio->lock));
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
@ -369,10 +363,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
|
||||||
if (intr)
|
if (intr)
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
/* Sanity check to make sure rio is connected, powered, etc */
|
/* Sanity check to make sure rio is connected, powered, etc */
|
||||||
if ( rio == NULL ||
|
if (rio->present == 0 || rio->rio_dev == NULL) {
|
||||||
rio->present == 0 ||
|
|
||||||
rio->rio_dev == NULL )
|
|
||||||
{
|
|
||||||
mutex_unlock(&(rio->lock));
|
mutex_unlock(&(rio->lock));
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <linux/usb.h>
|
#include <linux/usb.h>
|
||||||
|
|
||||||
|
@ -34,6 +35,8 @@ static struct usb_device_id id_table [] = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE (usb, id_table);
|
MODULE_DEVICE_TABLE (usb, id_table);
|
||||||
|
|
||||||
|
static DEFINE_MUTEX(open_disc_mutex);
|
||||||
|
|
||||||
|
|
||||||
struct usb_lcd {
|
struct usb_lcd {
|
||||||
struct usb_device * udev; /* init: probe_lcd */
|
struct usb_device * udev; /* init: probe_lcd */
|
||||||
|
@ -79,12 +82,16 @@ static int lcd_open(struct inode *inode, struct file *file)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&open_disc_mutex);
|
||||||
dev = usb_get_intfdata(interface);
|
dev = usb_get_intfdata(interface);
|
||||||
if (!dev)
|
if (!dev) {
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
/* increment our usage count for the device */
|
/* increment our usage count for the device */
|
||||||
kref_get(&dev->kref);
|
kref_get(&dev->kref);
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
|
|
||||||
/* grab a power reference */
|
/* grab a power reference */
|
||||||
r = usb_autopm_get_interface(interface);
|
r = usb_autopm_get_interface(interface);
|
||||||
|
@ -393,8 +400,10 @@ static void lcd_disconnect(struct usb_interface *interface)
|
||||||
struct usb_lcd *dev;
|
struct usb_lcd *dev;
|
||||||
int minor = interface->minor;
|
int minor = interface->minor;
|
||||||
|
|
||||||
|
mutex_lock(&open_disc_mutex);
|
||||||
dev = usb_get_intfdata(interface);
|
dev = usb_get_intfdata(interface);
|
||||||
usb_set_intfdata(interface, NULL);
|
usb_set_intfdata(interface, NULL);
|
||||||
|
mutex_unlock(&open_disc_mutex);
|
||||||
|
|
||||||
/* give back our minor */
|
/* give back our minor */
|
||||||
usb_deregister_dev(interface, &lcd_class);
|
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 usb_serial *serial = port->serial;
|
||||||
struct ark3116_private *priv = usb_get_serial_port_data(port);
|
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;
|
unsigned long flags;
|
||||||
int baud;
|
int baud;
|
||||||
int ark3116_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) = tty_std_termios;
|
||||||
port->tty->termios->c_cflag = B9600 | CS8
|
port->tty->termios->c_cflag = B9600 | CS8
|
||||||
| CREAD | HUPCL | CLOCAL;
|
| CREAD | HUPCL | CLOCAL;
|
||||||
|
termios->c_ispeed = 9600;
|
||||||
|
termios->c_ospeed = 9600;
|
||||||
priv->termios_initialized = 1;
|
priv->termios_initialized = 1;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
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);
|
buf = kmalloc(1, GFP_KERNEL);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
|
@ -254,9 +258,13 @@ static void ark3116_set_termios(struct usb_serial_port *port,
|
||||||
case 115200:
|
case 115200:
|
||||||
case 230400:
|
case 230400:
|
||||||
case 460800:
|
case 460800:
|
||||||
|
/* Report the resulting rate back to the caller */
|
||||||
|
tty_encode_baud_rate(port->tty, baud, baud);
|
||||||
break;
|
break;
|
||||||
/* set 9600 as default (if given baudrate is invalid for example) */
|
/* set 9600 as default (if given baudrate is invalid for example) */
|
||||||
default:
|
default:
|
||||||
|
tty_encode_baud_rate(port->tty, 9600, 9600);
|
||||||
|
case 0:
|
||||||
baud = 9600;
|
baud = 9600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,6 +310,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
|
||||||
/* TEST ARK3116_SND(154, 0xFE, 0x40, 0xFFFF, 0x0006); */
|
/* TEST ARK3116_SND(154, 0xFE, 0x40, 0xFFFF, 0x0006); */
|
||||||
|
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -272,9 +272,6 @@ static void ch341_set_termios(struct usb_serial_port *port,
|
||||||
|
|
||||||
dbg("ch341_set_termios()");
|
dbg("ch341_set_termios()");
|
||||||
|
|
||||||
if (!tty || !tty->termios)
|
|
||||||
return;
|
|
||||||
|
|
||||||
baud_rate = tty_get_baud_rate(tty);
|
baud_rate = tty_get_baud_rate(tty);
|
||||||
|
|
||||||
switch (baud_rate) {
|
switch (baud_rate) {
|
||||||
|
@ -299,6 +296,11 @@ static void ch341_set_termios(struct usb_serial_port *port,
|
||||||
* (cflag & PARENB) : parity {NONE, EVEN, ODD}
|
* (cflag & PARENB) : parity {NONE, EVEN, ODD}
|
||||||
* (cflag & CSTOPB) : stop bits [1, 2]
|
* (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 = {
|
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) {
|
if (serial->type->set_termios) {
|
||||||
|
struct ktermios dummy;
|
||||||
/* build up a fake tty structure so that the open call has something
|
/* build up a fake tty structure so that the open call has something
|
||||||
* to look at to get the cflag value */
|
* to look at to get the cflag value */
|
||||||
tty = kzalloc(sizeof(*tty), GFP_KERNEL);
|
tty = kzalloc(sizeof(*tty), GFP_KERNEL);
|
||||||
|
@ -177,12 +178,13 @@ static int usb_console_setup(struct console *co, char *options)
|
||||||
kfree (tty);
|
kfree (tty);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
memset(&dummy, 0, sizeof(struct ktermios));
|
||||||
termios->c_cflag = cflag;
|
termios->c_cflag = cflag;
|
||||||
tty->termios = termios;
|
tty->termios = termios;
|
||||||
port->tty = tty;
|
port->tty = tty;
|
||||||
|
|
||||||
/* set up the initial termios settings */
|
/* set up the initial termios settings */
|
||||||
serial->type->set_termios(port, NULL);
|
serial->type->set_termios(port, &dummy);
|
||||||
port->tty = NULL;
|
port->tty = NULL;
|
||||||
kfree (termios);
|
kfree (termios);
|
||||||
kfree (tty);
|
kfree (tty);
|
||||||
|
|
|
@ -361,7 +361,6 @@ static void cp2101_get_termios (struct usb_serial_port *port)
|
||||||
dbg("%s - no tty structures", __FUNCTION__);
|
dbg("%s - no tty structures", __FUNCTION__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cflag = port->tty->termios->c_cflag;
|
|
||||||
|
|
||||||
cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
|
cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
|
||||||
/* Convert to baudrate */
|
/* Convert to baudrate */
|
||||||
|
@ -369,40 +368,9 @@ static void cp2101_get_termios (struct usb_serial_port *port)
|
||||||
baud = BAUD_RATE_GEN_FREQ / baud;
|
baud = BAUD_RATE_GEN_FREQ / baud;
|
||||||
|
|
||||||
dbg("%s - baud rate = %d", __FUNCTION__, baud);
|
dbg("%s - baud rate = %d", __FUNCTION__, baud);
|
||||||
cflag &= ~CBAUD;
|
|
||||||
switch (baud) {
|
tty_encode_baud_rate(port->tty, baud, baud);
|
||||||
/*
|
cflag = port->tty->termios->c_cflag;
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
cp2101_get_config(port, CP2101_BITS, &bits, 2);
|
cp2101_get_config(port, CP2101_BITS, &bits, 2);
|
||||||
cflag &= ~CSIZE;
|
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,
|
static void cp2101_set_termios (struct usb_serial_port *port,
|
||||||
struct ktermios *old_termios)
|
struct ktermios *old_termios)
|
||||||
{
|
{
|
||||||
unsigned int cflag, old_cflag=0;
|
unsigned int cflag, old_cflag;
|
||||||
int baud=0, bits;
|
int baud=0, bits;
|
||||||
unsigned int modem_ctl[4];
|
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__);
|
dbg("%s - no tty structures", __FUNCTION__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
port->tty->termios->c_cflag &= ~CMSPAR;
|
||||||
|
|
||||||
cflag = port->tty->termios->c_cflag;
|
cflag = port->tty->termios->c_cflag;
|
||||||
old_cflag = old_termios->c_cflag;
|
old_cflag = old_termios->c_cflag;
|
||||||
baud = tty_get_baud_rate(port->tty);
|
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__,
|
dbg("%s - Setting baud rate to %d baud", __FUNCTION__,
|
||||||
baud);
|
baud);
|
||||||
if (cp2101_set_config_single(port, CP2101_BAUDRATE,
|
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 "
|
dev_err(&port->dev, "Baud rate requested not "
|
||||||
"supported by device\n");
|
"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 the number of data bits is to be updated */
|
||||||
if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
|
if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
|
||||||
|
|
|
@ -973,6 +973,8 @@ static void digi_set_termios(struct usb_serial_port *port,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* set parity */
|
/* set parity */
|
||||||
|
tty->termios->c_cflag &= ~CMSPAR;
|
||||||
|
|
||||||
if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) {
|
if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) {
|
||||||
if (cflag&PARENB) {
|
if (cflag&PARENB) {
|
||||||
if (cflag&PARODD)
|
if (cflag&PARODD)
|
||||||
|
@ -1054,15 +1056,15 @@ static void digi_set_termios(struct usb_serial_port *port,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set output flow control */
|
/* set output flow control */
|
||||||
if ((iflag&IXON) != (old_iflag&IXON)
|
if ((iflag & IXON) != (old_iflag & IXON)
|
||||||
|| (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) {
|
|| (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
|
||||||
arg = 0;
|
arg = 0;
|
||||||
if (iflag&IXON)
|
if (iflag & IXON)
|
||||||
arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
|
arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
|
||||||
else
|
else
|
||||||
arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
|
arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
|
||||||
|
|
||||||
if (cflag&CRTSCTS) {
|
if (cflag & CRTSCTS) {
|
||||||
arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS;
|
arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS;
|
||||||
} else {
|
} else {
|
||||||
arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS;
|
arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS;
|
||||||
|
@ -1076,8 +1078,8 @@ static void digi_set_termios(struct usb_serial_port *port,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set receive enable/disable */
|
/* set receive enable/disable */
|
||||||
if ((cflag&CREAD) != (old_cflag&CREAD)) {
|
if ((cflag & CREAD) != (old_cflag & CREAD)) {
|
||||||
if (cflag&CREAD)
|
if (cflag & CREAD)
|
||||||
arg = DIGI_ENABLE;
|
arg = DIGI_ENABLE;
|
||||||
else
|
else
|
||||||
arg = DIGI_DISABLE;
|
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)
|
if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0)
|
||||||
dbg("digi_set_termios: write oob failed, ret=%d", ret);
|
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)
|
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);
|
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.
|
* The empeg-car player wants these particular tty settings.
|
||||||
* You could, for example, change the baud rate, however the
|
* 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:
|
* The default requirements for this device are:
|
||||||
*/
|
*/
|
||||||
port->tty->termios->c_iflag
|
termios->c_iflag
|
||||||
&= ~(IGNBRK /* disable ignore break */
|
&= ~(IGNBRK /* disable ignore break */
|
||||||
| BRKINT /* disable break causes interrupt */
|
| BRKINT /* disable break causes interrupt */
|
||||||
| PARMRK /* disable mark parity errors */
|
| 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 */
|
| ICRNL /* disable translate CR to NL */
|
||||||
| IXON); /* disable enable XON/XOFF flow control */
|
| IXON); /* disable enable XON/XOFF flow control */
|
||||||
|
|
||||||
port->tty->termios->c_oflag
|
termios->c_oflag
|
||||||
&= ~OPOST; /* disable postprocess output characters */
|
&= ~OPOST; /* disable postprocess output characters */
|
||||||
|
|
||||||
port->tty->termios->c_lflag
|
termios->c_lflag
|
||||||
&= ~(ECHO /* disable echo input characters */
|
&= ~(ECHO /* disable echo input characters */
|
||||||
| ECHONL /* disable echo new line */
|
| ECHONL /* disable echo new line */
|
||||||
| ICANON /* disable erase, kill, werase, and rprnt special characters */
|
| ICANON /* disable erase, kill, werase, and rprnt special characters */
|
||||||
| ISIG /* disable interrupt, quit, and suspend special characters */
|
| ISIG /* disable interrupt, quit, and suspend special characters */
|
||||||
| IEXTEN); /* disable non-POSIX special characters */
|
| IEXTEN); /* disable non-POSIX special characters */
|
||||||
|
|
||||||
port->tty->termios->c_cflag
|
termios->c_cflag
|
||||||
&= ~(CSIZE /* no size */
|
&= ~(CSIZE /* no size */
|
||||||
| PARENB /* disable parity bit */
|
| PARENB /* disable parity bit */
|
||||||
| CBAUD); /* clear current baud rate */
|
| CBAUD); /* clear current baud rate */
|
||||||
|
|
||||||
port->tty->termios->c_cflag
|
termios->c_cflag
|
||||||
|= (CS8 /* character size 8 bits */
|
|= CS8; /* character size 8 bits */
|
||||||
| B115200); /* baud rate 115200 */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force low_latency on; otherwise the pushes are scheduled;
|
* 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. :)
|
* on the floor. We don't want to drop bytes on the floor. :)
|
||||||
*/
|
*/
|
||||||
port->tty->low_latency = 1;
|
port->tty->low_latency = 1;
|
||||||
|
tty_encode_baud_rate(port->tty, 115200, 115200);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -294,7 +294,7 @@ struct ftdi_private {
|
||||||
|
|
||||||
__u16 interface; /* FT2232C port interface (0 for FT232/245) */
|
__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 */
|
int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
|
||||||
|
|
||||||
spinlock_t tx_lock; /* spinlock for transmit state */
|
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) {
|
if (div_value == 0) {
|
||||||
dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__, baud);
|
dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__, baud);
|
||||||
div_value = ftdi_sio_b9600;
|
div_value = ftdi_sio_b9600;
|
||||||
|
baud = 9600;
|
||||||
div_okay = 0;
|
div_okay = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -886,6 +887,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
|
||||||
div_value = ftdi_232am_baud_to_divisor(baud);
|
div_value = ftdi_232am_baud_to_divisor(baud);
|
||||||
} else {
|
} else {
|
||||||
dbg("%s - Baud rate too high!", __FUNCTION__);
|
dbg("%s - Baud rate too high!", __FUNCTION__);
|
||||||
|
baud = 9600;
|
||||||
div_value = ftdi_232am_baud_to_divisor(9600);
|
div_value = ftdi_232am_baud_to_divisor(9600);
|
||||||
div_okay = 0;
|
div_okay = 0;
|
||||||
}
|
}
|
||||||
|
@ -899,6 +901,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
|
||||||
dbg("%s - Baud rate too high!", __FUNCTION__);
|
dbg("%s - Baud rate too high!", __FUNCTION__);
|
||||||
div_value = ftdi_232bm_baud_to_divisor(9600);
|
div_value = ftdi_232bm_baud_to_divisor(9600);
|
||||||
div_okay = 0;
|
div_okay = 0;
|
||||||
|
baud = 9600;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} /* priv->chip_type */
|
} /* priv->chip_type */
|
||||||
|
@ -909,6 +912,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
|
||||||
ftdi_chip_name[priv->chip_type]);
|
ftdi_chip_name[priv->chip_type]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tty_encode_baud_rate(port->tty, baud, baud);
|
||||||
return(div_value);
|
return(div_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1263,7 +1267,7 @@ static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
|
||||||
|
|
||||||
priv->flags |= ASYNC_SPD_CUST;
|
priv->flags |= ASYNC_SPD_CUST;
|
||||||
priv->custom_divisor = 77;
|
priv->custom_divisor = 77;
|
||||||
priv->force_baud = B38400;
|
priv->force_baud = 38400;
|
||||||
} /* ftdi_USB_UIRT_setup */
|
} /* ftdi_USB_UIRT_setup */
|
||||||
|
|
||||||
/* Setup for the HE-TIRA1 device, which requires hardwired
|
/* 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->flags |= ASYNC_SPD_CUST;
|
||||||
priv->custom_divisor = 240;
|
priv->custom_divisor = 240;
|
||||||
priv->force_baud = B38400;
|
priv->force_baud = 38400;
|
||||||
priv->force_rtscts = 1;
|
priv->force_rtscts = 1;
|
||||||
} /* ftdi_HE_TIRA1_setup */
|
} /* 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 */
|
/* ftdi_set_termios will send usb control messages */
|
||||||
if (port->tty)
|
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 -
|
/* FIXME: Flow control might be enabled, so it should be checked -
|
||||||
we have no control of defaults! */
|
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)
|
static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
|
||||||
{ /* ftdi_termios */
|
{ /* ftdi_termios */
|
||||||
struct usb_device *dev = port->serial->dev;
|
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 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 */
|
__u16 urb_value; /* will hold the new flags */
|
||||||
char buf[1]; /* Perhaps I should dynamically alloc this? */
|
char buf[1]; /* Perhaps I should dynamically alloc this? */
|
||||||
|
|
||||||
// Added for xon/xoff support
|
// Added for xon/xoff support
|
||||||
unsigned int iflag = port->tty->termios->c_iflag;
|
unsigned int iflag = termios->c_iflag;
|
||||||
unsigned char vstop;
|
unsigned char vstop;
|
||||||
unsigned char vstart;
|
unsigned char vstart;
|
||||||
|
|
||||||
dbg("%s", __FUNCTION__);
|
dbg("%s", __FUNCTION__);
|
||||||
|
|
||||||
/* Force baud rate if this device requires it, unless it is set to B0. */
|
/* 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__);
|
dbg("%s: forcing baud rate for this device", __FUNCTION__);
|
||||||
port->tty->termios->c_cflag &= ~CBAUD;
|
tty_encode_baud_rate(port->tty, priv->force_baud,
|
||||||
port->tty->termios->c_cflag |= priv->force_baud;
|
priv->force_baud);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Force RTS-CTS if this device requires it. */
|
/* Force RTS-CTS if this device requires it. */
|
||||||
if (priv->force_rtscts) {
|
if (priv->force_rtscts) {
|
||||||
dbg("%s: forcing rtscts for this device", __FUNCTION__);
|
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
|
/* 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
|
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 */
|
/* Set number of data bits, parity, stop bits */
|
||||||
|
|
||||||
|
termios->c_cflag &= ~CMSPAR;
|
||||||
|
|
||||||
urb_value = 0;
|
urb_value = 0;
|
||||||
urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 :
|
urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 :
|
||||||
FTDI_SIO_SET_DATA_STOP_BITS_1);
|
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
|
// Set the vstart and vstop -- could have been done up above where
|
||||||
// a lot of other dereferencing is done but that would be very
|
// a lot of other dereferencing is done but that would be very
|
||||||
// inefficient as vstart and vstop are not always needed
|
// inefficient as vstart and vstop are not always needed
|
||||||
vstart=port->tty->termios->c_cc[VSTART];
|
vstart = termios->c_cc[VSTART];
|
||||||
vstop=port->tty->termios->c_cc[VSTOP];
|
vstop = termios->c_cc[VSTOP];
|
||||||
urb_value=(vstop << 8) | (vstart);
|
urb_value=(vstop << 8) | (vstart);
|
||||||
|
|
||||||
if (usb_control_msg(dev,
|
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 */
|
/* only do something if we have a bulk out endpoint */
|
||||||
if (serial->num_bulk_out) {
|
if (serial->num_bulk_out) {
|
||||||
spin_lock_bh(&port->lock);
|
unsigned long flags;
|
||||||
|
spin_lock_irqsave(&port->lock, flags);
|
||||||
if (port->write_urb_busy) {
|
if (port->write_urb_busy) {
|
||||||
spin_unlock_bh(&port->lock);
|
spin_unlock_irqrestore(&port->lock, flags);
|
||||||
dbg("%s - already writing", __FUNCTION__);
|
dbg("%s - already writing", __FUNCTION__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
port->write_urb_busy = 1;
|
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;
|
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)
|
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 edgeport_port *edge_port = usb_get_serial_port_data(port);
|
||||||
struct tty_struct *tty = port->tty;
|
struct tty_struct *tty = port->tty;
|
||||||
unsigned int cflag;
|
unsigned int cflag;
|
||||||
|
|
||||||
if (!port->tty || !port->tty->termios) {
|
|
||||||
dbg ("%s - no tty or termios", __FUNCTION__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cflag = tty->termios->c_cflag;
|
cflag = tty->termios->c_cflag;
|
||||||
dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
|
dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
|
||||||
tty->termios->c_cflag, tty->termios->c_iflag);
|
tty->termios->c_cflag, tty->termios->c_iflag);
|
||||||
if (old_termios) {
|
dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
|
||||||
dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
|
old_termios->c_cflag, old_termios->c_iflag);
|
||||||
old_termios->c_cflag, old_termios->c_iflag);
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg("%s - port %d", __FUNCTION__, port->number);
|
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);
|
dbg("%s - baud rate = %d", __FUNCTION__, baud);
|
||||||
status = send_cmd_write_baud_rate (edge_port, 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;
|
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);
|
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);
|
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:
|
default:
|
||||||
ir_baud = SPEED_9600;
|
ir_baud = SPEED_9600;
|
||||||
baud = 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)
|
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);
|
result = usb_submit_urb (port->write_urb, GFP_KERNEL);
|
||||||
if (result)
|
if (result)
|
||||||
dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, 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;
|
struct keyspan_port_private *p_priv;
|
||||||
const struct keyspan_device_details *d_details;
|
const struct keyspan_device_details *d_details;
|
||||||
unsigned int cflag;
|
unsigned int cflag;
|
||||||
|
struct tty_struct *tty = port->tty;
|
||||||
|
|
||||||
dbg("%s", __FUNCTION__);
|
dbg("%s", __FUNCTION__);
|
||||||
|
|
||||||
p_priv = usb_get_serial_port_data(port);
|
p_priv = usb_get_serial_port_data(port);
|
||||||
d_details = p_priv->device_details;
|
d_details = p_priv->device_details;
|
||||||
cflag = port->tty->termios->c_cflag;
|
cflag = tty->termios->c_cflag;
|
||||||
device_port = port->number - port->serial->minor;
|
device_port = port->number - port->serial->minor;
|
||||||
|
|
||||||
/* Baud rate calculation takes baud rate as an integer
|
/* Baud rate calculation takes baud rate as an integer
|
||||||
so other rates can be generated if desired. */
|
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 no match or invalid, don't change */
|
||||||
if (baud_rate >= 0
|
if (d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
|
||||||
&& d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
|
|
||||||
NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
|
NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
|
||||||
/* FIXME - more to do here to ensure rate changes cleanly */
|
/* FIXME - more to do here to ensure rate changes cleanly */
|
||||||
|
/* FIXME - calcuate exact rate from divisor ? */
|
||||||
p_priv->baud = baud_rate;
|
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. */
|
/* set CTS/RTS handshake etc. */
|
||||||
p_priv->cflag = cflag;
|
p_priv->cflag = cflag;
|
||||||
p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
|
p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
|
||||||
|
|
||||||
|
/* Mark/Space not supported */
|
||||||
|
tty->termios->c_cflag &= ~CMSPAR;
|
||||||
|
|
||||||
keyspan_send_setup(port, 0);
|
keyspan_send_setup(port, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -616,8 +616,9 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old
|
||||||
case 1200:
|
case 1200:
|
||||||
urb_val = SUSBCR_SBR_1200;
|
urb_val = SUSBCR_SBR_1200;
|
||||||
break;
|
break;
|
||||||
case 9600:
|
|
||||||
default:
|
default:
|
||||||
|
speed = 9600;
|
||||||
|
case 9600:
|
||||||
urb_val = SUSBCR_SBR_9600;
|
urb_val = SUSBCR_SBR_9600;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -641,6 +642,8 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old
|
||||||
urb_val |= SUSBCR_SPASB_NoParity;
|
urb_val |= SUSBCR_SPASB_NoParity;
|
||||||
strcat(settings, "No Parity");
|
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,
|
result = usb_control_msg( port->serial->dev,
|
||||||
usb_rcvctrlpipe(port->serial->dev, 0 ),
|
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;
|
tty = mos7840_port->port->tty;
|
||||||
|
|
||||||
if ((!tty) || (!tty->termios)) {
|
|
||||||
dbg("%s - no tty structures", __FUNCTION__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg("%s", "Entering .......... \n");
|
dbg("%s", "Entering .......... \n");
|
||||||
|
|
||||||
lData = LCR_BITS_8;
|
lData = LCR_BITS_8;
|
||||||
|
@ -2151,11 +2146,6 @@ static void mos7840_set_termios(struct usb_serial_port *port,
|
||||||
|
|
||||||
tty = port->tty;
|
tty = port->tty;
|
||||||
|
|
||||||
if (!port->tty || !port->tty->termios) {
|
|
||||||
dbg("%s - no tty or termios", __FUNCTION__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mos7840_port->open) {
|
if (!mos7840_port->open) {
|
||||||
dbg("%s - port not opened", __FUNCTION__);
|
dbg("%s - port not opened", __FUNCTION__);
|
||||||
return;
|
return;
|
||||||
|
@ -2165,19 +2155,10 @@ static void mos7840_set_termios(struct usb_serial_port *port,
|
||||||
|
|
||||||
cflag = tty->termios->c_cflag;
|
cflag = tty->termios->c_cflag;
|
||||||
|
|
||||||
if (!cflag) {
|
|
||||||
dbg("%s %s\n", __FUNCTION__, "cflag is NULL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
|
dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
|
||||||
tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
|
tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
|
||||||
|
dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
|
||||||
if (old_termios) {
|
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);
|
dbg("%s - port %d", __FUNCTION__, port->number);
|
||||||
|
|
||||||
/* change the port settings to the new ones specified */
|
/* 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, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
|
||||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
|
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
|
||||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
|
{ 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, 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, 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 */
|
{ 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)
|
struct ktermios *old_termios)
|
||||||
{
|
{
|
||||||
dbg("%s", __FUNCTION__);
|
dbg("%s", __FUNCTION__);
|
||||||
|
/* Doesn't support option setting */
|
||||||
|
tty_termios_copy_hw(port->tty->termios, old_termios);
|
||||||
option_send_setup(port);
|
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_RSAQ3) },
|
||||||
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
|
{ 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) },
|
||||||
|
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
|
||||||
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
|
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
|
||||||
{ USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
|
{ USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
|
||||||
{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_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);
|
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);
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
if (!priv->termios_initialized) {
|
if (!priv->termios_initialized) {
|
||||||
*(port->tty->termios) = tty_std_termios;
|
*(port->tty->termios) = tty_std_termios;
|
||||||
port->tty->termios->c_cflag = B9600 | CS8 | CREAD |
|
port->tty->termios->c_cflag = B9600 | CS8 | CREAD |
|
||||||
HUPCL | CLOCAL;
|
HUPCL | CLOCAL;
|
||||||
|
port->tty->termios->c_ispeed = 9600;
|
||||||
|
port->tty->termios->c_ospeed = 9600;
|
||||||
priv->termios_initialized = 1;
|
priv->termios_initialized = 1;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
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);
|
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);
|
kfree(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#define IODATA_VENDOR_ID 0x04bb
|
#define IODATA_VENDOR_ID 0x04bb
|
||||||
#define IODATA_PRODUCT_ID 0x0a03
|
#define IODATA_PRODUCT_ID 0x0a03
|
||||||
|
#define IODATA_PRODUCT_ID_RSAQ5 0x0a0e
|
||||||
|
|
||||||
#define ELCOM_VENDOR_ID 0x056e
|
#define ELCOM_VENDOR_ID 0x056e
|
||||||
#define ELCOM_PRODUCT_ID 0x5003
|
#define ELCOM_PRODUCT_ID 0x5003
|
||||||
|
|
|
@ -224,7 +224,7 @@ static void sierra_set_termios(struct usb_serial_port *port,
|
||||||
struct ktermios *old_termios)
|
struct ktermios *old_termios)
|
||||||
{
|
{
|
||||||
dbg("%s", __FUNCTION__);
|
dbg("%s", __FUNCTION__);
|
||||||
|
tty_termios_copy_hw(port->tty->termios, old_termios);
|
||||||
sierra_send_setup(port);
|
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 */
|
/* pass on to the driver specific version of this function if it is available */
|
||||||
if (port->serial->type->set_termios)
|
if (port->serial->type->set_termios)
|
||||||
port->serial->type->set_termios(port, old);
|
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)
|
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);
|
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);
|
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)
|
static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios)
|
||||||
{
|
{
|
||||||
dbg("%s -port %d", __FUNCTION__, port->number);
|
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);
|
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);
|
port_settings.baud = tty_get_baud_rate(port->tty);
|
||||||
dbg("%s - baud rate = %d", __FUNCTION__, port_settings.baud);
|
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 */
|
/* handle any settings that aren't specified in the tty structure */
|
||||||
port_settings.lloop = 0;
|
port_settings.lloop = 0;
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ config USB_STORAGE_FREECOM
|
||||||
config USB_STORAGE_ISD200
|
config USB_STORAGE_ISD200
|
||||||
bool "ISD-200 USB/ATA Bridge support"
|
bool "ISD-200 USB/ATA Bridge support"
|
||||||
depends on USB_STORAGE
|
depends on USB_STORAGE
|
||||||
depends on BLK_DEV_IDE=y || BLK_DEV_IDE=USB_STORAGE
|
|
||||||
---help---
|
---help---
|
||||||
Say Y here if you want to use USB Mass Store devices based
|
Say Y here if you want to use USB Mass Store devices based
|
||||||
on the In-Systems Design ISD-200 USB/ATA bridge.
|
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);
|
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
|
* isd200_get_inquiry_data
|
||||||
|
@ -1018,7 +1121,7 @@ static int isd200_get_inquiry_data( struct us_data *us )
|
||||||
int i;
|
int i;
|
||||||
__be16 *src;
|
__be16 *src;
|
||||||
__u16 *dest;
|
__u16 *dest;
|
||||||
ide_fix_driveid(id);
|
isd200_fix_driveid(id);
|
||||||
|
|
||||||
US_DEBUGP(" Identify Data Structure:\n");
|
US_DEBUGP(" Identify Data Structure:\n");
|
||||||
US_DEBUGP(" config = 0x%x\n", id->config);
|
US_DEBUGP(" config = 0x%x\n", id->config);
|
||||||
|
|
Loading…
Add table
Reference in a new issue