Commit 5d9c2d03 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleed-2.6

into kroah.com:/home/greg/linux/BK/usb-2.6
parents c9e6b4d9 d7624365
......@@ -211,6 +211,62 @@ ZyXEL omni.net lcd plus ISDN TA
azummo@towertech.it
Cypress M8 CY4601 Family Serial Driver
This driver was in most part developed by Neil "koyama" Whelchel. It
has been improved since that previous form to support dynamic serial
line settings and improved line handling. The driver is for the most
part stable and has been tested on an smp machine. (dual p2)
Chipsets supported under CY4601 family:
CY7C63723, CY7C63742, CY7C63743, CY7C64013
Devices supported:
-DeLorme's USB Earthmate (SiRF Star II lp arch)
-Cypress HID->COM RS232 adapter
Note: Cypress Semiconductor claims no affiliation with the
the hid->com device.
Most devices using chipsets under the CY4601 family should
work with the driver. As long as they stay true to the CY4601
usbserial specification.
Technical notes:
The Earthmate starts out at 4800 8N1 by default... the driver will
upon start init to this setting. usbserial core provides the rest
of the termios settings, along with some custom termios so that the
output is in proper format and parsable.
The device can be put into sirf mode by issuing NMEA command:
$PSRF100,<protocol>,<baud>,<databits>,<stopbits>,<parity>*CHECKSUM
$PSRF100,0,9600,8,1,0*0C
It should then be sufficient to change the port termios to match this
to begin communicating.
As far as I can tell it supports pretty much every sirf command as
documented online available with firmware 2.31, with some unknown
message ids.
The hid->com adapter can run at a maximum baud of 115200bps. Please note
that the device has trouble or is incapable of raising line voltage properly.
It will be fine with null modem links, as long as you do not try to link two
together without hacking the adapter to set the line high.
The driver is smp safe. Performance with the driver is rather low when using
it for transfering files. This is being worked on, but I would be willing to
accept patches. An urb queue or packet buffer would likely fit the bill here.
If you have any questions, problems, patches, feature requests, etc. you can
contact me here via email:
dignome@gmail.com
(your problems/patches can alternately be submitted to usb-devel)
Digi AccelePort Driver
This driver supports the Digi AccelePort USB 2 and 4 devices, 2 port
......
......@@ -2336,6 +2336,15 @@ L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB SERIAL CYPRESS M8 DRIVER
P: Lonnie Mendez
M: dignome@gmail.com
L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
W: http://geocities.com/i0xox0i
W: http://firstlight.net/cvs
USB SERIAL CYBERJACK PINPAD/E-COM DRIVER
L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
......
......@@ -308,6 +308,8 @@ config BLK_DEV_UB
This driver supports certain USB attached storage devices
such as flash keys.
Warning: Enabling this cripples the usb-storage driver.
If unsure, say N.
config BLK_DEV_RAM
......
......@@ -8,13 +8,11 @@
* and is not licensed separately. See file COPYING for details.
*
* TODO (sorted by decreasing priority)
* -- ZIP does "ub: resid 18 len 0 act 0" and whole transport quits (toggles?)
* -- Do resets with usb_device_reset (needs a thread context, use khubd)
* -- set readonly flag for CDs, set removable flag for CF readers
* -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
* -- support pphaneuf's SDDR-75 with two LUNs (also broken capacity...)
* -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
* -- do something about spin-down devices, they are extremely dangerous
* (ZIP is one. Needs spin-up command as well.)
* -- verify the 13 conditions and do bulk resets
* -- normal pool of commands instead of cmdv[]?
* -- kill last_pipe and simply do two-state clearing on both pipes
......@@ -105,13 +103,11 @@ struct ub_dev;
#define UB_MAX_SECTORS 64
/*
* A second ought to be enough for a 32K transfer (UB_MAX_SECTORS)
* even if a webcam hogs the bus (famous last words).
* Some CDs need a second to spin up though.
* ZIP drive rejects commands when it's not spinning,
* so it does not need long timeouts either.
* A second is more than enough for a 32K transfer (UB_MAX_SECTORS)
* even if a webcam hogs the bus, but some devices need time to spin up.
*/
#define UB_URB_TIMEOUT (HZ*2)
#define UB_DATA_TIMEOUT (HZ*5) /* ZIP does spin-ups in the data phase */
#define UB_CTRL_TIMEOUT (HZ/2) /* 500ms ought to be enough to clear a stall */
/*
......@@ -188,7 +184,7 @@ struct ub_capacity {
*/
#define SCMD_ST_HIST_SZ 8
#define SCMD_TRACE_SZ 15 /* No more than 256 (trace_index) */
#define SCMD_TRACE_SZ 63 /* Less than 4KB of 61-byte lines */
struct ub_scsi_cmd_trace {
int hcur;
......@@ -267,6 +263,7 @@ struct ub_dev {
int changed; /* Media was changed */
int removable;
int readonly;
int first_open; /* Kludge. See ub_bd_open. */
char name[8];
struct usb_device *dev;
struct usb_interface *intf;
......@@ -888,9 +885,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
int pipe;
int rc;
/* P3 */ /** printk("ub: urb status %d pipe 0x%08x len %d act %d\n",
urb->status, urb->pipe, urb->transfer_buffer_length, urb->actual_length); **/
if (atomic_read(&sc->poison)) {
/* A little too simplistic, I feel... */
goto Bad_End;
......@@ -959,9 +953,12 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
ub_cmdtr_state(sc, cmd);
return;
}
if (urb->status != 0)
if (urb->status != 0) {
printk("ub: cmd #%d cmd status (%d)\n", cmd->tag, urb->status); /* P3 */
goto Bad_End;
}
if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
printk("ub: cmd #%d xferred %d\n", cmd->tag, urb->actual_length); /* P3 */
/* XXX Must do reset here to unconfuse the device */
goto Bad_End;
}
......@@ -993,7 +990,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
return;
}
sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT;
add_timer(&sc->work_timer);
cmd->state = UB_CMDST_DATA;
......@@ -1379,12 +1376,7 @@ static void ub_revalidate(struct ub_dev *sc)
sc->readonly = 0; /* XXX Query this from the device */
/*
* XXX sd.c sets capacity to zero in such case. However, it doesn't
* work for us. In case of zero capacity, block layer refuses to
* have the /dev/uba opened (why?) Set capacity to some random value.
*/
sc->capacity.nsec = 50;
sc->capacity.nsec = 0;
sc->capacity.bsize = 512;
sc->capacity.bshift = 0;
......@@ -1399,7 +1391,7 @@ static void ub_revalidate(struct ub_dev *sc)
* We keep this because sd.c has retries for capacity.
*/
if (ub_sync_read_cap(sc, &sc->capacity) != 0) {
sc->capacity.nsec = 100;
sc->capacity.nsec = 0;
sc->capacity.bsize = 512;
sc->capacity.bshift = 0;
}
......@@ -1428,6 +1420,26 @@ static int ub_bd_open(struct inode *inode, struct file *filp)
sc->openc++;
spin_unlock_irqrestore(&ub_lock, flags);
/*
* This is a workaround for a specific problem in our block layer.
* In 2.6.9, register_disk duplicates the code from rescan_partitions.
* However, if we do add_disk with a device which persistently reports
* a changed media, add_disk calls register_disk, which does do_open,
* which will call rescan_paritions for changed media. After that,
* register_disk attempts to do it all again and causes double kobject
* registration and a eventually an oops on module removal.
*
* The bottom line is, Al Viro says that we should not allow
* bdev->bd_invalidated to be set when doing add_disk no matter what.
*/
if (sc->first_open) {
if (sc->changed) {
sc->first_open = 0;
rc = -ENOMEDIUM;
goto err_open;
}
}
if (sc->removable || sc->readonly)
check_disk_change(inode->i_bdev);
......@@ -1467,6 +1479,8 @@ static int ub_bd_release(struct inode *inode, struct file *filp)
spin_lock_irqsave(&ub_lock, flags);
--sc->openc;
if (sc->openc == 0)
sc->first_open = 0;
if (sc->openc == 0 && atomic_read(&sc->poison))
ub_cleanup(sc);
spin_unlock_irqrestore(&ub_lock, flags);
......@@ -1559,13 +1573,9 @@ static int ub_bd_media_changed(struct gendisk *disk)
*/
if (ub_sync_tur(sc) != 0) {
sc->changed = 1;
/* P3 */ printk("%s: made changed\n", sc->name);
return 1;
}
/* The sd.c clears this before returning (one-shot flag). Why? */
/* P3 */ printk("%s: %s changed\n", sc->name,
sc->changed? "is": "was not");
return sc->changed;
}
......@@ -1919,6 +1929,8 @@ static int ub_probe(struct usb_interface *intf,
}
sc->removable = 1; /* XXX Query this from the device */
sc->changed = 1; /* ub_revalidate clears only */
sc->first_open = 1;
ub_revalidate(sc);
/* This is pretty much a long term P3 */
......
......@@ -308,7 +308,7 @@ static int pci_device_suspend(struct device * dev, u32 state)
dev_state = state_conversion[state];
if (drv && drv->suspend)
i = drv->suspend(pci_dev, dev_state);
else
pci_save_state(pci_dev);
return i;
}
......
......@@ -937,8 +937,7 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
while (wait_time > 0 &&
readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
wait_time -= 10;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((HZ*10 + 999) / 1000);
msleep(10);
}
}
......@@ -987,8 +986,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
wait_time = 500;
do {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((HZ*10+999)/1000);
msleep(10);
wait_time -= 10;
pci_read_config_dword(pdev,
hcc_params + EHCI_USBLEGSUP,
......
......@@ -411,6 +411,8 @@ static int releaseintf(struct dev_state *ps, unsigned int ifnum)
static int checkintf(struct dev_state *ps, unsigned int ifnum)
{
if (ps->dev->state != USB_STATE_CONFIGURED)
return -EHOSTUNREACH;
if (ifnum >= 8*sizeof(ps->ifclaimed))
return -EINVAL;
if (test_bit(ifnum, &ps->ifclaimed))
......@@ -450,6 +452,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
{
int ret = 0;
if (ps->dev->state != USB_STATE_CONFIGURED)
return -EHOSTUNREACH;
if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
return 0;
......@@ -595,7 +599,7 @@ static int proc_control(struct dev_state *ps, void __user *arg)
usb_lock_device(dev);
}
free_page((unsigned long)tbuf);
if (i<0) {
if (i<0 && i != -EPIPE) {
dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL "
"failed cmd %s rqt %u rq %u len %u ret %d\n",
current->comm, ctrl.bRequestType, ctrl.bRequest,
......@@ -1131,7 +1135,7 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg)
}
if (ps->dev->state != USB_STATE_CONFIGURED)
retval = -ENODEV;
retval = -EHOSTUNREACH;
else if (!(intf = usb_ifnum_to_if (ps->dev, ctrl.ifno)))
retval = -EINVAL;
else switch (ctrl.ioctl_code) {
......
......@@ -38,14 +38,6 @@
/*-------------------------------------------------------------------------*/
static void hcd_pci_release(struct usb_bus *bus)
{
struct usb_hcd *hcd = bus->hcpriv;
if (hcd)
hcd->driver->hcd_free(hcd);
}
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
......@@ -78,6 +70,7 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
if (pci_enable_device (dev) < 0)
return -ENODEV;
dev->current_state = 0;
if (!dev->irq) {
dev_err (&dev->dev,
......@@ -160,7 +153,7 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
if ((retval = hcd_buffer_create (hcd)) != 0) {
clean_3:
driver->hcd_free (hcd);
kfree (hcd);
goto clean_2;
}
......@@ -194,8 +187,8 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
usb_bus_init (&hcd->self);
hcd->self.op = &usb_hcd_operations;
hcd->self.release = &usb_hcd_release;
hcd->self.hcpriv = (void *) hcd;
hcd->self.release = &hcd_pci_release;
init_timer (&hcd->rh_timer);
INIT_LIST_HEAD (&hcd->dev_list);
......@@ -268,6 +261,18 @@ EXPORT_SYMBOL (usb_hcd_pci_remove);
#ifdef CONFIG_PM
static char __attribute_used__ *pci_state(u32 state)
{
switch (state) {
case 0: return "D0";
case 1: return "D1";
case 2: return "D2";
case 3: return "D3hot";
case 4: return "D3cold";
}
return NULL;
}
/**
* usb_hcd_pci_suspend - power management suspend of a PCI-based HCD
* @dev: USB Host Controller being suspended
......@@ -288,16 +293,32 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state)
* PM-sensitive HCDs may already have done this.
*/
has_pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM);
if (has_pci_pm)
dev_dbg(hcd->self.controller, "suspend D%d --> D%d\n",
dev->current_state, state);
if (state > 4)
state = 4;
switch (hcd->state) {
case USB_STATE_HALT:
dev_dbg (hcd->self.controller, "halted; hcd not suspended\n");
break;
case HCD_STATE_SUSPENDED:
dev_dbg (hcd->self.controller, "hcd already suspended\n");
dev_dbg (hcd->self.controller, "PCI %s --> %s\n",
pci_state(dev->current_state),
pci_state(has_pci_pm ? state : 0));
if (state > 3)
state = 3;
if (state == dev->current_state)
break;
else if (state < dev->current_state)
retval = -EIO;
else if (has_pci_pm)
retval = pci_set_power_state (dev, state);
if (retval == 0)
dev->dev.power.power_state = state;
else
dev_dbg (hcd->self.controller,
"re-suspend fail, %d\n", retval);
break;
default:
retval = hcd->driver->suspend (hcd, state);
......@@ -308,22 +329,47 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state)
else {
hcd->state = HCD_STATE_SUSPENDED;
pci_save_state (dev);
#ifdef CONFIG_USB_SUSPEND
pci_enable_wake (dev, state, hcd->remote_wakeup);
pci_enable_wake (dev, 4, hcd->remote_wakeup);
#endif
/* no DMA or IRQs except in D0 */
pci_disable_device (dev);
free_irq (hcd->irq, hcd);
if (has_pci_pm)
if (has_pci_pm) {
retval = pci_set_power_state (dev, state);
/* POLICY: ignore D1/D2/D3hot differences;
* we know D3hot will always work.
*/
if (retval < 0 && state < 3) {
retval = pci_set_power_state (dev, 3);
if (retval == 0)
state = 3;
}
if (retval == 0) {
dev->dev.power.power_state = state;
#ifdef CONFIG_USB_SUSPEND
pci_enable_wake (dev, state,
hcd->remote_wakeup);
pci_enable_wake (dev, 4,
hcd->remote_wakeup);
#endif
}
} else {
if (state > 3)
state = 3;
dev->dev.power.power_state = state;
}
if (retval < 0) {
dev_dbg (&dev->dev,
"PCI suspend fail, %d\n",
"PCI %s suspend fail, %d\n",
pci_state(state),
retval);
(void) usb_hcd_pci_resume (dev);
} else {
dev_dbg(hcd->self.controller,
"suspended to PCI %s%s\n",
pci_state(dev->current_state),
has_pci_pm ? "" : " (legacy)");
}
}
}
......@@ -345,9 +391,11 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
hcd = pci_get_drvdata(dev);
has_pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM);
if (has_pci_pm)
dev_dbg(hcd->self.controller, "resume from state D%d\n",
dev->current_state);
/* D3cold resume isn't usually reported this way... */
dev_dbg(hcd->self.controller, "resume from PCI %s%s\n",
pci_state(dev->current_state),
has_pci_pm ? "" : " (legacy)");
if (hcd->state != HCD_STATE_SUSPENDED) {
dev_dbg (hcd->self.controller,
......@@ -366,7 +414,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
"can't restore IRQ after resume!\n");
return retval;
}
pci_set_master (dev);
hcd->saw_irq = 0;
pci_restore_state (dev);
#ifdef CONFIG_USB_SUSPEND
pci_enable_wake (dev, dev->current_state, 0);
......
......@@ -435,8 +435,6 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
/* non-generic request */
if (HCD_IS_SUSPENDED (hcd->state))
urb->status = -EAGAIN;
else if (!HCD_IS_RUNNING (hcd->state))
urb->status = -ENODEV;
else
urb->status = hcd->driver->hub_control (hcd,
typeReq, wValue, wIndex,
......@@ -445,13 +443,16 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
error:
/* "protocol stall" on error */
urb->status = -EPIPE;
dev_dbg (hcd->self.controller, "unsupported hub control message (maxchild %d)\n",
urb->dev->maxchild);
}
if (urb->status) {
urb->actual_length = 0;
dev_dbg (hcd->self.controller, "CTRL: TypeReq=0x%x val=0x%x idx=0x%x len=%d ==> %d\n",
typeReq, wValue, wIndex, wLength, urb->status);
if (urb->status != -EPIPE) {
dev_dbg (hcd->self.controller,
"CTRL: TypeReq=0x%x val=0x%x "
"idx=0x%x len=%d ==> %d\n",
typeReq, wValue, wIndex,
wLength, urb->status);
}
}
if (bufp) {
if (urb->transfer_buffer_length < len)
......@@ -540,7 +541,7 @@ static void rh_report_status (unsigned long ptr)
urb->actual_length = length;
urb->status = 0;
urb->hcpriv = NULL;
} else
} else if (!urb->dev->dev.power.power_state)
mod_timer (&hcd->rh_timer, jiffies + HZ/4);
spin_unlock (&hcd_data_lock);
spin_unlock (&urb->lock);
......@@ -572,11 +573,12 @@ static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb)
/*-------------------------------------------------------------------------*/
int usb_rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb)
static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
{
unsigned long flags;
/* note: always a synchronous unlink */
if ((unsigned long) urb == hcd->rh_timer.data) {
del_timer_sync (&hcd->rh_timer);
hcd->rh_timer.data = 0;
......@@ -584,6 +586,21 @@ int usb_rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb)
urb->hcpriv = NULL;
usb_hcd_giveback_urb (hcd, urb, NULL);
local_irq_restore (flags);
} else if (usb_pipeendpoint(urb->pipe) == 0) {
spin_lock_irq(&urb->lock); /* from usb_kill_urb */
++urb->reject;
spin_unlock_irq(&urb->lock);
wait_event(usb_kill_urb_queue,
atomic_read(&urb->use_count) == 0);
spin_lock_irq(&urb->lock);
--urb->reject;
spin_unlock_irq(&urb->lock);
} else
return -EINVAL;
return 0;
}
......@@ -1175,8 +1192,8 @@ unlink1 (struct usb_hcd *hcd, struct urb *urb)
{
int value;
if (urb == (struct urb *) hcd->rh_timer.data)
value = usb_rh_status_dequeue (hcd, urb);
if (urb->dev == hcd->self.root_hub)
value = usb_rh_urb_dequeue (hcd, urb);
else {
/* The only reason an HCD might fail this call is if
......@@ -1264,7 +1281,7 @@ static int hcd_unlink_urb (struct urb *urb, int status)
* never get completion IRQs ... maybe even the ones we need to
* finish unlinking the initial failed usb_set_address().
*/
if (!hcd->saw_irq && hcd->rh_timer.data != (unsigned long) urb) {
if (!hcd->saw_irq && hcd->self.root_hub != urb->dev) {
dev_warn (hcd->self.controller, "Unlink after no-IRQ? "
"Different ACPI or APIC settings may help."
"\n");
......@@ -1605,3 +1622,13 @@ void usb_hc_died (struct usb_hcd *hcd)
}
EXPORT_SYMBOL (usb_hc_died);
/*-------------------------------------------------------------------------*/
void usb_hcd_release(struct usb_bus *bus)
{
struct usb_hcd *hcd;
hcd = container_of (bus, struct usb_hcd, self);
kfree(hcd);
}
EXPORT_SYMBOL (usb_hcd_release);
......@@ -191,8 +191,13 @@ struct hc_driver {
int (*get_frame_number) (struct usb_hcd *hcd);
/* memory lifecycle */
/* Note: The absence of hcd_free reflects a temporary situation;
* in the near future hcd_alloc will disappear as well and all
* allocations/deallocations will be handled by usbcore. For the
* moment, drivers are required to return a pointer that the core
* can pass to kfree, i.e., the struct usb_hcd must be the _first_
* member of a larger driver-specific structure. */
struct usb_hcd *(*hcd_alloc) (void);
void (*hcd_free) (struct usb_hcd *hcd);
/* manage i/o requests, device state */
int (*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb,
......@@ -215,7 +220,6 @@ struct hc_driver {
extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs);
extern void usb_bus_init (struct usb_bus *bus);
extern int usb_rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb);
#ifdef CONFIG_PCI
struct pci_dev;
......@@ -361,6 +365,8 @@ static inline int hcd_register_root (struct usb_device *usb_dev,
return usb_register_root_hub (usb_dev, hcd->self.controller);
}
extern void usb_hcd_release (struct usb_bus *);
extern void usb_set_device_state(struct usb_device *udev,
enum usb_device_state new_state);
......
......@@ -1516,7 +1516,7 @@ static int hub_port_suspend(struct usb_device *hdev, int port)
* Linux (2.6) currently has NO mechanisms to initiate that: no khubd
* timer, no SRP, no requests through sysfs.
*/
static int __usb_suspend_device (struct usb_device *udev, int port, u32 state)
int __usb_suspend_device (struct usb_device *udev, int port, u32 state)
{
int status;
......@@ -1524,9 +1524,7 @@ static int __usb_suspend_device (struct usb_device *udev, int port, u32 state)
if (port < 0)
return port;
if (state <= udev->dev.power.power_state
|| state < PM_SUSPEND_MEM
|| udev->state == USB_STATE_SUSPENDED
if (udev->dev.power.power_state
|| udev->state == USB_STATE_NOTATTACHED) {
return 0;
}
......@@ -1590,7 +1588,6 @@ static int __usb_suspend_device (struct usb_device *udev, int port, u32 state)
*/
if (state > PM_SUSPEND_MEM) {
dev_warn(&udev->dev, "no poweroff yet, suspending instead\n");
state = PM_SUSPEND_MEM;
}
/* "global suspend" of the HC-to-USB interface (root hub), or
......@@ -1606,9 +1603,11 @@ static int __usb_suspend_device (struct usb_device *udev, int port, u32 state)
status = hub_port_suspend(udev->parent, port);
if (status == 0)
udev->dev.power.power_state = state;
udev->dev.power.power_state = PM_SUSPEND_MEM;
up(&udev->serialize);
return status;
}
EXPORT_SYMBOL(__usb_suspend_device);
/**
* usb_suspend_device - suspend a usb device
......@@ -1821,6 +1820,7 @@ int usb_resume_device(struct usb_device *udev)
->actconfig->interface[0]);
}
} else if (udev->state == USB_STATE_SUSPENDED) {
// NOTE this fails if parent is also suspended...
status = hub_port_resume(udev->parent, port);
} else {
status = 0;
......@@ -1834,10 +1834,11 @@ int usb_resume_device(struct usb_device *udev)
usb_unlock_device(udev);
/* rebind drivers that had no suspend() */
if (status == 0) {
usb_lock_all_devices();
bus_rescan_devices(&usb_bus_type);
usb_unlock_all_devices();
}
return status;
}
......@@ -1895,6 +1896,9 @@ static int hub_resume(struct usb_interface *intf)
unsigned port;
int status;
if (intf->dev.power.power_state == PM_SUSPEND_ON)
return 0;
for (port = 0; port < hdev->maxchild; port++) {
struct usb_device *udev;
u16 portstat, portchange;
......@@ -1913,7 +1917,7 @@ static int hub_resume(struct usb_interface *intf)
continue;
}
if (!udev)
if (!udev || status < 0)
continue;
down (&udev->serialize);
if (portstat & USB_PORT_STAT_SUSPEND)
......@@ -2240,8 +2244,8 @@ hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port,
/* Should we verify that the value is valid? */
i = udev->descriptor.bMaxPacketSize0;
dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
if (udev->epmaxpacketin[0] != i) {
dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
usb_disable_endpoint(udev, 0 + USB_DIR_IN);
usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
udev->epmaxpacketin[0] = udev->epmaxpacketout[0] = i;
......@@ -2547,6 +2551,14 @@ static void hub_events(void)
usb_get_dev(hdev);
spin_unlock_irq(&hub_event_lock);
dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
hdev->state, hub->descriptor
? hub->descriptor->bNbrPorts
: 0,
/* NOTE: expects max 15 ports... */
(u16) hub->change_bits[0],
(u16) hub->event_bits[0]);
/* Lock the device, then check to see if we were
* disconnected while waiting for the lock to succeed. */
if (locktree(hdev) < 0)
......
......@@ -34,10 +34,6 @@ static void timeout_kill(unsigned long data)
{
struct urb *urb = (struct urb *) data;
dev_warn(&urb->dev->dev, "%s timeout on ep%d%s\n",
usb_pipecontrol(urb->pipe) ? "control" : "bulk",
usb_pipeendpoint(urb->pipe),
usb_pipein(urb->pipe) ? "in" : "out");
usb_unlink_urb(urb);
}
......@@ -68,8 +64,14 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
wait_for_completion(&done);
status = urb->status;
/* note: HCDs return ETIMEDOUT for other reasons too */
if (status == -ECONNRESET)
if (status == -ECONNRESET) {
dev_warn(&urb->dev->dev,
"%s timed out on ep%d%s\n",
current->comm,
usb_pipeendpoint(urb->pipe),
usb_pipein(urb->pipe) ? "in" : "out");
status = -ETIMEDOUT;
}
if (timeout > 0)
del_timer_sync(&timer);
}
......@@ -549,8 +551,7 @@ void usb_sg_cancel (struct usb_sg_request *io)
*
* Gets a USB descriptor. Convenience functions exist to simplify
* getting some types of descriptors. Use
* usb_get_device_descriptor() for USB_DT_DEVICE (not exported),
* and usb_get_string() or usb_string() for USB_DT_STRING.
* usb_get_string() or usb_string() for USB_DT_STRING.
* Device (USB_DT_DEVICE) and configuration descriptors (USB_DT_CONFIG)
* are part of the device structure.
* In addition to a number of USB-standard descriptors, some
......@@ -703,6 +704,8 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
int err;
unsigned int u, idx;
if (dev->state == USB_STATE_SUSPENDED)
return -EHOSTUNREACH;
if (size <= 0 || !buf || !index)
return -EINVAL;
buf[0] = 0;
......@@ -755,8 +758,8 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
return err;
}
/**
* usb_get_device_descriptor - (re)reads the device descriptor
/*
* usb_get_device_descriptor - (re)reads the device descriptor (usbcore)
* @dev: the device whose device descriptor is being updated
* @size: how much of the descriptor to read
* Context: !in_interrupt ()
......
......@@ -63,7 +63,8 @@ const char *usbcore_name = "usbcore";
int nousb; /* Disable USB when built into kernel image */
/* Not honored on modular build */
static DECLARE_RWSEM(usb_all_devices_rwsem);
DECLARE_RWSEM(usb_all_devices_rwsem);
EXPORT_SYMBOL(usb_all_devices_rwsem);
static int generic_probe (struct device *dev)
......@@ -97,6 +98,7 @@ int usb_probe_interface(struct device *dev)
if (!driver->probe)
return error;
/* FIXME we'd much prefer to just resume it ... */
if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED)
return -EHOSTUNREACH;
......@@ -1393,6 +1395,10 @@ static int usb_generic_suspend(struct device *dev, u32 state)
struct usb_interface *intf;
struct usb_driver *driver;
/* there's only one USB suspend state */
if (dev->power.power_state)
return 0;
if (dev->driver == &usb_generic_driver)
return usb_suspend_device (to_usb_device(dev), state);
......
......@@ -13,7 +13,7 @@ obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o
#
g_zero-objs := zero.o usbstring.o config.o epautoconf.o
g_ether-objs := ether.o usbstring.o config.o epautoconf.o
g_serial-objs := serial.o usbstring.o epautoconf.o
g_serial-objs := serial.o usbstring.o config.o epautoconf.o
gadgetfs-objs := inode.o
g_file_storage-objs := file_storage.o usbstring.o config.o \
epautoconf.o
......
This diff is collapsed.
......@@ -856,7 +856,7 @@ static inline void __init hs_subset_descriptors(void)
/* descriptors that are built on-demand */
static char manufacturer [40];
static char manufacturer [50];
static char product_desc [40] = DRIVER_DESC;
#ifdef DEV_CONFIG_CDC
......@@ -2183,7 +2183,7 @@ static int eth_stop (struct net_device *net)
);
/* ensure there are no more active requests */
if (dev->gadget->speed != USB_SPEED_UNKNOWN) {
if (dev->config) {
usb_ep_disable (dev->in_ep);
usb_ep_disable (dev->out_ep);
if (netif_carrier_ok (dev->net)) {
......
......@@ -1010,7 +1010,7 @@ static const struct usb_descriptor_header *hs_function[] = {
/* The CBI specification limits the serial string to 12 uppercase hexadecimal
* characters. */
static char manufacturer[40];
static char manufacturer[50];
static char serial[13];
/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
......@@ -1035,7 +1035,9 @@ static struct usb_gadget_strings stringtab = {
static int populate_config_buf(struct usb_gadget *gadget,
u8 *buf, u8 type, unsigned index)
{
#ifdef CONFIG_USB_GADGET_DUALSPEED
enum usb_device_speed speed = gadget->speed;
#endif
int len;
const struct usb_descriptor_header **function;
......
This diff is collapsed.
......@@ -396,7 +396,7 @@ static const struct usb_descriptor_header *hs_loopback_function [] = {
#endif /* !CONFIG_USB_GADGET_DUALSPEED */
static char manufacturer [40];
static char manufacturer [50];
static char serial [40];
/* static strings, in UTF-8 */
......
......@@ -97,7 +97,7 @@
* 2001-June Works with usb-storage and NEC EHCI on 2.4
*/
#define DRIVER_VERSION "2004-May-10"
#define DRIVER_VERSION "26 Oct 2004"
#define DRIVER_AUTHOR "David Brownell"
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
......@@ -207,7 +207,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
}
/* idle the controller (from running) */
static void ehci_ready (struct ehci_hcd *ehci)
static void ehci_quiesce (struct ehci_hcd *ehci)
{
u32 temp;
......@@ -217,11 +217,8 @@ static void ehci_ready (struct ehci_hcd *ehci)
#endif
/* wait for any schedule enables/disables to take effect */
temp = 0;
if (ehci->async->qh_next.qh)
temp = STS_ASS;
if (ehci->next_uframe != -1)
temp |= STS_PSS;
temp = readl (&ehci->regs->command) << 10;
temp &= STS_ASS | STS_PSS;
if (handshake (&ehci->regs->status, STS_ASS | STS_PSS,
temp, 16 * 125) != 0) {
ehci->hcd.state = USB_STATE_HALT;
......@@ -402,17 +399,22 @@ static int ehci_start (struct usb_hcd *hcd)
int retval;
u32 hcc_params;
u8 sbrn = 0;
int first;
/* skip some things on restart paths */
first = (ehci->watchdog.data == 0);
if (first) {
init_timer (&ehci->watchdog);
ehci->watchdog.function = ehci_watchdog;
ehci->watchdog.data = (unsigned long) ehci;
}
/*
* hw default: 1K periodic list heads, one per frame.
* periodic_size can shrink by USBCMD update if hcc_params allows.
*/
ehci->periodic_size = DEFAULT_I_TDPS;
if ((retval = ehci_mem_init (ehci, GFP_KERNEL)) < 0)
if (first && (retval = ehci_mem_init (ehci, GFP_KERNEL)) < 0)
return retval;
/* controllers may cache some of the periodic schedule ... */
......@@ -423,6 +425,7 @@ static int ehci_start (struct usb_hcd *hcd)
ehci->i_thresh = 2 + HCC_ISOC_THRES (hcc_params);
ehci->reclaim = NULL;
ehci->reclaim_ready = 0;
ehci->next_uframe = -1;
/* controller state: unknown --> reset */
......@@ -469,6 +472,7 @@ static int ehci_start (struct usb_hcd *hcd)
* its dummy is used in hw_alt_next of many tds, to prevent the qh
* from automatically advancing to the next td after short reads.
*/
if (first) {
ehci->async->qh_next.qh = NULL;
ehci->async->hw_next = QH_NEXT (ehci->async->qh_dma);
ehci->async->hw_info1 = cpu_to_le32 (QH_HEAD);
......@@ -477,6 +481,7 @@ static int ehci_start (struct usb_hcd *hcd)
ehci->async->qh_state = QH_STATE_LINKED;
ehci->async->hw_alt_next = QTD_NEXT (ehci->async->dummy->qtd_dma);
writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next);
}
/*
* hcc_params controls whether ehci->regs->segment must (!!!)
......@@ -527,12 +532,15 @@ static int ehci_start (struct usb_hcd *hcd)
/* wire up the root hub */
bus = hcd_to_bus (hcd);
udev = usb_alloc_dev (NULL, bus, 0);
udev = first ? usb_alloc_dev (NULL, bus, 0) : bus->root_hub;
if (!udev) {
done2:
ehci_mem_cleanup (ehci);
return -ENOMEM;
}
udev->speed = USB_SPEED_HIGH;
udev->state = first ? USB_STATE_ATTACHED : USB_STATE_CONFIGURED;
udev->dev.power.power_state = PM_SUSPEND_ON;
/*
* Start, enabling full USB 2.0 functionality ... usb 1.1 devices
......@@ -540,8 +548,10 @@ static int ehci_start (struct usb_hcd *hcd)
* involved with the root hub. (Except where one is integrated,
* and there's no companion controller unless maybe for USB OTG.)
*/
if (first) {
ehci->reboot_notifier.notifier_call = ehci_reboot;
register_reboot_notifier (&ehci->reboot_notifier);
}
ehci->hcd.state = USB_STATE_RUNNING;
writel (FLAG_CF, &ehci->regs->configured_flag);
......@@ -549,21 +559,23 @@ static int ehci_start (struct usb_hcd *hcd)
temp = HC_VERSION(readl (&ehci->caps->hc_capbase));
ehci_info (ehci,
"USB %x.%x enabled, EHCI %x.%02x, driver %s\n",
"USB %x.%x %s, EHCI %x.%02x, driver %s\n",
((sbrn & 0xf0)>>4), (sbrn & 0x0f),
first ? "initialized" : "restarted",
temp >> 8, temp & 0xff, DRIVER_VERSION);
/*
* From here on, khubd concurrently accesses the root
* hub; drivers will be talking to enumerated devices.
* (On restart paths, khubd already knows about the root
* hub and could find work as soon as we wrote FLAG_CF.)
*
* Before this point the HC was idle/ready. After, khubd
* and device drivers may start it running.
*/
udev->speed = USB_SPEED_HIGH;
if (hcd_register_root (udev, hcd) != 0) {
if (first && hcd_register_root (udev, hcd) != 0) {
if (hcd->state == USB_STATE_RUNNING)
ehci_ready (ehci);
ehci_quiesce (ehci);
ehci_reset (ehci);
usb_put_dev (udev);
retval = -ENODEV;
......@@ -572,6 +584,7 @@ static int ehci_start (struct usb_hcd *hcd)
writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */
if (first)
create_debug_files (ehci);
return 0;
......@@ -586,24 +599,23 @@ static void ehci_stop (struct usb_hcd *hcd)
ehci_dbg (ehci, "stop\n");
/* no more interrupts ... */
if (hcd->state == USB_STATE_RUNNING)
ehci_ready (ehci);
if (in_interrupt ()) { /* must not happen!! */
ehci_err (ehci, "stopped in_interrupt!\n");
return;
}
del_timer_sync (&ehci->watchdog);
/* Turn off port power on all root hub ports. */
rh_ports = HCS_N_PORTS (ehci->hcs_params);
for (port = 1; port <= rh_ports; port++) {
ehci_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER,
for (port = 1; port <= rh_ports; port++)
(void) ehci_hub_control(hcd,
ClearPortFeature, USB_PORT_FEAT_POWER,
port, NULL, 0);
}
/* no more interrupts ... */
del_timer_sync (&ehci->watchdog);
spin_lock_irq(&ehci->lock);
if (HCD_IS_RUNNING (ehci->hcd.state))
ehci_quiesce (ehci);
ehci_reset (ehci);
writel (0, &ehci->regs->intr_enable);
spin_unlock_irq(&ehci->lock);
/* let companion controllers work when we aren't */
writel (0, &ehci->regs->configured_flag);
......@@ -641,7 +653,8 @@ static int ehci_get_frame (struct usb_hcd *hcd)
/* suspend/resume, section 4.3 */
/* These routines rely on PCI to handle powerdown and wakeup, and
/* These routines rely on the bus (pci, platform, etc)
* to handle powerdown and wakeup, and currently also on
* transceivers that don't need any software attention to set up
* the right sort of wakeup.
*/
......@@ -650,6 +663,9 @@ static int ehci_suspend (struct usb_hcd *hcd, u32 state)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
if (hcd->self.root_hub->dev.power.power_state)
return 0;
while (time_before (jiffies, ehci->next_statechange))
msleep (100);
......@@ -668,19 +684,51 @@ static int ehci_suspend (struct usb_hcd *hcd, u32 state)
static int ehci_resume (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
int retval;
unsigned port;
struct usb_device *root = hcd->self.root_hub;
int retval = -EINVAL;
// maybe restore (PCI) FLADJ
while (time_before (jiffies, ehci->next_statechange))
msleep (100);
#ifdef CONFIG_USB_SUSPEND
retval = usb_resume_device (hcd->self.root_hub);
#else
/* FIXME lock root hub */
/* If any port is suspended, we know we can/must resume the HC. */
for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) {
u32 status;
port--;
status = readl (&ehci->regs->port_status [port]);
if (status & PORT_SUSPEND) {
down (&hcd->self.root_hub->serialize);
retval = ehci_hub_resume (hcd);
#endif
up (&hcd->self.root_hub->serialize);
break;
}
if (!root->children [port])
continue;
dbg_port (ehci, __FUNCTION__, port + 1, status);
usb_set_device_state (root->children[port],
USB_STATE_NOTATTACHED);
}
/* Else reset, to cope with power loss or flush-to-storage
* style "resume" having activated BIOS during reboot.
*/
if (port == 0) {
(void) ehci_halt (ehci);
(void) ehci_reset (ehci);
(void) ehci_hc_reset (hcd);
/* emptying the schedule aborts any urbs */
spin_lock_irq (&ehci->lock);
if (ehci->reclaim)
ehci->reclaim_ready = 1;
ehci_work (ehci, NULL);
spin_unlock_irq (&ehci->lock);
/* restart; khubd will disconnect devices */
retval = ehci_start (hcd);
}
if (retval == 0)
hcd->self.controller->power.power_state = 0;
return retval;
......@@ -716,7 +764,8 @@ static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs)
* misplace IRQs, and should let us run completely without IRQs.
* such lossage has been observed on both VT6202 and VT8235.
*/
if ((ehci->async->qh_next.ptr != 0) || (ehci->periodic_sched != 0))
if (HCD_IS_RUNNING (ehci->hcd.state) && (ehci->async->qh_next.ptr != 0
|| ehci->periodic_sched != 0))
timer_action (ehci, TIMER_IO_WATCHDOG);
}
......@@ -1047,7 +1096,6 @@ static const struct hc_driver ehci_driver = {
* memory lifecycle (except per-request)
*/
.hcd_alloc = ehci_hcd_alloc,
.hcd_free = ehci_hcd_free,
/*
* managing i/o requests and associated device resources
......
......@@ -35,7 +35,6 @@ static int ehci_hub_suspend (struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
struct usb_device *root = hcd_to_bus (&ehci->hcd)->root_hub;
int port;
int status = 0;
if (root->dev.power.power_state != 0)
return 0;
......@@ -45,9 +44,22 @@ static int ehci_hub_suspend (struct usb_hcd *hcd)
port = HCS_N_PORTS (ehci->hcs_params);
spin_lock_irq (&ehci->lock);
/* for hcd->state HCD_STATE_SUSPENDED, also stop the non-USB side */
root->dev.power.power_state = 3;
root->state = USB_STATE_SUSPENDED;
/* stop schedules, clean any completed work */
if (HCD_IS_RUNNING(hcd->state))
ehci_quiesce (ehci);
ehci->command = readl (&ehci->regs->command);
if (ehci->reclaim)
ehci->reclaim_ready = 1;
ehci_work(ehci, NULL);
/* suspend any active/unsuspended ports, maybe allow wakeup */
while (port--) {
u32 t1 = readl (&ehci->regs->port_status [port]);
u32 __iomem *reg = &ehci->regs->port_status [port];
u32 t1 = readl (reg);
u32 t2 = t1;
if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
......@@ -60,24 +72,16 @@ static int ehci_hub_suspend (struct usb_hcd *hcd)
if (t1 != t2) {
ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
port + 1, t1, t2);
writel (t2, &ehci->regs->port_status [port]);
writel (t2, reg);
}
}
/* stop schedules, then turn off HC and clean any completed work */
if (hcd->state == USB_STATE_RUNNING)
ehci_ready (ehci);
ehci->command = readl (&ehci->regs->command);
writel (ehci->command & ~CMD_RUN, &ehci->regs->command);
if (ehci->reclaim)
ehci->reclaim_ready = 1;
ehci_work(ehci, NULL);
(void) handshake (&ehci->regs->status, STS_HALT, STS_HALT, 2000);
/* turn off now-idle HC */
ehci_halt (ehci);
root->dev.power.power_state = 3;
ehci->next_statechange = jiffies + msecs_to_jiffies(10);
spin_unlock_irq (&ehci->lock);
return status;
return 0;
}
......@@ -96,12 +100,16 @@ static int ehci_hub_resume (struct usb_hcd *hcd)
/* re-init operational registers in case we lost power */
if (readl (&ehci->regs->intr_enable) == 0) {
temp = 1;
writel (INTR_MASK, &ehci->regs->intr_enable);
writel (0, &ehci->regs->segment);
writel (ehci->periodic_dma, &ehci->regs->frame_list);
writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next);
/* FIXME will this work even (pci) vAUX was lost? */
}
/* FIXME will this work even if (pci) vAUX was lost? */
} else
temp = 0;
ehci_dbg(ehci, "resume root hub%s\n",
temp ? " after power loss" : "");
/* restore CMD_RUN, framelist size, and irq threshold */
writel (ehci->command, &ehci->regs->command);
......@@ -135,8 +143,10 @@ static int ehci_hub_resume (struct usb_hcd *hcd)
temp |= CMD_ASE;
if (ehci->periodic_sched)
temp |= CMD_PSE;
if (temp)
writel (ehci->command | temp, &ehci->regs->command);
if (temp) {
ehci->command |= temp;
writel (ehci->command, &ehci->regs->command);
}
root->dev.power.power_state = 0;
ehci->next_statechange = jiffies + msecs_to_jiffies(5);
......
......@@ -50,11 +50,6 @@ static struct usb_hcd *ehci_hcd_alloc (void)
return NULL;
}
static void ehci_hcd_free (struct usb_hcd *hcd)
{
kfree (hcd_to_ehci (hcd));
}
/*-------------------------------------------------------------------------*/
/* Allocate the key transfer structures from the previously allocated pool */
......
......@@ -307,6 +307,9 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
} else {
stopped = 1;
if (unlikely (!HCD_IS_RUNNING (ehci->hcd.state)))
urb->status = -ESHUTDOWN;
/* ignore active urbs unless some previous qtd
* for the urb faulted (including short read) or
* its urb was canceled. we may patch qh or qtds.
......
......@@ -1836,7 +1836,9 @@ scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs)
while (q.ptr != 0) {
unsigned uf;
union ehci_shadow temp;
int live;
live = HCD_IS_RUNNING (ehci->hcd.state);
switch (type) {
case Q_TYPE_QH:
/* handle any completions */
......@@ -1861,7 +1863,7 @@ scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs)
case Q_TYPE_ITD:
/* skip itds for later in the frame */
rmb ();
for (uf = uframes; uf < 8; uf++) {
for (uf = live ? uframes : 8; uf < 8; uf++) {
if (0 == (q.itd->hw_transaction [uf]
& ITD_ACTIVE))
continue;
......@@ -1885,7 +1887,8 @@ scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs)
q = *q_p;
break;
case Q_TYPE_SITD:
if (q.sitd->hw_results & SITD_ACTIVE) {
if ((q.sitd->hw_results & SITD_ACTIVE)
&& live) {
q_p = &q.sitd->sitd_next;
hw_p = &q.sitd->hw_next;
type = Q_NEXT_TYPE (q.sitd->hw_next);
......
......@@ -47,6 +47,13 @@ struct ehci_stats {
#define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */
struct ehci_hcd { /* one per controller */
/* glue to PCI and HCD framework */
struct usb_hcd hcd; /* must come first! */
struct ehci_caps __iomem *caps;
struct ehci_regs __iomem *regs;
__u32 hcs_params; /* cached register copy */
spinlock_t lock;
/* async schedule support */
......@@ -69,12 +76,6 @@ struct ehci_hcd { /* one per controller */
/* per root hub port */
unsigned long reset_done [EHCI_MAX_ROOT_PORTS];
/* glue to PCI and HCD framework */
struct usb_hcd hcd;
struct ehci_caps __iomem *caps;
struct ehci_regs __iomem *regs;
__u32 hcs_params; /* cached register copy */
/* per-HC memory pools (could be per-bus, but ...) */
struct dma_pool *qh_pool; /* qh per active urb */
struct dma_pool *qtd_pool; /* one or more per qh */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -146,6 +146,7 @@ int usb_hcd_lh7a404_probe (const struct hc_driver *driver,
usb_bus_init (&hcd->self);
hcd->self.op = &usb_hcd_operations;
hcd->self.release = &usb_hcd_release;
hcd->self.hcpriv = (void *) hcd;
hcd->self.bus_name = "lh7a404";
hcd->product_desc = "LH7A404 OHCI";
......@@ -165,9 +166,8 @@ int usb_hcd_lh7a404_probe (const struct hc_driver *driver,
err2:
hcd_buffer_destroy (hcd);
if (hcd)
driver->hcd_free(hcd);
err1:
kfree(hcd);
lh7a404_stop_hc(dev);
release_mem_region(dev->resource[0].start,
dev->resource[0].end
......@@ -191,8 +191,6 @@ int usb_hcd_lh7a404_probe (const struct hc_driver *driver,
*/
void usb_hcd_lh7a404_remove (struct usb_hcd *hcd, struct platform_device *dev)
{
void *base;
pr_debug ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
if (in_interrupt ())
......@@ -211,9 +209,6 @@ void usb_hcd_lh7a404_remove (struct usb_hcd *hcd, struct platform_device *dev)
usb_deregister_bus (&hcd->self);
base = hcd->regs;
hcd->driver->hcd_free (hcd);
lh7a404_stop_hc(dev);
release_mem_region(dev->resource[0].start,
dev->resource[0].end
......@@ -265,7 +260,6 @@ static const struct hc_driver ohci_lh7a404_hc_driver = {
* memory lifecycle (except per-request)
*/
.hcd_alloc = ohci_hcd_alloc,
.hcd_free = ohci_hcd_free,
/*
* managing i/o requests and associated device resources
......
......@@ -40,11 +40,6 @@ static struct usb_hcd *ohci_hcd_alloc (void)
return NULL;
}
static void ohci_hcd_free (struct usb_hcd *hcd)
{
kfree (hcd_to_ohci (hcd));
}
/*-------------------------------------------------------------------------*/
static int ohci_mem_init (struct ohci_hcd *ohci)
......@@ -104,7 +99,7 @@ td_alloc (struct ohci_hcd *hc, int mem_flags)
if (td) {
/* in case hc fetches it, make it look dead */
memset (td, 0, sizeof *td);
td->hwNextTD = cpu_to_le32 (dma);
td->hwNextTD = cpu_to_hc32 (hc, dma);
td->td_dma = dma;
/* hashed in td_fill */
}
......@@ -120,7 +115,7 @@ td_free (struct ohci_hcd *hc, struct td *td)
prev = &(*prev)->td_hash;
if (*prev)
*prev = td->td_hash;
else if ((td->hwINFO & TD_DONE) != 0)
else if ((td->hwINFO & cpu_to_hc32(hc, TD_DONE)) != 0)
ohci_dbg (hc, "no hash for td %p\n", td);
dma_pool_free (hc->td_cache, td, td->td_dma);
}
......
......@@ -42,21 +42,7 @@ extern int ocpi_enable(void);
static int omap_ohci_clock_power(int on)
{
if (on) {
if (cpu_is_omap1510()) {
/* Use DPLL, not APLL */
omap_writel(omap_readl(ULPD_APLL_CTRL) & ~APLL_NDPLL_SWITCH,
ULPD_APLL_CTRL);
/* Enable DPLL */
omap_writel(omap_readl(ULPD_DPLL_CTRL) | DPLL_PLL_ENABLE,
ULPD_DPLL_CTRL);
/* Software request for USB 48MHz clock */
omap_writel(omap_readl(ULPD_SOFT_REQ) | SOFT_REQ_REG_REQ,
ULPD_SOFT_REQ);
while (!(omap_readl(ULPD_DPLL_CTRL) & DPLL_LOCK));
}
/* for 1510, 48MHz DPLL is set up in usb init */
if (cpu_is_omap16xx()) {
/* Enable OHCI */
......@@ -98,14 +84,16 @@ static int omap_ohci_transceiver_power(int on)
{
if (on) {
if (machine_is_omap_innovator() && cpu_is_omap1510())
fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) | 0x20,
fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL)
| ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)),
INNOVATOR_FPGA_CAM_USB_CONTROL);
else if (machine_is_omap_osk()) {
/* FIXME: GPIO1 -> 1 on the TPS65010 I2C chip */
}
} else {
if (machine_is_omap_innovator() && cpu_is_omap1510())
fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) & ~0x20,
fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL)
& ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)),
INNOVATOR_FPGA_CAM_USB_CONTROL);
else if (machine_is_omap_osk()) {
/* FIXME: GPIO1 -> 0 on the TPS65010 I2C chip */
......@@ -322,7 +310,7 @@ int usb_hcd_omap_probe (const struct hc_driver *driver,
retval = omap_start_hc(ohci, pdev);
if (retval < 0)
goto err2;
goto err1;
retval = hcd_buffer_create (hcd);
if (retval != 0) {
......@@ -342,6 +330,7 @@ int usb_hcd_omap_probe (const struct hc_driver *driver,
usb_bus_init (&hcd->self);
hcd->self.op = &usb_hcd_operations;
hcd->self.release = &usb_hcd_release;
hcd->self.hcpriv = (void *) hcd;
hcd->self.bus_name = pdev->dev.bus_id;
hcd->product_desc = "OMAP OHCI";
......@@ -359,9 +348,8 @@ int usb_hcd_omap_probe (const struct hc_driver *driver,
err2:
hcd_buffer_destroy (hcd);
if (hcd)
driver->hcd_free(hcd);
err1:
kfree(hcd);
omap_stop_hc(pdev);
release_mem_region(pdev->resource[0].start,
......@@ -387,8 +375,6 @@ int usb_hcd_omap_probe (const struct hc_driver *driver,
*/
void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
{
void *base;
dev_info(&pdev->dev, "remove: state %x\n", hcd->state);
if (in_interrupt ())
......@@ -410,9 +396,6 @@ void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
usb_deregister_bus (&hcd->self);
base = hcd->regs;
hcd->driver->hcd_free (hcd);
omap_stop_hc(pdev);
release_mem_region(pdev->resource[0].start,
......@@ -464,7 +447,6 @@ static const struct hc_driver ohci_omap_hc_driver = {
* memory lifecycle (except per-request)
*/
.hcd_alloc = ohci_hcd_alloc,
.hcd_free = ohci_hcd_free,
/*
* managing i/o requests and associated device resources
......
......@@ -204,7 +204,6 @@ static const struct hc_driver ohci_pci_hc_driver = {
* memory lifecycle (except per-request)
*/
.hcd_alloc = ohci_hcd_alloc,
.hcd_free = ohci_hcd_free,
/*
* managing i/o requests and associated device resources
......
......@@ -244,6 +244,7 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
usb_bus_init (&hcd->self);
hcd->self.op = &usb_hcd_operations;
hcd->self.release = &usb_hcd_release;
hcd->self.hcpriv = (void *) hcd;
hcd->self.bus_name = "pxa27x";
hcd->product_desc = "PXA27x OHCI";
......@@ -262,9 +263,8 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
err2:
hcd_buffer_destroy (hcd);
if (hcd)
driver->hcd_free(hcd);
err1:
kfree(hcd);
pxa27x_stop_hc(dev);
release_mem_region(dev->resource[0].start,
dev->resource[0].end
......@@ -288,8 +288,6 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
*/
void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev)
{
void *base;
pr_debug ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
if (in_interrupt ())
......@@ -308,9 +306,6 @@ void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev)
usb_deregister_bus (&hcd->self);
base = hcd->regs;
hcd->driver->hcd_free (hcd);
pxa27x_stop_hc(dev);
release_mem_region(dev->resource[0].start,
dev->resource[0].end - dev->resource[0].start + 1);
......@@ -359,7 +354,6 @@ static const struct hc_driver ohci_pxa27x_hc_driver = {
* memory lifecycle (except per-request)
*/
.hcd_alloc = ohci_hcd_alloc,
.hcd_free = ohci_hcd_free,
/*
* managing i/o requests and associated device resources
......
This diff is collapsed.
......@@ -194,6 +194,7 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver,
usb_bus_init (&hcd->self);
hcd->self.op = &usb_hcd_operations;
hcd->self.release = &usb_hcd_release;
hcd->self.hcpriv = (void *) hcd;
hcd->self.bus_name = "sa1111";
hcd->product_desc = "SA-1111 OHCI";
......@@ -213,9 +214,8 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver,
err2:
hcd_buffer_destroy (hcd);
if (hcd)
driver->hcd_free(hcd);
err1:
kfree(hcd);
sa1111_stop_hc(dev);
release_mem_region(dev->res.start, dev->res.end - dev->res.start + 1);
return retval;
......@@ -237,8 +237,6 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver,
*/
void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev)
{
void *base;
info ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
if (in_interrupt ())
......@@ -257,9 +255,6 @@ void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev)
usb_deregister_bus (&hcd->self);
base = hcd->regs;
hcd->driver->hcd_free (hcd);
sa1111_stop_hc(dev);
release_mem_region(dev->res.start, dev->res.end - dev->res.start + 1);
}
......@@ -308,7 +303,6 @@ static const struct hc_driver ohci_sa1111_hc_driver = {
* memory lifecycle (except per-request)
*/
.hcd_alloc = ohci_hcd_alloc,
.hcd_free = ohci_hcd_free,
/*
* managing i/o requests and associated device resources
......
This diff is collapsed.
This diff is collapsed.
......@@ -324,7 +324,7 @@ enum uhci_state {
* a subset of what the full implementation needs.
*/
struct uhci_hcd {
struct usb_hcd hcd;
struct usb_hcd hcd; /* must come first! */
#ifdef CONFIG_PROC_FS
/* procfs */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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