Commit 8a51beef authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 88d0505c c8682fb0
...@@ -254,7 +254,7 @@ firmware_data_write(struct kobject *kobj, ...@@ -254,7 +254,7 @@ firmware_data_write(struct kobject *kobj,
return retval; return retval;
} }
static struct bin_attribute firmware_attr_data_tmpl = { static struct bin_attribute firmware_attr_data_tmpl = {
.attr = {.name = "data", .mode = 0644}, .attr = {.name = "data", .mode = 0644, .owner = THIS_MODULE},
.size = 0, .size = 0,
.read = firmware_data_read, .read = firmware_data_read,
.write = firmware_data_write, .write = firmware_data_write,
......
...@@ -121,7 +121,7 @@ init_ti_parallel(int minor) ...@@ -121,7 +121,7 @@ init_ti_parallel(int minor)
/* ----- global defines ----------------------------------------------- */ /* ----- global defines ----------------------------------------------- */
#define START(x) { x=jiffies+HZ/(timeout/10); } #define START(x) { x = jiffies + (HZ * timeout) / 10; }
#define WAIT(x) { \ #define WAIT(x) { \
if (time_before((x), jiffies)) return -1; \ if (time_before((x), jiffies)) return -1; \
if (need_resched()) schedule(); } if (need_resched()) schedule(); }
......
...@@ -155,6 +155,7 @@ static struct bin_attribute eeprom_attr = { ...@@ -155,6 +155,7 @@ static struct bin_attribute eeprom_attr = {
.attr = { .attr = {
.name = "eeprom", .name = "eeprom",
.mode = S_IRUGO, .mode = S_IRUGO,
.owner = THIS_MODULE,
}, },
.size = EEPROM_SIZE, .size = EEPROM_SIZE,
.read = eeprom_read, .read = eeprom_read,
......
...@@ -402,6 +402,7 @@ static struct bin_attribute sysfs_fw_dump_attr = { ...@@ -402,6 +402,7 @@ static struct bin_attribute sysfs_fw_dump_attr = {
.attr = { .attr = {
.name = "fw_dump", .name = "fw_dump",
.mode = S_IRUSR | S_IWUSR, .mode = S_IRUSR | S_IWUSR,
.owner = THIS_MODULE,
}, },
.size = 0, .size = 0,
.read = qla2x00_sysfs_read_fw_dump, .read = qla2x00_sysfs_read_fw_dump,
...@@ -415,6 +416,7 @@ static struct bin_attribute sysfs_nvram_attr = { ...@@ -415,6 +416,7 @@ static struct bin_attribute sysfs_nvram_attr = {
.attr = { .attr = {
.name = "nvram", .name = "nvram",
.mode = S_IRUSR | S_IWUSR, .mode = S_IRUSR | S_IWUSR,
.owner = THIS_MODULE,
}, },
.size = sizeof(nvram_t), .size = sizeof(nvram_t),
.read = qla2x00_sysfs_read_nvram, .read = qla2x00_sysfs_read_nvram,
......
...@@ -573,53 +573,61 @@ static int acm_probe (struct usb_interface *intf, ...@@ -573,53 +573,61 @@ static int acm_probe (struct usb_interface *intf,
struct usb_device *dev; struct usb_device *dev;
struct acm *acm; struct acm *acm;
struct usb_host_config *cfacm; struct usb_host_config *cfacm;
struct usb_interface *data; struct usb_interface *data = NULL;
struct usb_host_interface *ifcom, *ifdata; struct usb_host_interface *ifcom, *ifdata = NULL;
struct usb_endpoint_descriptor *epctrl, *epread, *epwrite; struct usb_endpoint_descriptor *epctrl = NULL;
struct usb_endpoint_descriptor *epread = NULL;
struct usb_endpoint_descriptor *epwrite = NULL;
int readsize, ctrlsize, minor, j; int readsize, ctrlsize, minor, j;
unsigned char *buf; unsigned char *buf;
dev = interface_to_usbdev (intf); dev = interface_to_usbdev (intf);
cfacm = dev->actconfig; cfacm = dev->actconfig;
for (j = 0; j < cfacm->desc.bNumInterfaces - 1; j++) { /* We know we're probe()d with the control interface. */
ifcom = intf->cur_altsetting;
if (usb_interface_claimed(cfacm->interface[j]) ||
usb_interface_claimed(cfacm->interface[j + 1]))
continue;
/* We know we're probe()d with the control interface. /* ACM doesn't guarantee the data interface is
* FIXME ACM doesn't guarantee the data interface is
* adjacent to the control interface, or that if one * adjacent to the control interface, or that if one
* is there it's not for call management ... so use * is there it's not for call management ... so find
* the cdc union descriptor whenever there is one. * it
*/ */
ifcom = intf->cur_altsetting; for (j = 0; j < cfacm->desc.bNumInterfaces; j++) {
if (intf == cfacm->interface[j]) {
ifdata = cfacm->interface[j + 1]->cur_altsetting;
data = cfacm->interface[j + 1];
} else if (intf == cfacm->interface[j + 1]) {
ifdata = cfacm->interface[j]->cur_altsetting; ifdata = cfacm->interface[j]->cur_altsetting;
data = cfacm->interface[j]; data = cfacm->interface[j];
} else
continue;
if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2) if (ifdata->desc.bInterfaceClass == 10 &&
continue; ifdata->desc.bNumEndpoints == 2) {
epctrl = &ifcom->endpoint[0].desc;
epctrl = &ifcom->endpoint[0].desc; epread = &ifdata->endpoint[0].desc;
epread = &ifdata->endpoint[0].desc; epwrite = &ifdata->endpoint[1].desc;
epwrite = &ifdata->endpoint[1].desc;
if ((epctrl->bEndpointAddress & 0x80) != 0x80 ||
(epctrl->bmAttributes & 3) != 3 ||
(epread->bmAttributes & 3) != 2 ||
(epwrite->bmAttributes & 3) != 2 ||
((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80)
goto next_interface;
if ((epread->bEndpointAddress & 0x80) != 0x80) {
epread = &ifdata->endpoint[1].desc;
epwrite = &ifdata->endpoint[0].desc;
}
dbg("found data interface at %d\n", j);
break;
} else {
next_interface:
ifdata = NULL;
data = NULL;
}
}
if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 || /* there's been a problem */
(epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 || if (!ifdata) {
((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80) dbg("interface not found (%p)\n", ifdata);
continue; return -ENODEV;
if ((epread->bEndpointAddress & 0x80) != 0x80) {
epread = &ifdata->endpoint[1].desc;
epwrite = &ifdata->endpoint[0].desc;
} }
for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
...@@ -696,16 +704,21 @@ static int acm_probe (struct usb_interface *intf, ...@@ -696,16 +704,21 @@ static int acm_probe (struct usb_interface *intf,
acm->line.databits = 8; acm->line.databits = 8;
acm_set_line(acm, &acm->line); acm_set_line(acm, &acm->line);
usb_driver_claim_interface(&acm_driver, data, acm); if ( (j = usb_driver_claim_interface(&acm_driver, data, acm)) != 0) {
err("claim failed");
usb_free_urb(acm->ctrlurb);
usb_free_urb(acm->readurb);
usb_free_urb(acm->writeurb);
kfree(acm);
kfree(buf);
return j;
}
tty_register_device(acm_tty_driver, minor, &intf->dev); tty_register_device(acm_tty_driver, minor, &intf->dev);
acm_table[minor] = acm; acm_table[minor] = acm;
usb_set_intfdata (intf, acm); usb_set_intfdata (intf, acm);
return 0; return 0;
}
return -EIO;
} }
static void acm_disconnect(struct usb_interface *intf) static void acm_disconnect(struct usb_interface *intf)
......
...@@ -284,6 +284,11 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state) ...@@ -284,6 +284,11 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state)
dev_dbg (hcd->self.controller, "suspend D%d --> D%d\n", dev_dbg (hcd->self.controller, "suspend D%d --> D%d\n",
dev->current_state, state); dev->current_state, state);
if (pci_find_capability(dev, PCI_CAP_ID_PM)) {
dev_dbg(hcd->self.controller, "No PM capability\n");
return 0;
}
switch (hcd->state) { switch (hcd->state) {
case USB_STATE_HALT: case USB_STATE_HALT:
dev_dbg (hcd->self.controller, "halted; hcd not suspended\n"); dev_dbg (hcd->self.controller, "halted; hcd not suspended\n");
......
...@@ -120,6 +120,7 @@ struct eth_dev { ...@@ -120,6 +120,7 @@ struct eth_dev {
unsigned long todo; unsigned long todo;
#define WORK_RX_MEMORY 0 #define WORK_RX_MEMORY 0
int rndis_config; int rndis_config;
u8 host_mac [ETH_ALEN];
}; };
/* This version autoconfigures as much as possible at run-time. /* This version autoconfigures as much as possible at run-time.
...@@ -159,9 +160,8 @@ static const char *EP_STATUS_NAME; ...@@ -159,9 +160,8 @@ static const char *EP_STATUS_NAME;
/* For hardware that can talk RNDIS and either of the above protocols, /* For hardware that can talk RNDIS and either of the above protocols,
* use this ID ... the windows INF files will know it. Unless it's * use this ID ... the windows INF files will know it. Unless it's
* used with CDC Ethernet, Linux hosts will need updates to choose the * used with CDC Ethernet, Linux 2.4 hosts will need updates to choose
* non-MSFT configuration, either in the kernel (2.4) or else from a * the non-RNDIS configuration.
* hotplug script (2.6).
*/ */
#define RNDIS_VENDOR_NUM 0x0525 /* NetChip */ #define RNDIS_VENDOR_NUM 0x0525 /* NetChip */
#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */ #define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */
...@@ -1334,8 +1334,10 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req) ...@@ -1334,8 +1334,10 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
struct eth_dev *dev = ep->driver_data; struct eth_dev *dev = ep->driver_data;
/* received RNDIS command from CDC_SEND_ENCAPSULATED_COMMAND */ /* received RNDIS command from CDC_SEND_ENCAPSULATED_COMMAND */
spin_lock(&dev->lock);
if (rndis_msg_parser (dev->rndis_config, (u8 *) req->buf)) if (rndis_msg_parser (dev->rndis_config, (u8 *) req->buf))
ERROR(dev, "%s: rndis parse error\n", __FUNCTION__ ); ERROR(dev, "%s: rndis parse error\n", __FUNCTION__ );
spin_unlock(&dev->lock);
} }
#endif /* RNDIS */ #endif /* RNDIS */
...@@ -1486,14 +1488,14 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1486,14 +1488,14 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|| !dev->config || !dev->config
|| ctrl->wIndex > 1) || ctrl->wIndex > 1)
break; break;
if (!dev->cdc && ctrl->wIndex != 0) if (!(dev->cdc || dev->rndis) && ctrl->wIndex != 0)
break; break;
/* if carrier is on, data interface is active. */ /* for CDC, iff carrier is on, data interface is active. */
*(u8 *)req->buf = if (dev->rndis || ctrl->wIndex != 1)
((ctrl->wIndex == 1) && netif_carrier_ok (dev->net)) *(u8 *)req->buf = 0;
? 1 else
: 0, *(u8 *)req->buf = netif_carrier_ok (dev->net) ? 1 : 0;
value = min (ctrl->wLength, (u16) 1); value = min (ctrl->wLength, (u16) 1);
break; break;
...@@ -1552,6 +1554,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1552,6 +1554,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
memcpy (req->buf, buf, value); memcpy (req->buf, buf, value);
req->complete = rndis_response_complete; req->complete = rndis_response_complete;
} }
/* else stalls ... spec says to avoid that */
} }
break; break;
#endif /* RNDIS */ #endif /* RNDIS */
...@@ -1590,6 +1593,8 @@ eth_disconnect (struct usb_gadget *gadget) ...@@ -1590,6 +1593,8 @@ eth_disconnect (struct usb_gadget *gadget)
eth_reset_config (dev); eth_reset_config (dev);
spin_unlock_irqrestore (&dev->lock, flags); spin_unlock_irqrestore (&dev->lock, flags);
/* FIXME RNDIS should enter RNDIS_UNINITIALIZED */
/* next we may get setup() calls to enumerate new connections; /* next we may get setup() calls to enumerate new connections;
* or an unbind() during shutdown (including removing module). * or an unbind() during shutdown (including removing module).
*/ */
...@@ -2376,19 +2381,19 @@ eth_bind (struct usb_gadget *gadget) ...@@ -2376,19 +2381,19 @@ eth_bind (struct usb_gadget *gadget)
*/ */
random_ether_addr(net->dev_addr); random_ether_addr(net->dev_addr);
#ifdef DEV_CONFIG_CDC
/* ... another address for the host, on the other end of the /* ... another address for the host, on the other end of the
* link, gets exported through CDC (see CDC spec table 41) * link, gets exported through CDC (see CDC spec table 41)
* and RNDIS.
*/ */
if (cdc) { if (cdc || rndis) {
u8 node_id [ETH_ALEN]; random_ether_addr(dev->host_mac);
#ifdef DEV_CONFIG_CDC
random_ether_addr(node_id);
snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X",
node_id [0], node_id [1], node_id [2], dev->host_mac [0], dev->host_mac [1],
node_id [3], node_id [4], node_id [5]); dev->host_mac [2], dev->host_mac [3],
} dev->host_mac [4], dev->host_mac [5]);
#endif #endif
}
if (rndis) { if (rndis) {
status = rndis_init(); status = rndis_init();
...@@ -2448,10 +2453,11 @@ eth_bind (struct usb_gadget *gadget) ...@@ -2448,10 +2453,11 @@ eth_bind (struct usb_gadget *gadget)
net->dev_addr [2], net->dev_addr [3], net->dev_addr [2], net->dev_addr [3],
net->dev_addr [4], net->dev_addr [5]); net->dev_addr [4], net->dev_addr [5]);
#ifdef DEV_CONFIG_CDC if (cdc || rndis)
if (cdc) INFO (dev, "HOST MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
INFO (dev, "CDC host enet %s\n", ethaddr); dev->host_mac [0], dev->host_mac [1],
#endif dev->host_mac [2], dev->host_mac [3],
dev->host_mac [4], dev->host_mac [5]);
#ifdef CONFIG_USB_ETH_RNDIS #ifdef CONFIG_USB_ETH_RNDIS
if (rndis) { if (rndis) {
...@@ -2468,6 +2474,7 @@ eth_bind (struct usb_gadget *gadget) ...@@ -2468,6 +2474,7 @@ eth_bind (struct usb_gadget *gadget)
} }
/* these set up a lot of the OIDs that RNDIS needs */ /* these set up a lot of the OIDs that RNDIS needs */
rndis_set_host_mac (dev->rndis_config, dev->host_mac);
if (rndis_set_param_dev (dev->rndis_config, dev->net, if (rndis_set_param_dev (dev->rndis_config, dev->net,
&dev->stats)) &dev->stats))
goto fail0; goto fail0;
......
...@@ -37,6 +37,16 @@ ...@@ -37,6 +37,16 @@
#include "rndis.h" #include "rndis.h"
/* The driver for your USB chip needs to support ep0 OUT to work with
* RNDIS, plus the same three descriptors as CDC Ethernet.
*
* Windows hosts need an INF file like Documentation/usb/linux.inf
*/
#ifndef __LITTLE_ENDIAN
#warning this code is missing all cpu_to_leXX() calls ...
#endif
#if 0 #if 0
#define DEBUG if (rndis_debug) printk #define DEBUG if (rndis_debug) printk
static int rndis_debug = 0; static int rndis_debug = 0;
...@@ -89,8 +99,12 @@ static u32 devFlags2currentFilter (struct net_device *dev) ...@@ -89,8 +99,12 @@ static u32 devFlags2currentFilter (struct net_device *dev)
static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev) static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev)
{ {
/* FIXME the filter is supposed to control what gets
* forwarded from gadget to host; but dev->flags controls
* reporting from host to gadget ...
*/
#if 0
if (!dev) return; if (!dev) return;
if (currentFilter & NDIS_PACKET_TYPE_MULTICAST) if (currentFilter & NDIS_PACKET_TYPE_MULTICAST)
dev->flags |= IFF_MULTICAST; dev->flags |= IFF_MULTICAST;
if (currentFilter & NDIS_PACKET_TYPE_BROADCAST) if (currentFilter & NDIS_PACKET_TYPE_BROADCAST)
...@@ -99,8 +113,13 @@ static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev) ...@@ -99,8 +113,13 @@ static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev)
dev->flags |= IFF_ALLMULTI; dev->flags |= IFF_ALLMULTI;
if (currentFilter & NDIS_PACKET_TYPE_PROMISCUOUS) if (currentFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
dev->flags |= IFF_PROMISC; dev->flags |= IFF_PROMISC;
#endif
} }
/* FIXME OMITTED OIDs, that RNDIS-on-USB "must" support, include
* - power management (OID_PNP_CAPABILITIES, ...)
* - network wakeup (OID_PNP_ENABLE_WAKE_UP, ...)
*/
/* NDIS Functions */ /* NDIS Functions */
static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
...@@ -114,8 +133,6 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) ...@@ -114,8 +133,6 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
if (!resp) return -ENOMEM; if (!resp) return -ENOMEM;
if (!resp) return -ENOMEM;
switch (OID) { switch (OID) {
/* mandatory */ /* mandatory */
case OID_GEN_SUPPORTED_LIST: case OID_GEN_SUPPORTED_LIST:
...@@ -178,7 +195,8 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) ...@@ -178,7 +195,8 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
case OID_GEN_LINK_SPEED: case OID_GEN_LINK_SPEED:
DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__); DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
length = 4; length = 4;
if (rndis_per_dev_params [configNr].media_state) if (rndis_per_dev_params [configNr].media_state
== NDIS_MEDIA_STATE_DISCONNECTED)
*((u32 *) resp + 6) = 0; *((u32 *) resp + 6) = 0;
else else
*((u32 *) resp + 6) = rndis_per_dev_params [configNr].speed; *((u32 *) resp + 6) = rndis_per_dev_params [configNr].speed;
...@@ -611,15 +629,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) ...@@ -611,15 +629,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
case OID_802_3_PERMANENT_ADDRESS: case OID_802_3_PERMANENT_ADDRESS:
DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__); DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].dev) { if (rndis_per_dev_params [configNr].dev) {
length = 6; length = ETH_ALEN;
memcpy ((u8 *) resp + 24, memcpy ((u8 *) resp + 24,
rndis_per_dev_params [configNr].dev->dev_addr, rndis_per_dev_params [configNr].host_mac,
length); length);
/*
* we need a MAC address and hope that
* (our MAC + 1) is not in use
*/
*((u8 *) resp + 29) += 1;
retval = 0; retval = 0;
} else { } else {
*((u32 *) resp + 6) = 0; *((u32 *) resp + 6) = 0;
...@@ -631,15 +644,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) ...@@ -631,15 +644,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
case OID_802_3_CURRENT_ADDRESS: case OID_802_3_CURRENT_ADDRESS:
DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__); DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].dev) { if (rndis_per_dev_params [configNr].dev) {
length = 6; length = ETH_ALEN;
memcpy ((u8 *) resp + 24, memcpy ((u8 *) resp + 24,
rndis_per_dev_params [configNr].dev->dev_addr, rndis_per_dev_params [configNr].host_mac,
length); length);
/*
* we need a MAC address and hope that
* (our MAC + 1) is not in use
*/
*((u8 *) resp + 29) += 1;
retval = 0; retval = 0;
} }
break; break;
...@@ -746,22 +754,38 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, ...@@ -746,22 +754,38 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
rndis_set_cmplt_type *resp; rndis_set_cmplt_type *resp;
int i, retval = -ENOTSUPP; int i, retval = -ENOTSUPP;
struct rndis_config_parameter *param; struct rndis_config_parameter *param;
struct rndis_params *params;
if (!r) return -ENOMEM; u8 *cp;
if (!r)
return -ENOMEM;
resp = (rndis_set_cmplt_type *) r->buf; resp = (rndis_set_cmplt_type *) r->buf;
if (!resp)
if (!resp) return -ENOMEM; return -ENOMEM;
cp = (u8 *)resp;
switch (OID) { switch (OID) {
case OID_GEN_CURRENT_PACKET_FILTER: case OID_GEN_CURRENT_PACKET_FILTER:
DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__); DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
currentFilter2devFlags ((u32) ((u8 *) resp + 28), params = &rndis_per_dev_params [configNr];
rndis_per_dev_params [configNr].dev); currentFilter2devFlags(cp[28], params->dev);
retval = 0; retval = 0;
if ((u32) ((u8 *) resp + 28))
rndis_per_dev_params [configNr].state = RNDIS_INITIALIZED; /* this call has a significant side effect: it's
else * what makes the packet flow start and stop, like
rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED; * activating the CDC Ethernet altsetting.
*/
if (cp[28]) {
params->state = RNDIS_DATA_INITIALIZED;
netif_carrier_on(params->dev);
if (netif_running(params->dev))
netif_wake_queue (params->dev);
} else {
params->state = RNDIS_INITIALIZED;
netif_carrier_off (params->dev);
netif_stop_queue (params->dev);
}
break; break;
case OID_802_3_MULTICAST_LIST: case OID_802_3_MULTICAST_LIST:
...@@ -937,10 +961,9 @@ static int rndis_keepalive_response (int configNr, ...@@ -937,10 +961,9 @@ static int rndis_keepalive_response (int configNr,
{ {
rndis_keepalive_cmplt_type *resp; rndis_keepalive_cmplt_type *resp;
rndis_resp_t *r; rndis_resp_t *r;
/* respond only in RNDIS_INITIALIZED state */ /* host "should" check only in RNDIS_DATA_INITIALIZED state */
if (rndis_per_dev_params [configNr].state != RNDIS_INITIALIZED)
return 0;
r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type)); r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type));
resp = (rndis_keepalive_cmplt_type *) r->buf; resp = (rndis_keepalive_cmplt_type *) r->buf;
if (!resp) return -ENOMEM; if (!resp) return -ENOMEM;
...@@ -1004,35 +1027,48 @@ int rndis_signal_disconnect (int configNr) ...@@ -1004,35 +1027,48 @@ int rndis_signal_disconnect (int configNr)
RNDIS_STATUS_MEDIA_DISCONNECT); RNDIS_STATUS_MEDIA_DISCONNECT);
} }
void rndis_set_host_mac (int configNr, const u8 *addr)
{
rndis_per_dev_params [configNr].host_mac = addr;
}
/* /*
* Message Parser * Message Parser
*/ */
int rndis_msg_parser (u8 configNr, u8 *buf) int rndis_msg_parser (u8 configNr, u8 *buf)
{ {
u32 MsgType, MsgLength, *tmp; u32 MsgType, MsgLength, *tmp;
struct rndis_params *params;
if (!buf) return -ENOMEM; if (!buf)
return -ENOMEM;
tmp = (u32 *) buf; tmp = (u32 *) buf;
MsgType = *tmp; MsgType = *tmp;
MsgLength = *(tmp + 1); MsgLength = *(tmp + 1);
if (configNr >= RNDIS_MAX_CONFIGS) return -ENOTSUPP; if (configNr >= RNDIS_MAX_CONFIGS)
return -ENOTSUPP;
params = &rndis_per_dev_params [configNr];
/* For USB: responses may take up to 10 seconds */
switch (MsgType) switch (MsgType)
{ {
case REMOTE_NDIS_INIZIALIZE_MSG: case REMOTE_NDIS_INITIALIZE_MSG:
DEBUG(KERN_INFO "%s: REMOTE_NDIS_INIZIALIZE_MSG\n", DEBUG(KERN_INFO "%s: REMOTE_NDIS_INITIALIZE_MSG\n",
__FUNCTION__ ); __FUNCTION__ );
rndis_per_dev_params [configNr].state = RNDIS_INITIALIZED; params->state = RNDIS_INITIALIZED;
return rndis_init_response (configNr, return rndis_init_response (configNr,
(rndis_init_msg_type *) buf); (rndis_init_msg_type *) buf);
break;
case REMOTE_NDIS_HALT_MSG: case REMOTE_NDIS_HALT_MSG:
DEBUG(KERN_INFO "%s: REMOTE_NDIS_HALT_MSG\n", DEBUG(KERN_INFO "%s: REMOTE_NDIS_HALT_MSG\n",
__FUNCTION__ ); __FUNCTION__ );
rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED; params->state = RNDIS_UNINITIALIZED;
if (params->dev) {
netif_carrier_off (params->dev);
netif_stop_queue (params->dev);
}
return 0; return 0;
case REMOTE_NDIS_QUERY_MSG: case REMOTE_NDIS_QUERY_MSG:
...@@ -1040,29 +1076,26 @@ int rndis_msg_parser (u8 configNr, u8 *buf) ...@@ -1040,29 +1076,26 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
__FUNCTION__ ); __FUNCTION__ );
return rndis_query_response (configNr, return rndis_query_response (configNr,
(rndis_query_msg_type *) buf); (rndis_query_msg_type *) buf);
break;
case REMOTE_NDIS_SET_MSG: case REMOTE_NDIS_SET_MSG:
DEBUG(KERN_INFO "%s: REMOTE_NDIS_SET_MSG\n", DEBUG(KERN_INFO "%s: REMOTE_NDIS_SET_MSG\n",
__FUNCTION__ ); __FUNCTION__ );
return rndis_set_response (configNr, return rndis_set_response (configNr,
(rndis_set_msg_type *) buf); (rndis_set_msg_type *) buf);
break;
case REMOTE_NDIS_RESET_MSG: case REMOTE_NDIS_RESET_MSG:
DEBUG(KERN_INFO "%s: REMOTE_NDIS_RESET_MSG\n", DEBUG(KERN_INFO "%s: REMOTE_NDIS_RESET_MSG\n",
__FUNCTION__ ); __FUNCTION__ );
return rndis_reset_response (configNr, return rndis_reset_response (configNr,
(rndis_reset_msg_type *) buf); (rndis_reset_msg_type *) buf);
break;
case REMOTE_NDIS_KEEPALIVE_MSG: case REMOTE_NDIS_KEEPALIVE_MSG:
/* For USB: host does this every 5 seconds */
DEBUG(KERN_INFO "%s: REMOTE_NDIS_KEEPALIVE_MSG\n", DEBUG(KERN_INFO "%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
__FUNCTION__ ); __FUNCTION__ );
return rndis_keepalive_response (configNr, return rndis_keepalive_response (configNr,
(rndis_keepalive_msg_type *) (rndis_keepalive_msg_type *)
buf); buf);
break;
default: default:
printk (KERN_ERR "%s: unknown RNDIS Message Type 0x%08X\n", printk (KERN_ERR "%s: unknown RNDIS Message Type 0x%08X\n",
...@@ -1240,9 +1273,15 @@ int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof, ...@@ -1240,9 +1273,15 @@ int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
"vendor ID : 0x%08X\n" "vendor ID : 0x%08X\n"
"vendor : %s\n", "vendor : %s\n",
param->confignr, (param->used) ? "y" : "n", param->confignr, (param->used) ? "y" : "n",
(param->state) ({ char *s = "?";
? "RNDIS_INITIALIZED" switch (param->state) {
: "RNDIS_UNINITIALIZED", case RNDIS_UNINITIALIZED:
s = "RNDIS_UNINITIALIZED"; break;
case RNDIS_INITIALIZED:
s = "RNDIS_INITIALIZED"; break;
case RNDIS_DATA_INITIALIZED:
s = "RNDIS_DATA_INITIALIZED"; break;
}; s; }),
param->medium, param->medium,
(param->media_state) ? 0 : param->speed*100, (param->media_state) ? 0 : param->speed*100,
(param->media_state) ? "disconnected" : "connected", (param->media_state) ? "disconnected" : "connected",
...@@ -1353,7 +1392,7 @@ int __init rndis_init (void) ...@@ -1353,7 +1392,7 @@ int __init rndis_init (void)
return 0; return 0;
} }
void __exit rndis_exit (void) void rndis_exit (void)
{ {
u8 i; u8 i;
char name [4]; char name [4];
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
*/ */
/* Message Set for Connectionless (802.3) Devices */ /* Message Set for Connectionless (802.3) Devices */
#define REMOTE_NDIS_INIZIALIZE_MSG 0x00000002U /* Initialize device */ #define REMOTE_NDIS_INITIALIZE_MSG 0x00000002U /* Initialize device */
#define REMOTE_NDIS_HALT_MSG 0x00000003U #define REMOTE_NDIS_HALT_MSG 0x00000003U
#define REMOTE_NDIS_QUERY_MSG 0x00000004U #define REMOTE_NDIS_QUERY_MSG 0x00000004U
#define REMOTE_NDIS_SET_MSG 0x00000005U #define REMOTE_NDIS_SET_MSG 0x00000005U
...@@ -280,6 +280,7 @@ typedef struct rndis_params ...@@ -280,6 +280,7 @@ typedef struct rndis_params
u32 medium; u32 medium;
u32 speed; u32 speed;
u32 media_state; u32 media_state;
const u8 *host_mac;
struct net_device *dev; struct net_device *dev;
struct net_device_stats *stats; struct net_device_stats *stats;
u32 vendorID; u32 vendorID;
...@@ -301,11 +302,13 @@ void rndis_add_hdr (struct sk_buff *skb); ...@@ -301,11 +302,13 @@ void rndis_add_hdr (struct sk_buff *skb);
int rndis_rm_hdr (u8 *buf, u32 *length); int rndis_rm_hdr (u8 *buf, u32 *length);
u8 *rndis_get_next_response (int configNr, u32 *length); u8 *rndis_get_next_response (int configNr, u32 *length);
void rndis_free_response (int configNr, u8 *buf); void rndis_free_response (int configNr, u8 *buf);
int rndis_signal_connect (int configNr); int rndis_signal_connect (int configNr);
int rndis_signal_disconnect (int configNr); int rndis_signal_disconnect (int configNr);
int rndis_state (int configNr); int rndis_state (int configNr);
extern void rndis_set_host_mac (int configNr, const u8 *addr);
int __init rndis_init (void); int __init rndis_init (void);
void __exit rndis_exit (void); void rndis_exit (void);
#endif /* _LINUX_RNDIS_H */ #endif /* _LINUX_RNDIS_H */
...@@ -330,6 +330,7 @@ static int ehci_hc_reset (struct usb_hcd *hcd) ...@@ -330,6 +330,7 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
{ {
struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_hcd *ehci = hcd_to_ehci (hcd);
u32 temp; u32 temp;
unsigned count = 256/4;
spin_lock_init (&ehci->lock); spin_lock_init (&ehci->lock);
...@@ -345,16 +346,21 @@ static int ehci_hc_reset (struct usb_hcd *hcd) ...@@ -345,16 +346,21 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
else else
temp = 0; temp = 0;
while (temp) { while (temp && count--) {
u32 cap; u32 cap;
pci_read_config_dword (to_pci_dev(ehci->hcd.self.controller), temp, &cap); pci_read_config_dword (to_pci_dev(ehci->hcd.self.controller),
temp, &cap);
ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp); ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp);
switch (cap & 0xff) { switch (cap & 0xff) {
case 1: /* BIOS/SMM/... handoff */ case 1: /* BIOS/SMM/... handoff */
if (bios_handoff (ehci, temp, cap) != 0) if (bios_handoff (ehci, temp, cap) != 0)
return -EOPNOTSUPP; return -EOPNOTSUPP;
break; break;
case 0x0a: /* appendix C */
ehci_dbg (ehci, "debug registers, BAR %d offset %d\n",
(cap >> 29) & 0x07, (cap >> 16) & 0x0fff);
break;
case 0: /* illegal reserved capability */ case 0: /* illegal reserved capability */
ehci_warn (ehci, "illegal capability!\n"); ehci_warn (ehci, "illegal capability!\n");
cap = 0; cap = 0;
...@@ -364,6 +370,10 @@ static int ehci_hc_reset (struct usb_hcd *hcd) ...@@ -364,6 +370,10 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
} }
temp = (cap >> 8) & 0xff; temp = (cap >> 8) & 0xff;
} }
if (!count) {
ehci_err (ehci, "bogus capabilities ... PCI problems!\n");
return -EIO;
}
#endif #endif
/* cache this readonly data; minimize PCI reads */ /* cache this readonly data; minimize PCI reads */
...@@ -577,7 +587,8 @@ static void ehci_stop (struct usb_hcd *hcd) ...@@ -577,7 +587,8 @@ static void ehci_stop (struct usb_hcd *hcd)
/* root hub is shut down separately (first, when possible) */ /* root hub is shut down separately (first, when possible) */
spin_lock_irq (&ehci->lock); spin_lock_irq (&ehci->lock);
ehci_work (ehci, NULL); if (ehci->async)
ehci_work (ehci, NULL);
spin_unlock_irq (&ehci->lock); spin_unlock_irq (&ehci->lock);
ehci_mem_cleanup (ehci); ehci_mem_cleanup (ehci);
......
...@@ -252,14 +252,18 @@ static int ehci_hub_control ( ...@@ -252,14 +252,18 @@ static int ehci_hub_control (
/* force reset to complete */ /* force reset to complete */
writel (temp & ~PORT_RESET, writel (temp & ~PORT_RESET,
&ehci->regs->port_status [wIndex]); &ehci->regs->port_status [wIndex]);
do { retval = handshake (
temp = readl ( &ehci->regs->port_status [wIndex],
&ehci->regs->port_status [wIndex]); PORT_RESET, 0, 500);
udelay (10); if (retval != 0) {
} while (temp & PORT_RESET); ehci_err (ehci, "port %d reset error %d\n",
wIndex + 1, retval);
goto error;
}
/* see what we found out */ /* see what we found out */
temp = check_reset_complete (ehci, wIndex, temp); temp = check_reset_complete (ehci, wIndex,
readl (&ehci->regs->port_status [wIndex]));
} }
// don't show wPortStatus if it's owned by a companion hc // don't show wPortStatus if it's owned by a companion hc
......
...@@ -382,6 +382,7 @@ static void uhci_insert_qh(struct uhci_hcd *uhci, struct uhci_qh *skelqh, struct ...@@ -382,6 +382,7 @@ static void uhci_insert_qh(struct uhci_hcd *uhci, struct uhci_qh *skelqh, struct
static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
{ {
struct uhci_qh *pqh; struct uhci_qh *pqh;
__u32 newlink;
if (!qh) if (!qh)
return; return;
...@@ -390,8 +391,24 @@ static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) ...@@ -390,8 +391,24 @@ static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
* Only go through the hoops if it's actually linked in * Only go through the hoops if it's actually linked in
*/ */
if (!list_empty(&qh->list)) { if (!list_empty(&qh->list)) {
pqh = list_entry(qh->list.prev, struct uhci_qh, list);
/* If our queue is nonempty, make the next URB the head */
if (!list_empty(&qh->urbp->queue_list)) {
struct urb_priv *nurbp;
nurbp = list_entry(qh->urbp->queue_list.next,
struct urb_priv, queue_list);
nurbp->queued = 0;
list_add(&nurbp->qh->list, &qh->list);
newlink = cpu_to_le32(nurbp->qh->dma_handle) | UHCI_PTR_QH;
} else
newlink = qh->link;
/* Fix up the previous QH's queue to link to either
* the new head of this queue or the start of the
* next endpoint's queue. */
pqh = list_entry(qh->list.prev, struct uhci_qh, list);
pqh->link = newlink;
if (pqh->urbp) { if (pqh->urbp) {
struct list_head *head, *tmp; struct list_head *head, *tmp;
...@@ -403,28 +420,19 @@ static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) ...@@ -403,28 +420,19 @@ static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
tmp = tmp->next; tmp = tmp->next;
turbp->qh->link = qh->link; turbp->qh->link = newlink;
} }
} }
pqh->link = qh->link;
mb(); mb();
/* Leave qh->link in case the HC is on the QH now, it will */ /* Leave qh->link in case the HC is on the QH now, it will */
/* continue the rest of the schedule */ /* continue the rest of the schedule */
qh->element = UHCI_PTR_TERM; qh->element = UHCI_PTR_TERM;
/* If our queue is nonempty, make the next URB the head */
if (!list_empty(&qh->urbp->queue_list)) {
struct urb_priv *nurbp;
nurbp = list_entry(qh->urbp->queue_list.next,
struct urb_priv, queue_list);
nurbp->queued = 0;
list_add_tail(&nurbp->qh->list, &qh->list);
}
list_del_init(&qh->list); list_del_init(&qh->list);
} }
list_del_init(&qh->urbp->queue_list);
qh->urbp = NULL; qh->urbp = NULL;
/* Check to see if the remove list is empty. Set the IOC bit */ /* Check to see if the remove list is empty. Set the IOC bit */
...@@ -579,7 +587,7 @@ static void uhci_delete_queued_urb(struct uhci_hcd *uhci, struct urb *urb) ...@@ -579,7 +587,7 @@ static void uhci_delete_queued_urb(struct uhci_hcd *uhci, struct urb *urb)
pltd->link = UHCI_PTR_TERM; pltd->link = UHCI_PTR_TERM;
} }
list_del_init(&urbp->queue_list); /* urbp->queue_list is handled in uhci_remove_qh() */
} }
static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *urb) static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* tiglusb -- Texas Instruments' USB GraphLink (aka SilverLink) driver. * tiglusb -- Texas Instruments' USB GraphLink (aka SilverLink) driver.
* Target: Texas Instruments graphing calculators (http://lpg.ticalc.org). * Target: Texas Instruments graphing calculators (http://lpg.ticalc.org).
* *
* Copyright (C) 2001-2002: * Copyright (C) 2001-2004:
* Romain Lievin <roms@lpg.ticalc.org> * Romain Lievin <roms@lpg.ticalc.org>
* Julien BLACHE <jb@technologeek.org> * Julien BLACHE <jb@technologeek.org>
* under the terms of the GNU General Public License. * under the terms of the GNU General Public License.
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
* 1.04, Julien: clean-up & fixes; Romain: 2.4 backport. * 1.04, Julien: clean-up & fixes; Romain: 2.4 backport.
* 1.05, Randy Dunlap: bug fix with the timeout parameter (divide-by-zero). * 1.05, Randy Dunlap: bug fix with the timeout parameter (divide-by-zero).
* 1.06, Romain: synched with 2.5, version/firmware changed (confusing). * 1.06, Romain: synched with 2.5, version/firmware changed (confusing).
* 1.07, Romain: fixed bad use of usb_clear_halt (invalid argument);
* timeout argument checked in ioctl + clean-up.
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -38,8 +40,8 @@ ...@@ -38,8 +40,8 @@
/* /*
* Version Information * Version Information
*/ */
#define DRIVER_VERSION "1.06" #define DRIVER_VERSION "1.07"
#define DRIVER_AUTHOR "Romain Lievin <roms@lpg.ticalc.org> & Julien Blache <jb@jblache.org>" #define DRIVER_AUTHOR "Romain Lievin <roms@tilp.info> & Julien Blache <jb@jblache.org>"
#define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver" #define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver"
#define DRIVER_LICENSE "GPL" #define DRIVER_LICENSE "GPL"
...@@ -72,15 +74,15 @@ clear_pipes (struct usb_device *dev) ...@@ -72,15 +74,15 @@ clear_pipes (struct usb_device *dev)
{ {
unsigned int pipe; unsigned int pipe;
pipe = usb_sndbulkpipe (dev, 1); pipe = usb_sndbulkpipe (dev, 2);
if (usb_clear_halt (dev, usb_pipeendpoint (pipe))) { if (usb_clear_halt (dev, pipe)) {
err ("clear_pipe (r), request failed"); err ("clear_pipe (w), request failed");
return -1; return -1;
} }
pipe = usb_sndbulkpipe (dev, 2); pipe = usb_rcvbulkpipe (dev, 1);
if (usb_clear_halt (dev, usb_pipeendpoint (pipe))) { if (usb_clear_halt (dev, pipe)) {
err ("clear_pipe (w), request failed"); err ("clear_pipe (r), request failed");
return -1; return -1;
} }
...@@ -181,17 +183,16 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos) ...@@ -181,17 +183,16 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
pipe = usb_rcvbulkpipe (s->dev, 1); pipe = usb_rcvbulkpipe (s->dev, 1);
result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_read, result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_read,
&bytes_read, HZ * 10 / timeout); &bytes_read, (HZ * timeout) / 10);
if (result == -ETIMEDOUT) { /* NAK */ if (result == -ETIMEDOUT) { /* NAK */
ret = result; if (!bytes_read)
if (!bytes_read) {
dbg ("quirk !"); dbg ("quirk !");
}
warn ("tiglusb_read, NAK received."); warn ("tiglusb_read, NAK received.");
ret = result;
goto out; goto out;
} else if (result == -EPIPE) { /* STALL -- shouldn't happen */ } else if (result == -EPIPE) { /* STALL -- shouldn't happen */
warn ("clear_halt request to remove STALL condition."); warn ("clear_halt request to remove STALL condition.");
if (usb_clear_halt (s->dev, usb_pipeendpoint (pipe))) if (usb_clear_halt (s->dev, pipe))
err ("clear_halt, request failed"); err ("clear_halt, request failed");
clear_device (s->dev); clear_device (s->dev);
ret = result; ret = result;
...@@ -243,7 +244,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t * ...@@ -243,7 +244,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
pipe = usb_sndbulkpipe (s->dev, 2); pipe = usb_sndbulkpipe (s->dev, 2);
result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_write, result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_write,
&bytes_written, HZ * 10 / timeout); &bytes_written, (HZ * timeout) / 10);
if (result == -ETIMEDOUT) { /* NAK */ if (result == -ETIMEDOUT) { /* NAK */
warn ("tiglusb_write, NAK received."); warn ("tiglusb_write, NAK received.");
...@@ -251,7 +252,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t * ...@@ -251,7 +252,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
goto out; goto out;
} else if (result == -EPIPE) { /* STALL -- shouldn't happen */ } else if (result == -EPIPE) { /* STALL -- shouldn't happen */
warn ("clear_halt request to remove STALL condition."); warn ("clear_halt request to remove STALL condition.");
if (usb_clear_halt (s->dev, usb_pipeendpoint (pipe))) if (usb_clear_halt (s->dev, pipe))
err ("clear_halt, request failed"); err ("clear_halt, request failed");
clear_device (s->dev); clear_device (s->dev);
ret = result; ret = result;
...@@ -292,15 +293,16 @@ tiglusb_ioctl (struct inode *inode, struct file *filp, ...@@ -292,15 +293,16 @@ tiglusb_ioctl (struct inode *inode, struct file *filp,
switch (cmd) { switch (cmd) {
case IOCTL_TIUSB_TIMEOUT: case IOCTL_TIUSB_TIMEOUT:
timeout = arg; // timeout value in tenth of seconds if (arg > 0)
timeout = arg;
else
ret = -EINVAL;
break; break;
case IOCTL_TIUSB_RESET_DEVICE: case IOCTL_TIUSB_RESET_DEVICE:
dbg ("IOCTL_TIGLUSB_RESET_DEVICE");
if (clear_device (s->dev)) if (clear_device (s->dev))
ret = -EIO; ret = -EIO;
break; break;
case IOCTL_TIUSB_RESET_PIPES: case IOCTL_TIUSB_RESET_PIPES:
dbg ("IOCTL_TIGLUSB_RESET_PIPES");
if (clear_pipes (s->dev)) if (clear_pipes (s->dev))
ret = -EIO; ret = -EIO;
break; break;
...@@ -447,7 +449,7 @@ static struct usb_driver tiglusb_driver = { ...@@ -447,7 +449,7 @@ static struct usb_driver tiglusb_driver = {
#ifndef MODULE #ifndef MODULE
/* /*
* You can use 'tiusb=timeout' * You can use 'tiusb=timeout' to set timeout.
*/ */
static int __init static int __init
tiglusb_setup (char *str) tiglusb_setup (char *str)
...@@ -457,10 +459,11 @@ tiglusb_setup (char *str) ...@@ -457,10 +459,11 @@ tiglusb_setup (char *str)
str = get_options (str, ARRAY_SIZE (ints), ints); str = get_options (str, ARRAY_SIZE (ints), ints);
if (ints[0] > 0) { if (ints[0] > 0) {
timeout = ints[1]; if (ints[1] > 0)
timeout = ints[1];
else
info ("tiglusb: wrong timeout value (0), using default value.");
} }
if (timeout <= 0)
timeout = TIMAXTIME;
return 1; return 1;
} }
...@@ -502,9 +505,6 @@ tiglusb_init (void) ...@@ -502,9 +505,6 @@ tiglusb_init (void)
info (DRIVER_DESC ", version " DRIVER_VERSION); info (DRIVER_DESC ", version " DRIVER_VERSION);
if (timeout <= 0)
timeout = TIMAXTIME;
return 0; return 0;
} }
......
...@@ -2107,8 +2107,12 @@ pl_set_QuickLink_features (struct usbnet *dev, int val) ...@@ -2107,8 +2107,12 @@ pl_set_QuickLink_features (struct usbnet *dev, int val)
static int pl_reset (struct usbnet *dev) static int pl_reset (struct usbnet *dev)
{ {
return pl_set_QuickLink_features (dev, /* some units seem to need this reset, others reject it utterly.
* FIXME be more like "naplink" or windows drivers.
*/
(void) pl_set_QuickLink_features (dev,
PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E); PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
return 0;
} }
static const struct driver_info prolific_info = { static const struct driver_info prolific_info = {
......
...@@ -463,8 +463,6 @@ static struct usb_device_id id_table_FT232BM [] = { ...@@ -463,8 +463,6 @@ static struct usb_device_id id_table_FT232BM [] = {
{ USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_2_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_2_PID, 0x400, 0xffff) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
...@@ -566,6 +564,8 @@ static struct usb_device_id id_table_combined [] = { ...@@ -566,6 +564,8 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_1_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_1_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_2_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_2_PID, 0x400, 0xffff) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
{ USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -56,7 +56,8 @@ int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -56,7 +56,8 @@ int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us)
/* /*
* LUN 0 corresponds to the CompactFlash card reader. * LUN 0 corresponds to the CompactFlash card reader.
*/ */
return usb_stor_CB_transport(srb, us); ret = usb_stor_CB_transport(srb, us);
break;
#ifdef CONFIG_USB_STORAGE_SDDR09 #ifdef CONFIG_USB_STORAGE_SDDR09
case 1: case 1:
...@@ -71,12 +72,14 @@ int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -71,12 +72,14 @@ int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us)
srb->device->lun = 0; us->srb->device->lun = 0; srb->device->lun = 0; us->srb->device->lun = 0;
ret = sddr09_transport(srb, us); ret = sddr09_transport(srb, us);
srb->device->lun = 1; us->srb->device->lun = 1; srb->device->lun = 1; us->srb->device->lun = 1;
break;
return ret;
#endif #endif
default: default:
US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun); US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun);
return USB_STOR_TRANSPORT_ERROR; ret = USB_STOR_TRANSPORT_ERROR;
break;
} }
return ret;
} }
...@@ -101,19 +101,27 @@ static int open(struct inode * inode, struct file * file) ...@@ -101,19 +101,27 @@ static int open(struct inode * inode, struct file * file)
if (!kobj || !attr) if (!kobj || !attr)
goto Done; goto Done;
/* Grab the module reference for this attribute if we have one */
error = -ENODEV;
if (!try_module_get(attr->attr.owner))
goto Done;
error = -EACCES; error = -EACCES;
if ((file->f_mode & FMODE_WRITE) && !attr->write) if ((file->f_mode & FMODE_WRITE) && !attr->write)
goto Done; goto Error;
if ((file->f_mode & FMODE_READ) && !attr->read) if ((file->f_mode & FMODE_READ) && !attr->read)
goto Done; goto Error;
error = -ENOMEM; error = -ENOMEM;
file->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL); file->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!file->private_data) if (!file->private_data)
goto Done; goto Error;
error = 0; error = 0;
goto Done;
Error:
module_put(attr->attr.owner);
Done: Done:
if (error && kobj) if (error && kobj)
kobject_put(kobj); kobject_put(kobj);
...@@ -123,10 +131,12 @@ static int open(struct inode * inode, struct file * file) ...@@ -123,10 +131,12 @@ static int open(struct inode * inode, struct file * file)
static int release(struct inode * inode, struct file * file) static int release(struct inode * inode, struct file * file)
{ {
struct kobject * kobj = file->f_dentry->d_parent->d_fsdata; struct kobject * kobj = file->f_dentry->d_parent->d_fsdata;
struct bin_attribute * attr = file->f_dentry->d_fsdata;
u8 * buffer = file->private_data; u8 * buffer = file->private_data;
if (kobj) if (kobj)
kobject_put(kobj); kobject_put(kobj);
module_put(attr->attr.owner);
kfree(buffer); kfree(buffer);
return 0; return 0;
} }
......
...@@ -42,7 +42,7 @@ static int object_path_length(struct kobject * kobj) ...@@ -42,7 +42,7 @@ static int object_path_length(struct kobject * kobj)
struct kobject * p = kobj; struct kobject * p = kobj;
int length = 1; int length = 1;
do { do {
length += strlen(p->name) + 1; length += strlen(kobject_name(p)) + 1;
p = p->parent; p = p->parent;
} while (p); } while (p);
return length; return length;
...@@ -54,11 +54,11 @@ static void fill_object_path(struct kobject * kobj, char * buffer, int length) ...@@ -54,11 +54,11 @@ static void fill_object_path(struct kobject * kobj, char * buffer, int length)
--length; --length;
for (p = kobj; p; p = p->parent) { for (p = kobj; p; p = p->parent) {
int cur = strlen(p->name); int cur = strlen(kobject_name(p));
/* back up enough to print this bus id with '/' */ /* back up enough to print this bus id with '/' */
length -= cur; length -= cur;
strncpy(buffer + length,p->name,cur); strncpy(buffer + length,kobject_name(p),cur);
*(buffer + --length) = '/'; *(buffer + --length) = '/';
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment