From d4a3557e6254dab46e70e53306449fb14239f619 Mon Sep 17 00:00:00 2001 From: Patrick Mochel Date: Wed, 24 Jul 2002 22:50:30 -0700 Subject: fix memory leak when driverfs symlink fails. --- drivers/base/fs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/fs.c b/drivers/base/fs.c index 754d789f53e8..65225deedf7d 100644 --- a/drivers/base/fs.c +++ b/drivers/base/fs.c @@ -106,13 +106,17 @@ static void fill_devpath(struct device * dev, char * path, int length) static int create_symlink(struct driver_dir_entry * parent, char * name, char * path) { struct driver_file_entry * entry; + int error; entry = kmalloc(sizeof(struct driver_file_entry),GFP_KERNEL); if (!entry) return -ENOMEM; entry->name = name; entry->mode = S_IRUGO; - return driverfs_create_symlink(parent,entry,path); + error = driverfs_create_symlink(parent,entry,path); + if (error) + kfree(entry); + return error; } int device_bus_link(struct device * dev) -- cgit v1.2.3 From 53aef8ecb38cad764661022dec0974c45cb44776 Mon Sep 17 00:00:00 2001 From: Brad Hards Date: Wed, 24 Jul 2002 22:57:48 -0700 Subject: [PATCH] trivial USB Config.help cleanups --- drivers/usb/Config.help | 13 +++++++++---- drivers/usb/class/Config.help | 4 ++++ drivers/usb/host/Config.help | 3 ++- drivers/usb/input/Config.help | 12 ++++++++---- drivers/usb/misc/Config.help | 2 +- drivers/usb/storage/Config.help | 13 ++++++++++++- 6 files changed, 36 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/Config.help b/drivers/usb/Config.help index fa161a19725b..034627ab0e43 100644 --- a/drivers/usb/Config.help +++ b/drivers/usb/Config.help @@ -11,13 +11,18 @@ CONFIG_USB to the PC via those ports. Say Y here if your computer has a USB port and you want to use USB - devices. You then need to say Y to at least one of "UHCI support" - or "OHCI support" below (the type of interface that the USB hardware + devices. You then need to say Y to at least one of "UHCI HCD support" + or "OHCI HCD support" below (the type of interface that the USB hardware in your computer provides to the operating system) and then choose - from among the drivers for USB peripherals. You may want to check + from amongst the drivers for USB peripherals. You may want to check out the information provided in and especially the links given in . + If you have a new USB 2.0 High Speed system, you should also choose + "EHCI HCD (USB 2.0) support" as well as at least one of UHCI or OHCI. + + It doesn't normally hurt to select them all if you are not certain. + This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). The module will be called usbcore.o. If you want to compile it as a @@ -39,7 +44,7 @@ CONFIG_USB_LONG_TIMEOUT CONFIG_USB_DEVICEFS If you say Y here (and to "/proc file system support" in the "File - systems section, above), you will get a file /proc/bus/usb/devices + systems" section, above), you will get a file /proc/bus/usb/devices which lists the devices currently connected to your USB bus or busses, a file /proc/bus/usb/drivers which lists the USB kernel client drivers currently loaded, and for every connected device a diff --git a/drivers/usb/class/Config.help b/drivers/usb/class/Config.help index 8387ea4b8f77..d745878ca6f6 100644 --- a/drivers/usb/class/Config.help +++ b/drivers/usb/class/Config.help @@ -3,6 +3,10 @@ CONFIG_USB_ACM Communication Device Class Abstract Control Model interface. Please read for details. + If your modem only reports "Cls=ff(vend.)" in the descriptors in + /proc/bus/usb/devices, then your modem will not work with this + driver. + This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). The module will be called acm.o. If you want to compile it as a diff --git a/drivers/usb/host/Config.help b/drivers/usb/host/Config.help index 7cfd9ff8e5aa..e344fde05e8f 100644 --- a/drivers/usb/host/Config.help +++ b/drivers/usb/host/Config.help @@ -12,7 +12,8 @@ CONFIG_USB_EHCI_HCD will connect to EHCI if it the device is high speed, otherwise they connect to a companion controller. If you configure EHCI, you should probably configure the OHCI (for NEC and some other vendors) USB Host - Controller Driver too. + Controller Driver or UHCI (for Via motherboards) Host Controller + Driver too. You may want to read . diff --git a/drivers/usb/input/Config.help b/drivers/usb/input/Config.help index aad9102e43ae..8c3e13404876 100644 --- a/drivers/usb/input/Config.help +++ b/drivers/usb/input/Config.help @@ -18,13 +18,13 @@ CONFIG_USB_HID CONFIG_USB_HIDINPUT Say Y here if you want to use a USB keyboard, mouse or joystick, - or any other HID input device. You also need Input layer support, - (CONFIG_INPUT) which you select under "Input core support". + or any other HID input device. You also need "Input core support", + (CONFIG_INPUT), which you select under "Input device support", above. If unsure, say Y. CONFIG_HID_FF - Say Y here is you want force feedback support for a few hid devices. See + Say Y here is you want force feedback support for a few HID devices. See below for a list of supported devices. See Documentation/input/ff.txt for a description of the force feedback API. @@ -36,10 +36,14 @@ CONFIG_LOGITECH_RUMBLE still be supported, but without force feedback. CONFIG_HID_PID - Say Y yes if you have a PID-compliant joystick and wish to enable force + Say Y here if you have a PID-compliant joystick and wish to enable force feedback for it. The Microsoft Sidewinder Force Feedback 2 is one such device. +CONFIG_LOGITECH_3D + Say Y here if you have a Logitech force feedback device from the + *3D family. + CONFIG_USB_HIDDEV Say Y here if you want to support HID devices (from the USB specification standpoint) that aren't strictly user interface diff --git a/drivers/usb/misc/Config.help b/drivers/usb/misc/Config.help index 34bde6d406cd..6321df2998c1 100644 --- a/drivers/usb/misc/Config.help +++ b/drivers/usb/misc/Config.help @@ -7,7 +7,7 @@ CONFIG_USB_AUERSWALD The module will be called auerswald.o. If you want to compile it as a module, say M here and read . -CONFIG_USB_BRLVOYAGER +CONFIG_USB_BRLVGER Say Y here if you want to use the Voyager USB Braille display from Tieman. See for more information. diff --git a/drivers/usb/storage/Config.help b/drivers/usb/storage/Config.help index 4acef81f9879..81131aef0bce 100644 --- a/drivers/usb/storage/Config.help +++ b/drivers/usb/storage/Config.help @@ -1,6 +1,9 @@ CONFIG_USB_STORAGE Say Y here if you want to connect USB mass storage devices to your - computer's USB port. + computer's USB port. This is the driver you need for USB floppy drives, + USB hard disks, USB tape drives and USB CD-ROMs, along with + similar devices. This driver may also be used for some cameras and + card readers. This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -44,3 +47,11 @@ CONFIG_USB_STORAGE_SDDR09 CONFIG_USB_STORAGE_SDDR55 Say Y here to include additional code to support the Sandisk SDDR-55 SmartMedia reader in the USB Mass Storage driver. + +CONFIG_USB_STORAGE_HP8200e + Say Y here to include additional code to support Hewlett-Packard + 8200e/8210e/8230e CD-Writer Plus drives. + +CONFIG_USB_STORAGE_JUMPSHOT + Say Y here to include additional code to support the Lexar Jumpshot + USB CompactFlash reader. -- cgit v1.2.3 From 48a7ed7b3216186f328d4947126c1d841e4daade Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 24 Jul 2002 22:58:01 -0700 Subject: [PATCH] ehci-hcd more polite on cardbus This patch makes the EHCI driver behave reasonably well in the cardbus configurations I can test ... basically, it now sees when a card is gone, and cleans up accordingly. There are also some related cleanups: hardware handshakes will time out (not that I've ever seen them fail), and some state management puts a bit more effort into being strictly to-spec. --- drivers/usb/host/ehci-hcd.c | 128 +++++++++++++++++++++++++++++++++--------- drivers/usb/host/ehci-q.c | 8 +-- drivers/usb/host/ehci-sched.c | 43 +++++++++----- 3 files changed, 133 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 74496b06a130..dcb10d5dc2cd 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -65,6 +65,8 @@ * * HISTORY: * + * 2002-07-25 Sanity check PCI reads, mostly for better cardbus support, + * clean up HC run state handshaking. * 2002-05-24 Preliminary FS/LS interrupts, using scheduling shortcuts * 2002-05-11 Clear TT errors for FS/LS ctrl/bulk. Fill in some other * missing pieces: enabling 64bit dma, handoff from BIOS/SMM. @@ -83,7 +85,7 @@ * 2001-June Works with usb-storage and NEC EHCI on 2.4 */ -#define DRIVER_VERSION "2002-May-24" +#define DRIVER_VERSION "2002-Jul-25" #define DRIVER_AUTHOR "David Brownell" #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver" @@ -112,6 +114,40 @@ MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes"); /*-------------------------------------------------------------------------*/ +/* + * handshake - spin reading hc until handshake completes or fails + * @ptr: address of hc register to be read + * @mask: bits to look at in result of read + * @done: value of those bits when handshake succeeds + * @usec: timeout in microseconds + * + * Returns negative errno, or zero on success + * + * Success happens when the "mask" bits have the specified value (hardware + * handshake done). There are two failure modes: "usec" have passed (major + * hardware flakeout), or the register reads as all-ones (hardware removed). + * + * That last failure should_only happen in cases like physical cardbus eject + * before driver shutdown. But it also seems to be caused by bugs in cardbus + * bridge shutdown: shutting down the bridge before the devices using it. + */ +static int handshake (u32 *ptr, u32 mask, u32 done, int usec) +{ + u32 result; + + do { + result = readl (ptr); + if (result == ~(u32)0) /* card removed */ + return -ENODEV; + result &= mask; + if (result == done) + return 0; + udelay (1); + usec--; + } while (usec > 0); + return -ETIMEDOUT; +} + /* * hc states include: unknown, halted, ready, running * transitional states are messy just now @@ -119,36 +155,65 @@ MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes"); * a "ready" hc can be finishing prefetched work */ -/* halt a non-running controller */ -static void ehci_reset (struct ehci_hcd *ehci) +/* force HC to halt state from unknown (EHCI spec section 2.3) */ +static int ehci_halt (struct ehci_hcd *ehci) +{ + u32 temp = readl (&ehci->regs->status); + + if ((temp & STS_HALT) != 0) + return 0; + + temp = readl (&ehci->regs->command); + temp &= ~CMD_RUN; + writel (temp, &ehci->regs->command); + return handshake (&ehci->regs->status, STS_HALT, STS_HALT, 16 * 125); +} + +/* reset a non-running (STS_HALT == 1) controller */ +static int ehci_reset (struct ehci_hcd *ehci) { u32 command = readl (&ehci->regs->command); command |= CMD_RESET; dbg_cmd (ehci, "reset", command); writel (command, &ehci->regs->command); - while (readl (&ehci->regs->command) & CMD_RESET) - continue; ehci->hcd.state = USB_STATE_HALT; + return handshake (&ehci->regs->command, CMD_RESET, 0, 050); } /* idle the controller (from running) */ static void ehci_ready (struct ehci_hcd *ehci) { - u32 command; + u32 temp; #ifdef DEBUG if (!HCD_IS_RUNNING (ehci->hcd.state)) BUG (); #endif - while (!(readl (&ehci->regs->status) & (STS_ASS | STS_PSS))) - udelay (100); - command = readl (&ehci->regs->command); - command &= ~(CMD_ASE | CMD_IAAD | CMD_PSE); - writel (command, &ehci->regs->command); + /* wait for any schedule enables/disables to take effect */ + temp = 0; + if (ehci->async) + temp = STS_ASS; + if (ehci->next_uframe != -1) + temp |= STS_PSS; + if (handshake (&ehci->regs->status, STS_ASS | STS_PSS, + temp, 16 * 125) != 0) { + ehci->hcd.state = USB_STATE_HALT; + return; + } - // hardware can take 16 microframes to turn off ... + /* then disable anything that's still active */ + temp = readl (&ehci->regs->command); + temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE); + writel (temp, &ehci->regs->command); + + /* hardware can take 16 microframes to turn off ... */ + if (handshake (&ehci->regs->status, STS_ASS | STS_PSS, + 0, 16 * 125) != 0) { + ehci->hcd.state = USB_STATE_HALT; + return; + } ehci->hcd.state = USB_STATE_READY; } @@ -236,6 +301,10 @@ static int ehci_start (struct usb_hcd *hcd) /* cache this readonly data; minimize PCI reads */ ehci->hcs_params = readl (&ehci->caps->hcs_params); + /* force HC to halt state */ + if ((retval = ehci_halt (ehci)) != 0) + return retval; + /* * hw default: 1K periodic list heads, one per frame. * periodic_size can shrink by USBCMD update if hcc_params allows. @@ -257,8 +326,10 @@ static int ehci_start (struct usb_hcd *hcd) /* controller state: unknown --> reset */ /* EHCI spec section 4.1 */ - // FIXME require STS_HALT before reset... - ehci_reset (ehci); + if ((retval = ehci_reset (ehci)) != 0) { + ehci_mem_cleanup (ehci); + return retval; + } writel (INTR_MASK, &ehci->regs->intr_enable); writel (ehci->periodic_dma, &ehci->regs->frame_list); @@ -335,8 +406,6 @@ done2: if (usb_register_root_hub (udev, &ehci->hcd.pdev->dev) != 0) { if (hcd->state == USB_STATE_RUNNING) ehci_ready (ehci); - while (readl (&ehci->regs->status) & (STS_ASS | STS_PSS)) - udelay (100); ehci_reset (ehci); hcd->self.root_hub = 0; usb_free_dev (udev); @@ -355,16 +424,14 @@ static void ehci_stop (struct usb_hcd *hcd) dbg ("%s: stop", hcd->self.bus_name); + /* no more interrupts ... */ if (hcd->state == USB_STATE_RUNNING) ehci_ready (ehci); - while (readl (&ehci->regs->status) & (STS_ASS | STS_PSS)) - udelay (100); ehci_reset (ehci); - // root hub is shut down separately (first, when possible) - scan_async (ehci); - if (ehci->next_uframe != -1) - scan_periodic (ehci); + /* root hub is shut down separately (first, when possible) */ + tasklet_disable (&ehci->tasklet); + ehci_tasklet ((unsigned long) ehci); ehci_mem_cleanup (ehci); dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); @@ -412,8 +479,6 @@ dbg ("%s: suspend port %d", hcd->self.bus_name, i); if (hcd->state == USB_STATE_RUNNING) ehci_ready (ehci); - while (readl (&ehci->regs->status) & (STS_ASS | STS_PSS)) - udelay (100); writel (readl (&ehci->regs->command) & ~CMD_RUN, &ehci->regs->command); // save pci FLADJ value @@ -489,6 +554,12 @@ static void ehci_irq (struct usb_hcd *hcd) u32 status = readl (&ehci->regs->status); int bh; + /* e.g. cardbus physical eject */ + if (status == ~(u32) 0) { + dbg ("%s: device removed!", hcd->self.bus_name); + goto dead; + } + status &= INTR_MASK; if (!status) /* irq sharing? */ return; @@ -517,10 +588,13 @@ static void ehci_irq (struct usb_hcd *hcd) /* PCI errors [4.15.2.4] */ if (unlikely ((status & STS_FATAL) != 0)) { - err ("%s: fatal error, state %x", hcd->self.bus_name, hcd->state); + err ("%s: fatal error, state %x", + hcd->self.bus_name, hcd->state); +dead: ehci_reset (ehci); - // generic layer kills/unlinks all urbs - // then tasklet cleans up the rest + /* generic layer kills/unlinks all urbs, then + * uses ehci_stop to clean up the rest + */ bh = 1; } diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 53062380a93f..3057d75b0fed 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -718,8 +718,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) u32 cmd = readl (&ehci->regs->command); /* in case a clear of CMD_ASE didn't take yet */ - while (readl (&ehci->regs->status) & STS_ASS) - udelay (100); + (void) handshake (&ehci->regs->status, STS_ASS, 0, 150); qh->hw_info1 |= __constant_cpu_to_le32 (QH_HEAD); /* [4.8] */ qh->qh_next.qh = qh; @@ -917,11 +916,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) if (ehci->hcd.state != USB_STATE_HALT) { if (cmd & CMD_PSE) writel (cmd & ~CMD_ASE, &ehci->regs->command); - else { + else ehci_ready (ehci); - while (readl (&ehci->regs->status) & STS_ASS) - udelay (100); - } } qh->qh_next.qh = ehci->async = 0; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index a2f25cd4d598..5e08204d34d9 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -171,15 +171,19 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe) /*-------------------------------------------------------------------------*/ -static void enable_periodic (struct ehci_hcd *ehci) +static int enable_periodic (struct ehci_hcd *ehci) { u32 cmd; + int status; /* did clearing PSE did take effect yet? * takes effect only at frame boundaries... */ - while (readl (&ehci->regs->status) & STS_PSS) - udelay (20); + status = handshake (&ehci->regs->status, STS_PSS, 0, 9 * 125); + if (status != 0) { + ehci->hcd.state = USB_STATE_HALT; + return status; + } cmd = readl (&ehci->regs->command) | CMD_PSE; writel (cmd, &ehci->regs->command); @@ -189,23 +193,29 @@ static void enable_periodic (struct ehci_hcd *ehci) /* make sure tasklet scans these */ ehci->next_uframe = readl (&ehci->regs->frame_index) % (ehci->periodic_size << 3); + return 0; } -static void disable_periodic (struct ehci_hcd *ehci) +static int disable_periodic (struct ehci_hcd *ehci) { u32 cmd; + int status; /* did setting PSE not take effect yet? * takes effect only at frame boundaries... */ - while (!(readl (&ehci->regs->status) & STS_PSS)) - udelay (20); + status = handshake (&ehci->regs->status, STS_PSS, STS_PSS, 9 * 125); + if (status != 0) { + ehci->hcd.state = USB_STATE_HALT; + return status; + } cmd = readl (&ehci->regs->command) & ~CMD_PSE; writel (cmd, &ehci->regs->command); /* posted write ... */ ehci->next_uframe = -1; + return 0; } /*-------------------------------------------------------------------------*/ @@ -217,6 +227,7 @@ static void intr_deschedule ( unsigned period ) { unsigned long flags; + int status; period >>= 3; // FIXME microframe periods not handled yet @@ -234,9 +245,11 @@ static void intr_deschedule ( /* maybe turn off periodic schedule */ if (!ehci->periodic_urbs) - disable_periodic (ehci); - else + status = disable_periodic (ehci); + else { + status = 0; vdbg ("periodic schedule still enabled"); + } spin_unlock_irqrestore (&ehci->lock, flags); @@ -245,7 +258,7 @@ static void intr_deschedule ( * (yeech!) to be sure it's done. * No other threads may be mucking with this qh. */ - if (((ehci_get_frame (&ehci->hcd) - frame) % period) == 0) + if (!status && ((ehci_get_frame (&ehci->hcd) - frame) % period) == 0) udelay (125); qh->qh_state = QH_STATE_IDLE; @@ -501,7 +514,7 @@ static int intr_submit ( /* maybe enable periodic schedule processing */ if (!ehci->periodic_urbs++) - enable_periodic (ehci); + status = enable_periodic (ehci); break; } while (frame); @@ -913,8 +926,12 @@ itd_schedule (struct ehci_hcd *ehci, struct urb *urb) usb_claim_bandwidth (urb->dev, urb, usecs, 1); /* maybe enable periodic schedule processing */ - if (!ehci->periodic_urbs++) - enable_periodic (ehci); + if (!ehci->periodic_urbs++) { + if ((status = enable_periodic (ehci)) != 0) { + // FIXME deschedule right away + err ("itd_schedule, enable = %d", status); + } + } return 0; @@ -994,7 +1011,7 @@ itd_complete ( /* defer stopping schedule; completion can submit */ ehci->periodic_urbs--; if (!ehci->periodic_urbs) - disable_periodic (ehci); + (void) disable_periodic (ehci); return flags; } -- cgit v1.2.3 From 4ff8e9346f2ffb0697b064964ce4edfb478455c2 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 24 Jul 2002 22:58:17 -0700 Subject: [PATCH] ohci unlink cleanups Attached is a patch that cleans up a few more issues in the OHCI unlink code. There may still be an ISO-IN data problem, I'll look at that separately since it seems unrelated to unlink issues. - Simplify/correct ED lifecycle * UNLINK is now for real: descheduled and waiting for SOF * finish_unlinks() expects descheduled EDs (may reschedule) * only ed_deschedule() turns off hardware schedule processing * no more NEW state * no more ED_URB_DEL flag (it added extra states) * new IDLE state, "not scheduled" (replaces previous UNLINKing) - Bugfixes * ed_get(), potential memleak is now gone * urb_enqueue(), won't submit to dead/sleeping hc * free_config(), rescans after SOF when needed * ed_schedule(), use wmb() * ed_schedule() and finish_unlinks(), more thorough about restarting control or bulk processing * finish_unlinks(), more cautious about reentering - General: * ed->ed_rm_list renamed ed_next; to be used more later * slightly shrink object code * rename some functions This leaves one notable issue in the unlink paths: the driver never waits for SOF after descheduling (empty) EDs. That's racey in most cases, though there are a few light-traffic cases where that's correct (in part because the ED is empty). Easy to fix once the rest of this is known to behave. --- drivers/usb/host/ohci-hcd.c | 108 ++++++++++++++------ drivers/usb/host/ohci-q.c | 242 +++++++++++++++++++++----------------------- drivers/usb/host/ohci.h | 19 ++-- 3 files changed, 203 insertions(+), 166 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 2ee09b0a3bcd..8d6010c1fdba 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -10,8 +10,15 @@ * [ (C) Copyright 1999 Gregory P. Smith] * * + * OHCI is the main "non-Intel/VIA" standard for USB 1.1 host controller + * interfaces (though some non-x86 Intel chips use it). It supports + * smarter hardware than UHCI. A download link for the spec available + * through the http://www.usb.org website. + * * History: * + * 2002/07/19 fixes to management of ED and schedule state. + * 2002/06/09 SA-1111 support (Christopher Hoover) * 2002/06/01 remember frame when HC won't see EDs any more; use that info * to fix urb unlink races caused by interrupt latency assumptions; * minor ED field and function naming updates @@ -95,12 +102,12 @@ /* * TO DO: * - * - "disabled" should be the hcd state + * - "disabled" and "sleeping" should be in hcd->state * - bandwidth alloc to generic code * - lots more testing!! */ -#define DRIVER_VERSION "2002-Jun-15" +#define DRIVER_VERSION "2002-Jul-19" #define DRIVER_AUTHOR "Roman Weissgaerber , David Brownell" #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver" @@ -140,6 +147,7 @@ static int ohci_urb_enqueue ( int i, size = 0; unsigned long flags; int bustime = 0; + int retval = 0; #ifdef OHCI_VERBOSE_DEBUG urb_print (urb, "SUB", usb_pipein (pipe)); @@ -191,19 +199,25 @@ static int ohci_urb_enqueue ( return -ENOMEM; memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *)); + spin_lock_irqsave (&ohci->lock, flags); + + /* don't submit to a dead HC */ + if (ohci->disabled || ohci->sleeping) { + retval = -ENODEV; + goto fail; + } + /* fill the private part of the URB */ urb_priv->length = size; urb_priv->ed = ed; /* allocate the TDs (updating hash chains) */ - spin_lock_irqsave (&ohci->lock, flags); for (i = 0; i < size; i++) { urb_priv->td [i] = td_alloc (ohci, SLAB_ATOMIC); if (!urb_priv->td [i]) { urb_priv->length = i; - urb_free_priv (ohci, urb_priv); - spin_unlock_irqrestore (&ohci->lock, flags); - return -ENOMEM; + retval = -ENOMEM; + goto fail; } } @@ -217,11 +231,11 @@ static int ohci_urb_enqueue ( switch (usb_pipetype (pipe)) { case PIPE_ISOCHRONOUS: if (urb->transfer_flags & USB_ISO_ASAP) { - urb->start_frame = ( (ed->state == ED_OPER) + urb->start_frame = ((ed->state != ED_IDLE) ? (ed->intriso.last_iso + 1) : (le16_to_cpu (ohci->hcca->frame_no) + 10)) & 0xffff; - } + } /* FALLTHROUGH */ case PIPE_INTERRUPT: if (urb->bandwidth == 0) { @@ -238,18 +252,20 @@ static int ohci_urb_enqueue ( urb->hcpriv = urb_priv; - /* link the ed into a chain if is not already */ - if (ed->state != ED_OPER) - ep_link (ohci, ed); + /* schedule the ed if needed */ + if (ed->state == ED_IDLE) + ed_schedule (ohci, ed); /* fill the TDs and link them to the ed; and * enable that part of the schedule, if needed */ td_submit_urb (urb); +fail: + if (retval) + urb_free_priv (ohci, urb_priv); spin_unlock_irqrestore (&ohci->lock, flags); - - return 0; + return retval; } /* @@ -270,19 +286,17 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) if (!ohci->disabled) { urb_priv_t *urb_priv; - /* flag the urb's data for deletion in some upcoming - * SF interrupt's delete list processing + /* Unless an IRQ completed the unlink while it was being + * handed to us, flag it for unlink and giveback, and force + * some upcoming INTR_SF to call finish_unlinks() */ spin_lock_irqsave (&ohci->lock, flags); urb_priv = urb->hcpriv; - - if (!urb_priv || (urb_priv->state == URB_DEL)) { - spin_unlock_irqrestore (&ohci->lock, flags); - return 0; + if (urb_priv) { + urb_priv->state = URB_DEL; + if (urb_priv->ed->state == ED_OPER) + start_urb_unlink (ohci, urb_priv->ed); } - - urb_priv->state = URB_DEL; - start_urb_unlink (ohci, urb_priv->ed); spin_unlock_irqrestore (&ohci->lock, flags); } else { /* @@ -290,12 +304,16 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) * any more ... just clean up every urb's memory. */ finish_urb (ohci, urb); - } + } return 0; } /*-------------------------------------------------------------------------*/ +/* frees config/altsetting state for endpoints, + * including ED memory, dummy TD, and bulk/intr data toggle + */ + static void ohci_free_config (struct usb_hcd *hcd, struct usb_device *udev) { @@ -303,7 +321,11 @@ ohci_free_config (struct usb_hcd *hcd, struct usb_device *udev) struct hcd_dev *dev = (struct hcd_dev *) udev->hcpriv; int i; unsigned long flags; +#ifdef DEBUG + int rescans = 0; +#endif +rescan: /* free any eds, and dummy tds, still hanging around */ spin_lock_irqsave (&ohci->lock, flags); for (i = 0; i < 32; i++) { @@ -312,27 +334,47 @@ ohci_free_config (struct usb_hcd *hcd, struct usb_device *udev) if (!ed) continue; - ed->state &= ~ED_URB_DEL; - if (ohci->disabled && ed->state == ED_OPER) - ed->state = ED_UNLINK; + if (ohci->disabled && ed->state != ED_IDLE) + ed->state = ED_IDLE; switch (ed->state) { - case ED_NEW: - break; - case ED_UNLINK: + case ED_UNLINK: /* wait a frame? */ + goto do_rescan; + case ED_IDLE: /* fully unlinked */ td_free (ohci, ed->dummy); break; - - case ED_OPER: default: +#ifdef DEBUG err ("illegal ED %d state in free_config, %d", i, ed->state); -#ifdef DEBUG - BUG (); #endif + /* ED_OPER: some driver disconnect() is broken, + * it didn't even start its unlinks much less wait + * for their completions. + * OTHERWISE: hcd bug, ed is garbage + */ + BUG (); } ed_free (ohci, ed); } spin_unlock_irqrestore (&ohci->lock, flags); + return; + +do_rescan: +#ifdef DEBUG + /* a driver->disconnect() returned before its unlinks completed? */ + if (in_interrupt ()) { + dbg ("WARNING: spin in interrupt; driver->disconnect() bug"); + dbg ("dev usb-%s-%s ep 0x%x", + ohci->hcd.self.bus_name, udev->devpath, i); + } + BUG_ON (!(readl (&ohci->regs->intrenable) & OHCI_INTR_SF)); + BUG_ON (rescans >= 2); /* HWBUG */ + rescans++; +#endif + + spin_unlock_irqrestore (&ohci->lock, flags); + wait_ms (1); + goto rescan; } static int ohci_get_frame (struct usb_hcd *hcd) diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 1d3de55b90b9..b04fc02bd375 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -170,50 +170,50 @@ static int ep_rev (int num_bits, int word) /* link an ed into one of the HC chains */ -static int ep_link (struct ohci_hcd *ohci, struct ed *edi) +static void ed_schedule (struct ohci_hcd *ohci, struct ed *ed) { int int_branch, i; int inter, interval, load; __u32 *ed_p; - volatile struct ed *ed = edi; ed->state = ED_OPER; + ed->hwNextED = 0; + wmb (); + + /* we care about rm_list when setting CLE/BLE in case the HC was at + * work on some TD when CLE/BLE was turned off, and isn't quiesced + * yet. finish_unlinks() restarts as needed, some upcoming INTR_SF. + */ switch (ed->type) { case PIPE_CONTROL: - ed->hwNextED = 0; if (ohci->ed_controltail == NULL) { writel (ed->dma, &ohci->regs->ed_controlhead); } else { ohci->ed_controltail->hwNextED = cpu_to_le32 (ed->dma); } ed->ed_prev = ohci->ed_controltail; - if (!ohci->ed_controltail - && !ohci->ed_rm_list - && !ohci->sleeping - ) { + if (!ohci->ed_controltail && !ohci->ed_rm_list) { ohci->hc_control |= OHCI_CTRL_CLE; + writel (0, &ohci->regs->ed_controlcurrent); writel (ohci->hc_control, &ohci->regs->control); } - ohci->ed_controltail = edi; + ohci->ed_controltail = ed; break; case PIPE_BULK: - ed->hwNextED = 0; if (ohci->ed_bulktail == NULL) { writel (ed->dma, &ohci->regs->ed_bulkhead); } else { ohci->ed_bulktail->hwNextED = cpu_to_le32 (ed->dma); } ed->ed_prev = ohci->ed_bulktail; - if (!ohci->ed_bulktail - && !ohci->ed_rm_list - && !ohci->sleeping - ) { + if (!ohci->ed_bulktail && !ohci->ed_rm_list) { ohci->hc_control |= OHCI_CTRL_BLE; + writel (0, &ohci->regs->ed_bulkcurrent); writel (ohci->hc_control, &ohci->regs->control); } - ohci->ed_bulktail = edi; + ohci->ed_bulktail = ed; break; case PIPE_INTERRUPT: @@ -231,17 +231,16 @@ static int ep_link (struct ohci_hcd *ohci, struct ed *edi) ed->hwNextED = *ed_p; *ed_p = cpu_to_le32 (ed->dma); } + wmb (); #ifdef OHCI_VERBOSE_DEBUG ohci_dump_periodic (ohci, "LINK_INT"); #endif break; case PIPE_ISOCHRONOUS: - ed->hwNextED = 0; - ed->interval = 1; + ed->ed_prev = ohci->ed_isotail; if (ohci->ed_isotail != NULL) { ohci->ed_isotail->hwNextED = cpu_to_le32 (ed->dma); - ed->ed_prev = ohci->ed_isotail; } else { for ( i = 0; i < NUM_INTS; i += inter) { inter = 1; @@ -251,15 +250,18 @@ static int ep_link (struct ohci_hcd *ohci, struct ed *edi) inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->interval); *ed_p = cpu_to_le32 (ed->dma); } - ed->ed_prev = NULL; } - ohci->ed_isotail = edi; + wmb (); + ohci->ed_isotail = ed; #ifdef OHCI_VERBOSE_DEBUG ohci_dump_periodic (ohci, "LINK_ISO"); #endif break; } - return 0; + + /* the HC may not see the schedule updates yet, but if it does + * then they'll be properly ordered. + */ } /*-------------------------------------------------------------------------*/ @@ -288,9 +290,8 @@ static void periodic_unlink ( * just the link to the ed is unlinked. * the link from the ed still points to another operational ed or 0 * so the HC can eventually finish the processing of the unlinked ed - * caller guarantees the ED has no active TDs. */ -static int start_ed_unlink (struct ohci_hcd *ohci, struct ed *ed) +static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed) { int i; @@ -361,15 +362,14 @@ static int start_ed_unlink (struct ohci_hcd *ohci, struct ed *ed) break; } - /* FIXME ED's "unlink" state is indeterminate; - * the HC might still be caching it (till SOF). - * - use ed_rm_list and finish_unlinks(), adding some state that - * prevents clobbering hw linkage before the appropriate SOF - * - a speedup: when only one urb is queued on the ed, save 1msec - * by making start_urb_unlink() use this routine to deschedule. + /* FIXME Except for a couple of exceptionally clean unlink cases + * (like unlinking the only c/b ED, with no TDs) HCs may still be + * caching this (till SOF). + * + * To avoid racing with the hardware, this needs to use ED_UNLINK + * and delay til next INTR_SF. Merge with start_urb_unlink(). */ - ed->state = ED_UNLINK; - return 0; + ed->state = ED_IDLE; } @@ -403,35 +403,27 @@ static struct ed *ed_get ( spin_lock_irqsave (&ohci->lock, flags); if (!(ed = dev->ep [ep])) { + struct td *td; + ed = ed_alloc (ohci, SLAB_ATOMIC); if (!ed) { /* out of memory */ goto done; } dev->ep [ep] = ed; - } - - if (ed->state & ED_URB_DEL) { - /* pending unlink request */ - ed = 0; - goto done; - } - - if (ed->state == ED_NEW) { - struct td *td; - ed->hwINFO = ED_SKIP; /* dummy td; end of td list for ed */ td = td_alloc (ohci, SLAB_ATOMIC); if (!td) { /* out of memory */ + ed_free (ohci, ed); ed = 0; goto done; } ed->dummy = td; ed->hwTailP = cpu_to_le32 (td->td_dma); ed->hwHeadP = ed->hwTailP; /* ED_C, ED_H zeroed */ - ed->state = ED_UNLINK; + ed->state = ED_IDLE; ed->type = type; } @@ -439,7 +431,7 @@ static struct ed *ed_get ( * state/mode info. Currently the upper layers don't support such * guarantees; we're lucky changing config/altsetting is rare. */ - if (ed->state == ED_UNLINK) { + if (ed->state == ED_IDLE) { u32 info; info = usb_pipedevice (pipe); @@ -494,30 +486,13 @@ done: /*-------------------------------------------------------------------------*/ /* request unlinking of an endpoint from an operational HC. - * put the ep on the rm_list and stop the bulk or ctrl list + * put the ep on the rm_list * real work is done at the next start frame (SF) hardware interrupt */ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed) { - /* already pending? */ - if (ed->state & ED_URB_DEL) - return; - ed->state |= ED_URB_DEL; - - ed->hwINFO |= ED_SKIP; - - switch (ed->type) { - case PIPE_CONTROL: /* stop control list */ - ohci->hc_control &= ~OHCI_CTRL_CLE; - writel (ohci->hc_control, - &ohci->regs->control); - break; - case PIPE_BULK: /* stop bulk list */ - ohci->hc_control &= ~OHCI_CTRL_BLE; - writel (ohci->hc_control, - &ohci->regs->control); - break; - } + ed_deschedule (ohci, ed); + ed->state = ED_UNLINK; /* SF interrupt might get delayed; record the frame counter value that * indicates when the HC isn't looking at it, so concurrent unlinks @@ -526,7 +501,7 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed) */ ed->tick = le16_to_cpu (ohci->hcca->frame_no) + 1; - ed->ed_rm_list = ohci->ed_rm_list; + ed->ed_next = ohci->ed_rm_list; ohci->ed_rm_list = ed; /* enable SOF interrupt */ @@ -744,13 +719,15 @@ static void td_done (struct urb *urb, struct td *td) u32 tdINFO = le32_to_cpup (&td->hwINFO); int cc = 0; - /* ISO ... drivers see per-TD length/status */ if (tdINFO & TD_ISO) { u16 tdPSW = le16_to_cpu (td->hwPSW [0]); int dlen = 0; cc = (tdPSW >> 12) & 0xF; + if (cc >= 0x0E) /* hc didn't touch? */ + return; + if (usb_pipeout (urb->pipe)) dlen = urb->iso_frame_desc [td->index].length; else @@ -759,9 +736,11 @@ static void td_done (struct urb *urb, struct td *td) urb->iso_frame_desc [td->index].actual_length = dlen; urb->iso_frame_desc [td->index].status = cc_to_error [cc]; - if (cc != 0) +#ifdef VERBOSE_DEBUG + if (cc != TD_CC_NOERROR) dbg (" urb %p iso TD %p (%d) len %d CC %d", urb, td, 1 + td->index, dlen, cc); +#endif /* BULK, INT, CONTROL ... drivers see aggregate length/status, * except that "setup" bytes aren't counted and "short" transfers @@ -783,7 +762,7 @@ static void td_done (struct urb *urb, struct td *td) if (cc == TD_DATAUNDERRUN && !(urb->transfer_flags & URB_SHORT_NOT_OK)) cc = TD_CC_NOERROR; - if (cc != TD_CC_NOERROR) { + if (cc != TD_CC_NOERROR && cc < 0x0E) { spin_lock (&urb->lock); if (urb->status == -EINPROGRESS) urb->status = cc_to_error [cc]; @@ -801,7 +780,7 @@ static void td_done (struct urb *urb, struct td *td) } #ifdef VERBOSE_DEBUG - if (cc != 0) + if (cc != TD_CC_NOERROR && cc < 0x0E) dbg (" urb %p TD %p (%d) CC %d, len=%d/%d", urb, td, 1 + td->index, cc, urb->actual_length, @@ -876,28 +855,39 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) static void finish_unlinks (struct ohci_hcd *ohci, u16 tick) { struct ed *ed, **last; - int ctrl = 0, bulk = 0; +rescan_all: for (last = &ohci->ed_rm_list, ed = *last; ed != NULL; ed = *last) { struct td *td, *td_next, *tdHeadP, *tdTailP; u32 *td_p; - int unlinked; + int completed, modified; /* only take off EDs that the HC isn't using, accounting for - * frame counter wraps. completion callbacks might prepend - * EDs to the list, they'll be checked next irq. + * frame counter wraps. */ - if (tick_before (tick, ed->tick)) { - last = &ed->ed_rm_list; + if (tick_before (tick, ed->tick) && !ohci->disabled) { + last = &ed->ed_next; continue; } - *last = ed->ed_rm_list; - ed->ed_rm_list = 0; - unlinked = 0; - /* unlink urbs from first one requested to queue end; - * leave earlier urbs alone + /* reentrancy: if we drop the schedule lock, someone might + * have modified this list. normally it's just prepending + * entries (which we'd ignore), but paranoia won't hurt. */ + *last = ed->ed_next; + ed->ed_next = 0; + modified = 0; + + /* unlink urbs as requested, but rescan the list after + * we call a completion since it might have unlinked + * another (earlier) urb + * + * FIXME use td_list to scan, not ed hashtables. + * completely abolish ed hashtables! + */ +rescan_this: + completed = 0; + tdTailP = dma_to_td (ohci, le32_to_cpup (&ed->hwTailP)); tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP)); td_p = &ed->hwHeadP; @@ -908,21 +898,18 @@ static void finish_unlinks (struct ohci_hcd *ohci, u16 tick) td_next = dma_to_td (ohci, le32_to_cpup (&td->hwNextTD)); - if (unlinked || (urb_priv->state == URB_DEL)) { - u32 tdINFO = le32_to_cpup (&td->hwINFO); - - unlinked = 1; + if (urb_priv->state == URB_DEL) { /* HC may have partly processed this TD */ - if (TD_CC_GET (tdINFO) < 0xE) - td_done (urb, td); + td_done (urb, td); + urb_priv->td_cnt++; + *td_p = td->hwNextTD | (*td_p & __constant_cpu_to_le32 (0x3)); /* URB is done; clean up */ - if (++ (urb_priv->td_cnt) == urb_priv->length) { - if (urb->status == -EINPROGRESS) - urb->status = -ECONNRESET; + if (urb_priv->td_cnt == urb_priv->length) { + modified = completed = 1; spin_unlock (&ohci->lock); finish_urb (ohci, urb); spin_lock (&ohci->lock); @@ -932,49 +919,52 @@ static void finish_unlinks (struct ohci_hcd *ohci, u16 tick) } } - /* FIXME actually want four cases here: - * (a) finishing URB unlink - * [a1] no URBs queued, so start ED unlink - * [a2] some (earlier) URBs still linked, re-enable - * (b) finishing ED unlink - * [b1] no URBs queued, ED is truly idle now - * ... we could set state ED_NEW and free dummy - * [b2] URBs now queued, link ED back into schedule - * right now we only have (a) - */ - ed->state &= ~ED_URB_DEL; - tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP)); - - if (tdHeadP == tdTailP) { - if (ed->state == ED_OPER) - start_ed_unlink (ohci, ed); - } else - ed->hwINFO &= ~ED_SKIP; + /* ED's now officially unlinked, hc doesn't see */ + ed->state = ED_IDLE; + ed->hwINFO &= ~ED_SKIP; + ed->hwHeadP &= ~cpu_to_le32 (ED_H); + ed->hwNextED = 0; - switch (ed->type) { - case PIPE_CONTROL: - ctrl = 1; - break; - case PIPE_BULK: - bulk = 1; - break; + /* but if there's work queued, reschedule */ + tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP)); + if (tdHeadP != tdTailP) { + if (completed) + goto rescan_this; + if (!ohci->disabled && !ohci->sleeping) + ed_schedule (ohci, ed); } + + if (modified) + goto rescan_all; } /* maybe reenable control and bulk lists */ - if (!ohci->disabled) { - if (ctrl) /* reset control list */ - writel (0, &ohci->regs->ed_controlcurrent); - if (bulk) /* reset bulk list */ - writel (0, &ohci->regs->ed_bulkcurrent); - if (!ohci->ed_rm_list) { - if (ohci->ed_controltail) - ohci->hc_control |= OHCI_CTRL_CLE; - if (ohci->ed_bulktail) - ohci->hc_control |= OHCI_CTRL_BLE; - writel (ohci->hc_control, &ohci->regs->control); + if (!ohci->disabled && !ohci->ed_rm_list) { + u32 command = 0, control = 0; + + if (ohci->ed_controltail) { + command |= OHCI_CLF; + if (!(ohci->hc_control & OHCI_CTRL_CLE)) { + control |= OHCI_CTRL_CLE; + writel (0, &ohci->regs->ed_controlcurrent); + } } - } + if (ohci->ed_bulktail) { + command |= OHCI_BLF; + if (!(ohci->hc_control & OHCI_CTRL_BLE)) { + control |= OHCI_CTRL_BLE; + writel (0, &ohci->regs->ed_bulkcurrent); + } + } + + /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ + if (control) { + ohci->hc_control |= control; + writel (ohci->hc_control, &ohci->regs->control); + } + if (command) + writel (command, &ohci->regs->cmdstatus); + } } @@ -1026,7 +1016,7 @@ static void dl_done_list (struct ohci_hcd *ohci, struct td *td) if ((ed->hwHeadP & __constant_cpu_to_le32 (TD_MASK)) == ed->hwTailP && (ed->state == ED_OPER)) - start_ed_unlink (ohci, ed); + ed_deschedule (ohci, ed); td = td_next; } spin_unlock_irqrestore (&ohci->lock, flags); diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 7969e669052d..d004af6fe207 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -31,15 +31,21 @@ struct ed { /* rest are purely for the driver's use */ dma_addr_t dma; /* addr of ED */ + struct td *dummy; /* next TD to activate */ + + /* host's view of schedule */ + struct ed *ed_next; /* on schedule or rm_list */ struct ed *ed_prev; /* for non-interrupt EDs */ - struct td *dummy; struct list_head td_list; /* "shadow list" of our TDs */ - u8 state; /* ED_{NEW,UNLINK,OPER} */ -#define ED_NEW 0x00 /* unused, no dummy td */ -#define ED_UNLINK 0x01 /* dummy td, maybe linked to hc */ -#define ED_OPER 0x02 /* dummy td, _is_ linked to hc */ -#define ED_URB_DEL 0x08 /* for unlinking; masked in */ + /* create --> IDLE --> OPER --> ... --> IDLE --> destroy + * usually: OPER --> UNLINK --> (IDLE | OPER) --> ... + * some special cases : OPER --> IDLE ... + */ + u8 state; /* ED_{IDLE,UNLINK,OPER} */ +#define ED_IDLE 0x00 /* NOT linked to HC */ +#define ED_UNLINK 0x01 /* being unlinked from hc */ +#define ED_OPER 0x02 /* IS linked to hc */ u8 type; /* PIPE_{BULK,...} */ u16 interval; /* interrupt, isochronous */ @@ -53,7 +59,6 @@ struct ed { /* HC may see EDs on rm_list until next frame (frame_no == tick) */ u16 tick; - struct ed *ed_rm_list; } __attribute__ ((aligned(16))); #define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */ -- cgit v1.2.3 From ebff966a4d0a92a98c7ff3ed64ba4eb9b9ed8e3e Mon Sep 17 00:00:00 2001 From: Adam Polkosnik Date: Wed, 24 Jul 2002 22:58:34 -0700 Subject: [PATCH] new USB scanner IDs just a couple of extra IDs for Canon USB Scanners --- drivers/usb/image/scanner.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h index 0fa9036358dc..6d726223090a 100644 --- a/drivers/usb/image/scanner.h +++ b/drivers/usb/image/scanner.h @@ -93,9 +93,12 @@ static struct usb_device_id scanner_device_ids [] = { { USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */ { USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */ /* Canon */ - { USB_DEVICE(0x04a9, 0x2202) }, /* FB620U */ + { USB_DEVICE(0x04a9, 0x2202) }, /* CanoScan FB620U */ + { USB_DEVICE(0x04a9, 0x2204) }, /* CanoScan FB630U/FB636U */ + { USB_DEVICE(0x04a9, 0x2206) }, /* CanoScan N650U/N656U */ + { USB_DEVICE(0x04a9, 0x2207) }, /* CanoScan N1220U */ + { USB_DEVICE(0x04a9, 0x2208) }, /* CanoScan D660U */ { USB_DEVICE(0x04a9, 0x220b) }, /* D646U */ - { USB_DEVICE(0x04a9, 0x2207) }, /* 1220U */ /* Colorado -- See Primax/Colorado below */ /* Epson -- See Seiko/Epson below */ /* Genius */ -- cgit v1.2.3 From cc6baa4fde28a57d38ccee7d6d3a59971a50019e Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Wed, 24 Jul 2002 23:57:25 -0700 Subject: [PATCH] resolve ACPI lockup A much needed (and widely tested) ACPI bugfix for kernel 2.5.28: An u8 was casted into an u32, then all 32 bits were zeroed. This can cause other values, e.g. "unsigned long flags" to be corrupted. When these flags==0 are "restored", the system locks hard. --- drivers/acpi/ec.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 3dba2994bd6a..1d15dea62180 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -134,7 +134,7 @@ static int acpi_ec_read ( struct acpi_ec *ec, u8 address, - u8 *data) + u32 *data) { acpi_status status = AE_OK; int result = 0; @@ -167,7 +167,7 @@ acpi_ec_read ( goto end; - acpi_hw_low_level_read(8, (u32*) data, &ec->data_addr, 0); + acpi_hw_low_level_read(8, data, &ec->data_addr, 0); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", *data, address)); @@ -237,7 +237,7 @@ end: static int acpi_ec_query ( struct acpi_ec *ec, - u8 *data) + u32 *data) { int result = 0; acpi_status status = AE_OK; @@ -269,7 +269,7 @@ acpi_ec_query ( if (result) goto end; - acpi_hw_low_level_read(8, (u32*) data, &ec->data_addr, 0); + acpi_hw_low_level_read(8, data, &ec->data_addr, 0); if (!*data) result = -ENODATA; @@ -328,7 +328,7 @@ acpi_ec_gpe_handler ( { acpi_status status = AE_OK; struct acpi_ec *ec = (struct acpi_ec *) data; - u8 value = 0; + u32 value = 0; unsigned long flags = 0; struct acpi_ec_query_data *query_data = NULL; @@ -336,7 +336,7 @@ acpi_ec_gpe_handler ( return; spin_lock_irqsave(&ec->lock, flags); - acpi_hw_low_level_read(8, (u32*) &value, &ec->command_addr, 0); + acpi_hw_low_level_read(8, &value, &ec->command_addr, 0); spin_unlock_irqrestore(&ec->lock, flags); /* TBD: Implement asynch events! @@ -398,6 +398,7 @@ acpi_ec_space_handler ( { int result = 0; struct acpi_ec *ec = NULL; + u32 tmp = 0; ACPI_FUNCTION_TRACE("acpi_ec_space_handler"); @@ -408,7 +409,8 @@ acpi_ec_space_handler ( switch (function) { case ACPI_READ: - result = acpi_ec_read(ec, (u8) address, (u8*) value); + result = acpi_ec_read(ec, (u8) address, &tmp); + *value = (acpi_integer) tmp; break; case ACPI_WRITE: result = acpi_ec_write(ec, (u8) address, (u8) *value); -- cgit v1.2.3 From 6050790ee84d7e4d7aa95a3490c4a082daf8f38e Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 24 Jul 2002 23:58:01 -0700 Subject: Interpreter update --- drivers/acpi/debugger/dbcmds.c | 5 +- drivers/acpi/debugger/dbfileio.c | 16 +- drivers/acpi/debugger/dbxface.c | 6 +- drivers/acpi/dispatcher/dsobject.c | 394 ++++++++--------- drivers/acpi/dispatcher/dsutils.c | 83 ++-- drivers/acpi/dispatcher/dswload.c | 20 +- drivers/acpi/dispatcher/dswstate.c | 6 +- drivers/acpi/executer/excreate.c | 4 +- drivers/acpi/executer/exdump.c | 6 +- drivers/acpi/executer/exoparg1.c | 24 +- drivers/acpi/executer/exutils.c | 61 +-- drivers/acpi/include/acconfig.h | 13 +- drivers/acpi/include/acdebug.h | 48 +-- drivers/acpi/include/acdisasm.h | 362 ++++++++++++++++ drivers/acpi/include/acglobal.h | 14 +- drivers/acpi/include/aclocal.h | 30 +- drivers/acpi/include/acmacros.h | 11 +- drivers/acpi/include/acnamesp.h | 4 +- drivers/acpi/include/acpiosxf.h | 8 +- drivers/acpi/include/acutils.h | 5 +- drivers/acpi/include/amlcode.h | 11 +- drivers/acpi/include/amlresrc.h | 37 +- drivers/acpi/include/platform/acenv.h | 17 +- drivers/acpi/namespace/nsdump.c | 89 +--- drivers/acpi/namespace/nsdumpdv.c | 124 ++++++ drivers/acpi/namespace/nsload.c | 110 ++--- drivers/acpi/namespace/nsxfeval.c | 719 ++++++++++++++++++++++++++++++++ drivers/acpi/namespace/nsxfobj.c | 765 ++-------------------------------- drivers/acpi/parser/psargs.c | 38 +- drivers/acpi/parser/psopcode.c | 4 +- drivers/acpi/parser/psparse.c | 4 +- drivers/acpi/parser/psutils.c | 4 +- drivers/acpi/resources/rsio.c | 23 +- drivers/acpi/resources/rsirq.c | 19 +- drivers/acpi/tables/tbrsdt.c | 8 +- drivers/acpi/utilities/utglobal.c | 58 +-- 36 files changed, 1763 insertions(+), 1387 deletions(-) create mode 100644 drivers/acpi/include/acdisasm.h create mode 100644 drivers/acpi/namespace/nsdumpdv.c create mode 100644 drivers/acpi/namespace/nsxfeval.c (limited to 'drivers') diff --git a/drivers/acpi/debugger/dbcmds.c b/drivers/acpi/debugger/dbcmds.c index 0a3a4282cbb3..6cb00097d1d5 100644 --- a/drivers/acpi/debugger/dbcmds.c +++ b/drivers/acpi/debugger/dbcmds.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: dbcmds - debug commands and output routines - * $Revision: 84 $ + * $Revision: 85 $ * ******************************************************************************/ @@ -31,6 +31,7 @@ #include "acevents.h" #include "acdebug.h" #include "acresrc.h" +#include "acdisasm.h" #ifdef ENABLE_DEBUGGER @@ -342,7 +343,7 @@ acpi_db_disassemble_aml ( num_statements = ACPI_STRTOUL (statements, NULL, 0); } - acpi_db_display_op (NULL, op, num_statements); + acpi_dm_disassemble (NULL, op, num_statements); } diff --git a/drivers/acpi/debugger/dbfileio.c b/drivers/acpi/debugger/dbfileio.c index d9c7406c7f0c..a814fc858135 100644 --- a/drivers/acpi/debugger/dbfileio.c +++ b/drivers/acpi/debugger/dbfileio.c @@ -2,7 +2,7 @@ * * Module Name: dbfileio - Debugger file I/O commands. These can't usually * be used when running the debugger in Ring 0 (Kernel mode) - * $Revision: 64 $ + * $Revision: 67 $ * ******************************************************************************/ @@ -30,7 +30,7 @@ #include "acnamesp.h" #include "actables.h" -#ifdef ENABLE_DEBUGGER +#if (defined ENABLE_DEBUGGER || defined ACPI_DISASSEMBLER) #define _COMPONENT ACPI_DEBUGGER ACPI_MODULE_NAME ("dbfileio") @@ -86,6 +86,7 @@ acpi_db_match_argument ( } +#ifdef ENABLE_DEBUGGER /******************************************************************************* * * FUNCTION: Acpi_db_close_debug_file @@ -148,6 +149,7 @@ acpi_db_open_debug_file ( #endif } +#endif #ifdef ACPI_APPLICATION @@ -190,7 +192,7 @@ acpi_db_load_table( status = acpi_tb_validate_table_header (&table_header); if ((ACPI_FAILURE (status)) || - (table_header.length > 524288)) /* 1/2 Mbyte should be enough */ { + (table_header.length > 0x800000)) /* 8 Mbyte should be enough */ { acpi_os_printf ("Table header is invalid!\n"); return (AE_ERROR); } @@ -296,7 +298,7 @@ ae_local_load_table ( } -#ifndef PARSER_ONLY +#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node); if (ACPI_FAILURE (status)) { /* Uninstall table and free the buffer */ @@ -330,7 +332,7 @@ acpi_db_get_acpi_table ( /* Get the entire file */ - acpi_os_printf ("Loading Acpi table from file %s\n", filename); + fprintf (stderr, "Loading Acpi table from file %s\n", filename); status = acpi_db_load_table (fp, &acpi_gbl_db_table_ptr, &table_length); fclose(fp); @@ -383,8 +385,8 @@ acpi_db_load_acpi_table ( return (status); } - acpi_os_printf ("%4.4s at %p successfully installed and loaded\n", - acpi_gbl_db_table_ptr->signature, acpi_gbl_db_table_ptr); + fprintf (stderr, "Acpi table [%4.4s] successfully installed and loaded\n", + acpi_gbl_db_table_ptr->signature); acpi_gbl_acpi_hardware_present = FALSE; diff --git a/drivers/acpi/debugger/dbxface.c b/drivers/acpi/debugger/dbxface.c index d0cad6347c5d..50d28c7ac8e4 100644 --- a/drivers/acpi/debugger/dbxface.c +++ b/drivers/acpi/debugger/dbxface.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: dbxface - AML Debugger external interfaces - * $Revision: 59 $ + * $Revision: 61 $ * ******************************************************************************/ @@ -27,6 +27,7 @@ #include "acpi.h" #include "amlcode.h" #include "acdebug.h" +#include "acdisasm.h" #ifdef ENABLE_DEBUGGER @@ -164,7 +165,7 @@ acpi_db_single_step ( /* Now we can display it */ - acpi_db_display_op (walk_state, display_op, ACPI_UINT32_MAX); + acpi_dm_disassemble (walk_state, display_op, ACPI_UINT32_MAX); if ((op->common.aml_opcode == AML_IF_OP) || (op->common.aml_opcode == AML_WHILE_OP)) { @@ -351,7 +352,6 @@ acpi_db_initialize (void) } if (!acpi_gbl_db_opt_verbose) { - acpi_gbl_db_disasm_indent = " "; acpi_gbl_db_opt_disasm = TRUE; acpi_gbl_db_opt_stats = FALSE; } diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index a78f428efe25..9923b6650cc4 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dsobject - Dispatcher object management routines - * $Revision: 104 $ + * $Revision: 105 $ * *****************************************************************************/ @@ -35,6 +35,7 @@ ACPI_MODULE_NAME ("dsobject") +#ifndef ACPI_NO_METHOD_EXECUTION /******************************************************************************* * * FUNCTION: Acpi_ds_init_one_object @@ -216,199 +217,6 @@ acpi_ds_initialize_objects ( } -/***************************************************************************** - * - * FUNCTION: Acpi_ds_init_object_from_op - * - * PARAMETERS: Walk_state - Current walk state - * Op - Parser op used to init the internal object - * Opcode - AML opcode associated with the object - * Ret_obj_desc - Namespace object to be initialized - * - * RETURN: Status - * - * DESCRIPTION: Initialize a namespace object from a parser Op and its - * associated arguments. The namespace object is a more compact - * representation of the Op and its arguments. - * - ****************************************************************************/ - -acpi_status -acpi_ds_init_object_from_op ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - u16 opcode, - acpi_operand_object **ret_obj_desc) -{ - const acpi_opcode_info *op_info; - acpi_operand_object *obj_desc; - acpi_status status = AE_OK; - - - ACPI_FUNCTION_TRACE ("Ds_init_object_from_op"); - - - obj_desc = *ret_obj_desc; - op_info = acpi_ps_get_opcode_info (opcode); - if (op_info->class == AML_CLASS_UNKNOWN) { - /* Unknown opcode */ - - return_ACPI_STATUS (AE_TYPE); - } - - /* Perform per-object initialization */ - - switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { - case ACPI_TYPE_BUFFER: - - /* - * Defer evaluation of Buffer Term_arg operand - */ - obj_desc->buffer.node = (acpi_namespace_node *) walk_state->operands[0]; - obj_desc->buffer.aml_start = op->named.data; - obj_desc->buffer.aml_length = op->named.length; - break; - - - case ACPI_TYPE_PACKAGE: - - /* - * Defer evaluation of Package Term_arg operand - */ - obj_desc->package.node = (acpi_namespace_node *) walk_state->operands[0]; - obj_desc->package.aml_start = op->named.data; - obj_desc->package.aml_length = op->named.length; - break; - - - case ACPI_TYPE_INTEGER: - - switch (op_info->type) { - case AML_TYPE_CONSTANT: - /* - * Resolve AML Constants here - AND ONLY HERE! - * All constants are integers. - * We mark the integer with a flag that indicates that it started life - * as a constant -- so that stores to constants will perform as expected (noop). - * (Zero_op is used as a placeholder for optional target operands.) - */ - obj_desc->common.flags = AOPOBJ_AML_CONSTANT; - - switch (opcode) { - case AML_ZERO_OP: - - obj_desc->integer.value = 0; - break; - - case AML_ONE_OP: - - obj_desc->integer.value = 1; - break; - - case AML_ONES_OP: - - obj_desc->integer.value = ACPI_INTEGER_MAX; - - /* Truncate value if we are executing from a 32-bit ACPI table */ - - acpi_ex_truncate_for32bit_table (obj_desc); - break; - - case AML_REVISION_OP: - - obj_desc->integer.value = ACPI_CA_SUPPORT_LEVEL; - break; - - default: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown constant opcode %X\n", opcode)); - status = AE_AML_OPERAND_TYPE; - break; - } - break; - - - case AML_TYPE_LITERAL: - - obj_desc->integer.value = op->common.value.integer; - break; - - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n", op_info->type)); - status = AE_AML_OPERAND_TYPE; - break; - } - break; - - - case ACPI_TYPE_STRING: - - obj_desc->string.pointer = op->common.value.string; - obj_desc->string.length = ACPI_STRLEN (op->common.value.string); - - /* - * The string is contained in the ACPI table, don't ever try - * to delete it - */ - obj_desc->common.flags |= AOPOBJ_STATIC_POINTER; - break; - - - case ACPI_TYPE_METHOD: - break; - - - case INTERNAL_TYPE_REFERENCE: - - switch (op_info->type) { - case AML_TYPE_LOCAL_VARIABLE: - - /* Split the opcode into a base opcode + offset */ - - obj_desc->reference.opcode = AML_LOCAL_OP; - obj_desc->reference.offset = opcode - AML_LOCAL_OP; - acpi_ds_method_data_get_node (AML_LOCAL_OP, obj_desc->reference.offset, - walk_state, (acpi_namespace_node **) &obj_desc->reference.object); - break; - - - case AML_TYPE_METHOD_ARGUMENT: - - /* Split the opcode into a base opcode + offset */ - - obj_desc->reference.opcode = AML_ARG_OP; - obj_desc->reference.offset = opcode - AML_ARG_OP; - break; - - - default: /* Other literals, etc.. */ - - if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { - /* Node was saved in Op */ - - obj_desc->reference.node = op->common.node; - } - - obj_desc->reference.opcode = opcode; - break; - } - break; - - - default: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %X\n", - ACPI_GET_OBJECT_TYPE (obj_desc))); - - status = AE_AML_OPERAND_TYPE; - break; - } - - return_ACPI_STATUS (status); -} - - /***************************************************************************** * * FUNCTION: Acpi_ds_build_internal_object @@ -781,4 +589,202 @@ acpi_ds_create_node ( return_ACPI_STATUS (status); } +#endif /* ACPI_NO_METHOD_EXECUTION */ + + +/***************************************************************************** + * + * FUNCTION: Acpi_ds_init_object_from_op + * + * PARAMETERS: Walk_state - Current walk state + * Op - Parser op used to init the internal object + * Opcode - AML opcode associated with the object + * Ret_obj_desc - Namespace object to be initialized + * + * RETURN: Status + * + * DESCRIPTION: Initialize a namespace object from a parser Op and its + * associated arguments. The namespace object is a more compact + * representation of the Op and its arguments. + * + ****************************************************************************/ + +acpi_status +acpi_ds_init_object_from_op ( + acpi_walk_state *walk_state, + acpi_parse_object *op, + u16 opcode, + acpi_operand_object **ret_obj_desc) +{ + const acpi_opcode_info *op_info; + acpi_operand_object *obj_desc; + acpi_status status = AE_OK; + + + ACPI_FUNCTION_TRACE ("Ds_init_object_from_op"); + + + obj_desc = *ret_obj_desc; + op_info = acpi_ps_get_opcode_info (opcode); + if (op_info->class == AML_CLASS_UNKNOWN) { + /* Unknown opcode */ + + return_ACPI_STATUS (AE_TYPE); + } + + /* Perform per-object initialization */ + + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_BUFFER: + + /* + * Defer evaluation of Buffer Term_arg operand + */ + obj_desc->buffer.node = (acpi_namespace_node *) walk_state->operands[0]; + obj_desc->buffer.aml_start = op->named.data; + obj_desc->buffer.aml_length = op->named.length; + break; + + + case ACPI_TYPE_PACKAGE: + + /* + * Defer evaluation of Package Term_arg operand + */ + obj_desc->package.node = (acpi_namespace_node *) walk_state->operands[0]; + obj_desc->package.aml_start = op->named.data; + obj_desc->package.aml_length = op->named.length; + break; + + + case ACPI_TYPE_INTEGER: + + switch (op_info->type) { + case AML_TYPE_CONSTANT: + /* + * Resolve AML Constants here - AND ONLY HERE! + * All constants are integers. + * We mark the integer with a flag that indicates that it started life + * as a constant -- so that stores to constants will perform as expected (noop). + * (Zero_op is used as a placeholder for optional target operands.) + */ + obj_desc->common.flags = AOPOBJ_AML_CONSTANT; + + switch (opcode) { + case AML_ZERO_OP: + + obj_desc->integer.value = 0; + break; + + case AML_ONE_OP: + + obj_desc->integer.value = 1; + break; + + case AML_ONES_OP: + + obj_desc->integer.value = ACPI_INTEGER_MAX; + + /* Truncate value if we are executing from a 32-bit ACPI table */ + +#ifndef ACPI_NO_METHOD_EXECUTION + acpi_ex_truncate_for32bit_table (obj_desc); +#endif + break; + + case AML_REVISION_OP: + + obj_desc->integer.value = ACPI_CA_SUPPORT_LEVEL; + break; + + default: + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown constant opcode %X\n", opcode)); + status = AE_AML_OPERAND_TYPE; + break; + } + break; + + + case AML_TYPE_LITERAL: + + obj_desc->integer.value = op->common.value.integer; + break; + + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n", op_info->type)); + status = AE_AML_OPERAND_TYPE; + break; + } + break; + + + case ACPI_TYPE_STRING: + + obj_desc->string.pointer = op->common.value.string; + obj_desc->string.length = ACPI_STRLEN (op->common.value.string); + + /* + * The string is contained in the ACPI table, don't ever try + * to delete it + */ + obj_desc->common.flags |= AOPOBJ_STATIC_POINTER; + break; + + + case ACPI_TYPE_METHOD: + break; + + + case INTERNAL_TYPE_REFERENCE: + + switch (op_info->type) { + case AML_TYPE_LOCAL_VARIABLE: + + /* Split the opcode into a base opcode + offset */ + + obj_desc->reference.opcode = AML_LOCAL_OP; + obj_desc->reference.offset = opcode - AML_LOCAL_OP; +#ifndef ACPI_NO_METHOD_EXECUTION + acpi_ds_method_data_get_node (AML_LOCAL_OP, obj_desc->reference.offset, + walk_state, (acpi_namespace_node **) &obj_desc->reference.object); +#endif + break; + + + case AML_TYPE_METHOD_ARGUMENT: + + /* Split the opcode into a base opcode + offset */ + + obj_desc->reference.opcode = AML_ARG_OP; + obj_desc->reference.offset = opcode - AML_ARG_OP; + break; + + default: /* Other literals, etc.. */ + + if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { + /* Node was saved in Op */ + + obj_desc->reference.node = op->common.node; + } + + obj_desc->reference.opcode = opcode; + break; + } + break; + + + default: + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %X\n", + ACPI_GET_OBJECT_TYPE (obj_desc))); + + status = AE_AML_OPERAND_TYPE; + break; + } + + return_ACPI_STATUS (status); +} + diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 77b50406d3a2..66b6d64bfe6d 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: dsutils - Dispatcher utilities - * $Revision: 93 $ + * $Revision: 94 $ * ******************************************************************************/ @@ -35,6 +35,7 @@ #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dsutils") +#ifndef ACPI_NO_METHOD_EXECUTION /******************************************************************************* * @@ -235,6 +236,47 @@ acpi_ds_delete_result_if_not_used ( } +/******************************************************************************* + * + * FUNCTION: Acpi_ds_resolve_operands + * + * PARAMETERS: Walk_state - Current walk state with operands on stack + * + * RETURN: Status + * + * DESCRIPTION: Resolve all operands to their values. Used to prepare + * arguments to a control method invocation (a call from one + * method to another.) + * + ******************************************************************************/ + +acpi_status +acpi_ds_resolve_operands ( + acpi_walk_state *walk_state) +{ + u32 i; + acpi_status status = AE_OK; + + + ACPI_FUNCTION_TRACE_PTR ("Ds_resolve_operands", walk_state); + + + /* + * Attempt to resolve each of the valid operands + * Method arguments are passed by value, not by reference + */ + for (i = 0; i < walk_state->num_operands; i++) { + status = acpi_ex_resolve_to_value (&walk_state->operands[i], walk_state); + if (ACPI_FAILURE (status)) { + break; + } + } + + return_ACPI_STATUS (status); +} +#endif + + /******************************************************************************* * * FUNCTION: Acpi_ds_create_operand @@ -515,42 +557,3 @@ cleanup: } -/******************************************************************************* - * - * FUNCTION: Acpi_ds_resolve_operands - * - * PARAMETERS: Walk_state - Current walk state with operands on stack - * - * RETURN: Status - * - * DESCRIPTION: Resolve all operands to their values. Used to prepare - * arguments to a control method invocation (a call from one - * method to another.) - * - ******************************************************************************/ - -acpi_status -acpi_ds_resolve_operands ( - acpi_walk_state *walk_state) -{ - u32 i; - acpi_status status = AE_OK; - - - ACPI_FUNCTION_TRACE_PTR ("Ds_resolve_operands", walk_state); - - - /* - * Attempt to resolve each of the valid operands - * Method arguments are passed by value, not by reference - */ - for (i = 0; i < walk_state->num_operands; i++) { - status = acpi_ex_resolve_to_value (&walk_state->operands[i], walk_state); - if (ACPI_FAILURE (status)) { - break; - } - } - - return_ACPI_STATUS (status); -} - diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index c73bbcaf6213..3da768ff5856 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dswload - Dispatcher namespace load callbacks - * $Revision: 67 $ + * $Revision: 69 $ * *****************************************************************************/ @@ -70,9 +70,11 @@ acpi_ds_init_callbacks ( break; case 3: +#ifndef ACPI_NO_METHOD_EXECUTION walk_state->parse_flags |= ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE; walk_state->descending_callback = acpi_ds_exec_begin_op; walk_state->ascending_callback = acpi_ds_exec_end_op; +#endif break; default: @@ -169,6 +171,11 @@ acpi_ds_load1_begin_op ( op->named.name = node->name.integer; +#if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)) + op->named.path = (u8 *) path; +#endif + + /* * Put the Node in the "op" object that the parser uses, so we * can get it again quickly when this scope is closed @@ -221,6 +228,7 @@ acpi_ds_load1_end_op ( object_type = walk_state->op_info->object_type; +#ifndef ACPI_NO_METHOD_EXECUTION if (walk_state->op_info->flags & AML_FIELD) { if (walk_state->opcode == AML_FIELD_OP || walk_state->opcode == AML_BANK_FIELD_OP || @@ -238,6 +246,7 @@ acpi_ds_load1_end_op ( return (status); } } +#endif if (op->common.aml_opcode == AML_NAME_OP) { /* For Name opcode, get the object type from the argument */ @@ -430,7 +439,9 @@ acpi_ds_load2_end_op ( acpi_namespace_node *node; acpi_parse_object *arg; acpi_namespace_node *new_node; +#ifndef ACPI_NO_METHOD_EXECUTION u32 i; +#endif ACPI_FUNCTION_NAME ("Ds_load2_end_op"); @@ -478,6 +489,7 @@ acpi_ds_load2_end_op ( } } + /* * Named operations are as follows: * @@ -515,6 +527,8 @@ acpi_ds_load2_end_op ( arg = op->common.value.arg; switch (walk_state->op_info->type) { +#ifndef ACPI_NO_METHOD_EXECUTION + case AML_TYPE_CREATE_FIELD: /* @@ -604,7 +618,7 @@ acpi_ds_load2_end_op ( } break; - +#endif /* ACPI_NO_METHOD_EXECUTION */ case AML_TYPE_NAMED_COMPLEX: @@ -629,6 +643,7 @@ acpi_ds_load2_end_op ( break; +#ifndef ACPI_NO_METHOD_EXECUTION case AML_REGION_OP: /* * The Op_region is not fully parsed at this time. Only valid argument is the Space_id. @@ -656,6 +671,7 @@ acpi_ds_load2_end_op ( status = acpi_ds_create_node (walk_state, node, op); break; +#endif /* ACPI_NO_METHOD_EXECUTION */ default: diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index 37bb06d5fd9b..c5f83e5704d0 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dswstate - Dispatcher parse tree walk management routines - * $Revision: 65 $ + * $Revision: 67 $ * *****************************************************************************/ @@ -837,7 +837,7 @@ acpi_ds_create_walk_state ( /* Init the method args/local */ -#ifndef _ACPI_ASL_COMPILER +#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) acpi_ds_method_data_init (walk_state); #endif @@ -858,7 +858,6 @@ acpi_ds_create_walk_state ( } -#ifndef _ACPI_ASL_COMPILER /******************************************************************************* * * FUNCTION: Acpi_ds_init_aml_walk @@ -943,7 +942,6 @@ acpi_ds_init_aml_walk ( status = acpi_ds_init_callbacks (walk_state, pass_number); return_ACPI_STATUS (status); } -#endif /******************************************************************************* diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c index 7ea92f53a22b..2f9c06242e88 100644 --- a/drivers/acpi/executer/excreate.c +++ b/drivers/acpi/executer/excreate.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: excreate - Named object creation - * $Revision: 92 $ + * $Revision: 93 $ * *****************************************************************************/ @@ -36,6 +36,7 @@ ACPI_MODULE_NAME ("excreate") +#ifndef ACPI_NO_METHOD_EXECUTION /***************************************************************************** * * FUNCTION: Acpi_ex_create_alias @@ -490,6 +491,7 @@ acpi_ex_create_power_resource ( return_ACPI_STATUS (status); } +#endif /***************************************************************************** * diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 49c68d410a68..634d2a4385d7 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: exdump - Interpreter debug output routines - * $Revision: 156 $ + * $Revision: 157 $ * *****************************************************************************/ @@ -575,14 +575,14 @@ acpi_ex_dump_object_descriptor ( { if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) { - return; + return_VOID; } } if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) { acpi_os_printf ("Ex_dump_object_descriptor: %p is not a valid ACPI object\n", obj_desc); - return; + return_VOID; } /* Common Fields */ diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c index 688e2b80c892..803b00ea38c3 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/executer/exoparg1.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exoparg1 - AML execution - opcodes with 1 argument - * $Revision: 140 $ + * $Revision: 141 $ * *****************************************************************************/ @@ -804,16 +804,7 @@ acpi_ex_opcode_1A_0T_1R ( switch (operand[0]->reference.target_type) { case ACPI_TYPE_BUFFER_FIELD: - /* Ensure that the Buffer arguments are evaluated */ - temp_desc = operand[0]->reference.object; -#if 0 - - status = acpi_ds_get_buffer_arguments (temp_desc); - if (ACPI_FAILURE (status)) { - goto cleanup; - } -#endif /* * Create a new object that contains one element of the @@ -841,14 +832,6 @@ acpi_ex_opcode_1A_0T_1R ( case ACPI_TYPE_PACKAGE: -#if 0 - /* Ensure that the Package arguments are evaluated */ - - status = acpi_ds_get_package_arguments (operand[0]->reference.object); - if (ACPI_FAILURE (status)) { - goto cleanup; - } -#endif /* * Return the referenced element of the package. We must add * another reference to the referenced object, however. @@ -884,6 +867,11 @@ acpi_ex_opcode_1A_0T_1R ( return_desc = operand[0]->reference.object; + if (ACPI_GET_DESCRIPTOR_TYPE (return_desc) == ACPI_DESC_TYPE_NAMED) { + + return_desc = acpi_ns_get_attached_object ((acpi_namespace_node *) return_desc); + } + /* Add another reference to the object! */ acpi_ut_add_reference (return_desc); diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c index 11005af6a7a2..6e5b06166f92 100644 --- a/drivers/acpi/executer/exutils.c +++ b/drivers/acpi/executer/exutils.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exutils - interpreter/scanner utilities - * $Revision: 100 $ + * $Revision: 102 $ * *****************************************************************************/ @@ -50,6 +50,34 @@ ACPI_MODULE_NAME ("exutils") +/******************************************************************************* + * + * FUNCTION: Acpi_ex_validate_object_type + * + * PARAMETERS: Type Object type to validate + * + * DESCRIPTION: Determine if a type is a valid ACPI object type + * + ******************************************************************************/ + +u8 +acpi_ex_validate_object_type ( + acpi_object_type type) +{ + + ACPI_FUNCTION_ENTRY (); + + + if ((type > ACPI_TYPE_MAX && type < INTERNAL_TYPE_BEGIN) || + (type > INTERNAL_TYPE_MAX)) { + return (FALSE); + } + + return (TRUE); +} + +#ifndef ACPI_NO_METHOD_EXECUTION + /******************************************************************************* * * FUNCTION: Acpi_ex_enter_interpreter @@ -116,33 +144,6 @@ acpi_ex_exit_interpreter (void) } -/******************************************************************************* - * - * FUNCTION: Acpi_ex_validate_object_type - * - * PARAMETERS: Type Object type to validate - * - * DESCRIPTION: Determine if a type is a valid ACPI object type - * - ******************************************************************************/ - -u8 -acpi_ex_validate_object_type ( - acpi_object_type type) -{ - - ACPI_FUNCTION_ENTRY (); - - - if ((type > ACPI_TYPE_MAX && type < INTERNAL_TYPE_BEGIN) || - (type > INTERNAL_TYPE_MAX)) { - return (FALSE); - } - - return (TRUE); -} - - /******************************************************************************* * * FUNCTION: Acpi_ex_truncate_for32bit_table @@ -263,6 +264,8 @@ acpi_ex_release_global_lock ( ACPI_REPORT_ERROR (("Could not release ACPI Global Lock\n")); } } + + return_VOID; } @@ -378,4 +381,4 @@ acpi_ex_unsigned_integer_to_string ( } } - +#endif diff --git a/drivers/acpi/include/acconfig.h b/drivers/acpi/include/acconfig.h index 3987706d5ecf..bc88390e874c 100644 --- a/drivers/acpi/include/acconfig.h +++ b/drivers/acpi/include/acconfig.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acconfig.h - Global configuration constants - * $Revision: 105 $ + * $Revision: 107 $ * *****************************************************************************/ @@ -54,7 +54,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20020702 +#define ACPI_CA_VERSION 0x20020725 /* Version of ACPI supported */ @@ -152,6 +152,15 @@ #define ACPI_MAX_ADDRESS_SPACE 255 +/* Array sizes. Used for range checking also */ + +#define NUM_ACCESS_TYPES 6 +#define NUM_UPDATE_RULES 3 +#define NUM_LOCK_RULES 2 +#define NUM_MATCH_OPS 6 +#define NUM_OPCODES 256 +#define NUM_FIELD_NAMES 2 + /* RSDP checksums */ #define ACPI_RSDP_CHECKSUM_LENGTH 20 diff --git a/drivers/acpi/include/acdebug.h b/drivers/acpi/include/acdebug.h index e76ad4b956fc..f32ebd8fe1bc 100644 --- a/drivers/acpi/include/acdebug.h +++ b/drivers/acpi/include/acdebug.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acdebug.h - ACPI/AML debugger - * $Revision: 62 $ + * $Revision: 63 $ * *****************************************************************************/ @@ -29,7 +29,6 @@ #define ACPI_DEBUG_BUFFER_SIZE 4196 - typedef struct command_info { NATIVE_CHAR *name; /* Command Name */ @@ -185,47 +184,6 @@ acpi_db_walk_for_specific_objects ( void **return_value); -/* - * dbdisasm - AML disassembler - */ - -void -acpi_db_display_op ( - acpi_walk_state *walk_state, - acpi_parse_object *origin, - u32 num_opcodes); - -void -acpi_db_display_namestring ( - NATIVE_CHAR *name); - -void -acpi_db_display_path ( - acpi_parse_object *op); - -void -acpi_db_display_opcode ( - acpi_walk_state *walk_state, - acpi_parse_object *op); - -void -acpi_db_decode_internal_object ( - acpi_operand_object *obj_desc); - -void -acpi_db_decode_node ( - acpi_namespace_node *node); - -u32 -acpi_db_block_type ( - acpi_parse_object *op); - -acpi_status -acpi_ps_display_object_pathname ( - acpi_walk_state *walk_state, - acpi_parse_object *op); - - /* * dbdisply - debug display commands */ @@ -282,6 +240,10 @@ void * acpi_db_get_pointer ( void *target); +void +acpi_db_decode_internal_object ( + acpi_operand_object *obj_desc); + /* * dbexec - debugger control method execution diff --git a/drivers/acpi/include/acdisasm.h b/drivers/acpi/include/acdisasm.h new file mode 100644 index 000000000000..6c126d07f728 --- /dev/null +++ b/drivers/acpi/include/acdisasm.h @@ -0,0 +1,362 @@ +/****************************************************************************** + * + * Name: acdisasm.h - AML disassembler + * $Revision: 2 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2002, R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ACDISASM_H__ +#define __ACDISASM_H__ + +#include "amlresrc.h" + + +#define BLOCK_NONE 0 +#define BLOCK_PAREN 1 +#define BLOCK_BRACE 2 +#define BLOCK_COMMA_LIST 4 + +extern const char *acpi_gbl_io_decode[2]; +extern const char *acpi_gbl_word_decode[4]; +extern const char *acpi_gbl_consume_decode[2]; +extern const char *acpi_gbl_min_decode[2]; +extern const char *acpi_gbl_max_decode[2]; +extern const char *acpi_gbl_DECdecode[2]; +extern const char *acpi_gbl_RNGdecode[4]; +extern const char *acpi_gbl_MEMdecode[4]; +extern const char *acpi_gbl_RWdecode[2]; +extern const char *acpi_gbl_irq_decode[2]; +extern const char *acpi_gbl_HEdecode[2]; +extern const char *acpi_gbl_LLdecode[2]; +extern const char *acpi_gbl_SHRdecode[2]; +extern const char *acpi_gbl_TYPdecode[4]; +extern const char *acpi_gbl_BMdecode[2]; +extern const char *acpi_gbl_SIZdecode[4]; +extern const NATIVE_CHAR *acpi_gbl_lock_rule[NUM_LOCK_RULES]; +extern const NATIVE_CHAR *acpi_gbl_access_types[NUM_ACCESS_TYPES]; +extern const NATIVE_CHAR *acpi_gbl_update_rules[NUM_UPDATE_RULES]; +extern const NATIVE_CHAR *acpi_gbl_match_ops[NUM_MATCH_OPS]; + + +typedef struct acpi_op_walk_info +{ + u32 level; + u32 bit_offset; + +} ACPI_OP_WALK_INFO; + +typedef +acpi_status (*ASL_WALK_CALLBACK) ( + acpi_parse_object *op, + u32 level, + void *context); + + +/* + * dmwalk + */ + +void +acpi_dm_walk_parse_tree ( + acpi_parse_object *op, + ASL_WALK_CALLBACK descending_callback, + ASL_WALK_CALLBACK ascending_callback, + void *context); + +acpi_status +acpi_dm_descending_op ( + acpi_parse_object *op, + u32 level, + void *context); + +acpi_status +acpi_dm_ascending_op ( + acpi_parse_object *op, + u32 level, + void *context); + + +/* + * dmopcode + */ + +void +acpi_dm_validate_name ( + char *name, + acpi_parse_object *op); + +u32 +acpi_dm_dump_name ( + char *name); + +void +acpi_dm_string ( + char *string); + +void +acpi_dm_unicode ( + acpi_parse_object *op); + +void +acpi_dm_disassemble ( + acpi_walk_state *walk_state, + acpi_parse_object *origin, + u32 num_opcodes); + +void +acpi_dm_namestring ( + NATIVE_CHAR *name); + +void +acpi_dm_display_path ( + acpi_parse_object *op); + +void +acpi_dm_disassemble_one_op ( + acpi_walk_state *walk_state, + ACPI_OP_WALK_INFO *info, + acpi_parse_object *op); + +void +acpi_dm_decode_internal_object ( + acpi_operand_object *obj_desc); + +void +acpi_dm_decode_node ( + acpi_namespace_node *node); + +u32 +acpi_dm_block_type ( + acpi_parse_object *op); + +u32 +acpi_dm_list_type ( + acpi_parse_object *op); + +acpi_status +acpi_ps_display_object_pathname ( + acpi_walk_state *walk_state, + acpi_parse_object *op); + +void +acpi_dm_method_flags ( + acpi_parse_object *op); + +void +acpi_dm_field_flags ( + acpi_parse_object *op); + +void +acpi_dm_address_space ( + u8 space_id); + +void +acpi_dm_region_flags ( + acpi_parse_object *op); + +void +acpi_dm_match_op ( + acpi_parse_object *op); + +void +acpi_dm_match_keyword ( + acpi_parse_object *op); + +u8 +acpi_dm_comma_if_list_member ( + acpi_parse_object *op); + +void +acpi_dm_comma_if_field_member ( + acpi_parse_object *op); + + +/* + * dmbuffer + */ + +void +acpi_is_eisa_id ( + acpi_parse_object *op); + +void +acpi_dm_eisa_id ( + u32 encoded_id); + +u8 +acpi_dm_is_unicode_buffer ( + acpi_parse_object *op); + +u8 +acpi_dm_is_string_buffer ( + acpi_parse_object *op); + + +/* + * dmresrc + */ + +void +acpi_dm_disasm_byte_list ( + u32 level, + u8 *byte_data, + u32 byte_count); + +void +acpi_dm_byte_list ( + ACPI_OP_WALK_INFO *info, + acpi_parse_object *op); + +void +acpi_dm_resource_descriptor ( + ACPI_OP_WALK_INFO *info, + u8 *byte_data, + u32 byte_count); + +u8 +acpi_dm_is_resource_descriptor ( + acpi_parse_object *op); + +void +acpi_dm_indent ( + u32 level); + +void +acpi_dm_bit_list ( + u16 mask); + + +/* + * dmresrcl + */ + +void +acpi_dm_io_flags ( + u8 flags); + +void +acpi_dm_memory_flags ( + u8 flags, + u8 specific_flags); + +void +acpi_dm_word_descriptor ( + ASL_WORD_ADDRESS_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_dword_descriptor ( + ASL_DWORD_ADDRESS_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_qword_descriptor ( + ASL_QWORD_ADDRESS_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_memory24_descriptor ( + ASL_MEMORY_24_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_memory32_descriptor ( + ASL_MEMORY_32_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_fixed_mem32_descriptor ( + ASL_FIXED_MEMORY_32_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_generic_register_descriptor ( + ASL_GENERAL_REGISTER_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_interrupt_descriptor ( + ASL_EXTENDED_XRUPT_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_vendor_large_descriptor ( + ASL_LARGE_VENDOR_DESC *resource, + u32 length, + u32 level); + + +/* + * dmresrcs + */ + +void +acpi_dm_irq_descriptor ( + ASL_IRQ_FORMAT_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_dma_descriptor ( + ASL_DMA_FORMAT_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_io_descriptor ( + ASL_IO_PORT_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_fixed_io_descriptor ( + ASL_FIXED_IO_PORT_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_start_dependent_descriptor ( + ASL_START_DEPENDENT_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_end_dependent_descriptor ( + ASL_START_DEPENDENT_DESC *resource, + u32 length, + u32 level); + +void +acpi_dm_vendor_small_descriptor ( + ASL_SMALL_VENDOR_DESC *resource, + u32 length, + u32 level); + + +#endif /* __ACDISASM_H__ */ diff --git a/drivers/acpi/include/acglobal.h b/drivers/acpi/include/acglobal.h index 1d10c1b4203a..28e9d46ae359 100644 --- a/drivers/acpi/include/acglobal.h +++ b/drivers/acpi/include/acglobal.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acglobal.h - Declarations for global variables - * $Revision: 126 $ + * $Revision: 128 $ * *****************************************************************************/ @@ -140,8 +140,9 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_present; extern u8 acpi_gbl_shutdown; extern u32 acpi_gbl_startup_flags; extern const u8 acpi_gbl_decode_to8bit[8]; -extern const NATIVE_CHAR *acpi_gbl_db_sleep_states[ACPI_NUM_SLEEP_STATES]; +extern const NATIVE_CHAR *acpi_gbl_db_sleep_states[ACPI_NUM_SLEEP_STATES]; extern const acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; +extern const NATIVE_CHAR *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; /***************************************************************************** @@ -237,6 +238,12 @@ ACPI_EXTERN ACPI_GPE_INDEX_INFO *acpi_gbl_gpe_number_to_index; ACPI_EXTERN u8 acpi_gbl_db_output_flags; +#ifdef ACPI_DISASSEMBLER + +ACPI_EXTERN u8 acpi_gbl_db_opt_disasm; +ACPI_EXTERN u8 acpi_gbl_db_opt_verbose; +#endif + #ifdef ENABLE_DEBUGGER @@ -247,9 +254,7 @@ ACPI_EXTERN int optind; ACPI_EXTERN NATIVE_CHAR *optarg; ACPI_EXTERN u8 acpi_gbl_db_opt_tables; -ACPI_EXTERN u8 acpi_gbl_db_opt_disasm; ACPI_EXTERN u8 acpi_gbl_db_opt_stats; -ACPI_EXTERN u8 acpi_gbl_db_opt_verbose; ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; @@ -261,7 +266,6 @@ ACPI_EXTERN NATIVE_CHAR acpi_gbl_db_debug_filename[40]; ACPI_EXTERN u8 acpi_gbl_db_output_to_file; ACPI_EXTERN NATIVE_CHAR *acpi_gbl_db_buffer; ACPI_EXTERN NATIVE_CHAR *acpi_gbl_db_filename; -ACPI_EXTERN NATIVE_CHAR *acpi_gbl_db_disasm_indent; ACPI_EXTERN u32 acpi_gbl_db_debug_level; ACPI_EXTERN u32 acpi_gbl_db_console_debug_level; ACPI_EXTERN acpi_table_header *acpi_gbl_db_table_ptr; diff --git a/drivers/acpi/include/aclocal.h b/drivers/acpi/include/aclocal.h index 54eb05fc66c8..d97fc5e8f8ab 100644 --- a/drivers/acpi/include/aclocal.h +++ b/drivers/acpi/include/aclocal.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: aclocal.h - Internal data types used across the ACPI subsystem - * $Revision: 168 $ + * $Revision: 172 $ * *****************************************************************************/ @@ -567,8 +567,8 @@ acpi_status (*ACPI_EXECUTE_OP) ( */ typedef struct acpi_opcode_info { -#ifdef _OPCODE_NAMES - NATIVE_CHAR *name; /* Opcode name (debug only) */ +#ifdef ACPI_DISASSEMBLER + NATIVE_CHAR *name; /* Opcode name (disassembler/debug only) */ #endif u32 parse_args; /* Grammar/Parse time arguments */ u32 runtime_args; /* Interpret time arguments */ @@ -603,15 +603,23 @@ typedef union acpi_parse_val u32 aml_offset; /* offset of declaration in AML */\ union acpi_parse_obj *parent; /* parent op */\ union acpi_parse_obj *next; /* next op */\ - ACPI_DEBUG_ONLY_MEMBERS (\ + ACPI_DISASM_ONLY_MEMBERS (\ + u8 disasm_flags; /* Used during AML disassembly */\ + u8 disasm_opcode; /* Subtype used for disassembly */\ NATIVE_CHAR aml_op_name[16]) /* op name (debug only) */\ /* NON-DEBUG members below: */\ acpi_namespace_node *node; /* for use by interpreter */\ acpi_parse_value value; /* Value or args associated with the opcode */\ +#define ACPI_DASM_BUFFER 0x00 +#define ACPI_DASM_RESOURCE 0x01 +#define ACPI_DASM_STRING 0x02 +#define ACPI_DASM_UNICODE 0x03 +#define ACPI_DASM_EISAID 0x04 +#define ACPI_DASM_MATCHOP 0x05 /* - * generic operation (eg. If, While, Store) + * generic operation (for example: If, While, Store) */ typedef struct acpi_parseobj_common { @@ -626,6 +634,7 @@ typedef struct acpi_parseobj_common typedef struct acpi_parseobj_named { ACPI_PARSE_COMMON + u8 *path; u8 *data; /* AML body or bytelist data */ u32 length; /* AML length */ u32 name; /* 4-byte name or zero if no name */ @@ -653,15 +662,15 @@ typedef struct acpi_parseobj_asl u32 logical_byte_offset; u32 end_line; u32 end_logical_line; - u16 parse_opcode; u32 acpi_btype; u32 aml_length; u32 aml_subtree_length; u32 final_aml_length; u32 final_aml_offset; + u16 parse_opcode; + u16 compile_flags; u8 aml_opcode_length; u8 aml_pkg_len_bytes; - u16 compile_flags; u8 extra; char parse_op_name[12]; @@ -705,6 +714,13 @@ typedef struct acpi_parse_state #define ACPI_PARSEOP_BYTELIST 0x08 #define ACPI_PARSEOP_IN_CACHE 0x80 +/* Parse object Disasm_flags */ + +#define ACPI_PARSEOP_IGNORE 0x01 +#define ACPI_PARSEOP_PARAMLIST 0x02 +#define ACPI_PARSEOP_EMPTY_TERMLIST 0x04 +#define ACPI_PARSEOP_SPECIAL 0x10 + /***************************************************************************** * diff --git a/drivers/acpi/include/acmacros.h b/drivers/acpi/include/acmacros.h index f48ac95210bf..c8e79b0f76d4 100644 --- a/drivers/acpi/include/acmacros.h +++ b/drivers/acpi/include/acmacros.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acmacros.h - C macros for the entire subsystem. - * $Revision: 124 $ + * $Revision: 125 $ * *****************************************************************************/ @@ -287,10 +287,12 @@ /* * Macros for the master AML opcode table */ -#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER) +#ifdef ACPI_DISASSEMBLER #define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags) {name,Pargs,Iargs,flags,obj_type,class,type} +#define ACPI_DISASM_ONLY_MEMBERS(a) a; #else #define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags) {Pargs,Iargs,flags,obj_type,class,type} +#define ACPI_DISASM_ONLY_MEMBERS(a) #endif #define ARG_TYPE_WIDTH 5 @@ -435,7 +437,6 @@ #define ACPI_DEBUG_DEFINE(a) a; #define ACPI_DEBUG_ONLY_MEMBERS(a) a; -#define _OPCODE_NAMES #define _VERBOSE_STRUCTURES @@ -515,10 +516,6 @@ #define return_VALUE(s) return(s) #define return_PTR(s) return(s) -#ifdef ENABLE_DEBUGGER -#define _OPCODE_NAMES -#endif - #endif /* diff --git a/drivers/acpi/include/acnamesp.h b/drivers/acpi/include/acnamesp.h index c5a90435c3f7..49c5223e1f27 100644 --- a/drivers/acpi/include/acnamesp.h +++ b/drivers/acpi/include/acnamesp.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acnamesp.h - Namespace subcomponent prototypes and defines - * $Revision: 125 $ + * $Revision: 126 $ * *****************************************************************************/ @@ -43,7 +43,7 @@ /* Definitions of the predefined namespace names */ #define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */ -#define ACPI_ROOT_NAME (u32) 0x2F202020 /* Root name is "/ " */ +#define ACPI_ROOT_NAME (u32) 0x5F5F5F5C /* Root name is "\___" */ #define ACPI_SYS_BUS_NAME (u32) 0x5F53425F /* Sys bus name is "_SB_" */ #define ACPI_NS_ROOT_PATH "\\" diff --git a/drivers/acpi/include/acpiosxf.h b/drivers/acpi/include/acpiosxf.h index 56d4037f8b46..b6cac89b91b9 100644 --- a/drivers/acpi/include/acpiosxf.h +++ b/drivers/acpi/include/acpiosxf.h @@ -204,7 +204,6 @@ acpi_os_read_port ( void *value, u32 width); - acpi_status acpi_os_write_port ( ACPI_IO_ADDRESS address, @@ -222,7 +221,6 @@ acpi_os_read_memory ( void *value, u32 width); - acpi_status acpi_os_write_memory ( ACPI_PHYSICAL_ADDRESS address, @@ -241,7 +239,6 @@ acpi_os_read_pci_configuration ( void *value, u32 width); - acpi_status acpi_os_write_pci_configuration ( acpi_pci_id *pci_id, @@ -259,7 +256,6 @@ acpi_os_readable ( void *pointer, u32 length); - u8 acpi_os_writable ( void *pointer, @@ -288,6 +284,10 @@ acpi_os_vprintf ( const NATIVE_CHAR *format, va_list args); +void +acpi_os_redirect_output ( + void *destination); + /* * Debug input diff --git a/drivers/acpi/include/acutils.h b/drivers/acpi/include/acutils.h index 46ea89bafd70..3af0afac24b5 100644 --- a/drivers/acpi/include/acutils.h +++ b/drivers/acpi/include/acutils.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures - * $Revision: 140 $ + * $Revision: 142 $ * *****************************************************************************/ @@ -224,6 +224,9 @@ extern const u8 _acpi_ctype[]; #define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD)) #define ACPI_IS_UPPER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP)) #define ACPI_IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO)) +#define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU)) +#define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP)) +#define ACPI_IS_ASCII(c) ((c) < 0x80) #endif /* ACPI_USE_SYSTEM_CLIBRARY */ diff --git a/drivers/acpi/include/amlcode.h b/drivers/acpi/include/amlcode.h index ddcffdf80897..b5802baca761 100644 --- a/drivers/acpi/include/amlcode.h +++ b/drivers/acpi/include/amlcode.h @@ -3,7 +3,7 @@ * Name: amlcode.h - Definitions for AML, as included in "definition blocks" * Declarations and definitions contained herein are derived * directly from the ACPI specification. - * $Revision: 68 $ + * $Revision: 69 $ * *****************************************************************************/ @@ -474,13 +474,4 @@ typedef enum #define METHOD_FLAGS_SYNCH_LEVEL 0xF0 -/* Array sizes. Used for range checking also */ - -#define NUM_ACCESS_TYPES 6 -#define NUM_UPDATE_RULES 3 -#define NUM_MATCH_OPS 7 -#define NUM_OPCODES 256 -#define NUM_FIELD_NAMES 2 - - #endif /* __AMLCODE_H__ */ diff --git a/drivers/acpi/include/amlresrc.h b/drivers/acpi/include/amlresrc.h index d8aa2befb2c1..a97dbf2f59e4 100644 --- a/drivers/acpi/include/amlresrc.h +++ b/drivers/acpi/include/amlresrc.h @@ -1,8 +1,8 @@ /****************************************************************************** * - * Module Name: aslresource.h - ASL resource descriptors - * $Revision: 19 $ + * Module Name: amlresrc.h - AML resource descriptors + * $Revision: 20 $ * *****************************************************************************/ @@ -25,8 +25,8 @@ */ -#ifndef __ASLRESOURCE_H -#define __ASLRESOURCE_H +#ifndef __AMLRESRC_H +#define __AMLRESRC_H #define ASL_RESNAME_ADDRESS "_ADR" @@ -80,11 +80,13 @@ typedef struct asl_resource_node /* - * Resource descriptors defined in the ACPI specification + * Resource descriptors defined in the ACPI specification. + * + * Alignment must be BYTE because these descriptors + * are used to overlay the AML byte stream. */ - - #pragma pack(1) + typedef struct asl_irq_format_desc { u8 descriptor_type; @@ -94,7 +96,6 @@ typedef struct asl_irq_format_desc } ASL_IRQ_FORMAT_DESC; -#pragma pack(1) typedef struct asl_irq_noflags_desc { u8 descriptor_type; @@ -103,7 +104,6 @@ typedef struct asl_irq_noflags_desc } ASL_IRQ_NOFLAGS_DESC; -#pragma pack(1) typedef struct asl_dma_format_desc { u8 descriptor_type; @@ -113,7 +113,6 @@ typedef struct asl_dma_format_desc } ASL_DMA_FORMAT_DESC; -#pragma pack(1) typedef struct asl_start_dependent_desc { u8 descriptor_type; @@ -122,7 +121,6 @@ typedef struct asl_start_dependent_desc } ASL_START_DEPENDENT_DESC; -#pragma pack(1) typedef struct asl_start_dependent_noprio_desc { u8 descriptor_type; @@ -130,7 +128,6 @@ typedef struct asl_start_dependent_noprio_desc } ASL_START_DEPENDENT_NOPRIO_DESC; -#pragma pack(1) typedef struct asl_end_dependent_desc { u8 descriptor_type; @@ -138,7 +135,6 @@ typedef struct asl_end_dependent_desc } ASL_END_DEPENDENT_DESC; -#pragma pack(1) typedef struct asl_io_port_desc { u8 descriptor_type; @@ -151,7 +147,6 @@ typedef struct asl_io_port_desc } ASL_IO_PORT_DESC; -#pragma pack(1) typedef struct asl_fixed_io_port_desc { u8 descriptor_type; @@ -161,7 +156,6 @@ typedef struct asl_fixed_io_port_desc } ASL_FIXED_IO_PORT_DESC; -#pragma pack(1) typedef struct asl_small_vendor_desc { u8 descriptor_type; @@ -170,7 +164,6 @@ typedef struct asl_small_vendor_desc } ASL_SMALL_VENDOR_DESC; -#pragma pack(1) typedef struct asl_end_tag_desc { u8 descriptor_type; @@ -181,7 +174,6 @@ typedef struct asl_end_tag_desc /* LARGE descriptors */ -#pragma pack(1) typedef struct asl_memory_24_desc { u8 descriptor_type; @@ -195,7 +187,6 @@ typedef struct asl_memory_24_desc } ASL_MEMORY_24_DESC; -#pragma pack(1) typedef struct asl_large_vendor_desc { u8 descriptor_type; @@ -205,7 +196,6 @@ typedef struct asl_large_vendor_desc } ASL_LARGE_VENDOR_DESC; -#pragma pack(1) typedef struct asl_memory_32_desc { u8 descriptor_type; @@ -219,7 +209,6 @@ typedef struct asl_memory_32_desc } ASL_MEMORY_32_DESC; -#pragma pack(1) typedef struct asl_fixed_memory_32_desc { u8 descriptor_type; @@ -231,7 +220,6 @@ typedef struct asl_fixed_memory_32_desc } ASL_FIXED_MEMORY_32_DESC; -#pragma pack(1) typedef struct asl_qword_address_desc { u8 descriptor_type; @@ -249,7 +237,6 @@ typedef struct asl_qword_address_desc } ASL_QWORD_ADDRESS_DESC; -#pragma pack(1) typedef struct asl_dword_address_desc { u8 descriptor_type; @@ -267,7 +254,6 @@ typedef struct asl_dword_address_desc } ASL_DWORD_ADDRESS_DESC; -#pragma pack(1) typedef struct asl_word_address_desc { u8 descriptor_type; @@ -285,7 +271,6 @@ typedef struct asl_word_address_desc } ASL_WORD_ADDRESS_DESC; -#pragma pack(1) typedef struct asl_extended_xrupt_desc { u8 descriptor_type; @@ -298,7 +283,6 @@ typedef struct asl_extended_xrupt_desc } ASL_EXTENDED_XRUPT_DESC; -#pragma pack(1) typedef struct asl_general_register_desc { u8 descriptor_type; @@ -311,6 +295,9 @@ typedef struct asl_general_register_desc } ASL_GENERAL_REGISTER_DESC; +/* restore default alignment */ + +#pragma pack() /* Union of all resource descriptors, sow we can allocate the worst case */ diff --git a/drivers/acpi/include/platform/acenv.h b/drivers/acpi/include/platform/acenv.h index 1cb3f2939509..47f8f1cb2d3e 100644 --- a/drivers/acpi/include/platform/acenv.h +++ b/drivers/acpi/include/platform/acenv.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acenv.h - Generation environment specific items - * $Revision: 95 $ + * $Revision: 99 $ * *****************************************************************************/ @@ -32,11 +32,13 @@ */ #ifdef _ACPI_DUMP_APP +#ifndef MSDOS #define ACPI_DEBUG +#endif #define ACPI_APPLICATION -#define ENABLE_DEBUGGER +#define ACPI_DISASSEMBLER +#define ACPI_NO_METHOD_EXECUTION #define ACPI_USE_SYSTEM_CLIBRARY -#define PARSER_ONLY #endif #ifdef _ACPI_EXEC_APP @@ -45,13 +47,15 @@ #define ACPI_DEBUG #define ACPI_APPLICATION #define ENABLE_DEBUGGER +#define ACPI_DISASSEMBLER #define ACPI_USE_SYSTEM_CLIBRARY #endif #ifdef _ACPI_ASL_COMPILER #define ACPI_DEBUG #define ACPI_APPLICATION -/* #define ENABLE_DEBUGGER */ +#define ACPI_DISASSEMBLER +#define ACPI_CONSTANT_EVAL_ONLY #define ACPI_USE_SYSTEM_CLIBRARY #endif @@ -183,7 +187,6 @@ /* * Use the standard C library headers. * We want to keep these to a minimum. - * */ #ifdef ACPI_USE_STANDARD_HEADERS @@ -213,12 +216,16 @@ #define ACPI_STRTOUL(d,s,n) strtoul((d), (s), (ACPI_SIZE)(n)) #define ACPI_MEMCPY(d,s,n) (void) memcpy((d), (s), (ACPI_SIZE)(n)) #define ACPI_MEMSET(d,s,n) (void) memset((d), (s), (ACPI_SIZE)(n)) + #define ACPI_TOUPPER toupper #define ACPI_TOLOWER tolower #define ACPI_IS_XDIGIT isxdigit #define ACPI_IS_DIGIT isdigit #define ACPI_IS_SPACE isspace #define ACPI_IS_UPPER isupper +#define ACPI_IS_PRINT isprint +#define ACPI_IS_ALPHA isalpha +#define ACPI_IS_ASCII isascii /****************************************************************************** * diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index da59d90b095f..5a6c8c520af4 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: nsdump - table dumping routines for debug - * $Revision: 136 $ + * $Revision: 137 $ * *****************************************************************************/ @@ -619,93 +619,6 @@ acpi_ns_dump_objects ( } -#ifndef _ACPI_ASL_COMPILER -/******************************************************************************* - * - * FUNCTION: Acpi_ns_dump_one_device - * - * PARAMETERS: Handle - Node to be dumped - * Level - Nesting level of the handle - * Context - Passed into Walk_namespace - * - * DESCRIPTION: Dump a single Node that represents a device - * This procedure is a User_function called by Acpi_ns_walk_namespace. - * - ******************************************************************************/ - -acpi_status -acpi_ns_dump_one_device ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value) -{ - acpi_device_info info; - acpi_status status; - u32 i; - - - ACPI_FUNCTION_NAME ("Ns_dump_one_device"); - - - status = acpi_ns_dump_one_object (obj_handle, level, context, return_value); - - status = acpi_get_object_info (obj_handle, &info); - if (ACPI_SUCCESS (status)) { - for (i = 0; i < level; i++) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); - } - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", - info.hardware_id, - ACPI_HIDWORD (info.address), ACPI_LODWORD (info.address), - info.current_status)); - } - - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ns_dump_root_devices - * - * PARAMETERS: None - * - * DESCRIPTION: Dump all objects of type "device" - * - ******************************************************************************/ - -void -acpi_ns_dump_root_devices (void) -{ - acpi_handle sys_bus_handle; - acpi_status status; - - - ACPI_FUNCTION_NAME ("Ns_dump_root_devices"); - - - /* Only dump the table if tracing is enabled */ - - if (!(ACPI_LV_TABLES & acpi_dbg_level)) { - return; - } - - status = acpi_get_handle (0, ACPI_NS_SYSTEM_BUS, &sys_bus_handle); - if (ACPI_FAILURE (status)) { - return; - } - - ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Display of all devices in the namespace:\n")); - - status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, sys_bus_handle, - ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, - acpi_ns_dump_one_device, NULL, NULL); -} - -#endif - /******************************************************************************* * * FUNCTION: Acpi_ns_dump_tables diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c new file mode 100644 index 000000000000..0c82ecb93b7d --- /dev/null +++ b/drivers/acpi/namespace/nsdumpdv.c @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * Module Name: nsdump - table dumping routines for debug + * $Revision: 1 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2002, R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "acpi.h" +#include "acnamesp.h" +#include "acparser.h" + + +#define _COMPONENT ACPI_NAMESPACE + ACPI_MODULE_NAME ("nsdumpdv") + + +#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER) + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_dump_one_device + * + * PARAMETERS: Handle - Node to be dumped + * Level - Nesting level of the handle + * Context - Passed into Walk_namespace + * + * DESCRIPTION: Dump a single Node that represents a device + * This procedure is a User_function called by Acpi_ns_walk_namespace. + * + ******************************************************************************/ + +acpi_status +acpi_ns_dump_one_device ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value) +{ + acpi_device_info info; + acpi_status status; + u32 i; + + + ACPI_FUNCTION_NAME ("Ns_dump_one_device"); + + + status = acpi_ns_dump_one_object (obj_handle, level, context, return_value); + + status = acpi_get_object_info (obj_handle, &info); + if (ACPI_SUCCESS (status)) { + for (i = 0; i < level; i++) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); + } + + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", + info.hardware_id, + ACPI_HIDWORD (info.address), ACPI_LODWORD (info.address), + info.current_status)); + } + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_dump_root_devices + * + * PARAMETERS: None + * + * DESCRIPTION: Dump all objects of type "device" + * + ******************************************************************************/ + +void +acpi_ns_dump_root_devices (void) +{ + acpi_handle sys_bus_handle; + acpi_status status; + + + ACPI_FUNCTION_NAME ("Ns_dump_root_devices"); + + + /* Only dump the table if tracing is enabled */ + + if (!(ACPI_LV_TABLES & acpi_dbg_level)) { + return; + } + + status = acpi_get_handle (0, ACPI_NS_SYSTEM_BUS, &sys_bus_handle); + if (ACPI_FAILURE (status)) { + return; + } + + ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Display of all devices in the namespace:\n")); + + status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, sys_bus_handle, + ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, + acpi_ns_dump_one_device, NULL, NULL); +} + +#endif + + diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index cfbb32ba5779..967ed83b6937 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: nsload - namespace loading/expanding/contracting procedures - * $Revision: 56 $ + * $Revision: 57 $ * *****************************************************************************/ @@ -37,59 +37,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_load_namespace - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. - * (DSDT points to either the BIOS or a buffer.) - * - ******************************************************************************/ - -acpi_status -acpi_ns_load_namespace ( - void) -{ - acpi_status status; - - - ACPI_FUNCTION_TRACE ("Acpi_load_name_space"); - - - /* There must be at least a DSDT installed */ - - if (acpi_gbl_DSDT == NULL) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "DSDT is not in memory\n")); - return_ACPI_STATUS (AE_NO_ACPI_TABLES); - } - - /* - * Load the namespace. The DSDT is required, - * but the SSDT and PSDT tables are optional. - */ - status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - /* Ignore exceptions from these */ - - (void) acpi_ns_load_table_by_type (ACPI_TABLE_SSDT); - (void) acpi_ns_load_table_by_type (ACPI_TABLE_PSDT); - - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, - "ACPI Namespace successfully loaded at root %p\n", - acpi_gbl_root_node)); - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ns_one_parse_pass + * FUNCTION: Ns_one_complete_parse * * PARAMETERS: Pass_number - 1 or 2 * Table_desc - The table to be parsed. @@ -203,6 +151,7 @@ acpi_ns_parse_table ( return_ACPI_STATUS (status); } +#ifndef ACPI_NO_METHOD_EXECUTION /******************************************************************************* * @@ -419,6 +368,58 @@ unlock_and_exit: } +/******************************************************************************* + * + * FUNCTION: Acpi_load_namespace + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. + * (DSDT points to either the BIOS or a buffer.) + * + ******************************************************************************/ + +acpi_status +acpi_ns_load_namespace ( + void) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("Acpi_load_name_space"); + + + /* There must be at least a DSDT installed */ + + if (acpi_gbl_DSDT == NULL) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "DSDT is not in memory\n")); + return_ACPI_STATUS (AE_NO_ACPI_TABLES); + } + + /* + * Load the namespace. The DSDT is required, + * but the SSDT and PSDT tables are optional. + */ + status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Ignore exceptions from these */ + + (void) acpi_ns_load_table_by_type (ACPI_TABLE_SSDT); + (void) acpi_ns_load_table_by_type (ACPI_TABLE_PSDT); + + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, + "ACPI Namespace successfully loaded at root %p\n", + acpi_gbl_root_node)); + + return_ACPI_STATUS (status); +} + + /******************************************************************************* * * FUNCTION: Acpi_ns_delete_subtree @@ -550,4 +551,5 @@ acpi_ns_unload_namespace ( return_ACPI_STATUS (status); } +#endif diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c new file mode 100644 index 000000000000..0eded64d3647 --- /dev/null +++ b/drivers/acpi/namespace/nsxfeval.c @@ -0,0 +1,719 @@ +/******************************************************************************* + * + * Module Name: nsxfeval - Public interfaces to the ACPI subsystem + * ACPI Object evaluation interfaces + * $Revision: 1 $ + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2002, R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "acpi.h" +#include "acnamesp.h" + + +#define _COMPONENT ACPI_NAMESPACE + ACPI_MODULE_NAME ("nsxfeval") + + +/******************************************************************************* + * + * FUNCTION: Acpi_evaluate_object_typed + * + * PARAMETERS: Handle - Object handle (optional) + * *Pathname - Object pathname (optional) + * **External_params - List of parameters to pass to method, + * terminated by NULL. May be NULL + * if no parameters are being passed. + * *Return_buffer - Where to put method's return value (if + * any). If NULL, no value is returned. + * Return_type - Expected type of return object + * + * RETURN: Status + * + * DESCRIPTION: Find and evaluate the given object, passing the given + * parameters if necessary. One of "Handle" or "Pathname" must + * be valid (non-null) + * + ******************************************************************************/ + +acpi_status +acpi_evaluate_object_typed ( + acpi_handle handle, + acpi_string pathname, + acpi_object_list *external_params, + acpi_buffer *return_buffer, + acpi_object_type return_type) +{ + acpi_status status; + u8 must_free = FALSE; + + + ACPI_FUNCTION_TRACE ("Acpi_evaluate_object_typed"); + + + /* Return buffer must be valid */ + + if (!return_buffer) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + if (return_buffer->length == ACPI_ALLOCATE_BUFFER) { + must_free = TRUE; + } + + /* Evaluate the object */ + + status = acpi_evaluate_object (handle, pathname, external_params, return_buffer); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Type ANY means "don't care" */ + + if (return_type == ACPI_TYPE_ANY) { + return_ACPI_STATUS (AE_OK); + } + + if (return_buffer->length == 0) { + /* Error because caller specifically asked for a return value */ + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "No return value\n")); + + return_ACPI_STATUS (AE_NULL_OBJECT); + } + + /* Examine the object type returned from Evaluate_object */ + + if (((acpi_object *) return_buffer->pointer)->type == return_type) { + return_ACPI_STATUS (AE_OK); + } + + /* Return object type does not match requested type */ + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Incorrect return type [%s] requested [%s]\n", + acpi_ut_get_type_name (((acpi_object *) return_buffer->pointer)->type), + acpi_ut_get_type_name (return_type))); + + if (must_free) { + /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ + + acpi_os_free (return_buffer->pointer); + return_buffer->pointer = NULL; + } + + return_buffer->length = 0; + return_ACPI_STATUS (AE_TYPE); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_evaluate_object + * + * PARAMETERS: Handle - Object handle (optional) + * *Pathname - Object pathname (optional) + * **External_params - List of parameters to pass to method, + * terminated by NULL. May be NULL + * if no parameters are being passed. + * *Return_buffer - Where to put method's return value (if + * any). If NULL, no value is returned. + * + * RETURN: Status + * + * DESCRIPTION: Find and evaluate the given object, passing the given + * parameters if necessary. One of "Handle" or "Pathname" must + * be valid (non-null) + * + ******************************************************************************/ + +acpi_status +acpi_evaluate_object ( + acpi_handle handle, + acpi_string pathname, + acpi_object_list *external_params, + acpi_buffer *return_buffer) +{ + acpi_status status; + acpi_operand_object **internal_params = NULL; + acpi_operand_object *internal_return_obj = NULL; + ACPI_SIZE buffer_space_needed; + u32 i; + + + ACPI_FUNCTION_TRACE ("Acpi_evaluate_object"); + + + /* + * If there are parameters to be passed to the object + * (which must be a control method), the external objects + * must be converted to internal objects + */ + if (external_params && external_params->count) { + /* + * Allocate a new parameter block for the internal objects + * Add 1 to count to allow for null terminated internal list + */ + internal_params = ACPI_MEM_CALLOCATE (((ACPI_SIZE) external_params->count + 1) * + sizeof (void *)); + if (!internal_params) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* + * Convert each external object in the list to an + * internal object + */ + for (i = 0; i < external_params->count; i++) { + status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i], + &internal_params[i]); + if (ACPI_FAILURE (status)) { + acpi_ut_delete_internal_object_list (internal_params); + return_ACPI_STATUS (status); + } + } + internal_params[external_params->count] = NULL; + } + + /* + * Three major cases: + * 1) Fully qualified pathname + * 2) No handle, not fully qualified pathname (error) + * 3) Valid handle + */ + if ((pathname) && + (acpi_ns_valid_root_prefix (pathname[0]))) { + /* + * The path is fully qualified, just evaluate by name + */ + status = acpi_ns_evaluate_by_name (pathname, internal_params, + &internal_return_obj); + } + else if (!handle) { + /* + * A handle is optional iff a fully qualified pathname + * is specified. Since we've already handled fully + * qualified names above, this is an error + */ + if (!pathname) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Both Handle and Pathname are NULL\n")); + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Handle is NULL and Pathname is relative\n")); + } + + status = AE_BAD_PARAMETER; + } + else { + /* + * We get here if we have a handle -- and if we have a + * pathname it is relative. The handle will be validated + * in the lower procedures + */ + if (!pathname) { + /* + * The null pathname case means the handle is for + * the actual object to be evaluated + */ + status = acpi_ns_evaluate_by_handle (handle, internal_params, + &internal_return_obj); + } + else { + /* + * Both a Handle and a relative Pathname + */ + status = acpi_ns_evaluate_relative (handle, pathname, internal_params, + &internal_return_obj); + } + } + + + /* + * If we are expecting a return value, and all went well above, + * copy the return value to an external object. + */ + if (return_buffer) { + if (!internal_return_obj) { + return_buffer->length = 0; + } + else { + if (ACPI_GET_DESCRIPTOR_TYPE (internal_return_obj) == ACPI_DESC_TYPE_NAMED) { + /* + * If we received a NS Node as a return object, this means that + * the object we are evaluating has nothing interesting to + * return (such as a mutex, etc.) We return an error because + * these types are essentially unsupported by this interface. + * We don't check up front because this makes it easier to add + * support for various types at a later date if necessary. + */ + status = AE_TYPE; + internal_return_obj = NULL; /* No need to delete a NS Node */ + return_buffer->length = 0; + } + + if (ACPI_SUCCESS (status)) { + /* + * Find out how large a buffer is needed + * to contain the returned object + */ + status = acpi_ut_get_object_size (internal_return_obj, + &buffer_space_needed); + if (ACPI_SUCCESS (status)) { + /* Validate/Allocate/Clear caller buffer */ + + status = acpi_ut_initialize_buffer (return_buffer, buffer_space_needed); + if (ACPI_FAILURE (status)) { + /* + * Caller's buffer is too small or a new one can't be allocated + */ + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "Needed buffer size %X, %s\n", + (u32) buffer_space_needed, acpi_format_exception (status))); + } + else { + /* + * We have enough space for the object, build it + */ + status = acpi_ut_copy_iobject_to_eobject (internal_return_obj, + return_buffer); + } + } + } + } + } + + /* Delete the return and parameter objects */ + + if (internal_return_obj) { + /* + * Delete the internal return object. (Or at least + * decrement the reference count by one) + */ + acpi_ut_remove_reference (internal_return_obj); + } + + /* + * Free the input parameter list (if we created one), + */ + if (internal_params) { + /* Free the allocated parameter block */ + + acpi_ut_delete_internal_object_list (internal_params); + } + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_walk_namespace + * + * PARAMETERS: Type - acpi_object_type to search for + * Start_object - Handle in namespace where search begins + * Max_depth - Depth to which search is to reach + * User_function - Called when an object of "Type" is found + * Context - Passed to user function + * Return_value - Location where return value of + * User_function is put if terminated early + * + * RETURNS Return value from the User_function if terminated early. + * Otherwise, returns NULL. + * + * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, + * starting (and ending) at the object specified by Start_handle. + * The User_function is called whenever an object that matches + * the type parameter is found. If the user function returns + * a non-zero value, the search is terminated immediately and this + * value is returned to the caller. + * + * The point of this procedure is to provide a generic namespace + * walk routine that can be called from multiple places to + * provide multiple services; the User Function can be tailored + * to each task, whether it is a print function, a compare + * function, etc. + * + ******************************************************************************/ + +acpi_status +acpi_walk_namespace ( + acpi_object_type type, + acpi_handle start_object, + u32 max_depth, + acpi_walk_callback user_function, + void *context, + void **return_value) +{ + acpi_status status; + + + ACPI_FUNCTION_TRACE ("Acpi_walk_namespace"); + + + /* Parameter validation */ + + if ((type > ACPI_TYPE_MAX) || + (!max_depth) || + (!user_function)) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* + * Lock the namespace around the walk. + * The namespace will be unlocked/locked around each call + * to the user function - since this function + * must be allowed to make Acpi calls itself. + */ + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_ns_walk_namespace (type, start_object, max_depth, ACPI_NS_WALK_UNLOCK, + user_function, context, return_value); + + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_get_device_callback + * + * PARAMETERS: Callback from Acpi_get_device + * + * RETURN: Status + * + * DESCRIPTION: Takes callbacks from Walk_namespace and filters out all non- + * present devices, or if they specified a HID, it filters based + * on that. + * + ******************************************************************************/ + +static acpi_status +acpi_ns_get_device_callback ( + acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value) +{ + acpi_status status; + acpi_namespace_node *node; + u32 flags; + acpi_device_id hid; + acpi_device_id cid; + acpi_get_devices_info *info; + + + info = context; + + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } + + node = acpi_ns_map_handle_to_node (obj_handle); + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } + + if (!node) { + return (AE_BAD_PARAMETER); + } + + /* + * Run _STA to determine if device is present + */ + status = acpi_ut_execute_STA (node, &flags); + if (ACPI_FAILURE (status)) { + return (AE_CTRL_DEPTH); + } + + if (!(flags & 0x01)) { + /* Don't return at the device or children of the device if not there */ + return (AE_CTRL_DEPTH); + } + + /* + * Filter based on device HID & CID + */ + if (info->hid != NULL) { + status = acpi_ut_execute_HID (node, &hid); + if (status == AE_NOT_FOUND) { + return (AE_OK); + } + else if (ACPI_FAILURE (status)) { + return (AE_CTRL_DEPTH); + } + + if (ACPI_STRNCMP (hid.buffer, info->hid, sizeof (hid.buffer)) != 0) { + status = acpi_ut_execute_CID (node, &cid); + if (status == AE_NOT_FOUND) { + return (AE_OK); + } + else if (ACPI_FAILURE (status)) { + return (AE_CTRL_DEPTH); + } + + /* TBD: Handle CID packages */ + + if (ACPI_STRNCMP (cid.buffer, info->hid, sizeof (cid.buffer)) != 0) { + return (AE_OK); + } + } + } + + status = info->user_function (obj_handle, nesting_level, info->context, return_value); + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_get_devices + * + * PARAMETERS: HID - HID to search for. Can be NULL. + * User_function - Called when a matching object is found + * Context - Passed to user function + * Return_value - Location where return value of + * User_function is put if terminated early + * + * RETURNS Return value from the User_function if terminated early. + * Otherwise, returns NULL. + * + * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, + * starting (and ending) at the object specified by Start_handle. + * The User_function is called whenever an object that matches + * the type parameter is found. If the user function returns + * a non-zero value, the search is terminated immediately and this + * value is returned to the caller. + * + * This is a wrapper for Walk_namespace, but the callback performs + * additional filtering. Please see Acpi_get_device_callback. + * + ******************************************************************************/ + +acpi_status +acpi_get_devices ( + NATIVE_CHAR *HID, + acpi_walk_callback user_function, + void *context, + void **return_value) +{ + acpi_status status; + acpi_get_devices_info info; + + + ACPI_FUNCTION_TRACE ("Acpi_get_devices"); + + + /* Parameter validation */ + + if (!user_function) { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* + * We're going to call their callback from OUR callback, so we need + * to know what it is, and their context parameter. + */ + info.context = context; + info.user_function = user_function; + info.hid = HID; + + /* + * Lock the namespace around the walk. + * The namespace will be unlocked/locked around each call + * to the user function - since this function + * must be allowed to make Acpi calls itself. + */ + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, + ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + ACPI_NS_WALK_UNLOCK, + acpi_ns_get_device_callback, &info, + return_value); + + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_attach_data + * + * PARAMETERS: + * + * RETURN: Status + * + * DESCRIPTION: + * + ******************************************************************************/ + +acpi_status +acpi_attach_data ( + acpi_handle obj_handle, + ACPI_OBJECT_HANDLER handler, + void *data) +{ + acpi_namespace_node *node; + acpi_status status; + + + /* Parameter validation */ + + if (!obj_handle || + !handler || + !data) { + return (AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Convert and validate the handle */ + + node = acpi_ns_map_handle_to_node (obj_handle); + if (!node) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + status = acpi_ns_attach_data (node, handler, data); + +unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_detach_data + * + * PARAMETERS: + * + * RETURN: Status + * + * DESCRIPTION: + * + ******************************************************************************/ + +acpi_status +acpi_detach_data ( + acpi_handle obj_handle, + ACPI_OBJECT_HANDLER handler) +{ + acpi_namespace_node *node; + acpi_status status; + + + /* Parameter validation */ + + if (!obj_handle || + !handler) { + return (AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Convert and validate the handle */ + + node = acpi_ns_map_handle_to_node (obj_handle); + if (!node) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + status = acpi_ns_detach_data (node, handler); + +unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_get_data + * + * PARAMETERS: + * + * RETURN: Status + * + * DESCRIPTION: + * + ******************************************************************************/ + +acpi_status +acpi_get_data ( + acpi_handle obj_handle, + ACPI_OBJECT_HANDLER handler, + void **data) +{ + acpi_namespace_node *node; + acpi_status status; + + + /* Parameter validation */ + + if (!obj_handle || + !handler || + !data) { + return (AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Convert and validate the handle */ + + node = acpi_ns_map_handle_to_node (obj_handle); + if (!node) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + status = acpi_ns_get_attached_data (node, handler, data); + +unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + return (status); +} + + diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c index def0a7318950..703308421005 100644 --- a/drivers/acpi/namespace/nsxfobj.c +++ b/drivers/acpi/namespace/nsxfobj.c @@ -2,7 +2,7 @@ * * Module Name: nsxfobj - Public interfaces to the ACPI subsystem * ACPI Object oriented interfaces - * $Revision: 112 $ + * $Revision: 113 $ * ******************************************************************************/ @@ -32,384 +32,6 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME ("nsxfobj") - -/******************************************************************************* - * - * FUNCTION: Acpi_evaluate_object_typed - * - * PARAMETERS: Handle - Object handle (optional) - * *Pathname - Object pathname (optional) - * **External_params - List of parameters to pass to method, - * terminated by NULL. May be NULL - * if no parameters are being passed. - * *Return_buffer - Where to put method's return value (if - * any). If NULL, no value is returned. - * Return_type - Expected type of return object - * - * RETURN: Status - * - * DESCRIPTION: Find and evaluate the given object, passing the given - * parameters if necessary. One of "Handle" or "Pathname" must - * be valid (non-null) - * - ******************************************************************************/ - -acpi_status -acpi_evaluate_object_typed ( - acpi_handle handle, - acpi_string pathname, - acpi_object_list *external_params, - acpi_buffer *return_buffer, - acpi_object_type return_type) -{ - acpi_status status; - u8 must_free = FALSE; - - - ACPI_FUNCTION_TRACE ("Acpi_evaluate_object_typed"); - - - /* Return buffer must be valid */ - - if (!return_buffer) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - if (return_buffer->length == ACPI_ALLOCATE_BUFFER) { - must_free = TRUE; - } - - /* Evaluate the object */ - - status = acpi_evaluate_object (handle, pathname, external_params, return_buffer); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - /* Type ANY means "don't care" */ - - if (return_type == ACPI_TYPE_ANY) { - return_ACPI_STATUS (AE_OK); - } - - if (return_buffer->length == 0) { - /* Error because caller specifically asked for a return value */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "No return value\n")); - - return_ACPI_STATUS (AE_NULL_OBJECT); - } - - /* Examine the object type returned from Evaluate_object */ - - if (((acpi_object *) return_buffer->pointer)->type == return_type) { - return_ACPI_STATUS (AE_OK); - } - - /* Return object type does not match requested type */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Incorrect return type [%s] requested [%s]\n", - acpi_ut_get_type_name (((acpi_object *) return_buffer->pointer)->type), - acpi_ut_get_type_name (return_type))); - - if (must_free) { - /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ - - acpi_os_free (return_buffer->pointer); - return_buffer->pointer = NULL; - } - - return_buffer->length = 0; - return_ACPI_STATUS (AE_TYPE); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_evaluate_object - * - * PARAMETERS: Handle - Object handle (optional) - * *Pathname - Object pathname (optional) - * **External_params - List of parameters to pass to method, - * terminated by NULL. May be NULL - * if no parameters are being passed. - * *Return_buffer - Where to put method's return value (if - * any). If NULL, no value is returned. - * - * RETURN: Status - * - * DESCRIPTION: Find and evaluate the given object, passing the given - * parameters if necessary. One of "Handle" or "Pathname" must - * be valid (non-null) - * - ******************************************************************************/ - -acpi_status -acpi_evaluate_object ( - acpi_handle handle, - acpi_string pathname, - acpi_object_list *external_params, - acpi_buffer *return_buffer) -{ - acpi_status status; - acpi_operand_object **internal_params = NULL; - acpi_operand_object *internal_return_obj = NULL; - ACPI_SIZE buffer_space_needed; - u32 i; - - - ACPI_FUNCTION_TRACE ("Acpi_evaluate_object"); - - - /* - * If there are parameters to be passed to the object - * (which must be a control method), the external objects - * must be converted to internal objects - */ - if (external_params && external_params->count) { - /* - * Allocate a new parameter block for the internal objects - * Add 1 to count to allow for null terminated internal list - */ - internal_params = ACPI_MEM_CALLOCATE (((ACPI_SIZE) external_params->count + 1) * - sizeof (void *)); - if (!internal_params) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - /* - * Convert each external object in the list to an - * internal object - */ - for (i = 0; i < external_params->count; i++) { - status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i], - &internal_params[i]); - if (ACPI_FAILURE (status)) { - acpi_ut_delete_internal_object_list (internal_params); - return_ACPI_STATUS (status); - } - } - internal_params[external_params->count] = NULL; - } - - /* - * Three major cases: - * 1) Fully qualified pathname - * 2) No handle, not fully qualified pathname (error) - * 3) Valid handle - */ - if ((pathname) && - (acpi_ns_valid_root_prefix (pathname[0]))) { - /* - * The path is fully qualified, just evaluate by name - */ - status = acpi_ns_evaluate_by_name (pathname, internal_params, - &internal_return_obj); - } - else if (!handle) { - /* - * A handle is optional iff a fully qualified pathname - * is specified. Since we've already handled fully - * qualified names above, this is an error - */ - if (!pathname) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Both Handle and Pathname are NULL\n")); - } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Handle is NULL and Pathname is relative\n")); - } - - status = AE_BAD_PARAMETER; - } - else { - /* - * We get here if we have a handle -- and if we have a - * pathname it is relative. The handle will be validated - * in the lower procedures - */ - if (!pathname) { - /* - * The null pathname case means the handle is for - * the actual object to be evaluated - */ - status = acpi_ns_evaluate_by_handle (handle, internal_params, - &internal_return_obj); - } - else { - /* - * Both a Handle and a relative Pathname - */ - status = acpi_ns_evaluate_relative (handle, pathname, internal_params, - &internal_return_obj); - } - } - - - /* - * If we are expecting a return value, and all went well above, - * copy the return value to an external object. - */ - if (return_buffer) { - if (!internal_return_obj) { - return_buffer->length = 0; - } - else { - if (ACPI_GET_DESCRIPTOR_TYPE (internal_return_obj) == ACPI_DESC_TYPE_NAMED) { - /* - * If we received a NS Node as a return object, this means that - * the object we are evaluating has nothing interesting to - * return (such as a mutex, etc.) We return an error because - * these types are essentially unsupported by this interface. - * We don't check up front because this makes it easier to add - * support for various types at a later date if necessary. - */ - status = AE_TYPE; - internal_return_obj = NULL; /* No need to delete a NS Node */ - return_buffer->length = 0; - } - - if (ACPI_SUCCESS (status)) { - /* - * Find out how large a buffer is needed - * to contain the returned object - */ - status = acpi_ut_get_object_size (internal_return_obj, - &buffer_space_needed); - if (ACPI_SUCCESS (status)) { - /* Validate/Allocate/Clear caller buffer */ - - status = acpi_ut_initialize_buffer (return_buffer, buffer_space_needed); - if (ACPI_FAILURE (status)) { - /* - * Caller's buffer is too small or a new one can't be allocated - */ - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Needed buffer size %X, %s\n", - (u32) buffer_space_needed, acpi_format_exception (status))); - } - else { - /* - * We have enough space for the object, build it - */ - status = acpi_ut_copy_iobject_to_eobject (internal_return_obj, - return_buffer); - } - } - } - } - } - - /* Delete the return and parameter objects */ - - if (internal_return_obj) { - /* - * Delete the internal return object. (Or at least - * decrement the reference count by one) - */ - acpi_ut_remove_reference (internal_return_obj); - } - - /* - * Free the input parameter list (if we created one), - */ - if (internal_params) { - /* Free the allocated parameter block */ - - acpi_ut_delete_internal_object_list (internal_params); - } - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_get_next_object - * - * PARAMETERS: Type - Type of object to be searched for - * Parent - Parent object whose children we are getting - * Last_child - Previous child that was found. - * The NEXT child will be returned - * Ret_handle - Where handle to the next object is placed - * - * RETURN: Status - * - * DESCRIPTION: Return the next peer object within the namespace. If Handle is - * valid, Scope is ignored. Otherwise, the first object within - * Scope is returned. - * - ******************************************************************************/ - -acpi_status -acpi_get_next_object ( - acpi_object_type type, - acpi_handle parent, - acpi_handle child, - acpi_handle *ret_handle) -{ - acpi_status status; - acpi_namespace_node *node; - acpi_namespace_node *parent_node = NULL; - acpi_namespace_node *child_node = NULL; - - - /* Parameter validation */ - - if (type > ACPI_TYPE_MAX) { - return (AE_BAD_PARAMETER); - } - - status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* If null handle, use the parent */ - - if (!child) { - /* Start search at the beginning of the specified scope */ - - parent_node = acpi_ns_map_handle_to_node (parent); - if (!parent_node) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - } - else { - /* Non-null handle, ignore the parent */ - /* Convert and validate the handle */ - - child_node = acpi_ns_map_handle_to_node (child); - if (!child_node) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - } - - /* Internal function does the real work */ - - node = acpi_ns_get_next_node (type, parent_node, child_node); - if (!node) { - status = AE_NOT_FOUND; - goto unlock_and_exit; - } - - if (ret_handle) { - *ret_handle = acpi_ns_convert_entry_to_handle (node); - } - - -unlock_and_exit: - - (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - return (status); -} - - /******************************************************************************* * * FUNCTION: Acpi_get_type @@ -535,271 +157,38 @@ unlock_and_exit: /******************************************************************************* * - * FUNCTION: Acpi_walk_namespace - * - * PARAMETERS: Type - acpi_object_type to search for - * Start_object - Handle in namespace where search begins - * Max_depth - Depth to which search is to reach - * User_function - Called when an object of "Type" is found - * Context - Passed to user function - * Return_value - Location where return value of - * User_function is put if terminated early - * - * RETURNS Return value from the User_function if terminated early. - * Otherwise, returns NULL. - * - * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, - * starting (and ending) at the object specified by Start_handle. - * The User_function is called whenever an object that matches - * the type parameter is found. If the user function returns - * a non-zero value, the search is terminated immediately and this - * value is returned to the caller. - * - * The point of this procedure is to provide a generic namespace - * walk routine that can be called from multiple places to - * provide multiple services; the User Function can be tailored - * to each task, whether it is a print function, a compare - * function, etc. - * - ******************************************************************************/ - -acpi_status -acpi_walk_namespace ( - acpi_object_type type, - acpi_handle start_object, - u32 max_depth, - acpi_walk_callback user_function, - void *context, - void **return_value) -{ - acpi_status status; - - - ACPI_FUNCTION_TRACE ("Acpi_walk_namespace"); - - - /* Parameter validation */ - - if ((type > ACPI_TYPE_MAX) || - (!max_depth) || - (!user_function)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - /* - * Lock the namespace around the walk. - * The namespace will be unlocked/locked around each call - * to the user function - since this function - * must be allowed to make Acpi calls itself. - */ - status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - status = acpi_ns_walk_namespace (type, start_object, max_depth, ACPI_NS_WALK_UNLOCK, - user_function, context, return_value); - - (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ns_get_device_callback + * FUNCTION: Acpi_get_next_object * - * PARAMETERS: Callback from Acpi_get_device + * PARAMETERS: Type - Type of object to be searched for + * Parent - Parent object whose children we are getting + * Last_child - Previous child that was found. + * The NEXT child will be returned + * Ret_handle - Where handle to the next object is placed * * RETURN: Status * - * DESCRIPTION: Takes callbacks from Walk_namespace and filters out all non- - * present devices, or if they specified a HID, it filters based - * on that. - * - ******************************************************************************/ - -static acpi_status -acpi_ns_get_device_callback ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - acpi_status status; - acpi_namespace_node *node; - u32 flags; - acpi_device_id hid; - acpi_device_id cid; - acpi_get_devices_info *info; - - - info = context; - - status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status)) { - return (status); - } - - node = acpi_ns_map_handle_to_node (obj_handle); - status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status)) { - return (status); - } - - if (!node) { - return (AE_BAD_PARAMETER); - } - - /* - * Run _STA to determine if device is present - */ - status = acpi_ut_execute_STA (node, &flags); - if (ACPI_FAILURE (status)) { - return (AE_CTRL_DEPTH); - } - - if (!(flags & 0x01)) { - /* Don't return at the device or children of the device if not there */ - return (AE_CTRL_DEPTH); - } - - /* - * Filter based on device HID & CID - */ - if (info->hid != NULL) { - status = acpi_ut_execute_HID (node, &hid); - if (status == AE_NOT_FOUND) { - return (AE_OK); - } - else if (ACPI_FAILURE (status)) { - return (AE_CTRL_DEPTH); - } - - if (ACPI_STRNCMP (hid.buffer, info->hid, sizeof (hid.buffer)) != 0) { - status = acpi_ut_execute_CID (node, &cid); - if (status == AE_NOT_FOUND) { - return (AE_OK); - } - else if (ACPI_FAILURE (status)) { - return (AE_CTRL_DEPTH); - } - - /* TBD: Handle CID packages */ - - if (ACPI_STRNCMP (cid.buffer, info->hid, sizeof (cid.buffer)) != 0) { - return (AE_OK); - } - } - } - - status = info->user_function (obj_handle, nesting_level, info->context, return_value); - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_get_devices - * - * PARAMETERS: HID - HID to search for. Can be NULL. - * User_function - Called when a matching object is found - * Context - Passed to user function - * Return_value - Location where return value of - * User_function is put if terminated early - * - * RETURNS Return value from the User_function if terminated early. - * Otherwise, returns NULL. - * - * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, - * starting (and ending) at the object specified by Start_handle. - * The User_function is called whenever an object that matches - * the type parameter is found. If the user function returns - * a non-zero value, the search is terminated immediately and this - * value is returned to the caller. - * - * This is a wrapper for Walk_namespace, but the callback performs - * additional filtering. Please see Acpi_get_device_callback. + * DESCRIPTION: Return the next peer object within the namespace. If Handle is + * valid, Scope is ignored. Otherwise, the first object within + * Scope is returned. * ******************************************************************************/ acpi_status -acpi_get_devices ( - NATIVE_CHAR *HID, - acpi_walk_callback user_function, - void *context, - void **return_value) +acpi_get_next_object ( + acpi_object_type type, + acpi_handle parent, + acpi_handle child, + acpi_handle *ret_handle) { acpi_status status; - acpi_get_devices_info info; - - - ACPI_FUNCTION_TRACE ("Acpi_get_devices"); - - - /* Parameter validation */ - - if (!user_function) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - /* - * We're going to call their callback from OUR callback, so we need - * to know what it is, and their context parameter. - */ - info.context = context; - info.user_function = user_function; - info.hid = HID; - - /* - * Lock the namespace around the walk. - * The namespace will be unlocked/locked around each call - * to the user function - since this function - * must be allowed to make Acpi calls itself. - */ - status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, - ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - ACPI_NS_WALK_UNLOCK, - acpi_ns_get_device_callback, &info, - return_value); - - (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_attach_data - * - * PARAMETERS: - * - * RETURN: Status - * - * DESCRIPTION: - * - ******************************************************************************/ - -acpi_status -acpi_attach_data ( - acpi_handle obj_handle, - ACPI_OBJECT_HANDLER handler, - void *data) -{ acpi_namespace_node *node; - acpi_status status; + acpi_namespace_node *parent_node = NULL; + acpi_namespace_node *child_node = NULL; /* Parameter validation */ - if (!obj_handle || - !handler || - !data) { + if (type > ACPI_TYPE_MAX) { return (AE_BAD_PARAMETER); } @@ -808,117 +197,43 @@ acpi_attach_data ( return (status); } - /* Convert and validate the handle */ - - node = acpi_ns_map_handle_to_node (obj_handle); - if (!node) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - - status = acpi_ns_attach_data (node, handler, data); - -unlock_and_exit: - (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_detach_data - * - * PARAMETERS: - * - * RETURN: Status - * - * DESCRIPTION: - * - ******************************************************************************/ - -acpi_status -acpi_detach_data ( - acpi_handle obj_handle, - ACPI_OBJECT_HANDLER handler) -{ - acpi_namespace_node *node; - acpi_status status; - + /* If null handle, use the parent */ - /* Parameter validation */ + if (!child) { + /* Start search at the beginning of the specified scope */ - if (!obj_handle || - !handler) { - return (AE_BAD_PARAMETER); + parent_node = acpi_ns_map_handle_to_node (parent); + if (!parent_node) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } } + else { + /* Non-null handle, ignore the parent */ + /* Convert and validate the handle */ - status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status)) { - return (status); + child_node = acpi_ns_map_handle_to_node (child); + if (!child_node) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } } - /* Convert and validate the handle */ + /* Internal function does the real work */ - node = acpi_ns_map_handle_to_node (obj_handle); + node = acpi_ns_get_next_node (type, parent_node, child_node); if (!node) { - status = AE_BAD_PARAMETER; + status = AE_NOT_FOUND; goto unlock_and_exit; } - status = acpi_ns_detach_data (node, handler); - -unlock_and_exit: - (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_get_data - * - * PARAMETERS: - * - * RETURN: Status - * - * DESCRIPTION: - * - ******************************************************************************/ - -acpi_status -acpi_get_data ( - acpi_handle obj_handle, - ACPI_OBJECT_HANDLER handler, - void **data) -{ - acpi_namespace_node *node; - acpi_status status; - - - /* Parameter validation */ - - if (!obj_handle || - !handler || - !data) { - return (AE_BAD_PARAMETER); - } - - status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Convert and validate the handle */ - - node = acpi_ns_map_handle_to_node (obj_handle); - if (!node) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; + if (ret_handle) { + *ret_handle = acpi_ns_convert_entry_to_handle (node); } - status = acpi_ns_get_attached_data (node, handler, data); unlock_and_exit: + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return (status); } diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index bd9dab948f38..4fa6579cd8c3 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psargs - Parse AML opcode arguments - * $Revision: 61 $ + * $Revision: 62 $ * *****************************************************************************/ @@ -332,7 +332,7 @@ acpi_ps_get_next_namepath ( NATIVE_CHAR *path; acpi_parse_object *name_op; acpi_status status; - acpi_namespace_node *method_node = NULL; + acpi_operand_object *method_desc; acpi_namespace_node *node; acpi_generic_state scope_info; @@ -369,30 +369,36 @@ acpi_ps_get_next_namepath ( &node); if (ACPI_SUCCESS (status)) { if (node->type == ACPI_TYPE_METHOD) { - method_node = node; - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "method - %p Path=%p\n", - method_node, path)); + method_desc = acpi_ns_get_attached_object (node); + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Control Method - %p Desc %p Path=%p\n", + node, method_desc, path)); name_op = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP); - if (name_op) { - /* Change arg into a METHOD CALL and attach name to it */ + if (!name_op) { + return_VOID; + } - acpi_ps_init_op (arg, AML_INT_METHODCALL_OP); + /* Change arg into a METHOD CALL and attach name to it */ - name_op->common.value.name = path; + acpi_ps_init_op (arg, AML_INT_METHODCALL_OP); - /* Point METHODCALL/NAME to the METHOD Node */ + name_op->common.value.name = path; - name_op->common.node = method_node; - acpi_ps_append_arg (arg, name_op); + /* Point METHODCALL/NAME to the METHOD Node */ - if (!acpi_ns_get_attached_object (method_node)) { - return_VOID; - } + name_op->common.node = node; + acpi_ps_append_arg (arg, name_op); - *arg_count = (acpi_ns_get_attached_object (method_node))->method.param_count; + if (!method_desc) { + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Control Method - %p has no attached object\n", + node)); + return_VOID; } + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Control Method - %p Args %X\n", + node, method_desc->method.param_count)); + + *arg_count = method_desc->method.param_count; return_VOID; } diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c index 42fad5f92a77..2f2c593f330e 100644 --- a/drivers/acpi/parser/psopcode.c +++ b/drivers/acpi/parser/psopcode.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psopcode - Parser/Interpreter opcode information table - * $Revision: 70 $ + * $Revision: 71 $ * *****************************************************************************/ @@ -734,7 +734,7 @@ NATIVE_CHAR * acpi_ps_get_opcode_name ( u16 opcode) { -#ifdef ACPI_DEBUG +#ifdef ACPI_DISASSEMBLER const acpi_opcode_info *op; diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 0e24c31c6135..fd61b0863d25 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psparse - Parser top level AML parse routines - * $Revision: 128 $ + * $Revision: 129 $ * *****************************************************************************/ @@ -473,7 +473,7 @@ acpi_ps_parse_loop ( parser_state = &walk_state->parser_state; walk_state->arg_types = 0; -#ifndef PARSER_ONLY +#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) { /* We are restarting a preempted control method */ diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c index d8df196e3080..7605080eeb62 100644 --- a/drivers/acpi/parser/psutils.c +++ b/drivers/acpi/parser/psutils.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psutils - Parser miscellaneous utilities (Parser only) - * $Revision: 52 $ + * $Revision: 53 $ * *****************************************************************************/ @@ -186,7 +186,7 @@ acpi_ps_free_op ( ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Free retval op: %p\n", op)); } - if (op->common.flags == ACPI_PARSEOP_GENERIC) { + if (op->common.flags & ACPI_PARSEOP_GENERIC) { acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE, op); } else { diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index 11b2382e6ec2..3eda881b5ca0 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: rsio - IO and DMA resource descriptors - * $Revision: 21 $ + * $Revision: 22 $ * ******************************************************************************/ @@ -399,7 +399,7 @@ acpi_rs_dma_resource ( buffer += 1; temp8 = *buffer; - /* Decode the IRQ bits */ + /* Decode the DMA channel bits */ for (i = 0, index = 0; index < 8; index++) { if ((temp8 >> index) & 0x01) { @@ -407,19 +407,16 @@ acpi_rs_dma_resource ( i++; } } - if (i == 0) { - /* Zero channels is invalid! */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found Zero DMA channels in resource list\n")); - return_ACPI_STATUS (AE_BAD_DATA); - } - output_struct->data.dma.number_of_channels = i; + /* Zero DMA channels is valid */ - /* - * Calculate the structure size based upon the number of interrupts - */ - struct_size += ((ACPI_SIZE) output_struct->data.dma.number_of_channels - 1) * 4; + output_struct->data.dma.number_of_channels = i; + if (i > 0) { + /* + * Calculate the structure size based upon the number of interrupts + */ + struct_size += ((ACPI_SIZE) i - 1) * 4; + } /* * Point to Byte 2 diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 5366f27dcad7..ab0d142895f9 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: rsirq - IRQ resource descriptors - * $Revision: 29 $ + * $Revision: 30 $ * ******************************************************************************/ @@ -96,18 +96,15 @@ acpi_rs_irq_resource ( } } - if (i == 0) { - /* Zero interrupts is invalid! */ + /* Zero interrupts is valid */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found Zero interrupt levels in resource list\n")); - return_ACPI_STATUS (AE_BAD_DATA); - } output_struct->data.irq.number_of_interrupts = i; - - /* - * Calculate the structure size based upon the number of interrupts - */ - struct_size += ((ACPI_SIZE) output_struct->data.irq.number_of_interrupts - 1) * 4; + if (i > 0) { + /* + * Calculate the structure size based upon the number of interrupts + */ + struct_size += ((ACPI_SIZE) i - 1) * 4; + } /* * Point to Byte 3 if it is used diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c index 9aa4f425f2c2..3fe14948152b 100644 --- a/drivers/acpi/tables/tbrsdt.c +++ b/drivers/acpi/tables/tbrsdt.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: tbrsdt - ACPI RSDT table utilities - * $Revision: 1 $ + * $Revision: 2 $ * *****************************************************************************/ @@ -271,12 +271,6 @@ acpi_tb_get_table_rsdt ( return_ACPI_STATUS (status); } - /* - * Valid RSDT signature, verify the checksum. If it fails, just - * print a warning and ignore it. - */ - status = acpi_tb_verify_table_checksum (table_info.pointer); - /* Get the number of tables defined in the RSDT or XSDT */ acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info.pointer); diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 3641d106b886..97389a318f07 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: utglobal - Global variables for the ACPI subsystem - * $Revision: 164 $ + * $Revision: 165 $ * *****************************************************************************/ @@ -27,6 +27,7 @@ #include "acpi.h" #include "acnamesp.h" +#include "amlcode.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME ("utglobal") @@ -357,15 +358,15 @@ acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = /* Region type decoding */ -static const NATIVE_CHAR *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = +const NATIVE_CHAR *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { "System_memory", "System_iO", - "PCIConfig", + "PCI_Config", "Embedded_control", "SMBus", "CMOS", - "PCIBar_target", + "PCIBARTarget", "Data_table", }; @@ -555,55 +556,6 @@ acpi_ut_get_mutex_name ( } -/* Various strings for future use */ - -#if 0 -#include "amlcode.h" - -/* Data used in keeping track of fields */ - -static const NATIVE_CHAR *acpi_gbl_FEnames[NUM_FIELD_NAMES] = -{ - "skip", - "?access?" -}; /* FE = Field Element */ - - -static const NATIVE_CHAR *acpi_gbl_match_ops[NUM_MATCH_OPS] = -{ - "Error", - "MTR", - "MEQ", - "MLE", - "MLT", - "MGE", - "MGT" -}; - - -/* Access type decoding */ - -static const NATIVE_CHAR *acpi_gbl_access_types[NUM_ACCESS_TYPES] = -{ - "Any_acc", - "Byte_acc", - "Word_acc", - "DWord_acc", - "QWord_acc", - "Buffer_acc", -}; - - -/* Update rule decoding */ - -static const NATIVE_CHAR *acpi_gbl_update_rules[NUM_UPDATE_RULES] = -{ - "Preserve", - "Write_as_ones", - "Write_as_zeros" -}; -#endif /* Future use */ - #endif -- cgit v1.2.3 From 4916e11805b7e1ed5abddbca71ff36b752e2c470 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 24 Jul 2002 23:59:23 -0700 Subject: Use C99 initializers (Rusty Russell) --- drivers/acpi/ac.c | 16 ++++++++-------- drivers/acpi/battery.c | 16 ++++++++-------- drivers/acpi/bus.c | 10 +++++----- drivers/acpi/button.c | 16 ++++++++-------- drivers/acpi/fan.c | 16 ++++++++-------- drivers/acpi/pci_irq.c | 2 +- drivers/acpi/pci_link.c | 16 ++++++++-------- drivers/acpi/pci_root.c | 16 ++++++++-------- drivers/acpi/power.c | 16 ++++++++-------- drivers/acpi/processor.c | 16 ++++++++-------- drivers/acpi/system.c | 36 ++++++++++++++++++------------------ drivers/acpi/thermal.c | 16 ++++++++-------- 12 files changed, 96 insertions(+), 96 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index c98eefa44766..c9faecf0e450 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -1,5 +1,5 @@ /* - * acpi_ac.c - ACPI AC Adapter Driver ($Revision: 26 $) + * acpi_ac.c - ACPI AC Adapter Driver ($Revision: 27 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh @@ -47,13 +47,13 @@ int acpi_ac_add (struct acpi_device *device); int acpi_ac_remove (struct acpi_device *device, int type); static struct acpi_driver acpi_ac_driver = { - name: ACPI_AC_DRIVER_NAME, - class: ACPI_AC_CLASS, - ids: ACPI_AC_HID, - ops: { - add: acpi_ac_add, - remove: acpi_ac_remove, - }, + .name = ACPI_AC_DRIVER_NAME, + .class = ACPI_AC_CLASS, + .ids = ACPI_AC_HID, + .ops = { + .add = acpi_ac_add, + .remove = acpi_ac_remove, + }, }; struct acpi_ac { diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 6684da84decd..6a096d8c1463 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -1,5 +1,5 @@ /* - * acpi_battery.c - ACPI Battery Driver ($Revision: 36 $) + * acpi_battery.c - ACPI Battery Driver ($Revision: 37 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh @@ -52,13 +52,13 @@ static int acpi_battery_add (struct acpi_device *device); static int acpi_battery_remove (struct acpi_device *device, int type); static struct acpi_driver acpi_battery_driver = { - name: ACPI_BATTERY_DRIVER_NAME, - class: ACPI_BATTERY_CLASS, - ids: ACPI_BATTERY_HID, - ops: { - add: acpi_battery_add, - remove: acpi_battery_remove, - }, + .name = ACPI_BATTERY_DRIVER_NAME, + .class = ACPI_BATTERY_CLASS, + .ids = ACPI_BATTERY_HID, + .ops = { + .add = acpi_battery_add, + .remove = acpi_battery_remove, + }, }; struct acpi_battery_status { diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 900cbe0de6b2..881d02a7c5c7 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1,5 +1,5 @@ /* - * acpi_bus.c - ACPI Bus Driver ($Revision: 79 $) + * acpi_bus.c - ACPI Bus Driver ($Revision: 80 $) * * Copyright (C) 2001, 2002 Paul Diefenbaugh * @@ -97,10 +97,10 @@ static int acpi_device_suspend(struct device *dev, u32 state, u32 stage); static int acpi_device_resume(struct device *dev, u32 stage); static struct device_driver acpi_bus_driver = { - probe: acpi_device_probe, - remove: acpi_device_remove, - suspend: acpi_device_suspend, - resume: acpi_device_resume, + .probe = acpi_device_probe, + .remove = acpi_device_remove, + .suspend = acpi_device_suspend, + .resume = acpi_device_resume, }; diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 5beed76b3dd3..cdd6c926ea5c 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -1,5 +1,5 @@ /* - * acpi_button.c - ACPI Button Driver ($Revision: 29 $) + * acpi_button.c - ACPI Button Driver ($Revision: 30 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh @@ -47,13 +47,13 @@ int acpi_button_add (struct acpi_device *device); int acpi_button_remove (struct acpi_device *device, int type); static struct acpi_driver acpi_button_driver = { - name: ACPI_BUTTON_DRIVER_NAME, - class: ACPI_BUTTON_CLASS, - ids: "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E", - ops: { - add: acpi_button_add, - remove: acpi_button_remove, - }, + .name = ACPI_BUTTON_DRIVER_NAME, + .class = ACPI_BUTTON_CLASS, + .ids = "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E", + .ops = { + .add = acpi_button_add, + .remove = acpi_button_remove, + }, }; struct acpi_button { diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 3429bbf111be..3b3c728d3eac 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -1,5 +1,5 @@ /* - * acpi_fan.c - ACPI Fan Driver ($Revision: 28 $) + * acpi_fan.c - ACPI Fan Driver ($Revision: 29 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh @@ -47,13 +47,13 @@ int acpi_fan_add (struct acpi_device *device); int acpi_fan_remove (struct acpi_device *device, int type); static struct acpi_driver acpi_fan_driver = { - name: ACPI_FAN_DRIVER_NAME, - class: ACPI_FAN_CLASS, - ids: ACPI_FAN_HID, - ops: { - add: acpi_fan_add, - remove: acpi_fan_remove, - }, + .name = ACPI_FAN_DRIVER_NAME, + .class = ACPI_FAN_CLASS, + .ids = ACPI_FAN_HID, + .ops = { + .add = acpi_fan_add, + .remove = acpi_fan_remove, + }, }; struct acpi_fan { diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index a2b1cd595057..5d5edb42f24c 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -1,5 +1,5 @@ /* - * pci_irq.c - ACPI PCI Interrupt Routing ($Revision: 10 $) + * pci_irq.c - ACPI PCI Interrupt Routing ($Revision: 11 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 2320a8e016bd..b94b85b1cea4 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -1,5 +1,5 @@ /* - * pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 33 $) + * pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 34 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh @@ -54,13 +54,13 @@ static int acpi_pci_link_add (struct acpi_device *device); static int acpi_pci_link_remove (struct acpi_device *device, int type); static struct acpi_driver acpi_pci_link_driver = { - name: ACPI_PCI_LINK_DRIVER_NAME, - class: ACPI_PCI_LINK_CLASS, - ids: ACPI_PCI_LINK_HID, - ops: { - add: acpi_pci_link_add, - remove: acpi_pci_link_remove, - }, + .name = ACPI_PCI_LINK_DRIVER_NAME, + .class = ACPI_PCI_LINK_CLASS, + .ids = ACPI_PCI_LINK_HID, + .ops = { + .add = acpi_pci_link_add, + .remove = acpi_pci_link_remove, + }, }; struct acpi_pci_link_irq { diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 7fef16be6d47..a56fedea61b4 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -1,5 +1,5 @@ /* - * pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 39 $) + * pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 40 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh @@ -47,13 +47,13 @@ static int acpi_pci_root_add (struct acpi_device *device); static int acpi_pci_root_remove (struct acpi_device *device, int type); static struct acpi_driver acpi_pci_root_driver = { - name: ACPI_PCI_ROOT_DRIVER_NAME, - class: ACPI_PCI_ROOT_CLASS, - ids: ACPI_PCI_ROOT_HID, - ops: { - add: acpi_pci_root_add, - remove: acpi_pci_root_remove, - }, + .name = ACPI_PCI_ROOT_DRIVER_NAME, + .class = ACPI_PCI_ROOT_CLASS, + .ids = ACPI_PCI_ROOT_HID, + .ops = { + .add = acpi_pci_root_add, + .remove = acpi_pci_root_remove, + }, }; struct acpi_pci_root { diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 5e4f55dbfc90..986ebd729528 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -1,5 +1,5 @@ /* - * acpi_power.c - ACPI Bus Power Management ($Revision: 38 $) + * acpi_power.c - ACPI Bus Power Management ($Revision: 39 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh @@ -43,13 +43,13 @@ int acpi_power_add (struct acpi_device *device); int acpi_power_remove (struct acpi_device *device, int type); static struct acpi_driver acpi_power_driver = { - name: ACPI_POWER_DRIVER_NAME, - class: ACPI_POWER_CLASS, - ids: ACPI_POWER_HID, - ops: { - add: acpi_power_add, - remove: acpi_power_remove, - }, + .name = ACPI_POWER_DRIVER_NAME, + .class = ACPI_POWER_CLASS, + .ids = ACPI_POWER_HID, + .ops = { + .add = acpi_power_add, + .remove = acpi_power_remove, + }, }; struct acpi_power_resource diff --git a/drivers/acpi/processor.c b/drivers/acpi/processor.c index 028ee228dcb0..933251d46b19 100644 --- a/drivers/acpi/processor.c +++ b/drivers/acpi/processor.c @@ -1,5 +1,5 @@ /* - * acpi_processor.c - ACPI Processor Driver ($Revision: 69 $) + * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh @@ -78,13 +78,13 @@ static int acpi_processor_add (struct acpi_device *device); static int acpi_processor_remove (struct acpi_device *device, int type); static struct acpi_driver acpi_processor_driver = { - name: ACPI_PROCESSOR_DRIVER_NAME, - class: ACPI_PROCESSOR_CLASS, - ids: ACPI_PROCESSOR_HID, - ops: { - add: acpi_processor_add, - remove: acpi_processor_remove, - }, + .name = ACPI_PROCESSOR_DRIVER_NAME, + .class = ACPI_PROCESSOR_CLASS, + .ids = ACPI_PROCESSOR_HID, + .ops = { + .add = acpi_processor_add, + .remove = acpi_processor_remove, + }, }; /* Power Management */ diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 1bd1555510b0..bfd02982e234 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -1,5 +1,5 @@ /* - * acpi_system.c - ACPI System Driver ($Revision: 60 $) + * acpi_system.c - ACPI System Driver ($Revision: 63 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh @@ -63,13 +63,13 @@ static int acpi_system_add (struct acpi_device *device); static int acpi_system_remove (struct acpi_device *device, int type); static struct acpi_driver acpi_system_driver = { - name: ACPI_SYSTEM_DRIVER_NAME, - class: ACPI_SYSTEM_CLASS, - ids: ACPI_SYSTEM_HID, - ops: { - add: acpi_system_add, - remove: acpi_system_remove - }, + .name = ACPI_SYSTEM_DRIVER_NAME, + .class = ACPI_SYSTEM_CLASS, + .ids = ACPI_SYSTEM_HID, + .ops = { + .add = acpi_system_add, + .remove = acpi_system_remove + }, }; struct acpi_system @@ -383,10 +383,10 @@ static unsigned int acpi_system_poll_event(struct file *file, poll_table *wait); static struct file_operations acpi_system_event_ops = { - open: acpi_system_open_event, - read: acpi_system_read_event, - release: acpi_system_close_event, - poll: acpi_system_poll_event, + .open = acpi_system_open_event, + .read = acpi_system_read_event, + .release = acpi_system_close_event, + .poll = acpi_system_poll_event, }; static int @@ -479,7 +479,7 @@ acpi_system_poll_event( static ssize_t acpi_system_read_dsdt (struct file*, char*, size_t, loff_t*); static struct file_operations acpi_system_dsdt_ops = { - read: acpi_system_read_dsdt, + .read = acpi_system_read_dsdt, }; static ssize_t @@ -522,7 +522,7 @@ acpi_system_read_dsdt ( static ssize_t acpi_system_read_fadt (struct file*, char*, size_t, loff_t*); static struct file_operations acpi_system_fadt_ops = { - read: acpi_system_read_fadt, + .read = acpi_system_read_fadt, }; static ssize_t @@ -1165,15 +1165,15 @@ acpi_system_remove_fs ( /* Simple wrapper calling power down function. */ static void acpi_sysrq_power_off(int key, struct pt_regs *pt_regs, - struct tty_struct *tty) + struct tty_struct *tty) { acpi_power_off(); } struct sysrq_key_op sysrq_acpi_poweroff_op = { - handler: &acpi_sysrq_power_off, - help_msg: "Off", - action_msg: "Power Off\n" + .handler = &acpi_sysrq_power_off, + .help_msg = "Off", + .action_msg = "Power Off\n" }; #endif /* CONFIG_MAGIC_SYSRQ */ diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 0836b31843ca..bf5521e3403f 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -1,5 +1,5 @@ /* - * acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 40 $) + * acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 41 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh @@ -65,13 +65,13 @@ static int acpi_thermal_add (struct acpi_device *device); static int acpi_thermal_remove (struct acpi_device *device, int type); static struct acpi_driver acpi_thermal_driver = { - name: ACPI_THERMAL_DRIVER_NAME, - class: ACPI_THERMAL_CLASS, - ids: ACPI_THERMAL_HID, - ops: { - add: acpi_thermal_add, - remove: acpi_thermal_remove, - }, + .name = ACPI_THERMAL_DRIVER_NAME, + .class = ACPI_THERMAL_CLASS, + .ids = ACPI_THERMAL_HID, + .ops = { + .add = acpi_thermal_add, + .remove = acpi_thermal_remove, + }, }; struct acpi_thermal_state { -- cgit v1.2.3 From dda0273da9a6d695f4ae47d16c3e7e38c7d6e34d Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 25 Jul 2002 00:03:48 -0700 Subject: Last little bit of C99 init fixes Fix panic in EC driver (Dom B) Add a some more sanity checking (Richard Schaal) --- drivers/acpi/ec.c | 36 +++++++++++++++++++----------------- drivers/acpi/tables.c | 10 ++++++++++ 2 files changed, 29 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 3dba2994bd6a..a0fc74029b09 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1,5 +1,5 @@ /* - * acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 35 $) + * acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 38 $) * * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh @@ -62,15 +62,15 @@ static int acpi_ec_start (struct acpi_device *device); static int acpi_ec_stop (struct acpi_device *device, int type); static struct acpi_driver acpi_ec_driver = { - name: ACPI_EC_DRIVER_NAME, - class: ACPI_EC_CLASS, - ids: ACPI_EC_HID, - ops: { - add: acpi_ec_add, - remove: acpi_ec_remove, - start: acpi_ec_start, - stop: acpi_ec_stop, - }, + .name = ACPI_EC_DRIVER_NAME, + .class = ACPI_EC_CLASS, + .ids = ACPI_EC_HID, + .ops = { + .add = acpi_ec_add, + .remove = acpi_ec_remove, + .start = acpi_ec_start, + .stop = acpi_ec_stop, + }, }; struct acpi_ec { @@ -134,7 +134,7 @@ static int acpi_ec_read ( struct acpi_ec *ec, u8 address, - u8 *data) + u32 *data) { acpi_status status = AE_OK; int result = 0; @@ -167,7 +167,7 @@ acpi_ec_read ( goto end; - acpi_hw_low_level_read(8, (u32*) data, &ec->data_addr, 0); + acpi_hw_low_level_read(8, data, &ec->data_addr, 0); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", *data, address)); @@ -237,7 +237,7 @@ end: static int acpi_ec_query ( struct acpi_ec *ec, - u8 *data) + u32 *data) { int result = 0; acpi_status status = AE_OK; @@ -269,7 +269,7 @@ acpi_ec_query ( if (result) goto end; - acpi_hw_low_level_read(8, (u32*) data, &ec->data_addr, 0); + acpi_hw_low_level_read(8, data, &ec->data_addr, 0); if (!*data) result = -ENODATA; @@ -328,7 +328,7 @@ acpi_ec_gpe_handler ( { acpi_status status = AE_OK; struct acpi_ec *ec = (struct acpi_ec *) data; - u8 value = 0; + u32 value = 0; unsigned long flags = 0; struct acpi_ec_query_data *query_data = NULL; @@ -336,7 +336,7 @@ acpi_ec_gpe_handler ( return; spin_lock_irqsave(&ec->lock, flags); - acpi_hw_low_level_read(8, (u32*) &value, &ec->command_addr, 0); + acpi_hw_low_level_read(8, &value, &ec->command_addr, 0); spin_unlock_irqrestore(&ec->lock, flags); /* TBD: Implement asynch events! @@ -398,6 +398,7 @@ acpi_ec_space_handler ( { int result = 0; struct acpi_ec *ec = NULL; + u32 temp = 0; ACPI_FUNCTION_TRACE("acpi_ec_space_handler"); @@ -408,7 +409,8 @@ acpi_ec_space_handler ( switch (function) { case ACPI_READ: - result = acpi_ec_read(ec, (u8) address, (u8*) value); + result = acpi_ec_read(ec, (u8) address, &temp); + *value = (acpi_integer) temp; break; case ACPI_WRITE: result = acpi_ec_write(ec, (u8) address, (u8) *value); diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 8d5057758bfc..4a9f20ffa730 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -330,6 +330,11 @@ acpi_table_get_sdt ( return -ENODEV; } + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n"); + return -ENODEV; + } + sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 3; if (sdt.count > ACPI_MAX_TABLES) { printk(KERN_WARNING PREFIX "Truncated %lu XSDT entries\n", @@ -370,6 +375,11 @@ acpi_table_get_sdt ( return -ENODEV; } + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n"); + return -ENODEV; + } + sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 2; if (sdt.count > ACPI_MAX_TABLES) { printk(KERN_WARNING PREFIX "Truncated %lu RSDT entries\n", -- cgit v1.2.3 From 47f163419afbef5605e4c5960330b1916a3ead9e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 25 Jul 2002 01:07:01 -0700 Subject: [PATCH] USB: fixed the interface names to have the proper bus id. Thanks to David Brownell for pointing out where my previous patch was wrong. --- drivers/usb/core/usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index f1884e5ec9c2..4f53715471fb 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -947,8 +947,8 @@ static void usb_find_drivers(struct usb_device *dev) /* register this interface with driverfs */ interface->dev.parent = &dev->dev; interface->dev.bus = &usb_bus_type; - sprintf (&interface->dev.bus_id[0], "%s:%d", - dev->devpath, + sprintf (&interface->dev.bus_id[0], "%s-%s:%d", + dev->bus->bus_name, dev->devpath, interface->altsetting->bInterfaceNumber); if (!desc->iInterface || usb_string (dev, desc->iInterface, -- cgit v1.2.3 From b86c69e12550799a6b1aaffb36b5ce745db6484e Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 25 Jul 2002 10:30:36 +0100 Subject: [SERIAL] Remove drivers/char/serial_{21285,amba}.c These drivers are now part of drivers/serial --- drivers/char/serial_21285.c | 497 ----------- drivers/char/serial_amba.c | 2014 ------------------------------------------- 2 files changed, 2511 deletions(-) delete mode 100644 drivers/char/serial_21285.c delete mode 100644 drivers/char/serial_amba.c (limited to 'drivers') diff --git a/drivers/char/serial_21285.c b/drivers/char/serial_21285.c deleted file mode 100644 index d775644e96ad..000000000000 --- a/drivers/char/serial_21285.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * linux/drivers/char/serial_21285.c - * - * Driver for the serial port on the 21285 StrongArm-110 core logic chip. - * - * Based on drivers/char/serial.c - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define BAUD_BASE (mem_fclk_21285/64) - -#define SERIAL_21285_NAME "ttyFB" -#define SERIAL_21285_MAJOR 204 -#define SERIAL_21285_MINOR 4 - -#define SERIAL_21285_AUXNAME "cuafb" -#define SERIAL_21285_AUXMAJOR 205 -#define SERIAL_21285_AUXMINOR 4 - -static struct tty_driver rs285_driver, callout_driver; -static int rs285_refcount; -static struct tty_struct *rs285_table[1]; - -static struct termios *rs285_termios[1]; -static struct termios *rs285_termios_locked[1]; - -static char wbuf[1000], *putp = wbuf, *getp = wbuf, x_char; -static struct tty_struct *rs285_tty; -static int rs285_use_count; - -static int rs285_write_room(struct tty_struct *tty) -{ - return putp >= getp ? (sizeof(wbuf) - (long) putp + (long) getp) : ((long) getp - (long) putp - 1); -} - -static void rs285_rx_int(int irq, void *dev_id, struct pt_regs *regs) -{ - if (!rs285_tty) { - disable_irq(IRQ_CONRX); - return; - } - while (!(*CSR_UARTFLG & 0x10)) { - int ch, flag; - ch = *CSR_UARTDR; - flag = *CSR_RXSTAT; - if (flag & 4) - tty_insert_flip_char(rs285_tty, 0, TTY_OVERRUN); - if (flag & 2) - flag = TTY_PARITY; - else if (flag & 1) - flag = TTY_FRAME; - tty_insert_flip_char(rs285_tty, ch, flag); - } - tty_flip_buffer_push(rs285_tty); -} - -static void rs285_send_xchar(struct tty_struct *tty, char ch) -{ - x_char = ch; - enable_irq(IRQ_CONTX); -} - -static void rs285_throttle(struct tty_struct *tty) -{ - if (I_IXOFF(tty)) - rs285_send_xchar(tty, STOP_CHAR(tty)); -} - -static void rs285_unthrottle(struct tty_struct *tty) -{ - if (I_IXOFF(tty)) { - if (x_char) - x_char = 0; - else - rs285_send_xchar(tty, START_CHAR(tty)); - } -} - -static void rs285_tx_int(int irq, void *dev_id, struct pt_regs *regs) -{ - while (!(*CSR_UARTFLG & 0x20)) { - if (x_char) { - *CSR_UARTDR = x_char; - x_char = 0; - continue; - } - if (putp == getp) { - disable_irq(IRQ_CONTX); - break; - } - *CSR_UARTDR = *getp; - if (++getp >= wbuf + sizeof(wbuf)) - getp = wbuf; - } - if (rs285_tty) - wake_up_interruptible(&rs285_tty->write_wait); -} - -static inline int rs285_xmit(int ch) -{ - if (putp + 1 == getp || (putp + 1 == wbuf + sizeof(wbuf) && getp == wbuf)) - return 0; - *putp = ch; - if (++putp >= wbuf + sizeof(wbuf)) - putp = wbuf; - enable_irq(IRQ_CONTX); - return 1; -} - -static int rs285_write(struct tty_struct *tty, int from_user, - const u_char * buf, int count) -{ - int i; - - if (from_user && verify_area(VERIFY_READ, buf, count)) - return -EINVAL; - - for (i = 0; i < count; i++) { - char ch; - if (from_user) - __get_user(ch, buf + i); - else - ch = buf[i]; - if (!rs285_xmit(ch)) - break; - } - return i; -} - -static void rs285_put_char(struct tty_struct *tty, u_char ch) -{ - rs285_xmit(ch); -} - -static int rs285_chars_in_buffer(struct tty_struct *tty) -{ - return sizeof(wbuf) - rs285_write_room(tty); -} - -static void rs285_flush_buffer(struct tty_struct *tty) -{ - disable_irq(IRQ_CONTX); - putp = getp = wbuf; - if (x_char) - enable_irq(IRQ_CONTX); -} - -static inline void rs285_set_cflag(int cflag) -{ - int h_lcr, baud, quot; - - switch (cflag & CSIZE) { - case CS5: - h_lcr = 0x10; - break; - case CS6: - h_lcr = 0x30; - break; - case CS7: - h_lcr = 0x50; - break; - default: /* CS8 */ - h_lcr = 0x70; - break; - - } - if (cflag & CSTOPB) - h_lcr |= 0x08; - if (cflag & PARENB) - h_lcr |= 0x02; - if (!(cflag & PARODD)) - h_lcr |= 0x04; - - switch (cflag & CBAUD) { - case B200: baud = 200; break; - case B300: baud = 300; break; - case B1200: baud = 1200; break; - case B1800: baud = 1800; break; - case B2400: baud = 2400; break; - case B4800: baud = 4800; break; - default: - case B9600: baud = 9600; break; - case B19200: baud = 19200; break; - case B38400: baud = 38400; break; - case B57600: baud = 57600; break; - case B115200: baud = 115200; break; - } - - /* - * The documented expression for selecting the divisor is: - * BAUD_BASE / baud - 1 - * However, typically BAUD_BASE is not divisible by baud, so - * we want to select the divisor that gives us the minimum - * error. Therefore, we want: - * int(BAUD_BASE / baud - 0.5) -> - * int(BAUD_BASE / baud - (baud >> 1) / baud) -> - * int((BAUD_BASE - (baud >> 1)) / baud) - */ - quot = (BAUD_BASE - (baud >> 1)) / baud; - - *CSR_UARTCON = 0; - *CSR_L_UBRLCR = quot & 0xff; - *CSR_M_UBRLCR = (quot >> 8) & 0x0f; - *CSR_H_UBRLCR = h_lcr; - *CSR_UARTCON = 1; -} - -static void rs285_set_termios(struct tty_struct *tty, struct termios *old) -{ - if (old && tty->termios->c_cflag == old->c_cflag) - return; - rs285_set_cflag(tty->termios->c_cflag); -} - - -static void rs285_stop(struct tty_struct *tty) -{ - disable_irq(IRQ_CONTX); -} - -static void rs285_start(struct tty_struct *tty) -{ - enable_irq(IRQ_CONTX); -} - -static void rs285_wait_until_sent(struct tty_struct *tty, int timeout) -{ - int orig_jiffies = jiffies; - while (*CSR_UARTFLG & 8) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - current->state = TASK_RUNNING; -} - -static int rs285_open(struct tty_struct *tty, struct file *filp) -{ - int line; - - MOD_INC_USE_COUNT; - line = minor(tty->device) - tty->driver.minor_start; - if (line) { - MOD_DEC_USE_COUNT; - return -ENODEV; - } - - tty->driver_data = NULL; - if (!rs285_tty) - rs285_tty = tty; - - enable_irq(IRQ_CONRX); - rs285_use_count++; - return 0; -} - -static void rs285_close(struct tty_struct *tty, struct file *filp) -{ - if (!--rs285_use_count) { - rs285_wait_until_sent(tty, 0); - disable_irq(IRQ_CONRX); - disable_irq(IRQ_CONTX); - rs285_tty = NULL; - } - MOD_DEC_USE_COUNT; -} - -static int __init rs285_init(void) -{ - int baud = B9600; - - if (machine_is_personal_server()) - baud = B57600; - - rs285_driver.magic = TTY_DRIVER_MAGIC; - rs285_driver.driver_name = "serial_21285"; - rs285_driver.name = SERIAL_21285_NAME; - rs285_driver.major = SERIAL_21285_MAJOR; - rs285_driver.minor_start = SERIAL_21285_MINOR; - rs285_driver.num = 1; - rs285_driver.type = TTY_DRIVER_TYPE_SERIAL; - rs285_driver.subtype = SERIAL_TYPE_NORMAL; - rs285_driver.init_termios = tty_std_termios; - rs285_driver.init_termios.c_cflag = baud | CS8 | CREAD | HUPCL | CLOCAL; - rs285_driver.flags = TTY_DRIVER_REAL_RAW; - rs285_driver.refcount = &rs285_refcount; - rs285_driver.table = rs285_table; - rs285_driver.termios = rs285_termios; - rs285_driver.termios_locked = rs285_termios_locked; - - rs285_driver.open = rs285_open; - rs285_driver.close = rs285_close; - rs285_driver.write = rs285_write; - rs285_driver.put_char = rs285_put_char; - rs285_driver.write_room = rs285_write_room; - rs285_driver.chars_in_buffer = rs285_chars_in_buffer; - rs285_driver.flush_buffer = rs285_flush_buffer; - rs285_driver.throttle = rs285_throttle; - rs285_driver.unthrottle = rs285_unthrottle; - rs285_driver.send_xchar = rs285_send_xchar; - rs285_driver.set_termios = rs285_set_termios; - rs285_driver.stop = rs285_stop; - rs285_driver.start = rs285_start; - rs285_driver.wait_until_sent = rs285_wait_until_sent; - - callout_driver = rs285_driver; - callout_driver.name = SERIAL_21285_AUXNAME; - callout_driver.major = SERIAL_21285_AUXMAJOR; - callout_driver.subtype = SERIAL_TYPE_CALLOUT; - - if (request_irq(IRQ_CONRX, rs285_rx_int, 0, "rs285", NULL)) - panic("Couldn't get rx irq for rs285"); - - if (request_irq(IRQ_CONTX, rs285_tx_int, 0, "rs285", NULL)) - panic("Couldn't get tx irq for rs285"); - - if (tty_register_driver(&rs285_driver)) - printk(KERN_ERR "Couldn't register 21285 serial driver\n"); - if (tty_register_driver(&callout_driver)) - printk(KERN_ERR "Couldn't register 21285 callout driver\n"); - - return 0; -} - -static void __exit rs285_fini(void) -{ - unsigned long flags; - int ret; - - save_flags(flags); - cli(); - ret = tty_unregister_driver(&callout_driver); - if (ret) - printk(KERN_ERR "Unable to unregister 21285 callout driver " - "(%d)\n", ret); - ret = tty_unregister_driver(&rs285_driver); - if (ret) - printk(KERN_ERR "Unable to unregister 21285 driver (%d)\n", - ret); - free_irq(IRQ_CONTX, NULL); - free_irq(IRQ_CONRX, NULL); - restore_flags(flags); -} - -module_init(rs285_init); -module_exit(rs285_fini); - -#ifdef CONFIG_SERIAL_21285_CONSOLE -/************** console driver *****************/ - -static void rs285_console_write(struct console *co, const char *s, u_int count) -{ - int i; - - disable_irq(IRQ_CONTX); - for (i = 0; i < count; i++) { - while (*CSR_UARTFLG & 0x20); - *CSR_UARTDR = s[i]; - if (s[i] == '\n') { - while (*CSR_UARTFLG & 0x20); - *CSR_UARTDR = '\r'; - } - } - enable_irq(IRQ_CONTX); -} - -static kdev_t rs285_console_device(struct console *c) -{ - return mk_kdev(SERIAL_21285_MAJOR, SERIAL_21285_MINOR); -} - -static int __init rs285_console_setup(struct console *co, char *options) -{ - int baud = 9600; - int bits = 8; - int parity = 'n'; - int cflag = CREAD | HUPCL | CLOCAL; - - if (machine_is_personal_server()) - baud = 57600; - - if (options) { - char *s = options; - baud = simple_strtoul(options, NULL, 10); - while (*s >= '0' && *s <= '9') - s++; - if (*s) - parity = *s++; - if (*s) - bits = *s - '0'; - } - - /* - * Now construct a cflag setting. - */ - switch (baud) { - case 1200: - cflag |= B1200; - break; - case 2400: - cflag |= B2400; - break; - case 4800: - cflag |= B4800; - break; - case 9600: - cflag |= B9600; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 57600: - cflag |= B57600; - break; - case 115200: - cflag |= B115200; - break; - default: - cflag |= B9600; - break; - } - switch (bits) { - case 7: - cflag |= CS7; - break; - default: - cflag |= CS8; - break; - } - switch (parity) { - case 'o': - case 'O': - cflag |= PARODD; - break; - case 'e': - case 'E': - cflag |= PARENB; - break; - } - co->cflag = cflag; - rs285_set_cflag(cflag); - rs285_console_write(NULL, "\e[2J\e[Hboot ", 12); - if (options) - rs285_console_write(NULL, options, strlen(options)); - else - rs285_console_write(NULL, "no options", 10); - rs285_console_write(NULL, "\n", 1); - - return 0; -} - -static struct console rs285_cons = -{ - name: SERIAL_21285_NAME, - write: rs285_console_write, - device: rs285_console_device, - setup: rs285_console_setup, - flags: CON_PRINTBUFFER, - index: -1, -}; - -void __init rs285_console_init(void) -{ - register_console(&rs285_cons); -} - -#endif /* CONFIG_SERIAL_21285_CONSOLE */ - -MODULE_LICENSE("GPL"); diff --git a/drivers/char/serial_amba.c b/drivers/char/serial_amba.c deleted file mode 100644 index 48d416e6277e..000000000000 --- a/drivers/char/serial_amba.c +++ /dev/null @@ -1,2014 +0,0 @@ -/* - * linux/drivers/char/serial_amba.c - * - * Driver for AMBA serial ports - * - * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. - * - * Copyright 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * This is a generic driver for ARM AMBA-type serial ports. They - * have a lot of 16550-like features, but are not register compatable. - * Note that although they do have CTS, DCD and DSR inputs, they do - * not have an RI input, nor do they have DTR or RTS outputs. If - * required, these have to be supplied via some other means (eg, GPIO) - * and hooked into this driver. - * - * This could very easily become a generic serial driver for dumb UARTs - * (eg, {82,16x}50, 21285, SA1100). - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#define SERIAL_AMBA_NAME "ttyAM" -#define SERIAL_AMBA_MAJOR 204 -#define SERIAL_AMBA_MINOR 16 -#define SERIAL_AMBA_NR 2 - -#define CALLOUT_AMBA_NAME "cuaam" -#define CALLOUT_AMBA_MAJOR 205 -#define CALLOUT_AMBA_MINOR 16 -#define CALLOUT_AMBA_NR SERIAL_AMBA_NR - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#define DEBUG 0 -#define DEBUG_LEDS 0 - -#if DEBUG_LEDS -extern int get_leds(void); -extern int set_leds(int); -#endif - -/* - * Access routines for the AMBA UARTs - */ -#define UART_GET_INT_STATUS(p) IO_READ((p)->uart_base + AMBA_UARTIIR) -#define UART_GET_FR(p) IO_READ((p)->uart_base + AMBA_UARTFR) -#define UART_GET_CHAR(p) IO_READ((p)->uart_base + AMBA_UARTDR) -#define UART_PUT_CHAR(p, c) IO_WRITE((p)->uart_base + AMBA_UARTDR, (c)) -#define UART_GET_RSR(p) IO_READ((p)->uart_base + AMBA_UARTRSR) -#define UART_GET_CR(p) IO_READ((p)->uart_base + AMBA_UARTCR) -#define UART_PUT_CR(p,c) IO_WRITE((p)->uart_base + AMBA_UARTCR, (c)) -#define UART_GET_LCRL(p) IO_READ((p)->uart_base + AMBA_UARTLCR_L) -#define UART_PUT_LCRL(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_L, (c)) -#define UART_GET_LCRM(p) IO_READ((p)->uart_base + AMBA_UARTLCR_M) -#define UART_PUT_LCRM(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_M, (c)) -#define UART_GET_LCRH(p) IO_READ((p)->uart_base + AMBA_UARTLCR_H) -#define UART_PUT_LCRH(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_H, (c)) -#define UART_RX_DATA(s) (((s) & AMBA_UARTFR_RXFE) == 0) -#define UART_TX_READY(s) (((s) & AMBA_UARTFR_TXFF) == 0) -#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0) - -#define AMBA_UARTRSR_ANY (AMBA_UARTRSR_OE|AMBA_UARTRSR_BE|AMBA_UARTRSR_PE|AMBA_UARTRSR_FE) -#define AMBA_UARTFR_MODEM_ANY (AMBA_UARTFR_DCD|AMBA_UARTFR_DSR|AMBA_UARTFR_CTS) - -/* - * Things needed by tty driver - */ -static struct tty_driver ambanormal_driver, ambacallout_driver; -static int ambauart_refcount; -static struct tty_struct *ambauart_table[SERIAL_AMBA_NR]; -static struct termios *ambauart_termios[SERIAL_AMBA_NR]; -static struct termios *ambauart_termios_locked[SERIAL_AMBA_NR]; - -#if defined(CONFIG_SERIAL_AMBA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -/* - * Things needed internally to this driver - */ - -/* - * tmp_buf is used as a temporary buffer by serial_write. We need to - * lock it in case the copy_from_user blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static u_char *tmp_buf; -static DECLARE_MUTEX(tmp_buf_sem); - -#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 -#define AMBA_ISR_PASS_LIMIT 256 - -#define EVT_WRITE_WAKEUP 0 - -struct amba_icount { - __u32 cts; - __u32 dsr; - __u32 rng; - __u32 dcd; - __u32 rx; - __u32 tx; - __u32 frame; - __u32 overrun; - __u32 parity; - __u32 brk; - __u32 buf_overrun; -}; - -/* - * Static information about the port - */ -struct amba_port { - unsigned int uart_base; - unsigned int irq; - unsigned int uartclk; - unsigned int fifosize; - unsigned int tiocm_support; - void (*set_mctrl)(struct amba_port *, u_int mctrl); -}; - -/* - * This is the state information which is persistent across opens - */ -struct amba_state { - struct amba_icount icount; - unsigned int line; - unsigned int close_delay; - unsigned int closing_wait; - unsigned int custom_divisor; - unsigned int flags; - struct termios normal_termios; - struct termios callout_termios; - - int count; - struct amba_info *info; -}; - -#define AMBA_XMIT_SIZE 1024 -/* - * This is the state information which is only valid when the port is open. - */ -struct amba_info { - struct amba_port *port; - struct amba_state *state; - struct tty_struct *tty; - unsigned char x_char; - unsigned char old_status; - unsigned char read_status_mask; - unsigned char ignore_status_mask; - struct circ_buf xmit; - unsigned int flags; -#ifdef SUPPORT_SYSRQ - unsigned long sysrq; -#endif - - unsigned int event; - unsigned int timeout; - unsigned int lcr_h; - unsigned int mctrl; - int blocked_open; - pid_t session; - pid_t pgrp; - - struct tasklet_struct tlet; - - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; - wait_queue_head_t delta_msr_wait; -}; - -#ifdef CONFIG_SERIAL_AMBA_CONSOLE -static struct console ambauart_cons; -#endif -static void ambauart_change_speed(struct amba_info *info, struct termios *old_termios); -static void ambauart_wait_until_sent(struct tty_struct *tty, int timeout); - -#if 1 //def CONFIG_SERIAL_INTEGRATOR -static void amba_set_mctrl_null(struct amba_port *port, u_int mctrl) -{ -} - -static struct amba_port amba_ports[SERIAL_AMBA_NR] = { - { - uart_base: IO_ADDRESS(INTEGRATOR_UART0_BASE), - irq: IRQ_UARTINT0, - uartclk: 14745600, - fifosize: 8, - set_mctrl: amba_set_mctrl_null, - }, - { - uart_base: IO_ADDRESS(INTEGRATOR_UART1_BASE), - irq: IRQ_UARTINT1, - uartclk: 14745600, - fifosize: 8, - set_mctrl: amba_set_mctrl_null, - } -}; -#endif - -static struct amba_state amba_state[SERIAL_AMBA_NR]; - -static void ambauart_enable_rx_interrupt(struct amba_info *info) -{ - unsigned int cr; - - cr = UART_GET_CR(info->port); - cr |= AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE; - UART_PUT_CR(info->port, cr); -} - -static void ambauart_disable_rx_interrupt(struct amba_info *info) -{ - unsigned int cr; - - cr = UART_GET_CR(info->port); - cr &= ~(AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE); - UART_PUT_CR(info->port, cr); -} - -static void ambauart_enable_tx_interrupt(struct amba_info *info) -{ - unsigned int cr; - - cr = UART_GET_CR(info->port); - cr |= AMBA_UARTCR_TIE; - UART_PUT_CR(info->port, cr); -} - -static void ambauart_disable_tx_interrupt(struct amba_info *info) -{ - unsigned int cr; - - cr = UART_GET_CR(info->port); - cr &= ~AMBA_UARTCR_TIE; - UART_PUT_CR(info->port, cr); -} - -static void ambauart_stop(struct tty_struct *tty) -{ - struct amba_info *info = tty->driver_data; - unsigned long flags; - - save_flags(flags); cli(); - ambauart_disable_tx_interrupt(info); - restore_flags(flags); -} - -static void ambauart_start(struct tty_struct *tty) -{ - struct amba_info *info = tty->driver_data; - unsigned long flags; - - save_flags(flags); cli(); - if (info->xmit.head != info->xmit.tail - && info->xmit.buf) - ambauart_enable_tx_interrupt(info); - restore_flags(flags); -} - - -/* - * This routine is used by the interrupt handler to schedule - * processing in the software interrupt portion of the driver. - */ -static void ambauart_event(struct amba_info *info, int event) -{ - info->event |= 1 << event; - tasklet_schedule(&info->tlet); -} - -static void -#ifdef SUPPORT_SYSRQ -ambauart_rx_chars(struct amba_info *info, struct pt_regs *regs) -#else -ambauart_rx_chars(struct amba_info *info) -#endif -{ - struct tty_struct *tty = info->tty; - unsigned int status, ch, rsr, flg, ignored = 0; - struct amba_icount *icount = &info->state->icount; - struct amba_port *port = info->port; - - status = UART_GET_FR(port); - while (UART_RX_DATA(status)) { - ch = UART_GET_CHAR(port); - - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - icount->rx++; - - flg = TTY_NORMAL; - - /* - * Note that the error handling code is - * out of the main execution path - */ - rsr = UART_GET_RSR(port); - if (rsr & AMBA_UARTRSR_ANY) - goto handle_error; -#ifdef SUPPORT_SYSRQ - if (info->sysrq) { - if (ch && time_before(jiffies, info->sysrq)) { - handle_sysrq(ch, regs, NULL, NULL); - info->sysrq = 0; - goto ignore_char; - } - info->sysrq = 0; - } -#endif - error_return: - *tty->flip.flag_buf_ptr++ = flg; - *tty->flip.char_buf_ptr++ = ch; - tty->flip.count++; - ignore_char: - status = UART_GET_FR(port); - } -out: - tty_flip_buffer_push(tty); - return; - -handle_error: - if (rsr & AMBA_UARTRSR_BE) { - rsr &= ~(AMBA_UARTRSR_FE | AMBA_UARTRSR_PE); - icount->brk++; - -#ifdef SUPPORT_SYSRQ - if (info->state->line == ambauart_cons.index) { - if (!info->sysrq) { - info->sysrq = jiffies + HZ*5; - goto ignore_char; - } - } -#endif - } else if (rsr & AMBA_UARTRSR_PE) - icount->parity++; - else if (rsr & AMBA_UARTRSR_FE) - icount->frame++; - if (rsr & AMBA_UARTRSR_OE) - icount->overrun++; - - if (rsr & info->ignore_status_mask) { - if (++ignored > 100) - goto out; - goto ignore_char; - } - rsr &= info->read_status_mask; - - if (rsr & AMBA_UARTRSR_BE) - flg = TTY_BREAK; - else if (rsr & AMBA_UARTRSR_PE) - flg = TTY_PARITY; - else if (rsr & AMBA_UARTRSR_FE) - flg = TTY_FRAME; - - if (rsr & AMBA_UARTRSR_OE) { - /* - * CHECK: does overrun affect the current character? - * ASSUMPTION: it does not. - */ - *tty->flip.flag_buf_ptr++ = flg; - *tty->flip.char_buf_ptr++ = ch; - tty->flip.count++; - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - ch = 0; - flg = TTY_OVERRUN; - } -#ifdef SUPPORT_SYSRQ - info->sysrq = 0; -#endif - goto error_return; -} - -static void ambauart_tx_chars(struct amba_info *info) -{ - struct amba_port *port = info->port; - int count; - - if (info->x_char) { - UART_PUT_CHAR(port, info->x_char); - info->state->icount.tx++; - info->x_char = 0; - return; - } - if (info->xmit.head == info->xmit.tail - || info->tty->stopped - || info->tty->hw_stopped) { - ambauart_disable_tx_interrupt(info); - return; - } - - count = port->fifosize; - do { - UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]); - info->xmit.tail = (info->xmit.tail + 1) & (AMBA_XMIT_SIZE - 1); - info->state->icount.tx++; - if (info->xmit.head == info->xmit.tail) - break; - } while (--count > 0); - - if (CIRC_CNT(info->xmit.head, - info->xmit.tail, - AMBA_XMIT_SIZE) < WAKEUP_CHARS) - ambauart_event(info, EVT_WRITE_WAKEUP); - - if (info->xmit.head == info->xmit.tail) { - ambauart_disable_tx_interrupt(info); - } -} - -static void ambauart_modem_status(struct amba_info *info) -{ - unsigned int status, delta; - struct amba_icount *icount = &info->state->icount; - - status = UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY; - - delta = status ^ info->old_status; - info->old_status = status; - - if (!delta) - return; - - if (delta & AMBA_UARTFR_DCD) { - icount->dcd++; -#ifdef CONFIG_HARD_PPS - if ((info->flags & ASYNC_HARDPPS_CD) && - (status & AMBA_UARTFR_DCD) - hardpps(); -#endif - if (info->flags & ASYNC_CHECK_CD) { - if (status & AMBA_UARTFR_DCD) - wake_up_interruptible(&info->open_wait); - else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_CALLOUT_NOHUP))) { - if (info->tty) - tty_hangup(info->tty); - } - } - } - - if (delta & AMBA_UARTFR_DSR) - icount->dsr++; - - if (delta & AMBA_UARTFR_CTS) { - icount->cts++; - - if (info->flags & ASYNC_CTS_FLOW) { - status &= AMBA_UARTFR_CTS; - - if (info->tty->hw_stopped) { - if (status) { - info->tty->hw_stopped = 0; - ambauart_enable_tx_interrupt(info); - ambauart_event(info, EVT_WRITE_WAKEUP); - } - } else { - if (!status) { - info->tty->hw_stopped = 1; - ambauart_disable_tx_interrupt(info); - } - } - } - } - wake_up_interruptible(&info->delta_msr_wait); - -} - -static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs) -{ - struct amba_info *info = dev_id; - unsigned int status, pass_counter = 0; - -#if DEBUG_LEDS - // tell the world - set_leds(get_leds() | RED_LED); -#endif - - status = UART_GET_INT_STATUS(info->port); - do { - /* - * FIXME: what about clearing the interrupts? - */ - - if (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS)) -#ifdef SUPPORT_SYSRQ - ambauart_rx_chars(info, regs); -#else - ambauart_rx_chars(info); -#endif - if (status & AMBA_UARTIIR_TIS) - ambauart_tx_chars(info); - if (status & AMBA_UARTIIR_MIS) - ambauart_modem_status(info); - if (pass_counter++ > AMBA_ISR_PASS_LIMIT) - break; - - status = UART_GET_INT_STATUS(info->port); - } while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS | AMBA_UARTIIR_TIS)); - -#if DEBUG_LEDS - // tell the world - set_leds(get_leds() & ~RED_LED); -#endif -} - -static void ambauart_tasklet_action(unsigned long data) -{ - struct amba_info *info = (struct amba_info *)data; - struct tty_struct *tty; - - tty = info->tty; - if (!tty || !test_and_clear_bit(EVT_WRITE_WAKEUP, &info->event)) - return; - - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); -} - -static int ambauart_startup(struct amba_info *info) -{ - unsigned long flags; - unsigned long page; - int retval = 0; - - page = get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - save_flags(flags); cli(); - - if (info->flags & ASYNC_INITIALIZED) { - free_page(page); - goto errout; - } - - if (info->xmit.buf) - free_page(page); - else - info->xmit.buf = (unsigned char *) page; - - /* - * Allocate the IRQ - */ - retval = request_irq(info->port->irq, ambauart_int, 0, "amba", info); - if (retval) { - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - retval = 0; - } - goto errout; - } - - info->mctrl = 0; - if (info->tty->termios->c_cflag & CBAUD) - info->mctrl = TIOCM_RTS | TIOCM_DTR; - info->port->set_mctrl(info->port, info->mctrl); - - /* - * initialise the old status of the modem signals - */ - info->old_status = UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY; - - /* - * Finally, enable interrupts - */ - ambauart_enable_rx_interrupt(info); - - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - info->xmit.head = info->xmit.tail = 0; - - /* - * Set up the tty->alt_speed kludge - */ - if (info->tty) { - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - } - - /* - * and set the speed of the serial port - */ - ambauart_change_speed(info, 0); - - info->flags |= ASYNC_INITIALIZED; - restore_flags(flags); - return 0; - -errout: - restore_flags(flags); - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void ambauart_shutdown(struct amba_info *info) -{ - unsigned long flags; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - save_flags(flags); cli(); /* Disable interrupts */ - - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free the irq - * here so the queue might never be woken up - */ - wake_up_interruptible(&info->delta_msr_wait); - - /* - * Free the IRQ - */ - free_irq(info->port->irq, info); - - if (info->xmit.buf) { - unsigned long pg = (unsigned long) info->xmit.buf; - info->xmit.buf = NULL; - free_page(pg); - } - - /* - * disable all interrupts, disable the port - */ - UART_PUT_CR(info->port, 0); - - /* disable break condition and fifos */ - UART_PUT_LCRH(info->port, UART_GET_LCRH(info->port) & - ~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN)); - - if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) - info->mctrl &= ~(TIOCM_DTR|TIOCM_RTS); - info->port->set_mctrl(info->port, info->mctrl); - - /* kill off our tasklet */ - tasklet_kill(&info->tlet); - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; - restore_flags(flags); -} - -static void ambauart_change_speed(struct amba_info *info, struct termios *old_termios) -{ - unsigned int lcr_h, baud, quot, cflag, old_cr, bits; - unsigned long flags; - - if (!info->tty || !info->tty->termios) - return; - - cflag = info->tty->termios->c_cflag; - -#if DEBUG - printk("ambauart_set_cflag(0x%x) called\n", cflag); -#endif - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: lcr_h = AMBA_UARTLCR_H_WLEN_5; bits = 7; break; - case CS6: lcr_h = AMBA_UARTLCR_H_WLEN_6; bits = 8; break; - case CS7: lcr_h = AMBA_UARTLCR_H_WLEN_7; bits = 9; break; - default: lcr_h = AMBA_UARTLCR_H_WLEN_8; bits = 10; break; // CS8 - } - if (cflag & CSTOPB) { - lcr_h |= AMBA_UARTLCR_H_STP2; - bits ++; - } - if (cflag & PARENB) { - lcr_h |= AMBA_UARTLCR_H_PEN; - bits++; - if (!(cflag & PARODD)) - lcr_h |= AMBA_UARTLCR_H_EPS; - } - if (info->port->fifosize > 1) - lcr_h |= AMBA_UARTLCR_H_FEN; - - do { - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(info->tty); - if (!baud) - baud = 9600; - - if (baud == 38400 && - ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) - quot = info->state->custom_divisor; - else - quot = (info->port->uartclk / (16 * baud)) - 1; - - if (!quot && old_termios) { - info->tty->termios->c_cflag &= ~CBAUD; - info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); - old_termios = NULL; - } - } while (quot == 0 && old_termios); - - /* As a last resort, if the quotient is zero, default to 9600 bps */ - if (!quot) - quot = (info->port->uartclk / (16 * 9600)) - 1; - - info->timeout = (info->port->fifosize * HZ * bits * quot) / - (info->port->uartclk / 16); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - if (cflag & CRTSCTS) - info->flags |= ASYNC_CTS_FLOW; - else - info->flags &= ~ASYNC_CTS_FLOW; - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else - info->flags |= ASYNC_CHECK_CD; - - /* - * Set up parity check flag - */ -#define RELEVENT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - - info->read_status_mask = AMBA_UARTRSR_OE; - if (I_INPCK(info->tty)) - info->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE; - if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) - info->read_status_mask |= AMBA_UARTRSR_BE; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE; - if (I_IGNBRK(info->tty)) { - info->ignore_status_mask |= AMBA_UARTRSR_BE; - /* - * If we're ignoring parity and break indicators, - * ignore overruns to (for real raw support). - */ - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= AMBA_UARTRSR_OE; - } - - /* first, disable everything */ - save_flags(flags); cli(); - old_cr = UART_GET_CR(info->port) &= ~AMBA_UARTCR_MSIE; - - if ((info->flags & ASYNC_HARDPPS_CD) || - (cflag & CRTSCTS) || - !(cflag & CLOCAL)) - old_cr |= AMBA_UARTCR_MSIE; - - UART_PUT_CR(info->port, 0); - restore_flags(flags); - - /* Set baud rate */ - UART_PUT_LCRM(info->port, ((quot & 0xf00) >> 8)); - UART_PUT_LCRL(info->port, (quot & 0xff)); - - /* - * ----------v----------v----------v----------v----- - * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L - * ----------^----------^----------^----------^----- - */ - UART_PUT_LCRH(info->port, lcr_h); - UART_PUT_CR(info->port, old_cr); -} - -static void ambauart_put_char(struct tty_struct *tty, u_char ch) -{ - struct amba_info *info = tty->driver_data; - unsigned long flags; - - if (!tty || !info->xmit.buf) - return; - - save_flags(flags); cli(); - if (CIRC_SPACE(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE) != 0) { - info->xmit.buf[info->xmit.head] = ch; - info->xmit.head = (info->xmit.head + 1) & (AMBA_XMIT_SIZE - 1); - } - restore_flags(flags); -} - -static void ambauart_flush_chars(struct tty_struct *tty) -{ - struct amba_info *info = tty->driver_data; - unsigned long flags; - - if (info->xmit.head == info->xmit.tail - || tty->stopped - || tty->hw_stopped - || !info->xmit.buf) - return; - - save_flags(flags); cli(); - ambauart_enable_tx_interrupt(info); - restore_flags(flags); -} - -static int ambauart_write(struct tty_struct *tty, int from_user, - const u_char * buf, int count) -{ - struct amba_info *info = tty->driver_data; - unsigned long flags; - int c, ret = 0; - - if (!tty || !info->xmit.buf || !tmp_buf) - return 0; - - save_flags(flags); - if (from_user) { - down(&tmp_buf_sem); - while (1) { - int c1; - c = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - AMBA_XMIT_SIZE); - if (count < c) - c = count; - if (c <= 0) - break; - - c -= copy_from_user(tmp_buf, buf, c); - if (!c) { - if (!ret) - ret = -EFAULT; - break; - } - cli(); - c1 = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - AMBA_XMIT_SIZE); - if (c1 < c) - c = c1; - memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); - info->xmit.head = (info->xmit.head + c) & - (AMBA_XMIT_SIZE - 1); - restore_flags(flags); - buf += c; - count -= c; - ret += c; - } - up(&tmp_buf_sem); - } else { - cli(); - while (1) { - c = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - AMBA_XMIT_SIZE); - if (count < c) - c = count; - if (c <= 0) - break; - memcpy(info->xmit.buf + info->xmit.head, buf, c); - info->xmit.head = (info->xmit.head + c) & - (AMBA_XMIT_SIZE - 1); - buf += c; - count -= c; - ret += c; - } - restore_flags(flags); - } - if (info->xmit.head != info->xmit.tail - && !tty->stopped - && !tty->hw_stopped) - ambauart_enable_tx_interrupt(info); - return ret; -} - -static int ambauart_write_room(struct tty_struct *tty) -{ - struct amba_info *info = tty->driver_data; - - return CIRC_SPACE(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE); -} - -static int ambauart_chars_in_buffer(struct tty_struct *tty) -{ - struct amba_info *info = tty->driver_data; - - return CIRC_CNT(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE); -} - -static void ambauart_flush_buffer(struct tty_struct *tty) -{ - struct amba_info *info = tty->driver_data; - unsigned long flags; - -#if DEBUG - printk("ambauart_flush_buffer(%d) called\n", - minor(tty->device) - tty->driver.minor_start); -#endif - save_flags(flags); cli(); - info->xmit.head = info->xmit.tail = 0; - restore_flags(flags); - wake_up_interruptible(&tty->write_wait); - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void ambauart_send_xchar(struct tty_struct *tty, char ch) -{ - struct amba_info *info = tty->driver_data; - - info->x_char = ch; - if (ch) - ambauart_enable_tx_interrupt(info); -} - -static void ambauart_throttle(struct tty_struct *tty) -{ - struct amba_info *info = tty->driver_data; - unsigned long flags; - - if (I_IXOFF(tty)) - ambauart_send_xchar(tty, STOP_CHAR(tty)); - - if (tty->termios->c_cflag & CRTSCTS) { - save_flags(flags); cli(); - info->mctrl &= ~TIOCM_RTS; - info->port->set_mctrl(info->port, info->mctrl); - restore_flags(flags); - } -} - -static void ambauart_unthrottle(struct tty_struct *tty) -{ - struct amba_info *info = (struct amba_info *) tty->driver_data; - unsigned long flags; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - ambauart_send_xchar(tty, START_CHAR(tty)); - } - - if (tty->termios->c_cflag & CRTSCTS) { - save_flags(flags); cli(); - info->mctrl |= TIOCM_RTS; - info->port->set_mctrl(info->port, info->mctrl); - restore_flags(flags); - } -} - -static int get_serial_info(struct amba_info *info, struct serial_struct *retinfo) -{ - struct amba_state *state = info->state; - struct amba_port *port = info->port; - struct serial_struct tmp; - - memset(&tmp, 0, sizeof(tmp)); - tmp.type = 0; - tmp.line = state->line; - tmp.port = port->uart_base; - if (HIGH_BITS_OFFSET) - tmp.port_high = port->uart_base >> HIGH_BITS_OFFSET; - tmp.irq = port->irq; - tmp.flags = 0; - tmp.xmit_fifo_size = port->fifosize; - tmp.baud_base = port->uartclk / 16; - tmp.close_delay = state->close_delay; - tmp.closing_wait = state->closing_wait; - tmp.custom_divisor = state->custom_divisor; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int set_serial_info(struct amba_info *info, - struct serial_struct *newinfo) -{ - struct serial_struct new_serial; - struct amba_state *state, old_state; - struct amba_port *port; - unsigned long new_port; - unsigned int i, change_irq, change_port; - int retval = 0; - - if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) - return -EFAULT; - - state = info->state; - old_state = *state; - port = info->port; - - new_port = new_serial.port; - if (HIGH_BITS_OFFSET) - new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; - - change_irq = new_serial.irq != port->irq; - change_port = new_port != port->uart_base; - - if (!capable(CAP_SYS_ADMIN)) { - if (change_irq || change_port || - (new_serial.baud_base != port->uartclk / 16) || - (new_serial.close_delay != state->close_delay) || - (new_serial.xmit_fifo_size != port->fifosize) || - ((new_serial.flags & ~ASYNC_USR_MASK) != - (state->flags & ~ASYNC_USR_MASK))) - return -EPERM; - state->flags = ((state->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - info->flags = ((info->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - state->custom_divisor = new_serial.custom_divisor; - goto check_and_exit; - } - - if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || - (new_serial.baud_base < 9600)) - return -EINVAL; - - if (new_serial.type && change_port) { - for (i = 0; i < SERIAL_AMBA_NR; i++) - if ((port != amba_ports + i) && - amba_ports[i].uart_base != new_port) - return -EADDRINUSE; - } - - if ((change_port || change_irq) && (state->count > 1)) - return -EBUSY; - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - port->uartclk = new_serial.baud_base * 16; - state->flags = ((state->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | - (info->flags & ASYNC_INTERNAL_FLAGS)); - state->custom_divisor = new_serial.custom_divisor; - state->close_delay = new_serial.close_delay * HZ / 100; - state->closing_wait = new_serial.closing_wait * HZ / 100; - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - port->fifosize = new_serial.xmit_fifo_size; - - if (change_port || change_irq) { - /* - * We need to shutdown the serial port at the old - * port/irq combination. - */ - ambauart_shutdown(info); - port->irq = new_serial.irq; - port->uart_base = new_port; - } - -check_and_exit: - if (!port->uart_base) - return 0; - if (info->flags & ASYNC_INITIALIZED) { - if ((old_state.flags & ASYNC_SPD_MASK) != - (state->flags & ASYNC_SPD_MASK) || - (old_state.custom_divisor != state->custom_divisor)) { - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - ambauart_change_speed(info, NULL); - } - } else - retval = ambauart_startup(info); - return retval; -} - - -/* - * get_lsr_info - get line status register info - */ -static int get_lsr_info(struct amba_info *info, unsigned int *value) -{ - unsigned int result, status; - unsigned long flags; - - save_flags(flags); cli(); - status = UART_GET_FR(info->port); - restore_flags(flags); - result = status & AMBA_UARTFR_BUSY ? TIOCSER_TEMT : 0; - - /* - * If we're about to load something into the transmit - * register, we'll pretend the transmitter isn't empty to - * avoid a race condition (depending on when the transmit - * interrupt happens). - */ - if (info->x_char || - ((CIRC_CNT(info->xmit.head, info->xmit.tail, - AMBA_XMIT_SIZE) > 0) && - !info->tty->stopped && !info->tty->hw_stopped)) - result &= TIOCSER_TEMT; - - return put_user(result, value); -} - -static int get_modem_info(struct amba_info *info, unsigned int *value) -{ - unsigned int result = info->mctrl; - unsigned int status; - - status = UART_GET_FR(info->port); - if (status & AMBA_UARTFR_DCD) - result |= TIOCM_CAR; - if (status & AMBA_UARTFR_DSR) - result |= TIOCM_DSR; - if (status & AMBA_UARTFR_CTS) - result |= TIOCM_CTS; - - return put_user(result, value); -} - -static int set_modem_info(struct amba_info *info, unsigned int cmd, - unsigned int *value) -{ - unsigned int arg, old; - unsigned long flags; - - if (get_user(arg, value)) - return -EFAULT; - - old = info->mctrl; - switch (cmd) { - case TIOCMBIS: - info->mctrl |= arg; - break; - - case TIOCMBIC: - info->mctrl &= ~arg; - break; - - case TIOCMSET: - info->mctrl = arg; - break; - - default: - return -EINVAL; - } - save_flags(flags); cli(); - if (old != info->mctrl) - info->port->set_mctrl(info->port, info->mctrl); - restore_flags(flags); - return 0; -} - -static void ambauart_break_ctl(struct tty_struct *tty, int break_state) -{ - struct amba_info *info = tty->driver_data; - unsigned long flags; - unsigned int lcr_h; - - save_flags(flags); cli(); - lcr_h = UART_GET_LCRH(info->port); - if (break_state == -1) - lcr_h |= AMBA_UARTLCR_H_BRK; - else - lcr_h &= ~AMBA_UARTLCR_H_BRK; - UART_PUT_LCRH(info->port, lcr_h); - restore_flags(flags); -} - -static int ambauart_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct amba_info *info = tty->driver_data; - struct amba_icount cprev, cnow; - struct serial_icounter_struct icount; - unsigned long flags; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && - (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TIOCMGET: - return get_modem_info(info, (unsigned int *)arg); - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - return set_modem_info(info, cmd, (unsigned int *)arg); - case TIOCGSERIAL: - return get_serial_info(info, - (struct serial_struct *)arg); - case TIOCSSERIAL: - return set_serial_info(info, - (struct serial_struct *)arg); - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *)arg); - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - save_flags(flags); cli(); - /* note the counters on entry */ - cprev = info->state->icount; - /* Force modem status interrupts on */ - UART_PUT_CR(info->port, UART_GET_CR(info->port) | AMBA_UARTCR_MSIE); - restore_flags(flags); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - save_flags(flags); cli(); - cnow = info->state->icount; /* atomic copy */ - restore_flags(flags); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - case TIOCGICOUNT: - save_flags(flags); cli(); - cnow = info->state->icount; - restore_flags(flags); - icount.cts = cnow.cts; - icount.dsr = cnow.dsr; - icount.rng = cnow.rng; - icount.dcd = cnow.dcd; - icount.rx = cnow.rx; - icount.tx = cnow.tx; - icount.frame = cnow.frame; - icount.overrun = cnow.overrun; - icount.parity = cnow.parity; - icount.brk = cnow.brk; - icount.buf_overrun = cnow.buf_overrun; - - return copy_to_user((void *)arg, &icount, sizeof(icount)) - ? -EFAULT : 0; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void ambauart_set_termios(struct tty_struct *tty, struct termios *old_termios) -{ - struct amba_info *info = tty->driver_data; - unsigned long flags; - unsigned int cflag = tty->termios->c_cflag; - - if ((cflag ^ old_termios->c_cflag) == 0 && - RELEVENT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) - return; - - ambauart_change_speed(info, old_termios); - - /* Handle transition to B0 status */ - if ((old_termios->c_cflag & CBAUD) && - !(cflag & CBAUD)) { - save_flags(flags); cli(); - info->mctrl &= ~(TIOCM_RTS | TIOCM_DTR); - info->port->set_mctrl(info->port, info->mctrl); - restore_flags(flags); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - (cflag & CBAUD)) { - save_flags(flags); cli(); - info->mctrl |= TIOCM_DTR; - if (!(cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &tty->flags)) - info->mctrl |= TIOCM_RTS; - info->port->set_mctrl(info->port, info->mctrl); - restore_flags(flags); - } - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(cflag & CRTSCTS)) { - tty->hw_stopped = 0; - ambauart_start(tty); - } - -#if 0 - /* - * No need to wake up processes in open wait, since they - * sample the CLOCAL flag once, and don't recheck it. - * XXX It's not clear whether the current behavior is correct - * or not. Hence, this may change..... - */ - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&info->open_wait); -#endif -} - -static void ambauart_close(struct tty_struct *tty, struct file *filp) -{ - struct amba_info *info = tty->driver_data; - struct amba_state *state; - unsigned long flags; - - if (!info) - return; - - state = info->state; - -#if DEBUG - printk("ambauart_close() called\n"); -#endif - - save_flags(flags); cli(); - - if (tty_hung_up_p(filp)) { - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("ambauart_close: bad serial port count; tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - printk("rs_close: bad serial port count for %s%d: %d\n", - tty->driver.name, info->state->line, state->count); - state->count = 0; - } - if (state->count) { - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - info->flags |= ASYNC_CLOSING; - restore_flags(flags); - /* - * Save the termios structure, since this port may have - * separate termios for callout and dialin. - */ - if (info->flags & ASYNC_NORMAL_ACTIVE) - info->state->normal_termios = *tty->termios; - if (info->flags & ASYNC_CALLOUT_ACTIVE) - info->state->callout_termios = *tty->termios; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->state->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->state->closing_wait); - /* - * At this point, we stop accepting input. To do this, we - * disable the receive line status interrupts. - */ - if (info->flags & ASYNC_INITIALIZED) { - ambauart_disable_rx_interrupt(info); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - ambauart_wait_until_sent(tty, info->timeout); - } - ambauart_shutdown(info); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; - info->event = 0; - info->tty = NULL; - if (info->blocked_open) { - if (info->state->close_delay) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(info->state->close_delay); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| - ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - MOD_DEC_USE_COUNT; -} - -static void ambauart_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct amba_info *info = (struct amba_info *) tty->driver_data; - unsigned long char_time, expire; - unsigned int status; - - if (info->port->fifosize == 0) - return; - - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = (info->timeout - HZ/50) / info->port->fifosize; - char_time = char_time / 5; - if (char_time == 0) - char_time = 1; - if (timeout && timeout < char_time) - char_time = timeout; - /* - * If the transmitter hasn't cleared in twice the approximate - * amount of time to send the entire FIFO, it probably won't - * ever clear. This assumes the UART isn't doing flow - * control, which is currently the case. Hence, if it ever - * takes longer than info->timeout, this is probably due to a - * UART bug of some kind. So, we clamp the timeout parameter at - * 2*info->timeout. - */ - if (!timeout || timeout > 2 * info->timeout) - timeout = 2 * info->timeout; - - expire = jiffies + timeout; -#if DEBUG - printk("ambauart_wait_until_sent(%d), jiff=%lu, expire=%lu...\n", - minor(tty->device) - tty->driver.minor_start, jiffies, - expire); -#endif - while (UART_GET_FR(info->port) & AMBA_UARTFR_BUSY) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(char_time); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, expire)) - break; - status = UART_GET_FR(info->port); - } - set_current_state(TASK_RUNNING); -} - -static void ambauart_hangup(struct tty_struct *tty) -{ - struct amba_info *info = tty->driver_data; - struct amba_state *state = info->state; - - ambauart_flush_buffer(tty); - if (info->flags & ASYNC_CLOSING) - return; - ambauart_shutdown(info); - info->event = 0; - state->count = 0; - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); - info->tty = NULL; - wake_up_interruptible(&info->open_wait); -} - -static int block_til_ready(struct tty_struct *tty, struct file *filp, - struct amba_info *info) -{ - DECLARE_WAITQUEUE(wait, current); - struct amba_state *state = info->state; - unsigned long flags; - int do_clocal = 0, extra_count = 0, retval; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); - return (info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS; - } - - /* - * If this is a callout device, then just make sure the normal - * device isn't being used. - */ - if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { - if (info->flags & ASYNC_NORMAL_ACTIVE) - return -EBUSY; - if ((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_SESSION_LOCKOUT) && - (info->session != current->session)) - return -EBUSY; - if ((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_PGRP_LOCKOUT) && - (info->pgrp != current->pgrp)) - return -EBUSY; - info->flags |= ASYNC_CALLOUT_ACTIVE; - return 0; - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - if (info->flags & ASYNC_CALLOUT_ACTIVE) - return -EBUSY; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (info->flags & ASYNC_CALLOUT_ACTIVE) { - if (state->normal_termios.c_cflag & CLOCAL) - do_clocal = 1; - } else { - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - } - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, state->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); - save_flags(flags); cli(); - if (!tty_hung_up_p(filp)) { - extra_count = 1; - state->count--; - } - restore_flags(flags); - info->blocked_open++; - while (1) { - save_flags(flags); cli(); - if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && - (tty->termios->c_cflag & CBAUD)) { - info->mctrl = TIOCM_DTR | TIOCM_RTS; - info->port->set_mctrl(info->port, info->mctrl); - } - restore_flags(flags); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { - if (info->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; - break; - } - if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && - !(info->flags & ASYNC_CLOSING) && - (do_clocal || (UART_GET_FR(info->port) & AMBA_UARTFR_DCD))) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } - schedule(); - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&info->open_wait, &wait); - if (extra_count) - state->count++; - info->blocked_open--; - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static struct amba_info *ambauart_get(int line) -{ - struct amba_info *info; - struct amba_state *state = amba_state + line; - - state->count++; - if (state->info) - return state->info; - info = kmalloc(sizeof(struct amba_info), GFP_KERNEL); - if (info) { - memset(info, 0, sizeof(struct amba_info)); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_waitqueue_head(&info->delta_msr_wait); - info->flags = state->flags; - info->state = state; - info->port = amba_ports + line; - tasklet_init(&info->tlet, ambauart_tasklet_action, - (unsigned long)info); - } - if (state->info) { - kfree(info); - return state->info; - } - state->info = info; - return info; -} - -static int ambauart_open(struct tty_struct *tty, struct file *filp) -{ - struct amba_info *info; - int retval, line = minor(tty->device) - tty->driver.minor_start; - -#if DEBUG - printk("ambauart_open(%d) called\n", line); -#endif - - // is this a line that we've got? - MOD_INC_USE_COUNT; - if (line >= SERIAL_AMBA_NR) { - MOD_DEC_USE_COUNT; - return -ENODEV; - } - - info = ambauart_get(line); - if (!info) - return -ENOMEM; - - tty->driver_data = info; - info->tty = tty; - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - /* - * Make sure we have the temporary buffer allocated - */ - if (!tmp_buf) { - unsigned long page = get_zeroed_page(GFP_KERNEL); - if (tmp_buf) - free_page(page); - else if (!page) { - MOD_DEC_USE_COUNT; - return -ENOMEM; - } - tmp_buf = (u_char *)page; - } - - /* - * If the port is in the middle of closing, bail out now. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); - MOD_DEC_USE_COUNT; - return -EAGAIN; - } - - /* - * Start up the serial port - */ - retval = ambauart_startup(info); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - - if ((info->state->count == 1) && - (info->flags & ASYNC_SPLIT_TERMIOS)) { - if (tty->driver.subtype == SERIAL_TYPE_NORMAL) - *tty->termios = info->state->normal_termios; - else - *tty->termios = info->state->callout_termios; - } -#ifdef CONFIG_SERIAL_AMBA_CONSOLE - if (ambauart_cons.cflag && ambauart_cons.index == line) { - tty->termios->c_cflag = ambauart_cons.cflag; - ambauart_cons.cflag = 0; - } -#endif - ambauart_change_speed(info, NULL); - info->session = current->session; - info->pgrp = current->pgrp; - return 0; -} - -int __init ambauart_init(void) -{ - int i; - - ambanormal_driver.magic = TTY_DRIVER_MAGIC; - ambanormal_driver.driver_name = "serial_amba"; - ambanormal_driver.name = SERIAL_AMBA_NAME; - ambanormal_driver.major = SERIAL_AMBA_MAJOR; - ambanormal_driver.minor_start = SERIAL_AMBA_MINOR; - ambanormal_driver.num = SERIAL_AMBA_NR; - ambanormal_driver.type = TTY_DRIVER_TYPE_SERIAL; - ambanormal_driver.subtype = SERIAL_TYPE_NORMAL; - ambanormal_driver.init_termios = tty_std_termios; - ambanormal_driver.init_termios.c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; - ambanormal_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; - ambanormal_driver.refcount = &ambauart_refcount; - ambanormal_driver.table = ambauart_table; - ambanormal_driver.termios = ambauart_termios; - ambanormal_driver.termios_locked = ambauart_termios_locked; - - ambanormal_driver.open = ambauart_open; - ambanormal_driver.close = ambauart_close; - ambanormal_driver.write = ambauart_write; - ambanormal_driver.put_char = ambauart_put_char; - ambanormal_driver.flush_chars = ambauart_flush_chars; - ambanormal_driver.write_room = ambauart_write_room; - ambanormal_driver.chars_in_buffer = ambauart_chars_in_buffer; - ambanormal_driver.flush_buffer = ambauart_flush_buffer; - ambanormal_driver.ioctl = ambauart_ioctl; - ambanormal_driver.throttle = ambauart_throttle; - ambanormal_driver.unthrottle = ambauart_unthrottle; - ambanormal_driver.send_xchar = ambauart_send_xchar; - ambanormal_driver.set_termios = ambauart_set_termios; - ambanormal_driver.stop = ambauart_stop; - ambanormal_driver.start = ambauart_start; - ambanormal_driver.hangup = ambauart_hangup; - ambanormal_driver.break_ctl = ambauart_break_ctl; - ambanormal_driver.wait_until_sent = ambauart_wait_until_sent; - ambanormal_driver.read_proc = NULL; - - /* - * The callout device is just like the normal device except for - * the major number and the subtype code. - */ - ambacallout_driver = ambanormal_driver; - ambacallout_driver.name = CALLOUT_AMBA_NAME; - ambacallout_driver.major = CALLOUT_AMBA_MAJOR; - ambacallout_driver.subtype = SERIAL_TYPE_CALLOUT; - ambacallout_driver.read_proc = NULL; - ambacallout_driver.proc_entry = NULL; - - if (tty_register_driver(&ambanormal_driver)) - panic("Couldn't register AMBA serial driver\n"); - if (tty_register_driver(&ambacallout_driver)) - panic("Couldn't register AMBA callout driver\n"); - - for (i = 0; i < SERIAL_AMBA_NR; i++) { - struct amba_state *state = amba_state + i; - state->line = i; - state->close_delay = 5 * HZ / 10; - state->closing_wait = 30 * HZ; - state->callout_termios = ambacallout_driver.init_termios; - state->normal_termios = ambanormal_driver.init_termios; - } - - return 0; -} - -__initcall(ambauart_init); - -#ifdef CONFIG_SERIAL_AMBA_CONSOLE -/************** console driver *****************/ - -/* - * This code is currently never used; console->read is never called. - * Therefore, although we have an implementation, we don't use it. - * FIXME: the "const char *s" should be fixed to "char *s" some day. - * (when the definition in include/linux/console.h is also fixed) - */ -#ifdef used_and_not_const_char_pointer -static int ambauart_console_read(struct console *co, const char *s, u_int count) -{ - struct amba_port *port = &amba_ports[co->index]; - unsigned int status; - char *w; - int c; -#if DEBUG - printk("ambauart_console_read() called\n"); -#endif - - c = 0; - w = s; - while (c < count) { - status = UART_GET_FR(port); - if (UART_RX_DATA(status)) { - *w++ = UART_GET_CHAR(port); - c++; - } else { - // nothing more to get, return - return c; - } - } - // return the count - return c; -} -#endif - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console must be locked when we get here. - */ -static void ambauart_console_write(struct console *co, const char *s, u_int count) -{ - struct amba_port *port = &amba_ports[co->index]; - unsigned int status, old_cr; - int i; - - /* - * First save the CR then disable the interrupts - */ - old_cr = UART_GET_CR(port); - UART_PUT_CR(port, AMBA_UARTCR_UARTEN); - - /* - * Now, do each character - */ - for (i = 0; i < count; i++) { - do { - status = UART_GET_FR(port); - } while (!UART_TX_READY(status)); - UART_PUT_CHAR(port, s[i]); - if (s[i] == '\n') { - do { - status = UART_GET_FR(port); - } while (!UART_TX_READY(status)); - UART_PUT_CHAR(port, '\r'); - } - } - - /* - * Finally, wait for transmitter to become empty - * and restore the TCR - */ - do { - status = UART_GET_FR(port); - } while (status & AMBA_UARTFR_BUSY); - UART_PUT_CR(port, old_cr); -} - -static kdev_t ambauart_console_device(struct console *c) -{ - return mk_kdev(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + c->index); -} - -static int __init ambauart_console_setup(struct console *co, char *options) -{ - struct amba_port *port; - int baud = 38400; - int bits = 8; - int parity = 'n'; - u_int cflag = CREAD | HUPCL | CLOCAL; - u_int lcr_h, quot; - - if (co->index >= SERIAL_AMBA_NR) - co->index = 0; - - port = &amba_ports[co->index]; - - if (options) { - char *s = options; - baud = simple_strtoul(s, NULL, 10); - while (*s >= '0' && *s <= '9') - s++; - if (*s) parity = *s++; - if (*s) bits = *s - '0'; - } - - /* - * Now construct a cflag setting. - */ - switch (baud) { - case 1200: cflag |= B1200; break; - case 2400: cflag |= B2400; break; - case 4800: cflag |= B4800; break; - default: cflag |= B9600; baud = 9600; break; - case 19200: cflag |= B19200; break; - case 38400: cflag |= B38400; break; - case 57600: cflag |= B57600; break; - case 115200: cflag |= B115200; break; - } - switch (bits) { - case 7: cflag |= CS7; lcr_h = AMBA_UARTLCR_H_WLEN_7; break; - default: cflag |= CS8; lcr_h = AMBA_UARTLCR_H_WLEN_8; break; - } - switch (parity) { - case 'o': - case 'O': cflag |= PARODD; lcr_h |= AMBA_UARTLCR_H_PEN; break; - case 'e': - case 'E': cflag |= PARENB; lcr_h |= AMBA_UARTLCR_H_PEN | - AMBA_UARTLCR_H_EPS; break; - } - - co->cflag = cflag; - - if (port->fifosize > 1) - lcr_h |= AMBA_UARTLCR_H_FEN; - - quot = (port->uartclk / (16 * baud)) - 1; - - UART_PUT_LCRL(port, (quot & 0xff)); - UART_PUT_LCRM(port, (quot >> 8)); - UART_PUT_LCRH(port, lcr_h); - - /* we will enable the port as we need it */ - UART_PUT_CR(port, 0); - - return 0; -} - -static struct console ambauart_cons = -{ - name: SERIAL_AMBA_NAME, - write: ambauart_console_write, -#ifdef used_and_not_const_char_pointer - read: ambauart_console_read, -#endif - device: ambauart_console_device, - setup: ambauart_console_setup, - flags: CON_PRINTBUFFER, - index: -1, -}; - -void __init ambauart_console_init(void) -{ - register_console(&ambauart_cons); -} - -#endif /* CONFIG_SERIAL_AMBA_CONSOLE */ - -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From e5066df359ea4afa14b43fc46b17d9271da49bc7 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 25 Jul 2002 06:38:32 -0700 Subject: cmd640 IDE driver internal spinlocks for config etc accesses. This is no better or worse than the cli/sti the cmd640 driver used to have, but at least it compiles and works in the new scheme of things. Perfection can wait. Especially since that probably involves removing the PCI-related code, and just trusting the native Linux direct PCI accesses. --- drivers/ide/cmd640.c | 50 ++++++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c index 0c5f45be113a..742f8c7a54f3 100644 --- a/drivers/ide/cmd640.c +++ b/drivers/ide/cmd640.c @@ -214,17 +214,19 @@ static unsigned int cmd640_chip_version; * Therefore, we must use direct IO instead. */ +/* This is broken, but no more so than the old code.. */ +static spinlock_t cmd640_lock = SPIN_LOCK_UNLOCKED; + /* PCI method 1 access */ static void put_cmd640_reg_pci1 (unsigned short reg, byte val) { unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&cmd640_lock, flags); outl_p((reg & 0xfc) | cmd640_key, 0xcf8); outb_p(val, (reg & 3) | 0xcfc); - restore_flags(flags); + spin_unlock_irqrestore(&cmd640_lock, flags); } static u8 get_cmd640_reg_pci1 (unsigned short reg) @@ -232,11 +234,10 @@ static u8 get_cmd640_reg_pci1 (unsigned short reg) u8 b; unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&cmd640_lock, flags); outl_p((reg & 0xfc) | cmd640_key, 0xcf8); b = inb_p((reg & 3) | 0xcfc); - restore_flags(flags); + spin_unlock_irqrestore(&cmd640_lock, flags); return b; } @@ -246,12 +247,11 @@ static void put_cmd640_reg_pci2 (unsigned short reg, u8 val) { unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&cmd640_lock, flags); outb_p(0x10, 0xcf8); outb_p(val, cmd640_key + reg); outb_p(0, 0xcf8); - restore_flags(flags); + spin_unlock_irqrestore(&cmd640_lock, flags); } static u8 get_cmd640_reg_pci2 (unsigned short reg) @@ -259,12 +259,11 @@ static u8 get_cmd640_reg_pci2 (unsigned short reg) u8 b; unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&cmd640_lock, flags); outb_p(0x10, 0xcf8); b = inb_p(cmd640_key + reg); outb_p(0, 0xcf8); - restore_flags(flags); + spin_unlock_irqrestore(&cmd640_lock, flags); return b; } @@ -274,11 +273,10 @@ static void put_cmd640_reg_vlb (unsigned short reg, u8 val) { unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&cmd640_lock, flags); outb_p(reg, cmd640_key); outb_p(val, cmd640_key + 4); - restore_flags(flags); + spin_unlock_irqrestore(&cmd640_lock, flags); } static u8 get_cmd640_reg_vlb (unsigned short reg) @@ -286,11 +284,10 @@ static u8 get_cmd640_reg_vlb (unsigned short reg) u8 b; unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&cmd640_lock, flags); outb_p(reg, cmd640_key); b = inb_p(cmd640_key + 4); - restore_flags(flags); + spin_unlock_irqrestore(&cmd640_lock, flags); return b; } @@ -367,8 +364,7 @@ static int __init secondary_port_responding (void) { unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&cmd640_lock, flags); outb_p(0x0a, 0x170 + IDE_SELECT_OFFSET); /* select drive0 */ udelay(100); @@ -376,11 +372,11 @@ static int __init secondary_port_responding (void) outb_p(0x1a, 0x170 + IDE_SELECT_OFFSET); /* select drive1 */ udelay(100); if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x1a) { - restore_flags(flags); + spin_unlock_irqrestore(&cmd640_lock, flags); return 0; /* nothing responded */ } } - restore_flags(flags); + spin_unlock_irqrestore(&cmd640_lock, flags); return 1; /* success */ } @@ -461,8 +457,7 @@ static void set_prefetch_mode (unsigned int index, int mode) u8 b; unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&cmd640_lock, flags); b = get_cmd640_reg(reg); if (mode) { /* want prefetch on? */ # if CMD640_PREFETCH_MASKS @@ -478,7 +473,7 @@ static void set_prefetch_mode (unsigned int index, int mode) b |= prefetch_masks[index]; /* disable prefetch */ } put_cmd640_reg(reg, b); - restore_flags(flags); + spin_unlock_irqrestore(&cmd640_lock, flags); } /* @@ -579,8 +574,7 @@ static void program_drive_counts (unsigned int index) /* * Now that everything is ready, program the new timings */ - save_flags (flags); - cli(); + spin_lock(&cmd640_lock, flags); /* * Program the address_setup clocks into ARTTIM reg, * and then the active/recovery counts into the DRWTIM reg @@ -589,7 +583,7 @@ static void program_drive_counts (unsigned int index) setup_count |= get_cmd640_reg(arttim_regs[index]) & 0x3f; put_cmd640_reg(arttim_regs[index], setup_count); put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count)); - restore_flags(flags); + spin_unlock_irqrestore(&cmd640_lock, flags); } /* -- cgit v1.2.3 From ef27791d9367ce0712bf83669ea226aa60207ece Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 25 Jul 2002 07:19:22 -0700 Subject: Remove unnecessary (and now nonworking) "sti()" in parport interrupt probing --- drivers/parport/parport_pc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 37552f09dd46..2ef1d9a2d4e5 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -2058,7 +2058,6 @@ static int __devinit irq_probe_ECP(struct parport *pb) int i; unsigned long irqs; - sti(); irqs = probe_irq_on(); ECR_WRITE (pb, ECR_SPP << 5); /* Reset FIFO */ @@ -2093,7 +2092,6 @@ static int __devinit irq_probe_EPP(struct parport *pb) if (pb->modes & PARPORT_MODE_PCECR) oecr = inb (ECONTROL (pb)); - sti(); irqs = probe_irq_on(); if (pb->modes & PARPORT_MODE_PCECR) -- cgit v1.2.3 From 27a25d32ce566d6c6ba0cc244a8330f418c604bd Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 25 Jul 2002 07:25:13 -0700 Subject: Remove (broken) parport locking, add comment on fixing it. At least it compiles now. --- drivers/parport/share.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 49ab78ba1413..4985f18b9d1f 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -1006,14 +1006,20 @@ int parport_claim_or_block(struct pardevice *dev) #ifdef PARPORT_DEBUG_SHARING printk(KERN_DEBUG "%s: parport_claim() returned -EAGAIN\n", dev->name); #endif - save_flags (flags); - cli(); + /* + * FIXME!!! Use the proper locking for dev->waiting, + * and make this use the "wait_event_interruptible()" + * interfaces. The cli/sti that used to be here + * did nothing. + * + * See also parport_release() + */ + /* If dev->waiting is clear now, an interrupt gave us the port and we would deadlock if we slept. */ if (dev->waiting) { interruptible_sleep_on (&dev->wait_q); if (signal_pending (current)) { - restore_flags (flags); return -EINTR; } r = 1; @@ -1024,7 +1030,7 @@ int parport_claim_or_block(struct pardevice *dev) dev->name); #endif } - restore_flags(flags); + #ifdef PARPORT_DEBUG_SHARING if (dev->port->physport->cad != dev) printk(KERN_DEBUG "%s: exiting parport_claim_or_block " -- cgit v1.2.3 From 2e113f39069e0eb399050f24530bba1e0ab8d238 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 26 Jul 2002 03:11:09 +0100 Subject: [SERIAL] Fix buglet causing (eg) ttyS-14 Allocate positive instead of negative line numbers when 8250.c registers a new port with the core. This bug could cause registrations to erroneously fail, or oopsen when the pcmcia serial device is ejected. --- drivers/serial/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/core.c b/drivers/serial/core.c index 026b54b191d6..fec9988ad959 100644 --- a/drivers/serial/core.c +++ b/drivers/serial/core.c @@ -2425,7 +2425,7 @@ int uart_register_port(struct uart_driver *drv, struct uart_port *port) state->port->regshift = port->regshift; state->port->iotype = port->iotype; state->port->flags = port->flags; - state->port->line = drv->state - state; + state->port->line = state - drv->state; __uart_register_port(drv, state, state->port); -- cgit v1.2.3 From 095067da408f737ff80809e84f725fa441ec1486 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 25 Jul 2002 20:01:36 -0700 Subject: USB: fix compiler warning in drivers/usb/serial/digi_acceleport.c --- drivers/usb/serial/digi_acceleport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index eee56288d2ea..c7bebf111b96 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -1263,7 +1263,7 @@ static int digi_write( struct usb_serial_port *port, int from_user, unsigned long flags = 0; -dbg( "digi_write: TOP: port=%d, count=%d, from_user=%d, in_interrupt=%d", +dbg( "digi_write: TOP: port=%d, count=%d, from_user=%d, in_interrupt=%ld", priv->dp_port_num, count, from_user, in_interrupt() ); /* copy user data (which can sleep) before getting spin lock */ @@ -1744,7 +1744,7 @@ static void digi_shutdown( struct usb_serial *serial ) int i; -dbg( "digi_shutdown: TOP, in_interrupt()=%d", in_interrupt() ); +dbg( "digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt() ); /* stop reads and writes on all ports */ for( i=0; itype->num_ports+1; i++ ) { -- cgit v1.2.3 From 94d8a6bef60ec83a4cc50f91a3ecf50e1ec3df8d Mon Sep 17 00:00:00 2001 From: Johann Deneux Date: Thu, 25 Jul 2002 20:42:24 -0700 Subject: [PATCH] Merged hid-lgff.c and hid-lg3d.c Here is a patch wich moves hid-lg3d.c into hid-lgff.c. This allows to share the init code. A side-effect of this merge is that rumble pads are now handled the same way joysticks are. Instead of having one timer per effect, executing only when needed, we have one timer executing at regular intervals going over each effect. --- drivers/usb/input/Config.help | 11 +- drivers/usb/input/Config.in | 3 +- drivers/usb/input/Makefile | 5 +- drivers/usb/input/hid-ff.c | 16 +- drivers/usb/input/hid-lgff.c | 493 ++++++++++++++++++++++-------------------- 5 files changed, 279 insertions(+), 249 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/input/Config.help b/drivers/usb/input/Config.help index 8c3e13404876..58370e3c6c46 100644 --- a/drivers/usb/input/Config.help +++ b/drivers/usb/input/Config.help @@ -30,10 +30,13 @@ CONFIG_HID_FF If unsure, say N. -CONFIG_LOGITECH_RUMBLE - Say Y here if you have a Logitech WingMan Cordless rumble pad and if you - want to enable force feedback. Note: if you say N here, this device will - still be supported, but without force feedback. +CONFIG_LOGITECH_FF + Say Y here if you have one of these devices: + - Logitech WingMan Cordless RumblePad + - Logitech WingMan Force 3D + and if you want to enable force feedback for them. + Note: if you say N here, this device will still be supported, but without + force feedback. CONFIG_HID_PID Say Y here if you have a PID-compliant joystick and wish to enable force diff --git a/drivers/usb/input/Config.in b/drivers/usb/input/Config.in index 9c354df9e1a1..9eef9842e6b5 100644 --- a/drivers/usb/input/Config.in +++ b/drivers/usb/input/Config.in @@ -11,8 +11,7 @@ fi dep_mbool ' HID input layer support' CONFIG_USB_HIDINPUT $CONFIG_INPUT $CONFIG_USB_HID dep_mbool ' Force feedback support (EXPERIMENTAL)' CONFIG_HID_FF $CONFIG_USB_HIDINPUT $CONFIG_EXPERIMENTAL dep_mbool ' PID Devices' CONFIG_HID_PID $CONFIG_USB_HID $CONFIG_HID_FF -dep_mbool ' Logitech RumblePad support' CONFIG_LOGITECH_RUMBLE $CONFIG_USB_HID $CONFIG_HID_FF -dep_mbool ' Logitech WingMan Force 3D support' CONFIG_LOGITECH_3D $CONFIG_USB_HID $CONFIG_HID_FF +dep_mbool ' Logitech WingMan *3D support' CONFIG_LOGITECH_FF $CONFIG_USB_HID $CONFIG_HID_FF dep_mbool ' /dev/hiddev raw HID device support' CONFIG_USB_HIDDEV $CONFIG_USB_HID if [ "$CONFIG_USB_HID" != "y" ]; then diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index 610e68ca25dd..5e324c467793 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile @@ -16,12 +16,9 @@ endif ifeq ($(CONFIG_HID_PID),y) hid-objs += pid.o endif -ifeq ($(CONFIG_LOGITECH_RUMBLE),y) +ifeq ($(CONFIG_LOGITECH_FF),y) hid-objs += hid-lgff.o endif -ifeq ($(CONFIG_LOGITECH_3D),y) - hid-objs += hid-lg3dff.o -endif ifeq ($(CONFIG_HID_FF),y) hid-objs += hid-ff.o endif diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c index dc0fcaf424fa..ad6d27769db2 100644 --- a/drivers/usb/input/hid-ff.c +++ b/drivers/usb/input/hid-ff.c @@ -1,5 +1,5 @@ /* - * $Id: hid-ff.c,v 1.3 2002/06/09 11:06:38 jdeneux Exp $ + * $Id: hid-ff.c,v 1.2 2002/04/18 22:02:47 jdeneux Exp $ * * Force feedback support for hid devices. * Not all hid devices use the same protocol. For example, some use PID, @@ -44,17 +44,15 @@ extern int hid_pid_init(struct hid_device* hid); * devices, you need to add the USB vendor and product ids here. */ struct hid_ff_initializer { - __u16 idVendor; - __u16 idProduct; + u16 idVendor; + u16 idProduct; int (*init)(struct hid_device*); }; static struct hid_ff_initializer inits[] = { -#ifdef CONFIG_LOGITECH_RUMBLE +#ifdef CONFIG_LOGITECH_FF {0x46d, 0xc211, hid_lgff_init}, -#endif -#ifdef CONFIG_LOGITECH_3D - {0x46d, 0xc283, hid_lg3d_init}, + {0x46d, 0xc283, hid_lgff_init}, #endif #ifdef CONFIG_HID_PID {0x45e, 0x001b, hid_pid_init}, @@ -68,8 +66,8 @@ static struct hid_ff_initializer *hid_get_ff_init(__u16 idVendor, struct hid_ff_initializer *init; for (init = inits; init->idVendor - && !(init->idVendor == idVendor - && init->idProduct == idProduct); + && !(init->idVendor == idVendor + && init->idProduct == idProduct); init++); return init->idVendor? init : NULL; diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c index 8ae5cf004cfa..788c171c7b6f 100644 --- a/drivers/usb/input/hid-lgff.c +++ b/drivers/usb/input/hid-lgff.c @@ -4,6 +4,7 @@ * Force feedback support for hid-compliant for some of the devices from * Logitech, namely: * - WingMan Cordless RumblePad + * - WingMan Force 3D * * Copyright (c) 2002 Johann Deneux */ @@ -36,6 +37,11 @@ #include #include "hid.h" +#include "fixp-arith.h" + + +/* Periodicity of the update */ +#define PERIOD (HZ/10) #define RUN_AT(t) (jiffies + (t)) @@ -48,145 +54,243 @@ #define EFFECT_PLAYING 1 /* Effect is being played */ #define EFFECT_USED 2 +// For lgff_device::flags +#define DEVICE_CLOSING 0 /* The driver is being unitialised */ + /* Check that the current process can access an effect */ #define CHECK_OWNERSHIP(effect) (current->pid == 0 \ || effect.owner == current->pid) -/* **************************************************************************/ -/* Implements the protocol used by the Logitech WingMan Cordless RumblePad */ -/* **************************************************************************/ - #define LGFF_CHECK_OWNERSHIP(i, l) \ (i>=0 && ieffects[i].flags) \ && CHECK_OWNERSHIP(l->effects[i])) -#define LGFF_BUFFER_SIZE 64 #define LGFF_EFFECTS 8 -struct lgff_magnitudes { - unsigned char left; - unsigned char right; +struct device_type { + u16 idVendor; + u16 idProduct; + signed short *ff; }; struct lgff_effect { - int id; - struct hid_ff_logitech* lgff; - pid_t owner; - unsigned char left; /* Magnitude of vibration for left motor */ - unsigned char right; /* Magnitude of vibration for right motor */ - struct ff_replay replay; - unsigned int count; /* Number of times to play */ - struct timer_list timer; + + struct ff_effect effect; + unsigned long flags[1]; + unsigned int count; /* Number of times left to play */ + unsigned long started_at; /* When the effect started to play */ }; -struct hid_ff_logitech { +struct lgff_device { struct hid_device* hid; - struct urb* urbffout; /* Output URB used to send ff commands */ - struct usb_ctrlrequest ffcr; /* ff commands use control URBs */ - char buf[8]; - - spinlock_t xmit_lock; - unsigned int xmit_head, xmit_tail; - struct lgff_magnitudes xmit_data[LGFF_BUFFER_SIZE]; - long xmit_flags[1]; + struct hid_report* constant; + struct hid_report* rumble; + struct hid_report* condition; struct lgff_effect effects[LGFF_EFFECTS]; spinlock_t lock; /* device-level lock. Having locks on a per-effect basis could be nice, but isn't really necessary */ + + unsigned long flags[1]; /* Contains various information about the + state of the driver for this device */ + + struct timer_list timer; }; -static void hid_lgff_ctrl_out(struct urb *urb); +/* Callbacks */ static void hid_lgff_exit(struct hid_device* hid); static int hid_lgff_event(struct hid_device *hid, struct input_dev *input, unsigned int type, unsigned int code, int value); -static void hid_lgff_make_rumble(struct hid_device* hid); - static int hid_lgff_flush(struct input_dev *input, struct file *file); static int hid_lgff_upload_effect(struct input_dev *input, struct ff_effect *effect); static int hid_lgff_erase(struct input_dev *input, int id); -static void hid_lgff_ctrl_playback(struct hid_device* hid, struct lgff_effect*, - int play); + +/* Local functions */ +static void hid_lgff_input_init(struct hid_device* hid); static void hid_lgff_timer(unsigned long timer_data); +static struct hid_report* hid_lgff_duplicate_report(struct hid_report*); +static void hid_lgff_delete_report(struct hid_report*); + +static signed short ff_rumble[] = { + FF_RUMBLE, + -1 +}; + +static signed short ff_joystick[] = { + FF_CONSTANT, + -1 +}; +static struct device_type devices[] = { + {0x046d, 0xc211, ff_rumble}, + {0x046d, 0xc283, ff_joystick}, + {0x0000, 0x0000, ff_joystick} +}; int hid_lgff_init(struct hid_device* hid) { - struct hid_ff_logitech *private; - int i; - - /* Private data */ - private = kmalloc(sizeof(struct hid_ff_logitech), GFP_KERNEL); - if (!private) return -1; + struct lgff_device *private; + struct hid_report* report; + struct hid_field* field; - memset(private, 0, sizeof(struct hid_ff_logitech)); + /* Find the report to use */ + if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) { + err("No output report found"); + return -1; + } + /* Check that the report looks ok */ + report = (struct hid_report*)hid->report_enum[HID_OUTPUT_REPORT].report_list.next; + if (!report) { + err("NULL output report"); + return -1; + } + field = report->field[0]; + if (!field) { + err("NULL field"); + return -1; + } + private = kmalloc(sizeof(struct lgff_device), GFP_KERNEL); + if (!private) return -1; + memset(private, 0, sizeof(struct lgff_device)); hid->ff_private = private; - private->hid = hid; - spin_lock_init(&private->lock); - spin_lock_init(&private->xmit_lock); + /* Input init */ + hid_lgff_input_init(hid); + - private->buf[0] = 0x03; - private->buf[1] = 0x42; + private->constant = hid_lgff_duplicate_report(report); + if (!private->constant) { + kfree(private); + return -1; + } + private->constant->field[0]->value[0] = 0x51; + private->constant->field[0]->value[1] = 0x08; + private->constant->field[0]->value[2] = 0x7f; + private->constant->field[0]->value[3] = 0x7f; + + private->rumble = hid_lgff_duplicate_report(report); + if (!private->rumble) { + hid_lgff_delete_report(private->constant); + kfree(private); + return -1; + } + private->rumble->field[0]->value[0] = 0x03; + private->rumble->field[0]->value[1] = 0x42; - for (i=0; ieffects[i]; - struct timer_list* timer = &effect->timer; - init_timer(timer); - effect->id = i; - effect->lgff = private; - timer->data = (unsigned long)effect; - timer->function = hid_lgff_timer; + private->condition = hid_lgff_duplicate_report(report); + if (!private->condition) { + hid_lgff_delete_report(private->rumble); + hid_lgff_delete_report(private->constant); + kfree(private); + return -1; } + private->hid = hid; + + spin_lock_init(&private->lock); + init_timer(&private->timer); + private->timer.data = (unsigned long)private; + private->timer.function = hid_lgff_timer; + /* Event and exit callbacks */ hid->ff_exit = hid_lgff_exit; hid->ff_event = hid_lgff_event; - /* USB init */ - if (!(private->urbffout = usb_alloc_urb(0, GFP_KERNEL))) { - kfree(hid->ff_private); - return -1; + /* Start the update task */ + private->timer.expires = RUN_AT(PERIOD); + add_timer(&private->timer); /*TODO: only run the timer when at least + one effect is playing */ + + printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux \n"); + + return 0; +} + +static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report) +{ + struct hid_report* ret; + + ret = kmalloc(sizeof(struct lgff_device), GFP_KERNEL); + if (!ret) return NULL; + *ret = *report; + + ret->field[0] = kmalloc(sizeof(struct hid_field), GFP_KERNEL); + if (!ret->field[0]) { + kfree(ret); + return NULL; } + *ret->field[0] = *report->field[0]; - usb_fill_control_urb(private->urbffout, hid->dev, 0, - (void*) &private->ffcr, private->buf, 8, - hid_lgff_ctrl_out, hid); - dbg("Created ff output control urb"); + ret->field[0]->value = kmalloc(sizeof(s32[8]), GFP_KERNEL); + if (!ret->field[0]->value) { + kfree(ret->field[0]); + kfree(ret); + return NULL; + } + memset(ret->field[0]->value, 0, sizeof(s32[8])); + + return ret; +} + +static void hid_lgff_delete_report(struct hid_report* report) +{ + if (report) { + kfree(report->field[0]->value); + kfree(report->field[0]); + kfree(report); + } +} + +static void hid_lgff_input_init(struct hid_device* hid) +{ + struct device_type* dev = devices; + signed short* ff; + u16 idVendor = hid->dev->descriptor.idVendor; + u16 idProduct = hid->dev->descriptor.idProduct; + + while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct)) + dev++; + + ff = dev->ff; + + while (*ff >= 0) { + set_bit(*ff, hid->input.ffbit); + ++ff; + } - /* Input init */ hid->input.upload_effect = hid_lgff_upload_effect; hid->input.flush = hid_lgff_flush; - set_bit(FF_RUMBLE, hid->input.ffbit); + set_bit(EV_FF, hid->input.evbit); hid->input.ff_effects_max = LGFF_EFFECTS; - - printk(KERN_INFO "Force feedback for Logitech rumble devices by Johann Deneux \n"); - - return 0; } static void hid_lgff_exit(struct hid_device* hid) { - struct hid_ff_logitech *lgff = hid->ff_private; + struct lgff_device *lgff = hid->ff_private; - if (lgff->urbffout) { - usb_unlink_urb(lgff->urbffout); - usb_free_urb(lgff->urbffout); - } + set_bit(DEVICE_CLOSING, lgff->flags); + del_timer_sync(&lgff->timer); + + hid_lgff_delete_report(lgff->condition); + hid_lgff_delete_report(lgff->rumble); + hid_lgff_delete_report(lgff->constant); + + kfree(lgff); } static int hid_lgff_event(struct hid_device *hid, struct input_dev* input, unsigned int type, unsigned int code, int value) { - struct hid_ff_logitech *lgff = hid->ff_private; + struct lgff_device *lgff = hid->ff_private; struct lgff_effect *effect = lgff->effects + code; unsigned long flags; @@ -208,27 +312,16 @@ static int hid_lgff_event(struct hid_device *hid, struct input_dev* input, effect->count = value; - if (effect->replay.delay) { + if (effect->effect.replay.delay) { set_bit(EFFECT_STARTED, effect->flags); - effect->timer.expires = RUN_AT(effect->replay.delay * HZ / 1000); } else { - hid_lgff_ctrl_playback(hid, effect, value); - effect->timer.expires = RUN_AT(effect->replay.length * HZ / 1000); + set_bit(EFFECT_PLAYING, effect->flags); } - - add_timer(&effect->timer); + effect->started_at = jiffies; } else { /* value == 0 */ - if (test_and_clear_bit(EFFECT_STARTED, effect->flags)) { - del_timer(&effect->timer); - - } else if (test_and_clear_bit(EFFECT_PLAYING, effect->flags)) { - del_timer(&effect->timer); - hid_lgff_ctrl_playback(hid, effect, value); - } - - if (test_bit(EFFECT_PLAYING, effect->flags)) - warn("Effect %d still playing", code); + clear_bit(EFFECT_STARTED, effect->flags); + clear_bit(EFFECT_PLAYING, effect->flags); } spin_unlock_irqrestore(&lgff->lock, flags); @@ -241,7 +334,7 @@ static int hid_lgff_event(struct hid_device *hid, struct input_dev* input, static int hid_lgff_flush(struct input_dev *dev, struct file *file) { struct hid_device *hid = dev->private; - struct hid_ff_logitech *lgff = hid->ff_private; + struct lgff_device *lgff = hid->ff_private; int i; for (i=0; iff_effects_max; ++i) { @@ -265,13 +358,12 @@ static int hid_lgff_flush(struct input_dev *dev, struct file *file) static int hid_lgff_erase(struct input_dev *dev, int id) { struct hid_device *hid = dev->private; - struct hid_ff_logitech *lgff = hid->ff_private; + struct lgff_device *lgff = hid->ff_private; unsigned long flags; if (!LGFF_CHECK_OWNERSHIP(id, lgff)) return -EACCES; spin_lock_irqsave(&lgff->lock, flags); - hid_lgff_ctrl_playback(hid, lgff->effects + id, 0); lgff->effects[id].flags[0] = 0; spin_unlock_irqrestore(&lgff->lock, flags); @@ -282,7 +374,7 @@ static int hid_lgff_upload_effect(struct input_dev* input, struct ff_effect* effect) { struct hid_device *hid = input->private; - struct hid_ff_logitech *lgff = hid->ff_private; + struct lgff_device *lgff = hid->ff_private; struct lgff_effect new; int id; unsigned long flags; @@ -291,8 +383,6 @@ static int hid_lgff_upload_effect(struct input_dev* input, if (!test_bit(effect->type, input->ffbit)) return -EINVAL; - if (effect->type != FF_RUMBLE) return -EINVAL; - spin_lock_irqsave(&lgff->lock, flags); if (effect->id == -1) { @@ -317,25 +407,20 @@ static int hid_lgff_upload_effect(struct input_dev* input, id = effect->id; new = lgff->effects[id]; - new.right = effect->u.rumble.strong_magnitude >> 9; - new.left = effect->u.rumble.weak_magnitude >> 9; - new.replay = effect->replay; + new.effect = *effect; - /* If we updated an effect that was being played, we need to remake - the rumble effect */ if (test_bit(EFFECT_STARTED, lgff->effects[id].flags) || test_bit(EFFECT_STARTED, lgff->effects[id].flags)) { /* Changing replay parameters is not allowed (for the time being) */ - if (new.replay.delay != lgff->effects[id].replay.delay - || new.replay.length != lgff->effects[id].replay.length) { + if (new.effect.replay.delay != lgff->effects[id].effect.replay.delay + || new.effect.replay.length != lgff->effects[id].effect.replay.length) { spin_unlock_irqrestore(&lgff->lock, flags); return -ENOSYS; } lgff->effects[id] = new; - hid_lgff_make_rumble(hid); } else { lgff->effects[id] = new; @@ -345,151 +430,99 @@ static int hid_lgff_upload_effect(struct input_dev* input, return 0; } -static void hid_lgff_xmit(struct hid_device* hid) +static void hid_lgff_timer(unsigned long timer_data) { - struct hid_ff_logitech *lgff = hid->ff_private; - int err; - int tail; + struct lgff_device *lgff = (struct lgff_device*)timer_data; + struct hid_device *hid = lgff->hid; unsigned long flags; - - spin_lock_irqsave(&lgff->xmit_lock, flags); - - tail = lgff->xmit_tail; - if (lgff->xmit_head == tail) { - clear_bit(XMIT_RUNNING, lgff->xmit_flags); - spin_unlock_irqrestore(&lgff->xmit_lock, flags); - return; - } - lgff->buf[3] = lgff->xmit_data[tail].left; - lgff->buf[4] = lgff->xmit_data[tail].right; - tail++; tail &= LGFF_BUFFER_SIZE -1; - lgff->xmit_tail = tail; - - spin_unlock_irqrestore(&lgff->xmit_lock, flags); - - lgff->urbffout->pipe = usb_sndctrlpipe(hid->dev, 0); - lgff->ffcr.bRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE; - lgff->urbffout->transfer_buffer_length = lgff->ffcr.wLength = 8; - lgff->ffcr.bRequest = 9; - lgff->ffcr.wValue = 0x0203; /*NOTE: Potential problem with - little/big endian */ - lgff->ffcr.wIndex = 0; - - lgff->urbffout->dev = hid->dev; - - if ((err=usb_submit_urb(lgff->urbffout, GFP_ATOMIC))) - warn("usb_submit_urb returned %d", err); -} - -static void hid_lgff_make_rumble(struct hid_device* hid) -{ - struct hid_ff_logitech *lgff = hid->ff_private; - int left = 0, right = 0; + int x = 0x7f, y = 0x7f; // Coordinates of constant effects + unsigned int left = 0, right = 0; // Rumbling int i; - int head, tail; - unsigned long flags; - - for (i=0; ieffects[i].flags) - && test_bit(EFFECT_PLAYING, lgff->effects[i].flags)) { - left += lgff->effects[i].left; - right += lgff->effects[i].right; - } - } - - spin_lock_irqsave(&lgff->xmit_lock, flags); - head = lgff->xmit_head; - tail = lgff->xmit_tail; - - if (CIRC_SPACE(head, tail, LGFF_BUFFER_SIZE) < 1) { - warn("not enough space in xmit buffer to send new packet"); - spin_unlock_irqrestore(&lgff->xmit_lock, flags); - return; - } + spin_lock_irqsave(&lgff->lock, flags); - lgff->xmit_data[head].left = left > 0x7f ? 0x7f : left; - lgff->xmit_data[head].right = right > 0x7f ? 0x7f : right; - head++; head &= LGFF_BUFFER_SIZE -1; - lgff->xmit_head = head; + for (i=0; ieffects +i; - if (test_and_set_bit(XMIT_RUNNING, lgff->xmit_flags)) - spin_unlock_irqrestore(&lgff->xmit_lock, flags); - else { - spin_unlock_irqrestore(&lgff->xmit_lock, flags); - hid_lgff_xmit(hid); - } -} + if (test_bit(EFFECT_PLAYING, effect->flags)) { -static void hid_lgff_ctrl_out(struct urb *urb) -{ - struct hid_device *hid = urb->context; + switch (effect->effect.type) { + case FF_CONSTANT: { + //TODO: handle envelopes + int degrees = effect->effect.direction * 360 >> 16; + x += fixp_mult(fixp_sin(degrees), + fixp_new16(effect->effect.u.constant.level)); + y += fixp_mult(-fixp_cos(degrees), + fixp_new16(effect->effect.u.constant.level)); + } break; + case FF_RUMBLE: + right += effect->effect.u.rumble.strong_magnitude; + left += effect->effect.u.rumble.weak_magnitude; + break; + }; + + /* One run of the effect is finished playing */ + if (time_after(jiffies, + effect->started_at + + effect->effect.replay.delay*HZ/1000 + + effect->effect.replay.length*HZ/1000)) { + dbg("Finished playing once %d", i); + if (--effect->count <= 0) { + dbg("Stopped %d", i); + clear_bit(EFFECT_PLAYING, effect->flags); + } + else { + dbg("Start again %d", i); + if (effect->effect.replay.length != 0) { + clear_bit(EFFECT_PLAYING, effect->flags); + set_bit(EFFECT_STARTED, effect->flags); + } + effect->started_at = jiffies; + } + } + + } else if (test_bit(EFFECT_STARTED, lgff->effects[i].flags)) { + /* Check if we should start playing the effect */ + if (time_after(jiffies, + lgff->effects[i].started_at + + lgff->effects[i].effect.replay.delay*HZ/1000)) { + dbg("Now playing %d", i); + clear_bit(EFFECT_STARTED, lgff->effects[i].flags); + set_bit(EFFECT_PLAYING, lgff->effects[i].flags); + } + } + } - if (urb->status) - warn("hid_irq_ffout status %d received", urb->status); +#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff - hid_lgff_xmit(hid); -} + // Clamp values + CLAMP(x); + CLAMP(y); + CLAMP(left); + CLAMP(right); -/* Lock must be held by caller */ -static void hid_lgff_ctrl_playback(struct hid_device *hid, - struct lgff_effect *effect, int play) -{ - if (play) { - set_bit(EFFECT_PLAYING, effect->flags); - hid_lgff_make_rumble(hid); +#undef CLAMP - } else { - clear_bit(EFFECT_PLAYING, effect->flags); - hid_lgff_make_rumble(hid); + if (x != lgff->constant->field[0]->value[2] + || y != lgff->constant->field[0]->value[3]) { + lgff->constant->field[0]->value[2] = x; + lgff->constant->field[0]->value[3] = y; + dbg("(x,y)=(%04x, %04x)", x, y); + hid_submit_report(hid, lgff->constant, USB_DIR_OUT); } -} - -static void hid_lgff_timer(unsigned long timer_data) -{ - struct lgff_effect *effect = (struct lgff_effect*) timer_data; - struct hid_ff_logitech* lgff = effect->lgff; - int id = effect->id; - unsigned long flags; - - dbg("in hid_lgff_timer"); - - if (id < 0 || id >= LGFF_EFFECTS) { - warn("Bad effect id %d", id); - return; + if (left != lgff->rumble->field[0]->value[3] + || right != lgff->rumble->field[0]->value[4]) { + lgff->rumble->field[0]->value[3] = left; + lgff->rumble->field[0]->value[4] = right; + dbg("(left,right)=(%04x, %04x)", left, right); + hid_submit_report(hid, lgff->rumble, USB_DIR_OUT); } - effect = lgff->effects + id; - - spin_lock_irqsave(&lgff->lock, flags); - - if (!test_bit(EFFECT_USED, effect->flags)) { - warn("Unused effect id %d", id); - - } else if (test_bit(EFFECT_STARTED, effect->flags)) { - clear_bit(EFFECT_STARTED, effect->flags); - set_bit(EFFECT_PLAYING, effect->flags); - hid_lgff_ctrl_playback(lgff->hid, effect, 1); - effect->timer.expires = RUN_AT(effect->replay.length * HZ / 1000); - add_timer(&effect->timer); - - dbg("Effect %d starts playing", id); - } else if (test_bit(EFFECT_PLAYING, effect->flags)) { - clear_bit(EFFECT_PLAYING, effect->flags); - hid_lgff_ctrl_playback(lgff->hid, effect, 0); - if (--effect->count > 0) { - /*TODO: check that replay.delay is non-null */ - set_bit(EFFECT_STARTED, effect->flags); - effect->timer.expires = RUN_AT(effect->replay.delay * HZ / 1000); - add_timer(&effect->timer); - dbg("Effect %d restarted", id); - } else { - dbg("Effect %d stopped", id); - } - } else { - warn("Effect %d is not started nor playing", id); + if (!test_bit(DEVICE_CLOSING, lgff->flags)) { + lgff->timer.expires = RUN_AT(PERIOD); + add_timer(&lgff->timer); } - spin_unlock_irqrestore(&lgff->lock, flags); + spin_unlock_irqrestore(&lgff->lock, flags); } -- cgit v1.2.3 From e8450816b68444c5cbebc71666a9f296f6bcf92a Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Thu, 25 Jul 2002 20:46:53 -0700 Subject: [PATCH] Fixes needed to get Logitech WingMan 3D running Some fixes from Johann Deneux: Fixes needed to get WingMan Force 3D running. (Fix in fixp_cos and hid_init_reports). --- drivers/usb/input/fixp-arith.h | 8 +++++++- drivers/usb/input/hid-core.c | 4 +--- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/input/fixp-arith.h b/drivers/usb/input/fixp-arith.h index 1b3066daea1f..e20fa1a44b35 100644 --- a/drivers/usb/input/fixp-arith.h +++ b/drivers/usb/input/fixp-arith.h @@ -66,7 +66,13 @@ inline fixp_t fixp_new16(s16 a) inline fixp_t fixp_cos(unsigned int degrees) { int quadrant = (degrees / 90) & 3; - unsigned int i = (degrees % 90) >> 1; + unsigned int i = degrees % 90; + + if (quadrant == 1 || quadrant == 3) { + i = 89 - i; + } + + i >>= 1; return (quadrant == 1 || quadrant == 2)? -cos_table[i] : cos_table[i]; } diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 8c941083376c..81126a59e3e3 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1281,10 +1281,8 @@ void hid_init_reports(struct hid_device *hid) usb_unlink_urb(hid->urbout); } - if (err) { + if (err) warn("timeout initializing reports\n"); - return; - } report_enum = hid->report_enum + HID_INPUT_REPORT; list = report_enum->report_list.next; -- cgit v1.2.3 From 72ffa099ec6489e7cb64d23bf734d96c43d03c74 Mon Sep 17 00:00:00 2001 From: Art Haas Date: Thu, 25 Jul 2002 20:58:30 -0700 Subject: [PATCH] designated initializer patch for drivers_usb_misc_emi26.c Here's a patch for additional designated initializers in drivers/usb/misc/emi26.c. Patch is against 2.5.27. --- drivers/usb/misc/emi26.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index 2dd226a3a4c7..2440fa92405a 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c @@ -212,10 +212,10 @@ static void emi26_disconnect(struct usb_device *dev, void *drv_context) } struct usb_driver emi26_driver = { -name: "emi26 - firmware loader", -probe: emi26_probe, -disconnect: emi26_disconnect, -id_table: NULL, +.name = "emi26 - firmware loader", +.probe = emi26_probe, +.disconnect = emi26_disconnect, +.id_table = NULL, }; static int __init emi26_init (void) -- cgit v1.2.3 From 98fdd142118acc2127118c8544fcdad67bc5a328 Mon Sep 17 00:00:00 2001 From: Art Haas Date: Thu, 25 Jul 2002 20:58:44 -0700 Subject: [PATCH] designated initializers for drivers_usb_net_usbnet.c Here's a patch for additional designated initializers for drivers/usb/net/usbnet.c. Patch is against 2.5.27. --- drivers/usb/net/usbnet.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index c6ac7dd2821e..c5bc8e92c8cf 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c @@ -300,7 +300,7 @@ static const struct driver_info an2720_info = { // no reset available! // no check_connect available! - .in = 2, out: 2, // direction distinguishes these + .in = 2, .out = 2, // direction distinguishes these .epsize =64, }; @@ -321,7 +321,7 @@ static const struct driver_info an2720_info = { static const struct driver_info belkin_info = { .description = "Belkin, eTEK, or compatible", - .in = 1, out: 1, // direction distinguishes these + .in = 1, .out = 1, // direction distinguishes these .epsize =64, }; @@ -636,7 +636,7 @@ static const struct driver_info genelink_info = { .rx_fixup = genelink_rx_fixup, .tx_fixup = genelink_tx_fixup, - .in = 1, out: 2, + .in = 1, .out = 2, .epsize =64, #ifdef GENELINK_ACK @@ -674,7 +674,7 @@ static const struct driver_info linuxdev_info = { .description = "Linux Device", // no reset defined (yet?) .check_connect =linuxdev_check_connect, - .in = 2, out: 1, + .in = 2, .out = 1, .epsize =64, }; @@ -1125,7 +1125,7 @@ static const struct driver_info net1080_info = { .rx_fixup = net1080_rx_fixup, .tx_fixup = net1080_tx_fixup, - .in = 1, out: 1, // direction distinguishes these + .in = 1, .out = 1, // direction distinguishes these .epsize =64, }; @@ -1192,7 +1192,7 @@ static const struct driver_info prolific_info = { /* some PL-2302 versions seem to fail usb_set_interface() */ .reset = pl_reset, - .in = 3, out: 2, + .in = 3, .out = 2, .epsize =64, }; -- cgit v1.2.3 From 79fea11e6e7e39f7c52c5016c2cadb74ab5c336f Mon Sep 17 00:00:00 2001 From: Art Haas Date: Thu, 25 Jul 2002 20:59:05 -0700 Subject: [PATCH] designated initializer patch for drivers_usb_net_pegasus.c Here's a patch for additional designated initializers for drivers/usb/net/pegasus.c. Patch is against 2.5.27. --- drivers/usb/net/pegasus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 6728f5cfd6ce..908d7b32ad59 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -62,7 +62,7 @@ static int multicast_filter_limit = 32; static struct usb_eth_dev usb_dev_id[] = { #define PEGASUS_DEV(pn, vid, pid, flags) \ - {name:pn, vendor:vid, device:pid, private:flags}, + {.name = pn, .vendor = vid, .device = pid, .private = flags}, #include "pegasus.h" #undef PEGASUS_DEV {NULL, 0, 0, 0} @@ -70,7 +70,7 @@ static struct usb_eth_dev usb_dev_id[] = { static struct usb_device_id pegasus_ids[] = { #define PEGASUS_DEV(pn, vid, pid, flags) \ - {match_flags: USB_DEVICE_ID_MATCH_DEVICE, idVendor:vid, idProduct:pid}, + {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, #include "pegasus.h" #undef PEGASUS_DEV {} -- cgit v1.2.3 From 7398d54cd1f082f62fae244b04b00cf7dced4f91 Mon Sep 17 00:00:00 2001 From: Art Haas Date: Thu, 25 Jul 2002 20:59:37 -0700 Subject: [PATCH] designated initializers in drivers_usb_class_audio.c Here's a patch for additional designated initializers in drivers/usb/class/audio.c. Patch is against 2.5.27. --- drivers/usb/class/audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c index 07c5ea5b7e81..1187e7b58ecc 100644 --- a/drivers/usb/class/audio.c +++ b/drivers/usb/class/audio.c @@ -2745,8 +2745,8 @@ static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum, static void usb_audio_disconnect(struct usb_device *dev, void *ptr); static struct usb_device_id usb_audio_ids [] = { - { match_flags: (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS), - bInterfaceClass: USB_CLASS_AUDIO, bInterfaceSubClass: 1}, + { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS), + .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = 1}, { } /* Terminating entry */ }; -- cgit v1.2.3 From 55dc01fd9ea6633cb1232cc97d1d2eddd4f60c1b Mon Sep 17 00:00:00 2001 From: Greg Banks Date: Thu, 25 Jul 2002 20:59:53 -0700 Subject: [PATCH] PATCH 2.5: kconfig missing EXPERIMENTAL 3 (10_13) Symbols CONFIG_USB_STORAGE_DATAFAB, CONFIG_USB_STORAGE_HP8200e, CONFIG_USB_STORAGE_SDDR09, CONFIG_USB_STORAGE_SDDR55, and CONFIG_USB_STORAGE_JUMPSHOT depend on CONFIG_EXPERIMENTAL but do not say so in their banners. --- drivers/usb/storage/Config.in | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/Config.in b/drivers/usb/storage/Config.in index 7f630fb6d53d..6b67604160ca 100644 --- a/drivers/usb/storage/Config.in +++ b/drivers/usb/storage/Config.in @@ -6,11 +6,11 @@ if [ "$CONFIG_SCSI" = "n" ]; then fi dep_tristate ' USB Mass Storage support' CONFIG_USB_STORAGE $CONFIG_USB $CONFIG_SCSI dep_mbool ' USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG $CONFIG_USB_STORAGE - dep_mbool ' Datafab Compact Flash Reader support' CONFIG_USB_STORAGE_DATAFAB $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL + dep_mbool ' Datafab Compact Flash Reader support (EXPERIMENTAL)' CONFIG_USB_STORAGE_DATAFAB $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL dep_mbool ' Freecom USB/ATAPI Bridge support' CONFIG_USB_STORAGE_FREECOM $CONFIG_USB_STORAGE dep_mbool ' ISD-200 USB/ATA Bridge support' CONFIG_USB_STORAGE_ISD200 $CONFIG_USB_STORAGE dep_mbool ' Microtech CompactFlash/SmartMedia support' CONFIG_USB_STORAGE_DPCM $CONFIG_USB_STORAGE - dep_mbool ' HP CD-Writer 82xx support' CONFIG_USB_STORAGE_HP8200e $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL - dep_mbool ' SanDisk SDDR-09 (and other SmartMedia) support' CONFIG_USB_STORAGE_SDDR09 $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL - dep_mbool ' SanDisk SDDR-55 SmartMedia support' CONFIG_USB_STORAGE_SDDR55 $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL - dep_mbool ' Lexar Jumpshot Compact Flash Reader' CONFIG_USB_STORAGE_JUMPSHOT $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL + dep_mbool ' HP CD-Writer 82xx support (EXPERIMENTAL)' CONFIG_USB_STORAGE_HP8200e $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL + dep_mbool ' SanDisk SDDR-09 (and other SmartMedia) support (EXPERIMENTAL)' CONFIG_USB_STORAGE_SDDR09 $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL + dep_mbool ' SanDisk SDDR-55 SmartMedia support (EXPERIMENTAL)' CONFIG_USB_STORAGE_SDDR55 $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL + dep_mbool ' Lexar Jumpshot Compact Flash Reader (EXPERIMENTAL)' CONFIG_USB_STORAGE_JUMPSHOT $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL -- cgit v1.2.3 From 6141549c4a4adbc8f496dd3dcc90a704157de688 Mon Sep 17 00:00:00 2001 From: Art Haas Date: Thu, 25 Jul 2002 21:00:07 -0700 Subject: [PATCH] designated initializer patch for drivers_usb_input_hid-core.c Here's an patch for additional designated initializers for drivers/usb/input/hid-core.c. Patch is against 2.5.27. --- drivers/usb/input/hid-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 81126a59e3e3..b5743d2ac59b 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1549,8 +1549,8 @@ static void* hid_probe(struct usb_device *dev, unsigned int ifnum, } static struct usb_device_id hid_usb_ids [] = { - { match_flags: USB_DEVICE_ID_MATCH_INT_CLASS, - bInterfaceClass: USB_INTERFACE_CLASS_HID }, + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, + .bInterfaceClass = USB_INTERFACE_CLASS_HID }, { } /* Terminating entry */ }; -- cgit v1.2.3 From d531d3a3583c8f10f3c52bc93fae7dbf91b46138 Mon Sep 17 00:00:00 2001 From: Art Haas Date: Thu, 25 Jul 2002 21:00:20 -0700 Subject: [PATCH] designated initializers for drivers_usb_storage_usb.c Here's a patch for additional designated initializers for drivers/usb/storage/usb.c. Patch is against 2.5.27. --- drivers/usb/storage/usb.c | 72 +++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index c0bdea0c4e6e..e68801addae4 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -182,46 +182,46 @@ static struct us_unusual_dev us_unusual_dev_list[] = { # include "unusual_devs.h" # undef UNUSUAL_DEV /* Control/Bulk transport for all SubClass values */ - { useProtocol: US_SC_RBC, - useTransport: US_PR_CB}, - { useProtocol: US_SC_8020, - useTransport: US_PR_CB}, - { useProtocol: US_SC_QIC, - useTransport: US_PR_CB}, - { useProtocol: US_SC_UFI, - useTransport: US_PR_CB}, - { useProtocol: US_SC_8070, - useTransport: US_PR_CB}, - { useProtocol: US_SC_SCSI, - useTransport: US_PR_CB}, + { .useProtocol = US_SC_RBC, + .useTransport = US_PR_CB}, + { .useProtocol = US_SC_8020, + .useTransport = US_PR_CB}, + { .useProtocol = US_SC_QIC, + .useTransport = US_PR_CB}, + { .useProtocol = US_SC_UFI, + .useTransport = US_PR_CB}, + { .useProtocol = US_SC_8070, + .useTransport = US_PR_CB}, + { .useProtocol = US_SC_SCSI, + .useTransport = US_PR_CB}, /* Control/Bulk/Interrupt transport for all SubClass values */ - { useProtocol: US_SC_RBC, - useTransport: US_PR_CBI}, - { useProtocol: US_SC_8020, - useTransport: US_PR_CBI}, - { useProtocol: US_SC_QIC, - useTransport: US_PR_CBI}, - { useProtocol: US_SC_UFI, - useTransport: US_PR_CBI}, - { useProtocol: US_SC_8070, - useTransport: US_PR_CBI}, - { useProtocol: US_SC_SCSI, - useTransport: US_PR_CBI}, + { .useProtocol = US_SC_RBC, + .useTransport = US_PR_CBI}, + { .useProtocol = US_SC_8020, + .useTransport = US_PR_CBI}, + { .useProtocol = US_SC_QIC, + .useTransport = US_PR_CBI}, + { .useProtocol = US_SC_UFI, + .useTransport = US_PR_CBI}, + { .useProtocol = US_SC_8070, + .useTransport = US_PR_CBI}, + { .useProtocol = US_SC_SCSI, + .useTransport = US_PR_CBI}, /* Bulk-only transport for all SubClass values */ - { useProtocol: US_SC_RBC, - useTransport: US_PR_BULK}, - { useProtocol: US_SC_8020, - useTransport: US_PR_BULK}, - { useProtocol: US_SC_QIC, - useTransport: US_PR_BULK}, - { useProtocol: US_SC_UFI, - useTransport: US_PR_BULK}, - { useProtocol: US_SC_8070, - useTransport: US_PR_BULK}, - { useProtocol: US_SC_SCSI, - useTransport: US_PR_BULK}, + { .useProtocol = US_SC_RBC, + .useTransport = US_PR_BULK}, + { .useProtocol = US_SC_8020, + .useTransport = US_PR_BULK}, + { .useProtocol = US_SC_QIC, + .useTransport = US_PR_BULK}, + { .useProtocol = US_SC_UFI, + .useTransport = US_PR_BULK}, + { .useProtocol = US_SC_8070, + .useTransport = US_PR_BULK}, + { .useProtocol = US_SC_SCSI, + .useTransport = US_PR_BULK}, /* Terminating entry */ { 0 } -- cgit v1.2.3 From 75162c88a2660bb0321eb4dcb2e5b9e459cb73b9 Mon Sep 17 00:00:00 2001 From: Art Haas Date: Thu, 25 Jul 2002 21:00:34 -0700 Subject: [PATCH] designated initializer patch for drivers_usb_input_wacom.c Here's a patch for extra designated initializer conversions in drivers/usb/input/wacom.c. Patch is against 2.5.27. --- drivers/usb/input/wacom.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index e4a3b59f5668..b204affb8954 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c @@ -321,13 +321,13 @@ struct wacom_features wacom_features[] = { }; struct usb_device_id wacom_ids[] = { - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10), driver_info: 0 }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20), driver_info: 1 }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21), driver_info: 2 }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22), driver_info: 3 }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23), driver_info: 4 }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24), driver_info: 5 }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31), driver_info: 6 }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10), .driver_info = 0 }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20), .driver_info = 1 }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21), .driver_info = 2 }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22), .driver_info = 3 }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23), .driver_info = 4 }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24), .driver_info = 5 }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31), .driver_info = 6 }, { } }; -- cgit v1.2.3 From 97cf4c3447007f220968b66c8bda1db307b472be Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 25 Jul 2002 21:11:54 -0700 Subject: [PATCH] ohci-hcd cardbus unplug, remove interrupt length limit, * handle another cardbus unplug misbehavior - root hub kept polling, never stopped - starts to update hcd->state to match internal state * code to count/queue TDs for interrupt/bulk is now shared - removes (low level) interrupt transfer size limitation - both types already handled urb queueing - re-indents some TD queuing code (most of patch, by volume) * cleanup - use new container_of() macro, not list_entry() - report a previously unreported error (control data >4K) - simplify intr/bulk toggle reset - tweak TD debug dump - more object code shrinkage (often fits in 3 pages) Note that the control data size error is just a long-standing limitation of this driver, not a USB limitation! It could be fixed, if anyone starts to run into it. --- drivers/usb/host/ohci-dbg.c | 13 ++- drivers/usb/host/ohci-hcd.c | 36 +++++--- drivers/usb/host/ohci-hub.c | 10 ++- drivers/usb/host/ohci-q.c | 209 ++++++++++++++++++++++---------------------- drivers/usb/host/ohci.h | 2 +- 5 files changed, 144 insertions(+), 126 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index b968cfe92d35..4545a999df90 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -281,16 +281,21 @@ static void ohci_dump_td (char *label, struct td *td) cbp ? (be + 1 - cbp) : 0); } else { unsigned i; - dbg (" info %08x CC=%x DI=%d START=%04x", tmp, - TD_CC_GET(tmp), /* FC, */ + dbg (" info %08x CC=%x FC=%d DI=%d SF=%04x", tmp, + TD_CC_GET(tmp), + (tmp >> 24) & 0x07, (tmp & TD_DI) >> 21, tmp & 0x0000ffff); dbg (" bp0 %08x be %08x", le32_to_cpup (&td->hwCBP) & ~0x0fff, le32_to_cpup (&td->hwBE)); for (i = 0; i < MAXPSW; i++) { - dbg (" psw [%d] = %2x", i, - le16_to_cpu (td->hwPSW [i])); + u16 psw = le16_to_cpup (&td->hwPSW [i]); + int cc = (psw >> 12) & 0x0f; + dbg (" psw [%d] = %2x, CC=%x %s=%d", i, + psw, cc, + (cc >= 0x0e) ? "OFFSET" : "SIZE", + psw & 0x0fff); } } } diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 8d6010c1fdba..d7cc8c544068 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -125,6 +125,12 @@ #include "ohci.h" +static inline void disable (struct ohci_hcd *ohci) +{ + ohci->disabled = 1; + ohci->hcd.state = USB_STATE_HALT; +} + #include "ohci-hub.c" #include "ohci-dbg.c" #include "ohci-mem.c" @@ -158,12 +164,18 @@ static int ohci_urb_enqueue ( return -ENOMEM; /* for the private part of the URB we need the number of TDs (size) */ - switch (usb_pipetype (pipe)) { + switch (ed->type) { case PIPE_CONTROL: + /* td_submit_urb() doesn't yet handle these */ + if (urb->transfer_buffer_length > 4096) + return -EMSGSIZE; + /* 1 TD for setup, 1 for ACK, plus ... */ size = 2; /* FALLTHROUGH */ - case PIPE_BULK: + // case PIPE_INTERRUPT: + // case PIPE_BULK: + default: /* one TD for every 4096 Bytes (can be upto 8K) */ size += urb->transfer_buffer_length / 4096; /* ... and for any remaining bytes ... */ @@ -187,9 +199,6 @@ static int ohci_urb_enqueue ( urb->iso_frame_desc [i].status = -EXDEV; } break; - case PIPE_INTERRUPT: /* one TD */ - size = 1; - break; } /* allocate the private part of the URB */ @@ -242,9 +251,8 @@ static int ohci_urb_enqueue ( bustime = usb_check_bandwidth (urb->dev, urb); } if (bustime < 0) { - urb_free_priv (ohci, urb_priv); - spin_unlock_irqrestore (&ohci->lock, flags); - return bustime; + retval = bustime; + goto fail; } usb_claim_bandwidth (urb->dev, urb, bustime, usb_pipeisoc (urb->pipe)); @@ -259,7 +267,7 @@ static int ohci_urb_enqueue ( /* fill the TDs and link them to the ed; and * enable that part of the schedule, if needed */ - td_submit_urb (urb); + td_submit_urb (ohci, urb); fail: if (retval) @@ -513,7 +521,7 @@ static int hc_start (struct ohci_hcd *ohci) ohci->hcd.self.root_hub = udev = usb_alloc_dev (NULL, &ohci->hcd.self); ohci->hcd.state = USB_STATE_READY; if (!udev) { - ohci->disabled = 1; + disable (ohci); ohci->hc_control &= ~OHCI_CTRL_HCFS; writel (ohci->hc_control, &ohci->regs->control); return -ENOMEM; @@ -523,7 +531,7 @@ static int hc_start (struct ohci_hcd *ohci) udev->speed = USB_SPEED_FULL; if (usb_register_root_hub (udev, ohci->parent_dev) != 0) { usb_free_dev (udev); - ohci->disabled = 1; + disable (ohci); ohci->hc_control &= ~OHCI_CTRL_HCFS; writel (ohci->hc_control, &ohci->regs->control); return -ENODEV; @@ -549,8 +557,8 @@ static void ohci_irq (struct usb_hcd *hcd) /* cardbus/... hardware gone before remove() */ } else if ((ints = readl (®s->intrstatus)) == ~(u32)0) { - ohci->disabled++; - err ("%s device removed!", hcd->self.bus_name); + disable (ohci); + dbg ("%s device removed!", hcd->self.bus_name); return; /* interrupt for some other device? */ @@ -562,7 +570,7 @@ static void ohci_irq (struct usb_hcd *hcd) // dbg ("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); if (ints & OHCI_INTR_UE) { - ohci->disabled++; + disable (ohci); err ("OHCI Unrecoverable Error, %s disabled", hcd->self.bus_name); // e.g. due to PCI Master/Target Abort diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index e38860089a8b..9fd76677717d 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -22,7 +22,9 @@ */ #define read_roothub(hc, register, mask) ({ \ u32 temp = readl (&hc->regs->roothub.register); \ - if (hc->flags & OHCI_QUIRK_AMD756) \ + if (temp == -1) \ + disable (hc); \ + else if (hc->flags & OHCI_QUIRK_AMD756) \ while (temp & mask) \ temp = readl (&hc->regs->roothub.register); \ temp; }) @@ -71,8 +73,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) ports = roothub_a (ohci) & RH_A_NDP; if (ports > MAX_ROOT_PORTS) { - err ("%s: bogus NDP=%d", hcd->self.bus_name, ports); - err ("rereads as NDP=%d", + if (ohci->disabled) + return -ESHUTDOWN; + err ("%s bogus NDP=%d, rereads as NDP=%d", + hcd->self.bus_name, ports, readl (&ohci->regs->roothub.a) & RH_A_NDP); /* retry later; "should not happen" */ return 0; diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index b04fc02bd375..0fe88b71cc30 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -77,12 +77,12 @@ static void finish_urb (struct ohci_hcd *ohci, struct urb *urb) usb_hcd_giveback_urb (&ohci->hcd, urb); } -static void td_submit_urb (struct urb *urb); +static void td_submit_urb (struct ohci_hcd *ohci, struct urb *urb); /* Report interrupt transfer completion, maybe reissue */ -static void intr_resub (struct ohci_hcd *hc, struct urb *urb) +static inline void intr_resub (struct ohci_hcd *hc, struct urb *urb) { - urb_priv_t *urb_priv = urb->hcpriv; + struct urb_priv *urb_priv = urb->hcpriv; unsigned long flags; // FIXME rewrite this resubmit path. use pci_dma_sync_single() @@ -120,7 +120,7 @@ static void intr_resub (struct ohci_hcd *hc, struct urb *urb) spin_unlock (&urb->lock); spin_lock (&hc->lock); - td_submit_urb (urb); + td_submit_urb (hc, urb); spin_unlock_irqrestore (&hc->lock, flags); } @@ -518,12 +518,12 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed) /* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ static void -td_fill (struct ohci_hcd *ohci, unsigned int info, +td_fill (unsigned int info, dma_addr_t data, int len, struct urb *urb, int index) { struct td *td, *td_pt; - urb_priv_t *urb_priv = urb->hcpriv; + struct urb_priv *urb_priv = urb->hcpriv; int is_iso = info & TD_ISO; if (index >= urb_priv->length) { @@ -582,28 +582,30 @@ td_fill (struct ohci_hcd *ohci, unsigned int info, /*-------------------------------------------------------------------------*/ -/* prepare all TDs of a transfer */ - -static void td_submit_urb (struct urb *urb) -{ - urb_priv_t *urb_priv = urb->hcpriv; - struct ohci_hcd *ohci = hcd_to_ohci (urb->dev->bus->hcpriv); +/* Prepare all TDs of a transfer, and queue them onto the ED. + * Caller guarantees HC is active. + * Usually the ED is already on the schedule, so TDs might be + * processed as soon as they're queued. + */ +static void td_submit_urb ( + struct ohci_hcd *ohci, + struct urb *urb +) { + struct urb_priv *urb_priv = urb->hcpriv; dma_addr_t data; int data_len = urb->transfer_buffer_length; - int cnt = 0; - __u32 info = 0; - unsigned int toggle = 0; + int cnt = 0; + u32 info = 0; int is_out = usb_pipeout (urb->pipe); - /* OHCI handles the DATA-toggles itself, we just use the - * USB-toggle bits for resetting + /* OHCI handles the bulk/interrupt data toggles itself. We just + * use the device toggle bits for resetting, and rely on the fact + * that resetting toggle is meaningless if the endpoint is active. */ - if (usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) { - toggle = TD_T_TOGGLE; - } else { - toggle = TD_T_DATA0; + if (!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) { usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out, 1); + urb_priv->ed->hwHeadP &= ~ED_C; } urb_priv->td_cnt = 0; @@ -619,91 +621,88 @@ static void td_submit_urb (struct urb *urb) /* NOTE: TD_CC is set so we can tell which TDs the HC processed by * using TD_CC_GET, as well as by seeing them on the done list. + * (CC = NotAccessed ... 0x0F, or 0x0E in PSWs for ISO.) */ - switch (usb_pipetype (urb->pipe)) { - case PIPE_BULK: - info = is_out - ? TD_CC | TD_DP_OUT - : TD_CC | TD_DP_IN ; - /* TDs _could_ transfer up to 8K each */ - while (data_len > 4096) { - td_fill (ohci, - info | (cnt? TD_T_TOGGLE:toggle), - data, 4096, urb, cnt); - data += 4096; data_len -= 4096; cnt++; - } - /* maybe avoid ED halt on final TD short read */ - if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) - info |= TD_R; - td_fill (ohci, info | (cnt ? TD_T_TOGGLE : toggle), - data, data_len, urb, cnt); + switch (urb_priv->ed->type) { + + /* Bulk and interrupt are identical except for where in the schedule + * their EDs live. + */ + // case PIPE_BULK: + // case PIPE_INTERRUPT: + default: + info = is_out + ? TD_T_TOGGLE | TD_CC | TD_DP_OUT + : TD_T_TOGGLE | TD_CC | TD_DP_IN; + /* TDs _could_ transfer up to 8K each */ + while (data_len > 4096) { + td_fill (info, data, 4096, urb, cnt); + data += 4096; + data_len -= 4096; cnt++; - if ((urb->transfer_flags & USB_ZERO_PACKET) - && cnt < urb_priv->length) { - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), - 0, 0, urb, cnt); - cnt++; - } - /* start bulk list */ - if (!ohci->sleeping) { - wmb (); - writel (OHCI_BLF, &ohci->regs->cmdstatus); - } - break; + } + /* maybe avoid ED halt on final TD short read */ + if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) + info |= TD_R; + td_fill (info, data, data_len, urb, cnt); + cnt++; + if ((urb->transfer_flags & USB_ZERO_PACKET) + && cnt < urb_priv->length) { + td_fill (info, 0, 0, urb, cnt); + cnt++; + } + /* maybe kickstart bulk list */ + if (urb_priv->ed->type == PIPE_BULK) { + wmb (); + writel (OHCI_BLF, &ohci->regs->cmdstatus); + } + break; - case PIPE_INTERRUPT: - /* current policy: only one TD per request. - * otherwise identical to bulk, except for BLF - */ - info = TD_CC | toggle; - info |= is_out - ? TD_DP_OUT - : TD_R | TD_DP_IN; - td_fill (ohci, info, data, data_len, urb, cnt++); - break; - - case PIPE_CONTROL: - /* control requests don't use toggle state */ - info = TD_CC | TD_DP_SETUP | TD_T_DATA0; - td_fill (ohci, info, - pci_map_single (ohci->hcd.pdev, - urb->setup_packet, 8, - PCI_DMA_TODEVICE), - 8, urb, cnt++); - if (data_len > 0) { - info = TD_CC | TD_R | TD_T_DATA1; - info |= is_out ? TD_DP_OUT : TD_DP_IN; - /* NOTE: mishandles transfers >8K, some >4K */ - td_fill (ohci, info, data, data_len, - urb, cnt++); - } - info = is_out - ? TD_CC | TD_DP_IN | TD_T_DATA1 - : TD_CC | TD_DP_OUT | TD_T_DATA1; - td_fill (ohci, info, data, 0, urb, cnt++); - /* start control list */ - if (!ohci->sleeping) { - wmb (); - writel (OHCI_CLF, &ohci->regs->cmdstatus); - } - break; - - case PIPE_ISOCHRONOUS: - for (cnt = 0; cnt < urb->number_of_packets; cnt++) { - int frame = urb->start_frame; - - // FIXME scheduling should handle frame counter - // roll-around ... exotic case (and OHCI has - // a 2^16 iso range, vs other HCs max of 2^10) - frame += cnt * urb->interval; - frame &= 0xffff; - td_fill (ohci, TD_CC | TD_ISO | frame, - data + urb->iso_frame_desc [cnt].offset, - urb->iso_frame_desc [cnt].length, urb, cnt); - } - break; - } - if (urb_priv->length != cnt) + /* control manages DATA0/DATA1 toggle per-request; SETUP resets it, + * any DATA phase works normally, and the STATUS ack is special. + */ + case PIPE_CONTROL: + info = TD_CC | TD_DP_SETUP | TD_T_DATA0; + td_fill (info, + pci_map_single (ohci->hcd.pdev, + urb->setup_packet, 8, + PCI_DMA_TODEVICE), + 8, urb, cnt++); + if (data_len > 0) { + info = TD_CC | TD_R | TD_T_DATA1; + info |= is_out ? TD_DP_OUT : TD_DP_IN; + /* NOTE: mishandles transfers >8K, some >4K */ + td_fill (info, data, data_len, urb, cnt++); + } + info = is_out + ? TD_CC | TD_DP_IN | TD_T_DATA1 + : TD_CC | TD_DP_OUT | TD_T_DATA1; + td_fill (info, data, 0, urb, cnt++); + /* maybe kickstart control list */ + wmb (); + writel (OHCI_CLF, &ohci->regs->cmdstatus); + break; + + /* ISO has no retransmit, so no toggle; and it uses special TDs. + * Each TD could handle multiple consecutive frames (interval 1); + * we could often reduce the number of TDs here. + */ + case PIPE_ISOCHRONOUS: + for (cnt = 0; cnt < urb->number_of_packets; cnt++) { + int frame = urb->start_frame; + + // FIXME scheduling should handle frame counter + // roll-around ... exotic case (and OHCI has + // a 2^16 iso range, vs other HCs max of 2^10) + frame += cnt * urb->interval; + frame &= 0xffff; + td_fill (TD_CC | TD_ISO | frame, + data + urb->iso_frame_desc [cnt].offset, + urb->iso_frame_desc [cnt].length, urb, cnt); + } + break; + } + if (urb_priv->length != cnt) dbg ("TD LENGTH %d != CNT %d", urb_priv->length, cnt); } @@ -724,8 +723,10 @@ static void td_done (struct urb *urb, struct td *td) u16 tdPSW = le16_to_cpu (td->hwPSW [0]); int dlen = 0; + /* NOTE: assumes FC in tdINFO == 0 (and MAXPSW == 1) */ + cc = (tdPSW >> 12) & 0xF; - if (cc >= 0x0E) /* hc didn't touch? */ + if (tdINFO & TD_CC) /* hc didn't touch? */ return; if (usb_pipeout (urb->pipe)) diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index d004af6fe207..4af5cdf0aa34 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -401,5 +401,5 @@ struct ohci_hcd { struct usb_hcd hcd; }; -#define hcd_to_ohci(hcd_ptr) list_entry(hcd_ptr, struct ohci_hcd, hcd) +#define hcd_to_ohci(hcd_ptr) container_of(hcd_ptr, struct ohci_hcd, hcd) -- cgit v1.2.3 From 805f47cf9f1bdac09fd1852b6e3f42918efb34f6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 25 Jul 2002 21:46:28 -0700 Subject: USB: deleted hid-lg3dff.c as it's no longer needed. --- drivers/usb/input/hid-lg3dff.c | 444 ----------------------------------------- 1 file changed, 444 deletions(-) delete mode 100644 drivers/usb/input/hid-lg3dff.c (limited to 'drivers') diff --git a/drivers/usb/input/hid-lg3dff.c b/drivers/usb/input/hid-lg3dff.c deleted file mode 100644 index b9f5636dd614..000000000000 --- a/drivers/usb/input/hid-lg3dff.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * $$ - * - * Force feedback support for hid-compliant devices of the Logitech *3D family - * - * Copyright (c) 2002 Johann Deneux - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Should you need to contact me, the author, you can do so by - * e-mail - mail your message to - */ - -#include -#include - -#define DEBUG -#include - -#include - -#include "hid.h" -#include "fixp-arith.h" - -#define RUN_AT(t) (jiffies + (t)) - -/* Periodicity of the update */ -#define PERIOD (HZ/10) - -/* Effect status: lg3d_effect::flags */ -#define EFFECT_STARTED 0 /* Effect is going to play after some time - (ff_replay.delay) */ -#define EFFECT_PLAYING 1 /* Effect is being played */ -#define EFFECT_USED 2 - -/* Check that the current process can access an effect */ -#define CHECK_OWNERSHIP(i, l) \ - (i>=0 && ieffects[i].flags) \ - && (current->pid == 0 \ - || l->effects[i].owner == current->pid)) - -#define N_EFFECTS 8 - -struct lg3d_effect { - pid_t owner; - - struct ff_effect effect; /* Description of the effect */ - - unsigned int count; /* Number of times left to play */ - unsigned long flags[1]; - - unsigned long started_at; /* When the effect started to play */ -}; - -// For lg3d_device::flags -#define DEVICE_USB_XMIT 0 /* An URB is being sent */ -#define DEVICE_CLOSING 1 /* The driver is being unitialised */ - -struct lg3d_device { - struct hid_device* hid; - - struct urb* urbffout; /* Output URB used to send ff commands */ - struct usb_ctrlrequest ffcr; /* ff commands use control URBs */ - char buf[8]; - - struct lg3d_effect effects[N_EFFECTS]; - spinlock_t lock; /* device-level lock. Having locks on - a per-effect basis could be nice, but - isn't really necessary */ - struct timer_list timer; - unsigned long last_time; /* Last time the timer handler was - executed */ - - unsigned long flags[1]; /* Contains various information about the - state of the driver for this device */ -}; - -static void hid_lg3d_ctrl_out(struct urb *urb); -static void hid_lg3d_exit(struct hid_device* hid); -static int hid_lg3d_event(struct hid_device *hid, struct input_dev *input, - unsigned int type, unsigned int code, int value); -static int hid_lg3d_flush(struct input_dev *input, struct file *file); -static int hid_lg3d_upload_effect(struct input_dev *input, - struct ff_effect *effect); -static int hid_lg3d_erase(struct input_dev *input, int id); -static void hid_lg3d_timer(unsigned long timer_data); - - -int hid_lg3d_init(struct hid_device* hid) -{ - struct lg3d_device *private; - - /* Private data */ - private = kmalloc(sizeof(struct lg3d_device), GFP_KERNEL); - if (!private) return -1; - - memset(private, 0, sizeof(struct lg3d_device)); - - hid->ff_private = private; - - private->hid = hid; - spin_lock_init(&private->lock); - - /* Timer for the periodic update task */ - init_timer(&private->timer); - private->timer.data = (unsigned long)private; - private->timer.function = hid_lg3d_timer; - - /* Event and exit callbacks */ - hid->ff_exit = hid_lg3d_exit; - hid->ff_event = hid_lg3d_event; - - /* USB init */ - if (!(private->urbffout = usb_alloc_urb(0, GFP_KERNEL))) { - kfree(hid->ff_private); - return -1; - } - - usb_fill_control_urb(private->urbffout, hid->dev, 0, - (void*) &private->ffcr, private->buf, 8, - hid_lg3d_ctrl_out, hid); - dbg("Created ff output control urb"); - - /* Input init */ - hid->input.upload_effect = hid_lg3d_upload_effect; - hid->input.flush = hid_lg3d_flush; - set_bit(FF_CONSTANT, hid->input.ffbit); - set_bit(EV_FF, hid->input.evbit); - hid->input.ff_effects_max = N_EFFECTS; - - printk(KERN_INFO "Force feedback for Logitech *3D devices by Johann Deneux \n"); - - /* Start the update task */ - private->timer.expires = RUN_AT(PERIOD); - add_timer(&private->timer); /*TODO: only run the timer when at least - one effect is playing */ - - return 0; -} - -static void hid_lg3d_exit(struct hid_device* hid) -{ - struct lg3d_device *lg3d = hid->ff_private; - unsigned long flags; - - spin_lock_irqsave(&lg3d->lock, flags); - set_bit(DEVICE_CLOSING, lg3d->flags); - spin_unlock_irqrestore(&lg3d->lock, flags); - - del_timer_sync(&lg3d->timer); - - if (lg3d->urbffout) { - usb_unlink_urb(lg3d->urbffout); - usb_free_urb(lg3d->urbffout); - } - - kfree(lg3d); -} - -static int hid_lg3d_event(struct hid_device *hid, struct input_dev* input, - unsigned int type, unsigned int code, int value) -{ - struct lg3d_device *lg3d = hid->ff_private; - struct lg3d_effect *effect = lg3d->effects + code; - unsigned long flags; - - if (type != EV_FF) return -EINVAL; - if (!CHECK_OWNERSHIP(code, lg3d)) return -EACCES; - if (value < 0) return -EINVAL; - - spin_lock_irqsave(&lg3d->lock, flags); - - if (value > 0) { - if (test_bit(EFFECT_STARTED, effect->flags)) { - spin_unlock_irqrestore(&lg3d->lock, flags); - return -EBUSY; - } - if (test_bit(EFFECT_PLAYING, effect->flags)) { - spin_unlock_irqrestore(&lg3d->lock, flags); - return -EBUSY; - } - - effect->count = value; - - if (effect->effect.replay.delay) { - set_bit(EFFECT_STARTED, effect->flags); - } else { - set_bit(EFFECT_PLAYING, effect->flags); - } - effect->started_at = jiffies; - } - else { /* value == 0 */ - clear_bit(EFFECT_STARTED, effect->flags); - clear_bit(EFFECT_PLAYING, effect->flags); - } - - spin_unlock_irqrestore(&lg3d->lock, flags); - - return 0; -} - -/* Erase all effects this process owns */ -static int hid_lg3d_flush(struct input_dev *dev, struct file *file) -{ - struct hid_device *hid = dev->private; - struct lg3d_device *lg3d = hid->ff_private; - int i; - - for (i=0; iff_effects_max; ++i) { - - /*NOTE: no need to lock here. The only times EFFECT_USED is - modified is when effects are uploaded or when an effect is - erased. But a process cannot close its dev/input/eventX fd - and perform ioctls on the same fd all at the same time */ - if ( current->pid == lg3d->effects[i].owner - && test_bit(EFFECT_USED, lg3d->effects[i].flags)) { - - if (hid_lg3d_erase(dev, i)) - warn("erase effect %d failed", i); - } - - } - - return 0; -} - -static int hid_lg3d_erase(struct input_dev *dev, int id) -{ - struct hid_device *hid = dev->private; - struct lg3d_device *lg3d = hid->ff_private; - unsigned long flags; - - if (!CHECK_OWNERSHIP(id, lg3d)) return -EACCES; - - spin_lock_irqsave(&lg3d->lock, flags); - lg3d->effects[id].flags[0] = 0; - spin_unlock_irqrestore(&lg3d->lock, flags); - - return 0; -} - -static int hid_lg3d_upload_effect(struct input_dev* input, - struct ff_effect* effect) -{ - struct hid_device *hid = input->private; - struct lg3d_device *lg3d = hid->ff_private; - struct lg3d_effect new; - int id; - unsigned long flags; - - dbg("ioctl upload"); - - if (!test_bit(effect->type, input->ffbit)) return -EINVAL; - - if (effect->type != FF_CONSTANT) return -EINVAL; - - spin_lock_irqsave(&lg3d->lock, flags); - - if (effect->id == -1) { - int i; - - for (i=0; ieffects[i].flags); ++i); - if (i >= N_EFFECTS) { - spin_unlock_irqrestore(&lg3d->lock, flags); - return -ENOSPC; - } - - effect->id = i; - lg3d->effects[i].owner = current->pid; - lg3d->effects[i].flags[0] = 0; - set_bit(EFFECT_USED, lg3d->effects[i].flags); - } - else if (!CHECK_OWNERSHIP(effect->id, lg3d)) { - spin_unlock_irqrestore(&lg3d->lock, flags); - return -EACCES; - } - - id = effect->id; - new = lg3d->effects[id]; - - new.effect = *effect; - new.effect.replay = effect->replay; - - if (test_bit(EFFECT_STARTED, lg3d->effects[id].flags) - || test_bit(EFFECT_STARTED, lg3d->effects[id].flags)) { - - /* Changing replay parameters is not allowed (for the time - being) */ - if (new.effect.replay.delay != lg3d->effects[id].effect.replay.delay - || new.effect.replay.length != lg3d->effects[id].effect.replay.length) { - spin_unlock_irqrestore(&lg3d->lock, flags); - return -ENOSYS; - } - - lg3d->effects[id] = new; - - } else { - lg3d->effects[id] = new; - } - - spin_unlock_irqrestore(&lg3d->lock, flags); - return 0; -} - -static void hid_lg3d_ctrl_out(struct urb *urb) -{ - struct hid_device *hid = urb->context; - struct lg3d_device *lg3d = hid->ff_private; - unsigned long flags; - - spin_lock_irqsave(&lg3d->lock, flags); - - if (urb->status) - warn("hid_irq_ffout status %d received", urb->status); - clear_bit(DEVICE_USB_XMIT, lg3d->flags); - dbg("xmit = 0"); - - spin_unlock_irqrestore(&lg3d->lock, flags); -} - -static void hid_lg3d_timer(unsigned long timer_data) -{ - struct lg3d_device *lg3d = (struct lg3d_device*)timer_data; - struct hid_device *hid = lg3d->hid; - unsigned long flags; - int x, y; - int i; - int err; - - spin_lock_irqsave(&lg3d->lock, flags); - - if (test_bit(DEVICE_USB_XMIT, lg3d->flags)) { - if (lg3d->urbffout->status != -EINPROGRESS) { - warn("xmit *not* in progress"); - } - else { - dbg("xmit in progress"); - } - - spin_unlock_irqrestore(&lg3d->lock, flags); - - lg3d->timer.expires = RUN_AT(PERIOD); - add_timer(&lg3d->timer); - - return; - } - - x = 0x7f; - y = 0x7f; - - for (i=0; ieffects +i; - - if (test_bit(EFFECT_PLAYING, effect->flags)) { - - if (effect->effect.type == FF_CONSTANT) { - //TODO: handle envelopes - int degrees = effect->effect.direction * 360 >> 16; - x += fixp_mult(fixp_sin(degrees), - fixp_new16(effect->effect.u.constant.level)); - y += fixp_mult(-fixp_cos(degrees), - fixp_new16(effect->effect.u.constant.level)); - } - - /* One run of the effect is finished playing */ - if (time_after(jiffies, - effect->started_at - + effect->effect.replay.delay*HZ/1000 - + effect->effect.replay.length*HZ/1000)) { - dbg("Finished playing once"); - if (--effect->count <= 0) { - dbg("Stopped"); - clear_bit(EFFECT_PLAYING, effect->flags); - } - else { - dbg("Start again"); - if (effect->effect.replay.length != 0) { - clear_bit(EFFECT_PLAYING, effect->flags); - set_bit(EFFECT_STARTED, effect->flags); - } - effect->started_at = jiffies; - } - } - - } else if (test_bit(EFFECT_STARTED, lg3d->effects[i].flags)) { - dbg("Started"); - /* Check if we should start playing the effect */ - if (time_after(jiffies, - lg3d->effects[i].started_at - + lg3d->effects[i].effect.replay.delay*HZ/1000)) { - dbg("Now playing"); - clear_bit(EFFECT_STARTED, lg3d->effects[i].flags); - set_bit(EFFECT_PLAYING, lg3d->effects[i].flags); - } - } - } - - if (x < 0) x = 0; - if (x > 0xff) x = 0xff; - if (y < 0) y = 0; - if (y > 0xff) y = 0xff; - - lg3d->urbffout->pipe = usb_sndctrlpipe(hid->dev, 0); - lg3d->ffcr.bRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE; - lg3d->urbffout->transfer_buffer_length = lg3d->ffcr.wLength = 8; - lg3d->ffcr.bRequest = 9; - lg3d->ffcr.wValue = 0x0200; /*NOTE: Potential problem with - little/big endian */ - lg3d->ffcr.wIndex = 0; - - lg3d->urbffout->dev = hid->dev; - - lg3d->buf[0] = 0x51; - lg3d->buf[1] = 0x08; - lg3d->buf[2] = x; - lg3d->buf[3] = y; - - if ((err=usb_submit_urb(lg3d->urbffout, GFP_ATOMIC))) - warn("usb_submit_urb returned %d", err); - else - set_bit(DEVICE_USB_XMIT, lg3d->flags); - - if (!test_bit(DEVICE_CLOSING, lg3d->flags)) { - lg3d->timer.expires = RUN_AT(PERIOD); - add_timer(&lg3d->timer); - } - - spin_unlock_irqrestore(&lg3d->lock, flags); -} -- cgit v1.2.3 From 018122cad8161885388080b01993c18796c89f72 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 25 Jul 2002 21:52:38 -0700 Subject: USB: usb-serial.c update the version number, and document the previous changes. --- drivers/usb/serial/usbserial.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c index ae7f1f3da7a5..c232a4ec3010 100644 --- a/drivers/usb/serial/usbserial.c +++ b/drivers/usb/serial/usbserial.c @@ -15,6 +15,11 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (06/05/2002) gkh + * moved location of startup() call in serial_probe() until after all + * of the port information and endpoints are initialized. This makes + * things easier for some drivers. + * * (04/10/2002) gkh * added serial_read_proc function which creates a * /proc/tty/driver/usb-serial file. @@ -341,7 +346,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.5" +#define DRIVER_VERSION "v1.6" #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux-usb/" #define DRIVER_DESC "USB Serial Driver core" -- cgit v1.2.3 From 6e2868e599b37a3fe9d70192a247c5ed7be938aa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 25 Jul 2002 21:59:47 -0700 Subject: USB: added driver to support the I/O Networks TI based usb-serial devices. --- drivers/usb/serial/Config.help | 10 + drivers/usb/serial/Config.in | 1 + drivers/usb/serial/Makefile | 1 + drivers/usb/serial/io_fw_down3.h | 799 ++++++++++++ drivers/usb/serial/io_ti.c | 2684 ++++++++++++++++++++++++++++++++++++++ drivers/usb/serial/io_ti.h | 180 +++ drivers/usb/serial/io_usbvend.h | 113 +- 7 files changed, 3781 insertions(+), 7 deletions(-) create mode 100644 drivers/usb/serial/io_fw_down3.h create mode 100644 drivers/usb/serial/io_ti.c create mode 100644 drivers/usb/serial/io_ti.h (limited to 'drivers') diff --git a/drivers/usb/serial/Config.help b/drivers/usb/serial/Config.help index a677b959551b..3a00c995da1b 100644 --- a/drivers/usb/serial/Config.help +++ b/drivers/usb/serial/Config.help @@ -268,6 +268,16 @@ CONFIG_USB_SERIAL_EDGEPORT The module will be called io_edgeport.o. If you want to compile it as a module, say M here and read . +CONFIG_USB_SERIAL_EDGEPORT_TI + Say Y here if you want to use any of the devices from Inside Out + Networks (Digi) that are not supported by the io_edgeport driver. + This includes the Edgeport/1 device. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called io_ti.o. If you want to compile it + as a module, say M here and read . + CONFIG_USB_SERIAL_KLSI Say Y here if you want to use a KL5KUSB105 - based single port serial adapter. The most widely known -- and currently the only diff --git a/drivers/usb/serial/Config.in b/drivers/usb/serial/Config.in index d8be99dbf624..d277619c0322 100644 --- a/drivers/usb/serial/Config.in +++ b/drivers/usb/serial/Config.in @@ -19,6 +19,7 @@ dep_tristate ' USB Handspring Visor / Palm m50x / Sony Clie Driver' CONFIG_USB_ dep_tristate ' USB Compaq iPAQ / HP Jornada / Casio EM500 Driver' CONFIG_USB_SERIAL_IPAQ $CONFIG_USB_SERIAL dep_tristate ' USB IR Dongle Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_IR $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL dep_tristate ' USB Inside Out Edgeport Serial Driver' CONFIG_USB_SERIAL_EDGEPORT $CONFIG_USB_SERIAL +dep_tristate ' USB Inside Out Edgeport Serial Driver (TI devices)' CONFIG_USB_SERIAL_EDGEPORT_TI $CONFIG_USB_SERIAL dep_tristate ' USB Keyspan PDA Single Port Serial Driver' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL dep_tristate ' USB Keyspan USA-xxx Serial Driver' CONFIG_USB_SERIAL_KEYSPAN $CONFIG_USB_SERIAL dep_mbool ' USB Keyspan USA-28 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28 $CONFIG_USB_SERIAL_KEYSPAN diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 962d94746de6..1d6f5946bf27 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o obj-$(CONFIG_USB_SERIAL_EMPEG) += empeg.o obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o obj-$(CONFIG_USB_SERIAL_EDGEPORT) += io_edgeport.o +obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += io_ti.o obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o diff --git a/drivers/usb/serial/io_fw_down3.h b/drivers/usb/serial/io_fw_down3.h new file mode 100644 index 000000000000..56d319f0163d --- /dev/null +++ b/drivers/usb/serial/io_fw_down3.h @@ -0,0 +1,799 @@ +//************************************************************** +//* Edgeport Binary Image (for TI based products) +//* Generated by TIBin2C v1.00 +//* Copyright(c) 2001 Inside Out Networks, All rights reserved. +//************************************************************** + + +static int IMAGE_SIZE = 12166; + +struct EDGE_FIRMWARE_VERSION_INFO +{ + unsigned char MajorVersion; + unsigned char MinorVersion; + unsigned short BuildNumber; +}; + +static struct EDGE_FIRMWARE_VERSION_INFO IMAGE_VERSION_NAME = +{ + 4, 1, 0 // Major, Minor, Build + +}; + +static unsigned char IMAGE_ARRAY_NAME[] = +{ +// struct ImageHdr +// { +// WORD Length; +// BYTE CheckSum; +// }; +0x83, 0x2f, +0x33, + +0x02, 0x24, 0x84, 0x02, 0x1f, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x1a, 0x85, 0x45, +0x8c, 0x85, 0x46, 0x8a, 0xc0, 0xe0, 0xc0, 0xd0, 0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, +0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xe5, 0x44, +0x24, 0x08, 0xf8, 0xe6, 0x60, 0x2b, 0xe5, 0x44, 0x24, 0x10, 0xf8, 0xa6, 0x81, 0xe5, 0x44, 0x75, +0xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, 0x78, 0x92, 0xe5, 0x81, +0x04, 0xc3, 0x98, 0xf9, 0x94, 0x22, 0x40, 0x03, 0x02, 0x11, 0x1a, 0xe6, 0xf0, 0x08, 0xa3, 0xd9, +0xfa, 0x74, 0x08, 0x25, 0x44, 0xf8, 0x05, 0x44, 0x08, 0xe6, 0x54, 0x80, 0x70, 0x0c, 0xe5, 0x44, +0xb4, 0x07, 0xf3, 0x78, 0x08, 0x75, 0x44, 0x00, 0x80, 0xef, 0xe5, 0x44, 0x24, 0x10, 0xf8, 0x86, +0x81, 0xe5, 0x44, 0x75, 0xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, +0x78, 0x92, 0xe5, 0x81, 0x04, 0xc3, 0x98, 0xf9, 0xe0, 0xf6, 0x08, 0xa3, 0xd9, 0xfa, 0xd0, 0x07, +0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0x83, +0xd0, 0x82, 0xd0, 0xf0, 0xd0, 0xd0, 0xd0, 0xe0, 0x32, 0x30, 0x01, 0x4d, 0x30, 0xb4, 0x48, 0x10, +0x00, 0x45, 0x90, 0xff, 0x08, 0xe0, 0x54, 0x20, 0xf8, 0x90, 0xff, 0x48, 0xe0, 0x54, 0x20, 0xf9, +0x90, 0xff, 0x10, 0xe0, 0x54, 0x20, 0xfa, 0x90, 0xff, 0x50, 0xe0, 0x54, 0x20, 0xfb, 0x74, 0x00, +0xf5, 0x82, 0x74, 0xf8, 0xf5, 0x83, 0xe0, 0xc8, 0xf0, 0x68, 0x60, 0x02, 0x7e, 0x04, 0xa3, 0xe0, +0xc9, 0xf0, 0x69, 0x60, 0x02, 0x7e, 0x04, 0xa3, 0xe0, 0xca, 0xf0, 0x6a, 0x60, 0x02, 0x7e, 0x04, +0xa3, 0xe0, 0xcb, 0xf0, 0x6b, 0x60, 0x02, 0x7e, 0x04, 0x22, 0xc0, 0xe0, 0xc0, 0xd0, 0xc0, 0xf0, +0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, +0xc0, 0x06, 0xc0, 0x07, 0x90, 0xff, 0x93, 0x74, 0x01, 0xf0, 0xe5, 0x81, 0x94, 0xfd, 0x40, 0x03, +0x02, 0x11, 0x1a, 0x85, 0x47, 0x8d, 0x85, 0x48, 0x8b, 0x74, 0xae, 0xf5, 0x82, 0x74, 0xfa, 0xf5, +0x83, 0xe0, 0xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x4a, 0xe0, 0x30, 0xe7, 0x2c, +0x90, 0xff, 0x4e, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x20, +0xb4, 0x02, 0x1d, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x25, +0x13, 0x80, 0x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x04, 0xd0, 0x83, 0xd0, 0x82, +0xa3, 0xe0, 0xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x52, 0xe0, 0x30, 0xe7, 0x2c, +0x90, 0xff, 0x56, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x20, +0xb4, 0x02, 0x1d, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x25, +0x13, 0x80, 0x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x04, 0xd0, 0x83, 0xd0, 0x82, +0x20, 0x02, 0x03, 0x30, 0x01, 0x7b, 0x74, 0x16, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x14, +0xfc, 0xf0, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0x64, 0x04, 0x70, 0x0f, 0xec, 0x70, 0x62, 0x7e, +0x01, 0x12, 0x00, 0xc9, 0x7c, 0x0a, 0x7d, 0xfa, 0x02, 0x02, 0x22, 0x12, 0x00, 0xc9, 0xee, 0x64, +0x04, 0x60, 0x1d, 0xec, 0x70, 0x4b, 0x7c, 0x0a, 0xed, 0x14, 0xfd, 0x70, 0x15, 0xee, 0x64, 0x02, +0x60, 0x07, 0x7e, 0x02, 0x7d, 0x32, 0x02, 0x02, 0x22, 0x7e, 0x01, 0x7d, 0xfa, 0x02, 0x02, 0x22, +0x7c, 0x0a, 0x74, 0x16, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, +0xee, 0xf0, 0x14, 0x60, 0x18, 0x20, 0xe1, 0x0f, 0x20, 0x01, 0x06, 0xd2, 0xb1, 0xc2, 0xb0, 0x80, +0x10, 0xc2, 0xb1, 0xd2, 0xb0, 0x80, 0x0a, 0xc2, 0xb1, 0xc2, 0xb0, 0x80, 0x04, 0xd2, 0xb0, 0xd2, +0xb1, 0x78, 0x19, 0x79, 0x09, 0x7a, 0x07, 0xe7, 0x70, 0x04, 0xa6, 0x00, 0x80, 0x0b, 0xe6, 0x60, +0x08, 0x16, 0xe6, 0x70, 0x04, 0xe7, 0x44, 0x80, 0xf7, 0x08, 0x09, 0xda, 0xea, 0xe5, 0x43, 0x60, +0x13, 0x14, 0xf5, 0x43, 0x70, 0x0e, 0xe5, 0x44, 0x24, 0x08, 0xf8, 0x76, 0x00, 0x12, 0x10, 0x95, +0xd2, 0x8c, 0xd2, 0x8d, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, +0xd0, 0x01, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0xd0, 0xd0, 0xd0, 0xe0, 0x32, 0x90, +0xff, 0x04, 0xe0, 0x90, 0xfa, 0xb5, 0xf0, 0x90, 0xff, 0x06, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 0xec, +0xff, 0xea, 0xfe, 0xef, 0xc3, 0x94, 0x08, 0xee, 0x94, 0x01, 0x50, 0x02, 0x80, 0x04, 0x7e, 0x01, +0x7f, 0x08, 0x8e, 0x34, 0x8f, 0x35, 0x90, 0xff, 0x02, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 0xec, 0xff, +0xea, 0x90, 0xfa, 0xb9, 0xf0, 0xef, 0xa3, 0xf0, 0x12, 0x18, 0x49, 0x78, 0x24, 0x7c, 0x00, 0x7d, +0x00, 0x12, 0x19, 0x6c, 0x7e, 0x00, 0x7f, 0x05, 0x12, 0x13, 0x8f, 0xe4, 0xf5, 0x53, 0xe5, 0x53, +0xc3, 0x94, 0x02, 0x50, 0x0f, 0x12, 0x18, 0x2a, 0xe4, 0x12, 0x13, 0xfb, 0x05, 0x53, 0x04, 0x12, +0x18, 0x1b, 0x80, 0xea, 0x12, 0x18, 0x49, 0x90, 0xff, 0x00, 0xe0, 0xff, 0x54, 0x60, 0x24, 0xc0, +0x70, 0x03, 0x02, 0x08, 0xb8, 0x24, 0x40, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x90, 0xfa, 0xb5, 0xe0, +0xfe, 0x54, 0x0f, 0xf5, 0x53, 0xee, 0x30, 0xe7, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x0a, 0x90, +0xff, 0x01, 0xe0, 0x12, 0x15, 0x0f, 0x03, 0x55, 0x00, 0x04, 0x28, 0x01, 0x05, 0x2f, 0x03, 0x05, +0xf6, 0x05, 0x06, 0x38, 0x06, 0x07, 0x9a, 0x08, 0x07, 0xe2, 0x09, 0x08, 0x3e, 0x0a, 0x08, 0x7e, +0x0b, 0x00, 0x00, 0x0e, 0xac, 0xe5, 0x2c, 0x20, 0xe7, 0x03, 0x02, 0x0e, 0xac, 0x90, 0xfa, 0xb9, +0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x35, 0x64, 0x02, 0x45, 0x34, +0x60, 0x03, 0x02, 0x0e, 0xac, 0xef, 0x54, 0x1f, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x47, 0x24, 0x02, +0x60, 0x03, 0x02, 0x0e, 0xac, 0xee, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x12, 0x18, 0x2a, 0x74, 0x01, +0x12, 0x13, 0xfb, 0x78, 0x6d, 0xe6, 0x30, 0xe0, 0x08, 0x12, 0x18, 0x2a, 0x74, 0x02, 0x12, 0x13, +0xfb, 0x7f, 0x02, 0x02, 0x2f, 0x6a, 0xe5, 0x2c, 0x20, 0xe1, 0x09, 0x90, 0xfa, 0xb5, 0xe0, 0x60, +0x03, 0x02, 0x0e, 0xac, 0x90, 0xfa, 0xb5, 0xe0, 0xd3, 0x94, 0x01, 0x40, 0x03, 0x02, 0x0e, 0xac, +0x7f, 0x02, 0x02, 0x2f, 0x6a, 0xe5, 0x2c, 0x20, 0xe1, 0x0e, 0x90, 0xfa, 0xb5, 0xe0, 0xff, 0x60, +0x07, 0x64, 0x80, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x12, 0x0f, 0x38, 0x40, 0x03, 0x02, 0x0e, 0xac, +0xe5, 0x53, 0x70, 0x19, 0x30, 0x0a, 0x0b, 0x90, 0xff, 0x80, 0x12, 0x18, 0x27, 0x12, 0x13, 0xfb, +0x80, 0x24, 0x90, 0xff, 0x82, 0x12, 0x18, 0x27, 0x12, 0x13, 0xfb, 0x80, 0x19, 0x15, 0x53, 0x30, +0x0a, 0x0b, 0x12, 0x18, 0xbd, 0x12, 0x18, 0x25, 0x12, 0x13, 0xfb, 0x80, 0x09, 0x12, 0x18, 0xcb, +0x12, 0x18, 0x25, 0x12, 0x13, 0xfb, 0x12, 0x18, 0x2a, 0x12, 0x13, 0xb5, 0x60, 0x05, 0x74, 0x01, +0x12, 0x13, 0xfb, 0x7f, 0x02, 0x02, 0x2f, 0x6a, 0xe5, 0x2c, 0x30, 0xe7, 0x03, 0x02, 0x0e, 0xac, +0xe5, 0x35, 0x45, 0x34, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x12, 0x18, 0xd9, 0x14, 0x60, 0x2d, 0x14, +0x60, 0x59, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x90, 0xfa, 0xb9, 0xe0, 0x70, 0x04, 0xa3, +0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x90, 0xfa, 0xb5, 0xe0, 0x60, 0x03, 0x02, 0x0e, +0xac, 0x78, 0x6d, 0xe6, 0x54, 0xfe, 0xf6, 0xe4, 0xff, 0x02, 0x2f, 0x6a, 0xe5, 0x2c, 0x20, 0xe1, +0x06, 0x20, 0xe0, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x2c, 0x30, 0xe0, 0x09, 0x90, 0xfa, 0xb5, 0xe0, +0x60, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x2c, 0x30, 0xe1, 0x0c, 0x90, 0xfa, 0xb5, 0xe0, 0xd3, 0x94, +0x01, 0x40, 0x03, 0x02, 0x0e, 0xac, 0xe4, 0xff, 0x02, 0x2f, 0x6a, 0x90, 0xfa, 0xb9, 0xe0, 0x70, +0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x12, 0x0f, 0x38, 0x40, 0x03, 0x02, 0x0e, 0xac, +0xe5, 0x2c, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x2c, 0x30, 0xe0, 0x07, +0xe5, 0x53, 0x60, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x53, 0x70, 0x0f, 0x90, 0xff, 0x82, 0xe0, 0x54, +0xf7, 0xf0, 0x90, 0xff, 0x80, 0xe0, 0x54, 0xf7, 0xf0, 0x22, 0xe5, 0x53, 0x24, 0xfe, 0x60, 0x1b, +0x04, 0x70, 0x2e, 0x30, 0x0a, 0x0c, 0xa2, 0x0a, 0xe4, 0x33, 0xfd, 0x7f, 0x03, 0x12, 0x2a, 0xce, +0x80, 0x1f, 0xe4, 0xfd, 0x7f, 0x03, 0x12, 0x2a, 0xce, 0x80, 0x16, 0x30, 0x0a, 0x0c, 0xa2, 0x0a, +0xe4, 0x33, 0xfd, 0x7f, 0x04, 0x12, 0x2a, 0xce, 0x80, 0x07, 0xe4, 0xfd, 0x7f, 0x04, 0x12, 0x2a, +0xce, 0x15, 0x53, 0x30, 0x0a, 0x0b, 0x12, 0x18, 0xbd, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0x80, +0x09, 0x12, 0x18, 0xcb, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0xff, 0x02, 0x2f, 0x6a, 0xe5, +0x2c, 0x30, 0xe7, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x35, 0x45, 0x34, 0x60, 0x03, 0x02, 0x0e, 0xac, +0x12, 0x18, 0xd9, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x55, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0e, 0xac, +0x90, 0xfa, 0xb9, 0xe0, 0x70, 0x04, 0xa3, 0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x90, +0xfa, 0xb5, 0xe0, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x78, 0x6d, 0xe6, 0x44, 0x01, 0xf6, 0xe4, 0xff, +0x02, 0x2f, 0x6a, 0xe5, 0x2c, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x2c, +0x30, 0xe0, 0x07, 0xe5, 0x53, 0x60, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x2c, 0x30, 0xe1, 0x0a, 0xe5, +0x53, 0xd3, 0x94, 0x01, 0x40, 0x03, 0x02, 0x0e, 0xac, 0xe4, 0xff, 0x02, 0x2f, 0x6a, 0x90, 0xfa, +0xb9, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x90, 0xfa, 0xb5, 0xe0, 0xff, +0x12, 0x2f, 0x3b, 0x40, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x2c, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, +0x02, 0x0e, 0xac, 0xe5, 0x53, 0x70, 0x09, 0x30, 0x0a, 0x03, 0x02, 0x19, 0x7a, 0x02, 0x19, 0x3e, +0xe5, 0x2c, 0x20, 0xe1, 0x03, 0x02, 0x0e, 0xac, 0x15, 0x53, 0x30, 0x0a, 0x0b, 0x12, 0x18, 0xbd, +0xf5, 0x83, 0xe0, 0x44, 0x08, 0xf0, 0x80, 0x09, 0x12, 0x18, 0xcb, 0xf5, 0x83, 0xe0, 0x44, 0x08, +0xf0, 0xe4, 0xff, 0x02, 0x2f, 0x6a, 0xe5, 0x2c, 0x30, 0xe7, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x35, +0x45, 0x34, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x90, 0xfa, 0xb5, 0xe0, 0x60, 0x03, 0x02, 0x0e, 0xac, +0x12, 0x18, 0xd9, 0x60, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x2c, 0x30, 0xe1, 0x03, 0x02, 0x0e, 0xac, +0x90, 0xfa, 0xba, 0xe0, 0x90, 0xff, 0xff, 0xf0, 0xe0, 0x60, 0x05, 0x43, 0x2c, 0x01, 0x80, 0x03, +0x53, 0x2c, 0xfe, 0xe4, 0xff, 0x02, 0x2f, 0x6a, 0xe5, 0x2c, 0x20, 0xe7, 0x03, 0x02, 0x0e, 0xac, +0xe5, 0x35, 0x45, 0x34, 0x70, 0x03, 0x02, 0x0e, 0xac, 0x12, 0x18, 0xd9, 0x60, 0x03, 0x02, 0x0e, +0xac, 0x90, 0xfa, 0xb9, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xec, 0x24, 0xfe, 0x60, 0x3a, 0x14, 0x60, +0x75, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0e, 0xac, 0xed, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x12, 0x18, +0x49, 0x12, 0x19, 0x73, 0x7d, 0x03, 0x12, 0x0e, 0xf3, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x12, 0x0e, +0xb0, 0x90, 0xfa, 0xb2, 0xe0, 0xfd, 0xa3, 0x12, 0x18, 0x93, 0x12, 0x0f, 0x0f, 0x50, 0x02, 0x80, +0x04, 0xae, 0x34, 0xaf, 0x35, 0x02, 0x0f, 0x40, 0x12, 0x18, 0x49, 0x90, 0xf9, 0x65, 0xe0, 0x30, +0xe4, 0x0d, 0x12, 0x19, 0x73, 0x7d, 0x14, 0x12, 0x0e, 0xf3, 0x60, 0x10, 0x02, 0x0e, 0xac, 0x12, +0x19, 0x73, 0x7d, 0x04, 0x12, 0x0f, 0x47, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x12, 0x0e, 0xb0, 0x90, +0xfa, 0xb2, 0xe0, 0xfd, 0xa3, 0x12, 0x18, 0x93, 0x12, 0x0f, 0x0f, 0x50, 0x02, 0x80, 0x04, 0xae, +0x34, 0xaf, 0x35, 0x02, 0x0f, 0x40, 0x12, 0x19, 0x73, 0x7d, 0x05, 0x12, 0x0f, 0x47, 0x60, 0x03, +0x02, 0x0e, 0xac, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb2, 0x12, 0x18, 0x90, 0x7d, 0x01, 0x12, 0x23, +0xee, 0x90, 0xfa, 0xb3, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x14, 0x2f, 0x90, 0xfa, 0xba, 0xe0, 0x90, +0xfa, 0xb1, 0xf0, 0xe4, 0xf5, 0x52, 0x90, 0xfa, 0xb1, 0xe0, 0xff, 0xe5, 0x52, 0xc3, 0x9f, 0x50, +0x24, 0x12, 0x18, 0x8a, 0x12, 0x0f, 0x52, 0xff, 0xfd, 0x90, 0xfa, 0xb3, 0xe4, 0x8d, 0xf0, 0x12, +0x14, 0x2f, 0x90, 0xfa, 0xb2, 0xe0, 0xc3, 0x9f, 0xf0, 0xd3, 0x94, 0x00, 0x50, 0x03, 0x02, 0x0e, +0xac, 0x05, 0x52, 0x80, 0xd1, 0x12, 0x18, 0x8a, 0x12, 0x0f, 0x52, 0x24, 0xfe, 0xff, 0x90, 0xfa, +0xb2, 0xf0, 0xfd, 0xa3, 0xe4, 0x75, 0xf0, 0x02, 0x12, 0x14, 0x2f, 0x7a, 0xf9, 0x79, 0x6e, 0x7b, +0x01, 0x8b, 0x2d, 0x8a, 0x2e, 0x89, 0x2f, 0xe9, 0x24, 0x02, 0xf9, 0xe4, 0x3a, 0xfa, 0x12, 0x18, +0x90, 0x12, 0x23, 0xee, 0x8f, 0x52, 0x05, 0x52, 0x05, 0x52, 0x12, 0x18, 0x2a, 0xe5, 0x52, 0x12, +0x13, 0xfb, 0x12, 0x18, 0x2a, 0x90, 0x00, 0x01, 0x74, 0x03, 0x12, 0x14, 0x0d, 0xaf, 0x52, 0x7e, +0x00, 0xc3, 0xef, 0x95, 0x35, 0xee, 0x95, 0x34, 0x50, 0x02, 0x80, 0x04, 0xae, 0x34, 0xaf, 0x35, +0x8e, 0x30, 0x8f, 0x31, 0x02, 0x29, 0x2d, 0x02, 0x0e, 0xac, 0xe5, 0x2c, 0x20, 0xe7, 0x03, 0x02, +0x0e, 0xac, 0xe5, 0x35, 0x64, 0x01, 0x45, 0x34, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x90, 0xfa, 0xb5, +0xe0, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x90, 0xfa, 0xb9, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, +0x02, 0x0e, 0xac, 0x12, 0x18, 0xd9, 0x60, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x2c, 0x20, 0xe0, 0x06, +0x20, 0xe1, 0x03, 0x02, 0x0e, 0xac, 0x75, 0x2d, 0x00, 0x75, 0x2e, 0x00, 0x75, 0x2f, 0x29, 0x02, +0x0f, 0x2f, 0xe5, 0x2c, 0x30, 0xe7, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x35, 0x45, 0x34, 0x60, 0x03, +0x02, 0x0e, 0xac, 0x90, 0xfa, 0xb5, 0xe0, 0x60, 0x03, 0x02, 0x0e, 0xac, 0xd3, 0x90, 0xfa, 0xba, +0xe0, 0x94, 0x01, 0x90, 0xfa, 0xb9, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0e, 0xac, 0x12, 0x18, +0xd9, 0x60, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x2c, 0x20, 0xe0, 0x06, 0x20, 0xe1, 0x03, 0x02, 0x0e, +0xac, 0x90, 0xfa, 0xba, 0xe0, 0xf5, 0x29, 0xe5, 0x29, 0x70, 0x08, 0x43, 0x2c, 0x01, 0x53, 0x2c, +0xfd, 0x80, 0x06, 0x53, 0x2c, 0xfe, 0x43, 0x2c, 0x02, 0xe4, 0xff, 0x02, 0x2f, 0x6a, 0xe5, 0x2c, +0x20, 0xe7, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x35, 0x64, 0x01, 0x45, 0x34, 0x60, 0x03, 0x02, 0x0e, +0xac, 0x90, 0xfa, 0xb5, 0xe0, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x90, 0xfa, 0xb9, 0xe0, 0x70, 0x02, +0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0e, 0xac, 0x12, 0x18, 0xd9, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0e, +0xac, 0xe5, 0x2c, 0x20, 0xe1, 0x03, 0x02, 0x0e, 0xac, 0x7f, 0x01, 0x02, 0x2f, 0x6a, 0xe5, 0x2c, +0x30, 0xe7, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x35, 0x45, 0x34, 0x60, 0x03, 0x02, 0x0e, 0xac, 0xd3, +0x90, 0xfa, 0xba, 0xe0, 0x94, 0x00, 0x90, 0xfa, 0xb9, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0e, +0xac, 0x12, 0x18, 0xd9, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0e, 0xac, 0xe5, 0x2c, 0x20, 0xe1, 0x03, +0x02, 0x0e, 0xac, 0xe4, 0xff, 0x02, 0x2f, 0x6a, 0x90, 0xff, 0x01, 0x12, 0x19, 0x8a, 0xef, 0x12, +0x13, 0xfb, 0x90, 0xfa, 0xb5, 0x12, 0x19, 0x8a, 0x90, 0x00, 0x01, 0xef, 0x12, 0x14, 0x0d, 0x90, +0x00, 0x02, 0xe4, 0x12, 0x14, 0x0d, 0x74, 0x03, 0x12, 0x18, 0x1b, 0x90, 0xfa, 0xb9, 0xe0, 0xff, +0xa3, 0xe0, 0x85, 0x2f, 0x82, 0x85, 0x2e, 0x83, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xff, 0x01, +0xe0, 0x12, 0x15, 0x0f, 0x09, 0x3d, 0x02, 0x09, 0x5f, 0x04, 0x09, 0x81, 0x05, 0x09, 0xad, 0x06, +0x09, 0xcb, 0x07, 0x09, 0xe9, 0x08, 0x0a, 0x07, 0x09, 0x0a, 0x25, 0x0b, 0x0a, 0xda, 0x80, 0x0c, +0xfa, 0x81, 0x0d, 0x1c, 0x82, 0x0b, 0x21, 0x83, 0x0b, 0x6a, 0x84, 0x0b, 0x89, 0x85, 0x0b, 0xc5, +0x86, 0x0c, 0x07, 0x87, 0x0c, 0x95, 0x88, 0x0c, 0xd0, 0x89, 0x0a, 0x43, 0x92, 0x0a, 0x43, 0x93, +0x0d, 0xcf, 0xc0, 0x0e, 0x00, 0xc1, 0x0e, 0x11, 0xc2, 0x00, 0x00, 0x0e, 0x9b, 0xe5, 0x2c, 0x20, +0xe7, 0x05, 0x7f, 0x05, 0x02, 0x2e, 0xa5, 0x12, 0x18, 0xe0, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, +0xfd, 0x7c, 0x00, 0x7f, 0x07, 0x02, 0x10, 0x9c, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2c, 0xc0, 0xe5, +0x2c, 0x20, 0xe7, 0x05, 0x7f, 0x05, 0x02, 0x2e, 0xa5, 0x12, 0x18, 0xe0, 0x60, 0x03, 0x04, 0x70, +0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0c, 0x02, 0x10, 0x9c, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2c, +0xc0, 0xe5, 0x2c, 0x30, 0xe7, 0x03, 0x02, 0x0e, 0xaf, 0x12, 0x19, 0x99, 0x50, 0x06, 0xe5, 0x35, +0x45, 0x34, 0x70, 0x05, 0x7f, 0x02, 0x02, 0x2e, 0xa5, 0x90, 0xfa, 0xb5, 0xe0, 0x24, 0xfe, 0x24, +0xfd, 0x50, 0x02, 0x80, 0x03, 0x02, 0x2f, 0x28, 0x7f, 0x07, 0x02, 0x2e, 0xa5, 0xe5, 0x2c, 0x30, +0xe7, 0x03, 0x02, 0x0e, 0xaf, 0x12, 0x18, 0xe0, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, +0x00, 0x7f, 0x08, 0x02, 0x10, 0x9c, 0x7f, 0x07, 0x02, 0x2e, 0xa5, 0xe5, 0x2c, 0x30, 0xe7, 0x03, +0x02, 0x0e, 0xaf, 0x12, 0x18, 0xe0, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, +0x09, 0x02, 0x10, 0x9c, 0x7f, 0x07, 0x02, 0x2e, 0xa5, 0xe5, 0x2c, 0x30, 0xe7, 0x03, 0x02, 0x0e, +0xaf, 0x12, 0x18, 0xe0, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0a, 0x02, +0x10, 0x9c, 0x7f, 0x07, 0x02, 0x2e, 0xa5, 0xe5, 0x2c, 0x30, 0xe7, 0x03, 0x02, 0x0e, 0xaf, 0x12, +0x18, 0xe0, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0b, 0x02, 0x10, 0x9c, +0x7f, 0x07, 0x02, 0x2e, 0xa5, 0xe5, 0x2c, 0x30, 0xe7, 0x03, 0x02, 0x0e, 0xaf, 0x12, 0x18, 0xe0, +0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0e, 0x02, 0x10, 0x9c, 0x7f, 0x07, +0x02, 0x2e, 0xa5, 0xe5, 0x2c, 0x30, 0xe7, 0x56, 0x12, 0x18, 0xd9, 0x70, 0x4a, 0x90, 0xff, 0x02, +0xe0, 0xf5, 0x52, 0xe5, 0x52, 0xb4, 0x82, 0x05, 0x75, 0x52, 0x61, 0x80, 0x12, 0xe5, 0x52, 0xb4, +0x83, 0x05, 0x75, 0x52, 0x62, 0x80, 0x08, 0xe5, 0x52, 0xc4, 0x54, 0xf0, 0x04, 0xf5, 0x52, 0x12, +0x17, 0x8b, 0x12, 0x19, 0x6c, 0x12, 0x22, 0xb8, 0x12, 0x18, 0xe8, 0x12, 0x13, 0xce, 0x60, 0x05, +0x12, 0x2f, 0x76, 0x80, 0x06, 0x85, 0x2a, 0x30, 0x85, 0x2b, 0x31, 0x75, 0x2d, 0x01, 0x75, 0x2e, +0xf9, 0x75, 0x2f, 0x71, 0x02, 0x29, 0x2d, 0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2c, 0xc0, 0x12, 0x18, +0xd9, 0x60, 0x05, 0x7f, 0x05, 0x02, 0x2e, 0xa5, 0x12, 0x19, 0x99, 0x40, 0x05, 0x7f, 0x03, 0x02, +0x2e, 0xa5, 0x90, 0xff, 0x02, 0xe0, 0xf5, 0x52, 0xe5, 0x52, 0xb4, 0x82, 0x05, 0x75, 0x52, 0x61, +0x80, 0x12, 0xe5, 0x52, 0xb4, 0x83, 0x05, 0x75, 0x52, 0x62, 0x80, 0x08, 0xe5, 0x52, 0xc4, 0x54, +0xf0, 0x04, 0xf5, 0x52, 0x12, 0x17, 0x8b, 0x02, 0x2f, 0x28, 0x12, 0x19, 0xa3, 0x12, 0x27, 0x19, +0x12, 0x18, 0x9b, 0xe0, 0x54, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0xe0, 0x90, 0xfa, 0xb6, 0xf0, 0x78, +0x6e, 0x12, 0x14, 0xeb, 0x90, 0x00, 0x02, 0x12, 0x13, 0xce, 0x30, 0xe7, 0xf2, 0x90, 0x00, 0x02, +0xe4, 0x12, 0x14, 0x0d, 0x90, 0xfa, 0xb6, 0xe0, 0x44, 0x80, 0xff, 0xf0, 0x78, 0x82, 0xe6, 0xfc, +0x08, 0xe6, 0x8c, 0x83, 0x12, 0x18, 0xa3, 0xef, 0xf0, 0x12, 0x2f, 0x80, 0xe4, 0xff, 0x02, 0x2e, +0xa5, 0x90, 0xfa, 0xb5, 0xe0, 0x64, 0x01, 0x70, 0x1f, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x7e, 0x00, +0x70, 0x06, 0xa3, 0xe0, 0xf5, 0x90, 0x80, 0x2d, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0x90, 0x90, 0xfa, +0xba, 0xe0, 0x42, 0x90, 0xd2, 0xaf, 0x80, 0x1d, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x7e, 0x00, 0x70, +0x06, 0xa3, 0xe0, 0xf5, 0xb0, 0x80, 0x0e, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0xb0, 0x90, 0xfa, 0xba, +0xe0, 0x42, 0xb0, 0xd2, 0xaf, 0xe4, 0xff, 0x02, 0x2e, 0xa5, 0x12, 0x18, 0x49, 0x90, 0xfa, 0xb5, +0xe0, 0xb4, 0x01, 0x0a, 0x12, 0x18, 0x2a, 0xe5, 0x90, 0x12, 0x13, 0xfb, 0x80, 0x08, 0x12, 0x18, +0x2a, 0xe5, 0xb0, 0x12, 0x13, 0xfb, 0x02, 0x0f, 0x2f, 0x90, 0xf9, 0x65, 0xe0, 0x20, 0xe1, 0x30, +0x12, 0x18, 0x53, 0x60, 0x18, 0x04, 0x70, 0x28, 0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x09, 0x90, 0xff, +0xa4, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x19, 0x12, 0x19, 0xad, 0xf0, 0x80, 0x13, 0x90, 0xfa, 0xb6, +0xe0, 0x60, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x04, 0x12, 0x19, 0xb4, 0xf0, +0xe4, 0xff, 0x02, 0x2e, 0xa5, 0x90, 0xf9, 0x65, 0xe0, 0x20, 0xe1, 0x36, 0x12, 0x18, 0x53, 0x60, +0x1b, 0x04, 0x70, 0x2e, 0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20, +0xf0, 0x80, 0x1f, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80, 0x16, 0x90, 0xfa, 0xb6, 0xe0, +0x60, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x54, +0xdf, 0xf0, 0xe4, 0xff, 0x02, 0x2e, 0xa5, 0x12, 0x18, 0x53, 0x60, 0x46, 0x04, 0x60, 0x03, 0x02, +0x0c, 0x90, 0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x17, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x04, 0xf0, 0x90, +0xf9, 0x65, 0xe0, 0x30, 0xe1, 0x6a, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x61, 0x90, +0xff, 0xa4, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0xf9, 0x65, 0xe0, 0x30, 0xe1, 0x53, 0x30, 0x95, 0x09, +0x90, 0xff, 0xa4, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x47, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfd, 0xf0, +0x80, 0x3e, 0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x17, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x04, 0xf0, 0x90, +0xf9, 0x65, 0xe0, 0x30, 0xe1, 0x2a, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x21, 0x90, +0xff, 0xb4, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0xf9, 0x65, 0xe0, 0x30, 0xe1, 0x13, 0x30, 0x93, 0x09, +0x90, 0xff, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xfd, 0xf0, +0xe4, 0xff, 0x02, 0x2e, 0xa5, 0x12, 0x18, 0x53, 0x60, 0x1b, 0x04, 0x70, 0x2e, 0x90, 0xfa, 0xb6, +0xe0, 0x60, 0x09, 0x90, 0xff, 0xa2, 0xe0, 0x44, 0x40, 0xf0, 0x80, 0x1f, 0x90, 0xff, 0xa2, 0xe0, +0x54, 0xbf, 0xf0, 0x80, 0x16, 0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xb2, 0xe0, 0x44, +0x40, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb2, 0xe0, 0x54, 0xbf, 0xf0, 0xe4, 0xff, 0x02, 0x2e, 0xa5, +0x12, 0x18, 0x49, 0x12, 0x18, 0x5b, 0x60, 0x0f, 0x04, 0x70, 0x16, 0x90, 0xff, 0xa4, 0xe0, 0x12, +0x18, 0x2a, 0x12, 0x13, 0xfb, 0x80, 0x0a, 0x90, 0xff, 0xb4, 0xe0, 0x12, 0x18, 0x2a, 0x12, 0x13, +0xfb, 0x75, 0x30, 0x00, 0x75, 0x31, 0x01, 0x02, 0x29, 0x2d, 0xe4, 0xff, 0x12, 0x2e, 0xa5, 0x12, +0x19, 0x46, 0x7f, 0x03, 0x12, 0x11, 0x9f, 0x90, 0xff, 0xfc, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0xff, +0x7e, 0x00, 0x12, 0x2d, 0xee, 0xc2, 0x90, 0xc2, 0xaf, 0x00, 0x80, 0xfd, 0xe4, 0xf5, 0x54, 0xf5, +0x55, 0x90, 0xfa, 0xbb, 0x74, 0x3e, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0xfa, 0xb3, 0xf0, 0xa3, 0x74, +0x15, 0xf0, 0xe0, 0x54, 0x3f, 0xff, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0xfa, 0xb8, 0xf0, 0xd3, 0x94, +0x00, 0xe4, 0x94, 0x3e, 0x40, 0x08, 0x90, 0xfa, 0xbc, 0xe0, 0x90, 0xfa, 0xb8, 0xf0, 0x12, 0x0e, +0xd6, 0xe5, 0x23, 0x45, 0x22, 0x70, 0x73, 0x12, 0x18, 0x62, 0x90, 0xfa, 0xbb, 0x12, 0x19, 0x65, +0x60, 0x27, 0xd3, 0xef, 0x94, 0x40, 0xee, 0x94, 0x00, 0x40, 0x08, 0x90, 0xfa, 0xb8, 0x74, 0x40, +0xf0, 0x80, 0x08, 0x90, 0xfa, 0xbc, 0xe0, 0x90, 0xfa, 0xb8, 0xf0, 0x12, 0x0e, 0xd6, 0xe5, 0x23, +0x45, 0x22, 0x70, 0x46, 0x12, 0x18, 0x62, 0x80, 0xd1, 0x75, 0x52, 0x02, 0x90, 0xfa, 0xbb, 0xe4, +0xf0, 0xa3, 0x04, 0xf0, 0x90, 0xfa, 0xb3, 0xe4, 0xf0, 0xa3, 0x74, 0x0f, 0xf0, 0x7b, 0x00, 0x7a, +0x00, 0x79, 0x52, 0x90, 0xfa, 0xbc, 0xe0, 0xf5, 0x50, 0x7d, 0x0f, 0x7c, 0x00, 0x12, 0x26, 0x25, +0x75, 0x22, 0x00, 0x8f, 0x23, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x52, 0xe4, 0xf5, 0x40, 0xf5, 0x41, +0x7d, 0x01, 0x12, 0x23, 0xee, 0xe4, 0xf5, 0x22, 0xf5, 0x23, 0xaf, 0x23, 0x02, 0x2e, 0xa5, 0x90, +0xfa, 0xba, 0xe0, 0x90, 0xfa, 0xb6, 0xf0, 0x30, 0xe7, 0x10, 0xe0, 0x54, 0x0f, 0x90, 0xf9, 0x62, +0xf0, 0xd3, 0x94, 0x00, 0x40, 0x15, 0xc2, 0x95, 0x80, 0x11, 0x90, 0xfa, 0xb6, 0xe0, 0x54, 0x0f, +0x90, 0xf9, 0x61, 0xf0, 0xd3, 0x94, 0x00, 0x40, 0x02, 0xc2, 0x94, 0xe4, 0xff, 0x02, 0x2e, 0xa5, +0x12, 0x19, 0xa3, 0xbf, 0x01, 0x04, 0xd2, 0x93, 0x80, 0x02, 0xc2, 0x93, 0xe4, 0xff, 0x02, 0x2e, +0xa5, 0x90, 0xfa, 0xba, 0xe0, 0x90, 0xfa, 0xb6, 0xf0, 0x54, 0x03, 0x14, 0x60, 0x0a, 0x14, 0x60, +0x0f, 0x14, 0x60, 0x08, 0x24, 0x03, 0x70, 0x2b, 0xd2, 0x91, 0x80, 0x27, 0xc2, 0x91, 0x80, 0x23, +0x12, 0x19, 0xad, 0x12, 0x0e, 0xfe, 0x60, 0x04, 0xd2, 0x91, 0x80, 0x17, 0x90, 0xff, 0xa4, 0xe0, +0x44, 0x10, 0x12, 0x0e, 0xfe, 0xff, 0xbf, 0xa0, 0x04, 0xc2, 0x91, 0x80, 0x02, 0xd2, 0x91, 0x12, +0x19, 0xad, 0xf0, 0x90, 0xfa, 0xb6, 0xe0, 0x54, 0x0c, 0xff, 0x13, 0x13, 0x54, 0x3f, 0x14, 0x60, +0x0a, 0x14, 0x60, 0x0f, 0x14, 0x60, 0x08, 0x24, 0x03, 0x70, 0x2b, 0xd2, 0x92, 0x80, 0x27, 0xc2, +0x92, 0x80, 0x23, 0x12, 0x19, 0xb4, 0x12, 0x0f, 0x1e, 0x60, 0x04, 0xd2, 0x92, 0x80, 0x17, 0x90, +0xff, 0xb4, 0xe0, 0x44, 0x10, 0x12, 0x0f, 0x1e, 0xff, 0xbf, 0xa0, 0x04, 0xc2, 0x92, 0x80, 0x02, +0xd2, 0x92, 0x12, 0x19, 0xb4, 0xf0, 0xe4, 0xff, 0x02, 0x2e, 0xa5, 0xe5, 0x2c, 0x30, 0xe7, 0x07, +0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2c, 0xc0, 0x7f, 0x05, 0x02, 0x2e, 0xa5, 0x12, 0x2f, 0x76, 0x22, +0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb2, 0x90, 0xfa, 0xb3, 0xe0, 0xf5, 0x40, 0xa3, 0xe0, 0xf5, 0x41, +0x7d, 0x01, 0x12, 0x23, 0xee, 0x90, 0xfa, 0xb3, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x14, 0x2f, 0xab, +0x2d, 0xaa, 0x2e, 0xa9, 0x2f, 0x22, 0xaa, 0x54, 0xa9, 0x55, 0x7b, 0xff, 0x90, 0xfa, 0xb3, 0xe0, +0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 0xb8, 0xe0, 0xf5, 0x50, 0x12, 0x26, 0x25, 0x75, 0x22, 0x00, +0x8f, 0x23, 0x22, 0x12, 0x20, 0xc5, 0x7e, 0x00, 0x8e, 0x22, 0x8f, 0x23, 0xef, 0x22, 0xf0, 0x7f, +0x01, 0x12, 0x11, 0x9f, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xb7, 0xf0, 0x54, 0xa0, 0x22, 0x12, +0x23, 0xee, 0x8f, 0x52, 0x7e, 0x00, 0xc3, 0xef, 0x95, 0x35, 0xee, 0x95, 0x34, 0x22, 0xf0, 0x7f, +0x01, 0x12, 0x11, 0x9f, 0x90, 0xff, 0xb6, 0xe0, 0x90, 0xfa, 0xb7, 0xf0, 0x54, 0xa0, 0x22, 0x75, +0x30, 0x00, 0x75, 0x31, 0x01, 0x02, 0x29, 0x2d, 0x90, 0xfa, 0xb5, 0xe0, 0xff, 0x02, 0x2f, 0x3b, +0x8e, 0x30, 0x8f, 0x31, 0x02, 0x29, 0x2d, 0x12, 0x20, 0xc5, 0x7e, 0x00, 0x8e, 0x22, 0x8f, 0x23, +0xef, 0x22, 0x7d, 0x01, 0x12, 0x23, 0xee, 0x90, 0xfa, 0xb0, 0xe0, 0x22, 0xef, 0x90, 0xf8, 0x04, +0xf0, 0x22, 0xc0, 0xa8, 0xc2, 0xaf, 0xee, 0x60, 0x0a, 0xc0, 0x05, 0x7d, 0x7f, 0xdd, 0xfe, 0xde, +0xfa, 0xd0, 0x05, 0xef, 0xc3, 0x94, 0x15, 0x50, 0x03, 0xd0, 0xa8, 0x22, 0x13, 0x70, 0x03, 0xd0, +0xa8, 0x22, 0xff, 0xd5, 0x07, 0xfd, 0xd0, 0xa8, 0x22, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, +0x04, 0xc0, 0x05, 0xe5, 0x44, 0x24, 0x08, 0xf8, 0x86, 0x05, 0x53, 0x05, 0x7f, 0x7c, 0xff, 0x12, +0x0f, 0xfe, 0x7f, 0x00, 0x7e, 0x00, 0xe5, 0x49, 0x60, 0x46, 0xfc, 0x90, 0xf9, 0x19, 0xe0, 0x54, +0x7f, 0x6d, 0x70, 0x0f, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xa3, 0x15, +0x49, 0x80, 0x07, 0xa3, 0xa3, 0xa3, 0xdc, 0xe6, 0x80, 0x26, 0xdc, 0x06, 0xd0, 0x82, 0xd0, 0x83, +0x80, 0x1e, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xd0, 0x82, 0xd0, 0x83, 0xe8, 0xf0, +0xa3, 0xe9, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x80, 0xda, +0x12, 0x10, 0x95, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0x22, 0x85, 0xa8, +0x4a, 0x75, 0xa8, 0x88, 0xec, 0x70, 0x02, 0x7c, 0x3f, 0x8c, 0x43, 0x22, 0xe5, 0x44, 0x24, 0x08, +0xf8, 0x76, 0x00, 0x12, 0x10, 0xec, 0x80, 0xfb, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x04, +0xc0, 0x06, 0x7c, 0xff, 0x12, 0x0f, 0xfe, 0xe5, 0x49, 0x60, 0x42, 0xfe, 0x90, 0xf9, 0x19, 0xe0, +0x54, 0x7f, 0x6f, 0x70, 0x0b, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x15, 0x49, 0x80, 0x07, +0xa3, 0xa3, 0xa3, 0xde, 0xea, 0x80, 0x26, 0xde, 0x06, 0xd0, 0x82, 0xd0, 0x83, 0x80, 0xd8, 0xe0, +0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xd0, 0x82, 0xd0, 0x83, 0xe8, 0xf0, 0xa3, 0xe9, 0xf0, +0xa3, 0xea, 0xf0, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x80, 0xda, 0x78, 0x08, 0x08, +0x79, 0x18, 0x09, 0x7c, 0x01, 0xe6, 0x54, 0x7f, 0x6f, 0x70, 0x06, 0x76, 0x00, 0x77, 0x00, 0x80, +0x06, 0x08, 0x09, 0x0c, 0xbc, 0x08, 0xee, 0x12, 0x10, 0x95, 0xd0, 0x06, 0xd0, 0x04, 0xd0, 0x02, +0xd0, 0x01, 0xd0, 0x00, 0x22, 0x75, 0x43, 0x00, 0x85, 0x4a, 0xa8, 0x22, 0xc0, 0xf0, 0xc0, 0x82, +0xc0, 0x83, 0xc3, 0xe5, 0x49, 0x24, 0xe8, 0x50, 0x05, 0x12, 0x10, 0xec, 0x80, 0xf4, 0xef, 0x60, +0x31, 0x90, 0x2e, 0x2c, 0xe4, 0x93, 0xc3, 0x9f, 0x40, 0x2f, 0xc0, 0x04, 0x7c, 0xff, 0x12, 0x0f, +0xfe, 0xd0, 0x04, 0x43, 0x07, 0x80, 0xe5, 0x49, 0x75, 0xf0, 0x03, 0xa4, 0x24, 0x19, 0xf5, 0x82, +0xe4, 0x34, 0xf9, 0xf5, 0x83, 0xef, 0xf0, 0xec, 0xa3, 0xf0, 0xed, 0xa3, 0xf0, 0x05, 0x49, 0x12, +0x10, 0x95, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0x22, 0x02, 0x11, 0x1a, 0xc0, 0x04, 0x7c, 0x20, +0xd2, 0x8c, 0xd2, 0x8d, 0xd5, 0x04, 0xfd, 0xd0, 0x04, 0x22, 0x75, 0xa8, 0x00, 0x75, 0x88, 0x00, +0x75, 0xb8, 0x00, 0x75, 0xf0, 0x00, 0x75, 0xd0, 0x00, 0xe4, 0xf8, 0x90, 0xf8, 0x04, 0xf0, 0x90, +0x00, 0x00, 0xf6, 0x08, 0xb8, 0x00, 0xfb, 0x02, 0x00, 0x00, 0xc2, 0xaf, 0xe4, 0x90, 0xff, 0x48, +0xf0, 0x90, 0xff, 0x50, 0xf0, 0x90, 0xff, 0x08, 0xf0, 0x90, 0xff, 0x10, 0xf0, 0x90, 0xff, 0x80, +0xf0, 0xa3, 0xa3, 0xf0, 0xd2, 0xb1, 0xc2, 0xb0, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0x62, 0x7e, +0xff, 0x7f, 0xff, 0x12, 0x0f, 0x62, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0x62, 0xd2, 0xb0, 0xd2, +0xb1, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0x62, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0x62, 0x7e, +0xff, 0x7f, 0xff, 0x12, 0x0f, 0x62, 0x80, 0xcc, 0xc3, 0xee, 0x94, 0x02, 0x50, 0x04, 0x7e, 0x03, +0x7f, 0xe8, 0xef, 0xf4, 0xff, 0xee, 0xf4, 0xfe, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x8f, 0x48, 0x8e, +0x47, 0x22, 0xc3, 0xef, 0x94, 0xbc, 0xee, 0x94, 0x02, 0x50, 0x04, 0x7e, 0x07, 0x7f, 0xd0, 0xef, +0xf4, 0xff, 0xee, 0xf4, 0xfe, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x8f, 0x46, 0x8e, 0x45, 0x22, 0xef, +0x70, 0x01, 0x22, 0xc0, 0x00, 0xe5, 0x44, 0x24, 0x18, 0xf8, 0xa6, 0x07, 0xe5, 0x44, 0x24, 0x08, +0xf8, 0xc6, 0x54, 0x7f, 0xf6, 0xe6, 0x30, 0xe7, 0x03, 0xd0, 0x00, 0x22, 0x12, 0x10, 0xec, 0x80, +0xf4, 0xc0, 0x00, 0x7f, 0x01, 0xef, 0x24, 0x08, 0xf8, 0xe6, 0x60, 0x09, 0x0f, 0xbf, 0x08, 0xf5, +0x12, 0x10, 0xec, 0x80, 0xee, 0xd0, 0x00, 0x22, 0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, +0xc0, 0x06, 0xc0, 0x04, 0xed, 0x24, 0x10, 0xf8, 0x76, 0xa0, 0xed, 0x75, 0xf0, 0x21, 0xa4, 0x24, +0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, 0xc0, 0x82, 0xc0, 0x83, 0xa3, 0xa3, 0xe4, 0x78, +0x0d, 0xf0, 0xa3, 0xd8, 0xfc, 0xef, 0x54, 0x7f, 0x75, 0xf0, 0x02, 0xa4, 0x24, 0x0e, 0xf5, 0x82, +0xe5, 0xf0, 0x34, 0x2e, 0xf5, 0x83, 0xe4, 0x93, 0xfe, 0x74, 0x01, 0x93, 0xfc, 0xd0, 0x83, 0xd0, +0x82, 0xec, 0xf0, 0xa3, 0xee, 0xf0, 0xed, 0x24, 0x08, 0xf8, 0xef, 0x44, 0x80, 0xf6, 0xd0, 0x04, +0xd0, 0x06, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0x22, 0x75, 0x44, 0x00, 0x75, 0x49, +0x00, 0x7a, 0x08, 0x79, 0x18, 0x78, 0x08, 0x76, 0x00, 0x77, 0x00, 0x08, 0x09, 0xda, 0xf8, 0x90, +0xf8, 0x04, 0xe0, 0xfc, 0x90, 0x2e, 0x2c, 0xe4, 0x93, 0xc3, 0x9c, 0x50, 0x05, 0xe4, 0x90, 0xf8, +0x04, 0xf0, 0x78, 0x08, 0x74, 0x80, 0x44, 0x7f, 0xf6, 0x74, 0x01, 0x44, 0x10, 0xf5, 0x89, 0x75, +0xb8, 0x00, 0xd2, 0xab, 0xd2, 0xa9, 0x22, 0x75, 0x81, 0x91, 0xd2, 0x8e, 0xd2, 0x8c, 0xd2, 0xaf, +0xe5, 0x49, 0x60, 0x36, 0xff, 0x90, 0xf9, 0x19, 0xe0, 0x54, 0x80, 0x60, 0x28, 0x78, 0x08, 0x79, +0x08, 0xe0, 0x54, 0x7f, 0xfa, 0x7b, 0x00, 0xe6, 0x54, 0x7f, 0xb5, 0x02, 0x02, 0x7b, 0xff, 0x08, +0xd9, 0xf5, 0xeb, 0x70, 0x10, 0xea, 0xf0, 0xc0, 0x07, 0x12, 0x11, 0xc1, 0xad, 0x07, 0xaf, 0x02, +0x12, 0x11, 0xd8, 0xd0, 0x07, 0xa3, 0xa3, 0xa3, 0xdf, 0xce, 0x12, 0x10, 0xec, 0x80, 0xc1, 0xe7, +0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e, 0x88, +0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08, 0xdf, +0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83, 0xe3, +0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08, 0xdf, +0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c, 0x80, +0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10, 0x80, +0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33, 0x89, +0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, +0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0x0d, +0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0, 0xed, +0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, +0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde, 0xe8, +0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc, 0x88, +0xf0, 0xef, 0x60, 0x01, 0x0e, 0x4e, 0x60, 0xc3, 0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, +0x50, 0xb9, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xaf, 0x23, 0x23, 0x45, 0x82, +0x23, 0x90, 0x13, 0x0f, 0x73, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, +0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, +0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, +0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, +0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, +0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xf8, 0xbb, 0x01, +0x0d, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe8, 0xf0, 0x22, 0x50, 0x06, +0xe9, 0x25, 0x82, 0xc8, 0xf6, 0x22, 0xbb, 0xfe, 0x05, 0xe9, 0x25, 0x82, 0xc8, 0xf2, 0x22, 0xc5, +0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, +0x83, 0xe0, 0x38, 0xf0, 0x22, 0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, +0x82, 0x70, 0x02, 0x15, 0x83, 0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22, 0xbb, 0x01, 0x10, 0xe5, 0x82, +0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0, 0xa3, 0xe0, 0x22, 0x50, 0x09, +0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe, 0x0a, 0xe9, 0x25, 0x82, 0xf8, +0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83, 0xe9, 0x93, 0xf5, 0xf0, 0xa3, +0xe9, 0x93, 0x22, 0xbb, 0x01, 0x0a, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0xe5, 0xf0, 0xa3, 0xf0, 0x22, +0x50, 0x06, 0xf7, 0x09, 0xa7, 0xf0, 0x19, 0x22, 0xbb, 0xfe, 0x06, 0xf3, 0xe5, 0xf0, 0x09, 0xf3, +0x19, 0x22, 0xf8, 0xbb, 0x01, 0x11, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, +0xe8, 0xf0, 0xe5, 0xf0, 0xa3, 0xf0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xc8, 0xf6, 0x08, 0xa6, +0xf0, 0x22, 0xbb, 0xfe, 0x09, 0xe9, 0x25, 0x82, 0xc8, 0xf2, 0xe5, 0xf0, 0x08, 0xf2, 0x22, 0xa4, +0x25, 0x82, 0xf5, 0x82, 0xe5, 0xf0, 0x35, 0x83, 0xf5, 0x83, 0x22, 0xe6, 0xfb, 0x08, 0xe6, 0xfa, +0x08, 0xe6, 0xf9, 0x22, 0xeb, 0xf6, 0x08, 0xea, 0xf6, 0x08, 0xe9, 0xf6, 0x22, 0xe0, 0xfb, 0xa3, +0xe0, 0xfa, 0xa3, 0xe0, 0xf9, 0x22, 0xeb, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xe9, 0xf0, 0x22, 0xd0, +0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, +0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, +0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0x90, 0xff, 0xfa, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x16, 0xf0, 0x90, +0xff, 0xf9, 0x74, 0x02, 0xf0, 0x90, 0xfa, 0xcb, 0xe4, 0xf0, 0xa3, 0x74, 0x0b, 0xf0, 0x7b, 0x00, +0x7a, 0x00, 0x79, 0x37, 0x75, 0x40, 0x00, 0xf5, 0x41, 0x7d, 0x01, 0x12, 0x23, 0xee, 0xe5, 0x37, +0x24, 0x80, 0x90, 0xff, 0xf8, 0xf0, 0xe5, 0x37, 0x64, 0x07, 0x60, 0x0b, 0xe5, 0x37, 0x64, 0x06, +0x60, 0x05, 0xe5, 0x37, 0xb4, 0x14, 0x1b, 0xd2, 0x94, 0xd2, 0x95, 0xd2, 0x92, 0xd2, 0x93, 0xe5, +0x37, 0xb4, 0x07, 0x08, 0x90, 0xf9, 0x65, 0x74, 0x02, 0xf0, 0x80, 0x06, 0x90, 0xf9, 0x65, 0x74, +0x01, 0xf0, 0x90, 0xfa, 0xcb, 0xe4, 0xf0, 0xa3, 0x74, 0x0d, 0xf0, 0x12, 0x17, 0x71, 0x90, 0xff, +0xf5, 0xe5, 0x37, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcb, 0xe4, 0xfd, 0x12, 0x20, 0xc5, 0x90, +0xfa, 0xcb, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x14, 0x2f, 0x12, 0x17, 0x71, 0xe5, 0x37, 0x30, 0xe7, +0x02, 0xd2, 0x02, 0xe4, 0xf5, 0x2c, 0xf5, 0x2a, 0xf5, 0x2b, 0xf5, 0x29, 0x12, 0x19, 0x92, 0x12, +0x18, 0x49, 0x12, 0x19, 0x6c, 0x90, 0xf9, 0x66, 0x12, 0x15, 0x06, 0x90, 0xf9, 0x6b, 0x12, 0x15, +0x06, 0x90, 0xff, 0xff, 0xe4, 0xf0, 0x90, 0xff, 0x83, 0xe0, 0xe4, 0xf0, 0x90, 0xff, 0x81, 0x74, +0x80, 0xf0, 0xa3, 0x74, 0x84, 0xf0, 0x90, 0xff, 0x80, 0xf0, 0xe4, 0xf5, 0x37, 0xe5, 0x37, 0x12, +0x18, 0xbf, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x37, 0x12, 0x18, 0xcd, 0xf5, 0x83, 0xe4, 0xf0, 0x05, +0x37, 0xe5, 0x37, 0xb4, 0x07, 0xe7, 0x78, 0x80, 0x76, 0xfe, 0x08, 0x76, 0xf0, 0x90, 0x2f, 0x06, +0xe4, 0x93, 0xff, 0x78, 0x7e, 0xf6, 0xfd, 0xad, 0x07, 0x90, 0x2f, 0x13, 0xe4, 0x93, 0xff, 0x08, +0xf6, 0xff, 0xed, 0x54, 0x0f, 0xfd, 0x12, 0x18, 0xaf, 0x74, 0x84, 0xf0, 0xed, 0x75, 0xf0, 0x08, +0xa4, 0x24, 0x47, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xc3, 0x74, 0xf0, 0x9f, +0x78, 0x81, 0xf6, 0x74, 0xfe, 0x94, 0x00, 0x18, 0x12, 0x18, 0x41, 0xce, 0xc3, 0x13, 0xce, 0x13, +0xd8, 0xf9, 0xff, 0xed, 0x12, 0x19, 0x07, 0xef, 0xf0, 0xed, 0x12, 0x19, 0x2d, 0xe4, 0xf5, 0x37, +0xe5, 0x37, 0x90, 0x2f, 0x00, 0x93, 0xff, 0x78, 0x7e, 0xf6, 0xfd, 0xe5, 0x37, 0x25, 0xe0, 0x24, +0x07, 0xf5, 0x82, 0xe4, 0x34, 0x2f, 0xf5, 0x83, 0xe4, 0x93, 0x08, 0xf6, 0xed, 0x30, 0xe7, 0x53, +0x18, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x18, 0xaf, 0x12, 0x19, 0x15, 0x24, 0x47, 0xf5, 0x82, 0xe4, +0x34, 0xff, 0x12, 0x18, 0x31, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xe9, 0x12, 0x19, +0x07, 0xef, 0xf0, 0x12, 0x18, 0x38, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x19, 0x1a, +0x24, 0x45, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xe9, 0x12, 0x19, 0x2d, 0xe9, +0x75, 0xf0, 0x08, 0xa4, 0x24, 0x46, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x74, 0x80, 0xf0, +0x02, 0x17, 0x46, 0x78, 0x7e, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x18, 0xf9, 0x12, 0x19, 0x15, 0x24, +0x07, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0x12, 0x18, 0x31, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, +0x12, 0x19, 0x1a, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0x12, 0x18, +0x38, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x19, 0x1a, 0x24, 0x05, 0xf5, 0x82, 0xe4, +0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, +0x34, 0xff, 0xf5, 0x83, 0xe4, 0xf0, 0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, +0x34, 0xff, 0xf5, 0x83, 0xe4, 0xf0, 0x05, 0x37, 0xe5, 0x37, 0x64, 0x04, 0x60, 0x03, 0x02, 0x16, +0x70, 0x90, 0x2f, 0x05, 0xe4, 0x93, 0xff, 0x78, 0x7e, 0xf6, 0x12, 0x18, 0xf7, 0xe4, 0xf0, 0x90, +0x2f, 0x04, 0x93, 0xff, 0xf6, 0x12, 0x18, 0xad, 0xe4, 0xf0, 0x90, 0xff, 0xfd, 0x74, 0x05, 0xf0, +0x22, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x37, 0x90, 0xfa, 0xcb, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x14, +0x45, 0x85, 0xf0, 0x41, 0xf5, 0x40, 0x7d, 0x01, 0x02, 0x23, 0xee, 0xab, 0x2d, 0xaa, 0x2e, 0xa9, +0x2f, 0xe5, 0x52, 0x12, 0x13, 0xfb, 0x74, 0x01, 0x25, 0x2f, 0xf5, 0x2f, 0xe4, 0x35, 0x2e, 0xf5, +0x2e, 0xab, 0x2d, 0xfa, 0xa9, 0x2f, 0x74, 0x11, 0x12, 0x13, 0xfb, 0x74, 0x01, 0x25, 0x2f, 0xf5, +0x2f, 0xe4, 0x35, 0x2e, 0xf5, 0x2e, 0x90, 0xff, 0x06, 0xe0, 0xab, 0x2d, 0xaa, 0x2e, 0xa9, 0x2f, +0x12, 0x13, 0xfb, 0x74, 0x01, 0x25, 0x2f, 0xf5, 0x2f, 0xe4, 0x35, 0x2e, 0xf5, 0x2e, 0xab, 0x2d, +0xfa, 0xa9, 0x2f, 0xe4, 0x12, 0x13, 0xfb, 0x04, 0x25, 0x2f, 0xf5, 0x2f, 0xe4, 0x35, 0x2e, 0xf5, +0x2e, 0xab, 0x2d, 0xfa, 0xa9, 0x2f, 0xe4, 0x12, 0x13, 0xfb, 0x04, 0x25, 0x2f, 0xf5, 0x2f, 0xe4, +0x35, 0x2e, 0xf5, 0x2e, 0x90, 0xff, 0x04, 0xe0, 0xab, 0x2d, 0xaa, 0x2e, 0xa9, 0x2f, 0x12, 0x13, +0xfb, 0x74, 0x01, 0x25, 0x2f, 0xf5, 0x2f, 0xe4, 0x35, 0x2e, 0xf5, 0x2e, 0x90, 0xff, 0x05, 0xe0, +0xab, 0x2d, 0xaa, 0x2e, 0xa9, 0x2f, 0x12, 0x13, 0xfb, 0x74, 0x01, 0x25, 0x2f, 0xf5, 0x2f, 0xe4, +0x35, 0x2e, 0xf5, 0x2e, 0x22, 0xf5, 0x83, 0xe0, 0x54, 0x08, 0xab, 0x2d, 0xaa, 0x2e, 0xa9, 0x2f, +0x22, 0xf5, 0x83, 0xef, 0xf0, 0xfd, 0x7c, 0x00, 0xc3, 0x78, 0x81, 0xe6, 0x9d, 0xf6, 0x18, 0xe6, +0x9c, 0xf6, 0xe6, 0xfe, 0x08, 0xe6, 0x78, 0x03, 0x22, 0x75, 0x2d, 0x01, 0x75, 0x2e, 0xf9, 0x75, +0x2f, 0x6e, 0x22, 0x90, 0xfa, 0xba, 0xe0, 0x90, 0xfa, 0xb6, 0xf0, 0x90, 0xfa, 0xb5, 0xe0, 0x24, +0xfc, 0x22, 0x90, 0xfa, 0xb8, 0xe0, 0xff, 0x7e, 0x00, 0xc3, 0x90, 0xfa, 0xbc, 0xe0, 0x9f, 0xf0, +0x90, 0xfa, 0xbb, 0xe0, 0x9e, 0xf0, 0x90, 0xfa, 0xb3, 0xee, 0x8f, 0xf0, 0x12, 0x14, 0x2f, 0xef, +0x25, 0x55, 0xf5, 0x55, 0xee, 0x35, 0x54, 0xf5, 0x54, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb0, +0x90, 0xfa, 0xb3, 0xe0, 0xf5, 0x40, 0xa3, 0xe0, 0xf5, 0x41, 0x22, 0x78, 0x82, 0xe6, 0xfe, 0x08, +0xe6, 0x8e, 0x83, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x22, 0x54, 0x0f, 0x75, +0xf0, 0x08, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x22, 0xe5, 0x53, 0x75, +0xf0, 0x08, 0xa4, 0x24, 0x48, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0x22, 0xe5, 0x53, 0x75, 0xf0, 0x08, +0xa4, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0x22, 0x90, 0xff, 0x00, 0xe0, 0x54, 0x1f, 0x22, +0x90, 0xfa, 0xb5, 0xe0, 0xff, 0x24, 0xfc, 0x22, 0x75, 0x2a, 0x00, 0x8f, 0x2b, 0x90, 0xf9, 0x6b, +0x12, 0x14, 0xfd, 0x90, 0x00, 0x02, 0x22, 0x54, 0x0f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, +0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x22, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x41, 0xf5, 0x82, 0xe4, +0x34, 0xff, 0xf5, 0x83, 0x22, 0x74, 0x80, 0xf0, 0x08, 0xe6, 0xff, 0xe9, 0x75, 0xf0, 0x08, 0xa4, +0x22, 0x74, 0xae, 0x25, 0x36, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 0x22, 0x75, 0xf0, 0x08, +0xa4, 0x24, 0x42, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x74, 0x80, 0xf0, 0x22, 0x90, 0xff, +0x82, 0xe0, 0x44, 0x08, 0xf0, 0x22, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x03, 0xf0, 0x90, 0xff, 0xfc, +0xe0, 0x54, 0xfd, 0xf0, 0x22, 0x78, 0x6d, 0xe6, 0x54, 0xfd, 0xf6, 0x90, 0xff, 0xfd, 0x74, 0x65, +0xf0, 0x22, 0x12, 0x14, 0xdf, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x22, 0x7b, 0x01, 0x7a, 0xf9, +0x79, 0x6e, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb3, 0x22, 0x90, 0xff, 0x80, 0xe0, 0x44, 0x08, +0xf0, 0x22, 0x90, 0xff, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0x22, 0xe0, 0xff, 0x90, 0xf9, 0x66, 0x02, +0x14, 0xfd, 0x75, 0x30, 0x01, 0x75, 0x31, 0x09, 0x22, 0xd3, 0xe5, 0x35, 0x94, 0x08, 0xe5, 0x34, +0x94, 0x01, 0x22, 0x90, 0xfa, 0xba, 0xe0, 0xff, 0x90, 0xfa, 0xb6, 0xf0, 0x22, 0x90, 0xff, 0xa4, +0xe0, 0x54, 0xef, 0x22, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xef, 0x22, 0x8f, 0x38, 0x12, 0x27, 0x19, +0x78, 0x86, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, 0x08, 0x12, 0x20, 0x25, 0xe0, 0xfd, +0x12, 0x20, 0xa6, 0x8a, 0x83, 0x24, 0x0a, 0x12, 0x20, 0x25, 0xed, 0xf0, 0x12, 0x20, 0x7c, 0x24, +0x07, 0x12, 0x20, 0x25, 0xe0, 0xff, 0x12, 0x20, 0xbe, 0x24, 0x09, 0x12, 0x20, 0x25, 0xef, 0xf0, +0x90, 0xf9, 0x65, 0xe0, 0x30, 0xe4, 0x20, 0x08, 0x12, 0x20, 0x2f, 0xc0, 0x83, 0xc0, 0x82, 0xa3, +0xe0, 0x25, 0xe0, 0xff, 0x05, 0x82, 0xd5, 0x82, 0x02, 0x15, 0x83, 0x15, 0x82, 0xe0, 0x33, 0xd0, +0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0x78, 0x86, 0x12, 0x20, 0x2f, 0xe0, 0xfc, 0xa3, 0xe0, +0xfd, 0xec, 0xff, 0x12, 0x20, 0xa6, 0x8a, 0x83, 0x24, 0x08, 0x12, 0x20, 0x25, 0xef, 0xf0, 0xed, +0x12, 0x20, 0xbe, 0x24, 0x07, 0x12, 0x20, 0x25, 0xed, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, +0xe0, 0xff, 0x53, 0x07, 0xc7, 0x08, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x12, 0x20, 0x69, 0xa3, 0xe0, +0x30, 0xe3, 0x12, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0x12, 0x20, 0x25, 0xe0, 0x90, +0x2f, 0x4d, 0x93, 0x42, 0x07, 0x53, 0x07, 0xfb, 0x12, 0x20, 0xae, 0x24, 0x06, 0x12, 0x20, 0x25, +0xe0, 0x60, 0x03, 0x43, 0x07, 0x04, 0x53, 0x07, 0xfc, 0x78, 0x86, 0x12, 0x20, 0x96, 0x24, 0x04, +0x12, 0x20, 0x25, 0xe0, 0x42, 0x07, 0x43, 0x07, 0x80, 0x12, 0x20, 0xa6, 0xf5, 0x82, 0x8a, 0x83, +0xa3, 0xa3, 0xef, 0xf0, 0x12, 0x20, 0xbe, 0x24, 0x04, 0x12, 0x20, 0x25, 0xe0, 0xff, 0x8d, 0x82, +0x8c, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x30, 0xe1, 0x05, 0x53, 0x07, 0xdf, 0x80, +0x03, 0x43, 0x07, 0x20, 0xec, 0x30, 0xe4, 0x05, 0x53, 0x07, 0xef, 0x80, 0x03, 0x43, 0x07, 0x10, +0x90, 0xf9, 0x65, 0xe0, 0xfe, 0x54, 0x03, 0x60, 0x4c, 0x53, 0x07, 0xdf, 0xee, 0x30, 0xe1, 0x42, +0x12, 0x20, 0xae, 0x24, 0x09, 0x12, 0x20, 0x25, 0xe0, 0x14, 0x60, 0x31, 0x14, 0x60, 0x29, 0x14, +0x60, 0x26, 0x14, 0x60, 0x28, 0x24, 0x04, 0x70, 0x2c, 0xe5, 0x38, 0xb4, 0x03, 0x0d, 0x30, 0x95, +0x05, 0x43, 0x07, 0x02, 0x80, 0x1f, 0x53, 0x07, 0xfd, 0x80, 0x1a, 0x30, 0x93, 0x05, 0x43, 0x07, +0x02, 0x80, 0x12, 0x53, 0x07, 0xfd, 0x80, 0x0d, 0x43, 0x07, 0x02, 0x80, 0x08, 0x53, 0x07, 0xfd, +0x80, 0x03, 0x53, 0x07, 0xfd, 0x12, 0x20, 0x94, 0x24, 0x04, 0x12, 0x20, 0x25, 0xef, 0xf0, 0x8d, +0x82, 0x8c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xff, 0x90, 0xf9, 0x65, 0xe0, 0xfe, 0x54, 0x03, 0x60, +0x4a, 0xee, 0x30, 0xe1, 0x43, 0x08, 0x12, 0x20, 0xb0, 0x24, 0x09, 0x12, 0x20, 0x25, 0xe0, 0x14, +0x60, 0x2c, 0x14, 0x60, 0x2e, 0x14, 0x60, 0x26, 0x14, 0x60, 0x28, 0x24, 0x04, 0x70, 0x2c, 0xe5, +0x38, 0xb4, 0x03, 0x0d, 0x30, 0x94, 0x05, 0x53, 0x07, 0x7f, 0x80, 0x1f, 0x43, 0x07, 0x80, 0x80, +0x1a, 0x30, 0x92, 0x05, 0x53, 0x07, 0x7f, 0x80, 0x12, 0x43, 0x07, 0x80, 0x80, 0x0d, 0x53, 0x07, +0x7f, 0x80, 0x08, 0x43, 0x07, 0x80, 0x80, 0x03, 0x53, 0x07, 0x7f, 0x78, 0x86, 0x12, 0x20, 0x65, +0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x30, 0xe0, 0x05, 0x43, 0x07, 0x20, 0x80, 0x03, 0x53, 0x07, 0xdf, +0xec, 0x30, 0xe3, 0x05, 0x43, 0x07, 0x40, 0x80, 0x03, 0x53, 0x07, 0xbf, 0xec, 0x30, 0xe0, 0x05, +0x43, 0x07, 0x10, 0x80, 0x03, 0x53, 0x07, 0xef, 0xed, 0x30, 0xe4, 0x05, 0x43, 0x07, 0x08, 0x80, +0x03, 0x53, 0x07, 0xf7, 0xed, 0x30, 0xe5, 0x05, 0x43, 0x07, 0x04, 0x80, 0x03, 0x53, 0x07, 0xfb, +0xed, 0x30, 0xe6, 0x05, 0x43, 0x07, 0x01, 0x80, 0x03, 0x53, 0x07, 0xfe, 0xed, 0x30, 0xe7, 0x05, +0x43, 0x07, 0x02, 0x80, 0x03, 0x53, 0x07, 0xfd, 0x78, 0x84, 0x12, 0x20, 0x65, 0xa3, 0xef, 0xf0, +0x12, 0x2f, 0x80, 0x7f, 0x00, 0x22, 0x12, 0x0f, 0x89, 0x78, 0x8e, 0xef, 0xf6, 0x12, 0x27, 0x19, +0x12, 0x20, 0x70, 0x8e, 0x83, 0x24, 0x09, 0x12, 0x20, 0x25, 0xe0, 0xfd, 0x12, 0x20, 0x53, 0x90, +0x00, 0x0a, 0x12, 0x20, 0x78, 0x24, 0x0a, 0x12, 0x20, 0x25, 0xe0, 0x90, 0x00, 0x0b, 0x12, 0x14, +0x0d, 0x12, 0x20, 0x70, 0xf5, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x59, 0x12, 0x20, +0x7c, 0x24, 0x04, 0x12, 0x20, 0x25, 0xe0, 0xf5, 0x5a, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, +0xf5, 0x5b, 0xe5, 0x59, 0xc4, 0x13, 0x13, 0x13, 0x54, 0x01, 0x78, 0x8e, 0xf6, 0xd3, 0x94, 0x00, +0x40, 0x06, 0xe5, 0x5a, 0x30, 0xe1, 0x01, 0x06, 0x78, 0x8e, 0xe6, 0x12, 0x20, 0x52, 0x90, 0x00, +0x0c, 0xef, 0x12, 0x14, 0x0d, 0x78, 0x86, 0x12, 0x20, 0x2f, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, +0xff, 0x53, 0x07, 0x0c, 0x53, 0x06, 0xe6, 0xe5, 0x59, 0x30, 0xe5, 0x03, 0x43, 0x07, 0x01, 0xe5, +0x5a, 0x20, 0xe5, 0x0e, 0xe5, 0x59, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x59, 0x20, 0xe7, 0x03, 0x43, +0x07, 0x02, 0xe5, 0x59, 0x30, 0xe3, 0x03, 0x43, 0x07, 0x10, 0xe5, 0x59, 0x30, 0xe2, 0x03, 0x43, +0x07, 0x20, 0xe5, 0x59, 0x54, 0x03, 0x60, 0x03, 0x43, 0x07, 0x40, 0xe5, 0x59, 0x30, 0xe1, 0x03, +0x43, 0x07, 0x80, 0xe5, 0x59, 0x30, 0xe4, 0x03, 0x43, 0x06, 0x01, 0xe5, 0x59, 0x30, 0xe6, 0x03, +0x43, 0x06, 0x08, 0xe5, 0x5a, 0x20, 0xe4, 0x0e, 0xe5, 0x59, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x59, +0x20, 0xe7, 0x03, 0x43, 0x06, 0x10, 0x53, 0x07, 0xfb, 0x53, 0x06, 0x79, 0x90, 0x00, 0x05, 0xee, +0x8f, 0xf0, 0x12, 0x14, 0xb2, 0xe5, 0x5b, 0x30, 0xe3, 0x12, 0x54, 0x30, 0xff, 0xc4, 0x54, 0x0f, +0x12, 0x20, 0x52, 0x90, 0x00, 0x08, 0xef, 0x12, 0x14, 0x0d, 0x80, 0x0a, 0x12, 0x20, 0x53, 0x90, +0x00, 0x08, 0xe4, 0x12, 0x14, 0x0d, 0xe5, 0x5b, 0x54, 0x03, 0x12, 0x20, 0x52, 0x90, 0x00, 0x07, +0xef, 0x12, 0x14, 0x0d, 0xe5, 0x5b, 0x54, 0x04, 0xff, 0xc3, 0x13, 0x90, 0x00, 0x09, 0x12, 0x14, +0x0d, 0x90, 0x00, 0x07, 0x12, 0x13, 0xce, 0x70, 0x13, 0x12, 0x20, 0x53, 0xe9, 0x24, 0x09, 0xf9, +0xe4, 0x3a, 0xfa, 0x12, 0x13, 0xb5, 0xff, 0xc3, 0x13, 0x12, 0x13, 0xfb, 0x12, 0x20, 0x94, 0x24, +0x08, 0x12, 0x20, 0x25, 0xe0, 0xfe, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x07, 0x12, 0x20, +0x25, 0xe0, 0xfd, 0xee, 0xed, 0x12, 0x20, 0x52, 0x90, 0x00, 0x03, 0xee, 0x8f, 0xf0, 0x12, 0x14, +0xb2, 0x12, 0x2f, 0x80, 0x7d, 0x0a, 0xe4, 0xff, 0x12, 0x2c, 0xc0, 0x02, 0x10, 0x0c, 0x90, 0xfa, +0xe2, 0xe0, 0xb4, 0x03, 0x06, 0x7e, 0x00, 0x7f, 0x40, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x08, 0x90, +0xfa, 0xd6, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x00, 0x05, 0x12, 0x13, 0xce, 0xff, 0x7e, 0x00, +0x90, 0xfa, 0xd2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x70, 0x03, 0x7f, 0x08, 0x22, 0x90, 0x00, 0x08, +0x12, 0x14, 0x5b, 0xff, 0x90, 0xfa, 0xd4, 0xe5, 0xf0, 0xf0, 0xa3, 0xef, 0xf0, 0xae, 0x02, 0xaf, +0x01, 0x8e, 0x56, 0x8f, 0x57, 0x74, 0x0a, 0x25, 0x57, 0xf5, 0x57, 0xe4, 0x35, 0x56, 0xf5, 0x56, +0x90, 0xfa, 0xd7, 0xe0, 0xff, 0x14, 0xfe, 0x90, 0xfa, 0xd5, 0xe0, 0x5e, 0xfe, 0xc3, 0xef, 0x9e, +0xff, 0x90, 0xfa, 0xd9, 0xf0, 0xc3, 0x90, 0xfa, 0xd3, 0xe0, 0x9f, 0x90, 0xfa, 0xd2, 0xe0, 0x94, +0x00, 0x50, 0x06, 0xa3, 0xe0, 0x90, 0xfa, 0xd9, 0xf0, 0x12, 0x1e, 0x2d, 0x60, 0x03, 0xe0, 0xff, +0x22, 0x12, 0x2a, 0x80, 0x90, 0xfa, 0xd2, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x60, 0x2b, 0x90, +0xfa, 0xd6, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xd3, 0xef, 0x9d, 0xee, 0x9c, 0x40, 0x07, 0xe0, 0x90, +0xfa, 0xd9, 0xf0, 0x80, 0x08, 0x90, 0xfa, 0xd3, 0xe0, 0x90, 0xfa, 0xd9, 0xf0, 0x12, 0x1e, 0x2d, +0x60, 0x03, 0xe0, 0xff, 0x22, 0x12, 0x2a, 0x80, 0x80, 0xca, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x58, +0xe4, 0xf5, 0x40, 0xf5, 0x41, 0x7d, 0x01, 0x12, 0x23, 0xee, 0x7f, 0x00, 0x22, 0xaa, 0x56, 0xa9, +0x57, 0x7b, 0x01, 0x90, 0xfa, 0xd4, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 0xd9, 0xe0, 0xf5, +0x50, 0x12, 0x26, 0x25, 0x90, 0xfa, 0xd8, 0xef, 0xf0, 0x22, 0xef, 0x24, 0xae, 0x60, 0x52, 0x24, +0xfe, 0x60, 0x2e, 0x24, 0xfe, 0x70, 0x03, 0x02, 0x1e, 0xed, 0x24, 0x06, 0x60, 0x03, 0x02, 0x1f, +0x35, 0x78, 0x77, 0xe6, 0x54, 0xfb, 0xf6, 0x90, 0xff, 0xa5, 0xe0, 0xf5, 0x36, 0x44, 0x0f, 0xf0, +0x74, 0x33, 0x90, 0xfa, 0x90, 0xf0, 0xe5, 0x36, 0xa3, 0xf0, 0x90, 0xfa, 0xae, 0x74, 0x01, 0xf0, +0x22, 0x78, 0x78, 0xe6, 0x54, 0xfb, 0xf6, 0x90, 0xff, 0xb5, 0xe0, 0xf5, 0x36, 0x44, 0x0f, 0xf0, +0x74, 0x43, 0x90, 0xfa, 0x92, 0xf0, 0xe5, 0x36, 0xa3, 0xf0, 0x90, 0xfa, 0xaf, 0x74, 0x01, 0xf0, +0x22, 0x90, 0xfa, 0x9c, 0xe0, 0xa3, 0x20, 0xe5, 0x03, 0x02, 0x1f, 0x35, 0x90, 0xff, 0xa6, 0xe0, +0x90, 0xfa, 0xc9, 0xf0, 0xa3, 0xf0, 0x90, 0xfa, 0xc9, 0xe0, 0xff, 0x54, 0x0f, 0xfe, 0x60, 0x10, +0x90, 0xff, 0xa6, 0x12, 0x20, 0x83, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xc9, 0xf0, 0x80, 0xe6, +0x90, 0xfa, 0xca, 0xe0, 0xff, 0x74, 0x34, 0xfe, 0x12, 0x29, 0xda, 0xef, 0x70, 0x57, 0x90, 0xfa, +0xca, 0xe0, 0xff, 0x74, 0x34, 0x90, 0xfa, 0x94, 0xf0, 0xef, 0xa3, 0xf0, 0x22, 0x90, 0xfa, 0xa6, +0xe0, 0xa3, 0x30, 0xe5, 0x40, 0x90, 0xff, 0xb6, 0xe0, 0x90, 0xfa, 0xc9, 0xf0, 0xa3, 0xf0, 0x90, +0xfa, 0xc9, 0xe0, 0xff, 0x54, 0x0f, 0xfe, 0x60, 0x10, 0x90, 0xff, 0xb6, 0x12, 0x20, 0x83, 0x90, +0xff, 0xb6, 0xe0, 0x90, 0xfa, 0xc9, 0xf0, 0x80, 0xe6, 0x90, 0xfa, 0xca, 0xe0, 0xff, 0x74, 0x44, +0xfe, 0x12, 0x29, 0xda, 0xef, 0x70, 0x0e, 0x90, 0xfa, 0xca, 0xe0, 0xff, 0x74, 0x44, 0x90, 0xfa, +0x96, 0xf0, 0xef, 0xa3, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, +0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, +0x06, 0xc0, 0x07, 0x90, 0xff, 0x92, 0xe0, 0xff, 0x90, 0xfa, 0xc8, 0xf0, 0x90, 0xff, 0x92, 0xe4, +0xf0, 0xef, 0x12, 0x15, 0x0f, 0x1f, 0xed, 0x26, 0x1f, 0xed, 0x2e, 0x1f, 0x90, 0x30, 0x1f, 0x90, +0x32, 0x1f, 0x9e, 0x38, 0x1f, 0xb0, 0x3a, 0x1f, 0xe2, 0x3e, 0x1f, 0xcd, 0x44, 0x1f, 0xc2, 0x46, +0x1f, 0xd8, 0x50, 0x1f, 0xd8, 0x52, 0x1f, 0xd8, 0x54, 0x1f, 0xd8, 0x56, 0x00, 0x00, 0x1f, 0xf2, +0x90, 0xfa, 0xc8, 0xe0, 0xfd, 0x7c, 0x00, 0x7f, 0x01, 0x12, 0x10, 0x9c, 0x80, 0x62, 0x7c, 0x00, +0x7d, 0x01, 0x7f, 0x03, 0x12, 0x10, 0x9c, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x50, +0x7c, 0x00, 0x7d, 0x01, 0x7f, 0x02, 0x12, 0x10, 0x9c, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x40, 0xf0, +0x80, 0x3e, 0x7c, 0x00, 0x7d, 0x01, 0x7f, 0x05, 0x12, 0x10, 0x9c, 0x80, 0x33, 0x7c, 0x00, 0x7d, +0x01, 0x7f, 0x06, 0x12, 0x10, 0x9c, 0x80, 0x28, 0x90, 0xfa, 0xc8, 0xe0, 0xff, 0x12, 0x1e, 0x4a, +0x80, 0x1e, 0x7c, 0x00, 0x7d, 0x01, 0x7f, 0x04, 0x12, 0x10, 0x9c, 0x80, 0x13, 0x12, 0x25, 0x13, +0x80, 0x0e, 0x90, 0xfa, 0xc8, 0xe0, 0x24, 0x00, 0xff, 0xe4, 0x34, 0xff, 0xfe, 0x12, 0x29, 0xda, +0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, +0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x78, 0x82, 0xe6, 0xfe, 0x08, +0xe6, 0x24, 0x04, 0x8e, 0x83, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x22, 0x78, 0x82, 0xe6, +0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, 0x83, 0x22, 0x78, 0x86, 0xe6, 0xfe, 0x08, 0xe6, 0xaa, 0x06, +0xf8, 0xac, 0x02, 0x7d, 0x01, 0x7b, 0xff, 0x7a, 0x2f, 0x79, 0x52, 0x7e, 0x00, 0x7f, 0x0a, 0x02, +0x13, 0x8f, 0xff, 0x90, 0xf9, 0x6b, 0x02, 0x14, 0xfd, 0x90, 0xf9, 0x66, 0x12, 0x14, 0xfd, 0x90, +0x00, 0x04, 0x02, 0x13, 0xce, 0xe6, 0xfc, 0x08, 0xe6, 0xf5, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0x22, +0x78, 0x84, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x22, 0xed, 0x12, 0x14, 0x0d, 0x8f, 0x82, 0x8e, 0x83, +0xe5, 0x82, 0x22, 0xef, 0xf0, 0x90, 0xfa, 0xca, 0xe0, 0x54, 0x0f, 0x4e, 0xfe, 0xf0, 0xef, 0x54, +0xf0, 0x4e, 0xf0, 0x22, 0x78, 0x84, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x8c, 0x83, 0x22, 0xa6, 0x07, +0xe6, 0x24, 0x74, 0xf8, 0xe6, 0x22, 0x78, 0x84, 0xe6, 0xfa, 0x08, 0xe6, 0xfb, 0x22, 0x78, 0x86, +0xe6, 0xfc, 0x08, 0xe6, 0x8c, 0x83, 0x22, 0x26, 0xf6, 0x18, 0xee, 0x36, 0xf6, 0x22, 0x8b, 0x82, +0x8a, 0x83, 0xe5, 0x82, 0x22, 0x8b, 0x38, 0x8a, 0x39, 0x89, 0x3a, 0x8d, 0x3b, 0x90, 0xfa, 0xce, +0xe4, 0xf0, 0xa3, 0x74, 0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcd, 0x90, 0xfa, 0xce, 0xe0, +0xf5, 0x40, 0xa3, 0xe0, 0xf5, 0x41, 0x7d, 0x01, 0x12, 0x23, 0xee, 0x90, 0xfa, 0xcd, 0xe0, 0x65, +0x3b, 0x60, 0x46, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0xa3, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x21, +0x54, 0x90, 0xfa, 0xcd, 0xe0, 0xff, 0x90, 0xfa, 0xd0, 0xe4, 0x8f, 0xf0, 0x12, 0x14, 0x2f, 0x12, +0x21, 0x54, 0x90, 0xfa, 0xd0, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0xfa, 0xce, 0xcf, 0xf0, 0xa3, 0xef, +0xf0, 0x90, 0xfa, 0xcd, 0xe0, 0xa3, 0x75, 0xf0, 0x00, 0x12, 0x14, 0x2f, 0x90, 0xfa, 0xce, 0xe4, +0x75, 0xf0, 0x04, 0x12, 0x14, 0x2f, 0x02, 0x20, 0xd6, 0x90, 0xfa, 0xcf, 0xe0, 0x24, 0x01, 0xff, +0x90, 0xfa, 0xce, 0xe0, 0x34, 0x00, 0xab, 0x38, 0xaa, 0x39, 0xa9, 0x3a, 0x8f, 0xf0, 0x12, 0x14, +0x93, 0x7f, 0x00, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcd, 0x90, 0xfa, 0xce, 0xe4, 0x75, 0xf0, +0x01, 0x12, 0x14, 0x2f, 0x85, 0xf0, 0x41, 0xf5, 0x40, 0x7d, 0x01, 0x02, 0x23, 0xee, 0x8f, 0x68, +0x12, 0x27, 0x19, 0x12, 0x20, 0x70, 0x8e, 0x83, 0x24, 0x0b, 0x12, 0x20, 0x25, 0xe0, 0x54, 0xfb, +0xf0, 0x44, 0x02, 0xf0, 0x08, 0x12, 0x20, 0x65, 0xe0, 0xa3, 0x30, 0xe5, 0x0c, 0x12, 0x20, 0x7c, +0x24, 0x0b, 0x12, 0x20, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x78, 0x82, 0xe6, 0xfe, 0x08, 0xe6, 0xff, +0xf5, 0x82, 0x8e, 0x83, 0xe0, 0x54, 0xb8, 0xfd, 0xf0, 0xe5, 0x68, 0x24, 0xfe, 0x44, 0x20, 0xfc, +0x4d, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x20, 0x25, 0xe0, 0x54, 0xb8, 0xf0, 0x4c, 0xf0, 0x8f, +0x82, 0x8e, 0x83, 0xa3, 0x74, 0x03, 0xf0, 0x18, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, +0x05, 0x12, 0x20, 0x25, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x74, 0x95, 0x25, 0x68, 0xf5, 0x82, +0xe4, 0x34, 0xfa, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0x44, 0x03, 0xfc, 0xed, 0x4c, 0xd0, 0x82, 0xd0, +0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x20, +0x25, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x2f, 0x80, 0x74, 0x74, 0x25, 0x68, 0xf8, 0x74, 0x04, 0x46, +0xf6, 0x7f, 0x00, 0x22, 0x8b, 0x62, 0x8a, 0x63, 0x89, 0x64, 0x12, 0x2a, 0x62, 0x90, 0xfa, 0xbf, +0x12, 0x15, 0x06, 0xaa, 0x63, 0xa9, 0x64, 0x90, 0xfa, 0xc2, 0x12, 0x15, 0x06, 0x90, 0xfa, 0xc3, +0xe4, 0x75, 0xf0, 0x0a, 0x12, 0x14, 0x2f, 0x90, 0xfa, 0xc2, 0x12, 0x14, 0xfd, 0xe9, 0x24, 0x01, +0xf9, 0xe4, 0x3a, 0xfa, 0x90, 0xfa, 0xc5, 0x12, 0x15, 0x06, 0xab, 0x62, 0xaa, 0x63, 0xa9, 0x64, +0x12, 0x2a, 0x6e, 0xe0, 0xff, 0xc3, 0x13, 0xf0, 0xe4, 0x78, 0x88, 0xf6, 0x90, 0xfa, 0xbd, 0xe0, +0xff, 0x78, 0x88, 0xe6, 0xc3, 0x9f, 0x50, 0x4a, 0x90, 0xfa, 0xbf, 0x12, 0x2a, 0x43, 0xff, 0x78, +0x89, 0xf6, 0x90, 0xfa, 0xc2, 0x12, 0x2a, 0x43, 0xfe, 0xf4, 0x5f, 0xff, 0x78, 0x89, 0xf6, 0x12, +0x2a, 0x40, 0x5e, 0x4f, 0xff, 0x78, 0x89, 0xf6, 0x12, 0x2a, 0x49, 0x75, 0xf0, 0x02, 0x12, 0x14, +0x2f, 0x90, 0xfa, 0xc3, 0xe4, 0x75, 0xf0, 0x02, 0x12, 0x14, 0x2f, 0xab, 0x62, 0xaa, 0x63, 0xa9, +0x64, 0x90, 0x00, 0x04, 0x12, 0x13, 0xce, 0x30, 0xe4, 0x03, 0x12, 0x2a, 0x58, 0x78, 0x88, 0x06, +0x80, 0xaa, 0xe4, 0x90, 0xfa, 0xbe, 0xf0, 0x22, 0x8b, 0x5c, 0x8a, 0x5d, 0x89, 0x5e, 0x90, 0xfa, +0xbe, 0x74, 0x06, 0xf0, 0xe4, 0x90, 0xfa, 0xbd, 0xf0, 0x12, 0x13, 0xb5, 0x24, 0x6e, 0x60, 0x26, +0x14, 0x70, 0x70, 0x12, 0x2a, 0x2f, 0x60, 0x09, 0x24, 0x30, 0x70, 0x12, 0x12, 0x22, 0x14, 0x80, +0x62, 0x12, 0x2a, 0x79, 0x12, 0x1d, 0x5e, 0x90, 0xfa, 0xbe, 0xef, 0xf0, 0x80, 0x55, 0x90, 0xfa, +0xbe, 0x74, 0x81, 0xf0, 0x80, 0x4d, 0x12, 0x2a, 0x2f, 0x60, 0x09, 0x24, 0x30, 0x70, 0x3e, 0x12, +0x29, 0x85, 0x80, 0x3f, 0xe5, 0x5e, 0x24, 0x03, 0xf9, 0xe4, 0x35, 0x5d, 0xfa, 0x7b, 0x01, 0xc0, +0x03, 0xc0, 0x02, 0xc0, 0x01, 0x12, 0x2a, 0x79, 0x90, 0x00, 0x05, 0x12, 0x13, 0xce, 0xfd, 0x90, +0x00, 0x08, 0x12, 0x14, 0x5b, 0xf5, 0x41, 0x85, 0xf0, 0x40, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, +0x12, 0x23, 0xee, 0x90, 0xfa, 0xbd, 0xef, 0xf0, 0xe4, 0xa3, 0xf0, 0x80, 0x06, 0x90, 0xfa, 0xbe, +0x74, 0x81, 0xf0, 0x90, 0xfa, 0xbe, 0xe0, 0x12, 0x2a, 0x79, 0x90, 0x00, 0x02, 0x12, 0x14, 0x0d, +0x90, 0xfa, 0xbd, 0xe0, 0xff, 0x22, 0x12, 0x0f, 0x89, 0x7f, 0x02, 0x12, 0x11, 0x9f, 0x78, 0x6d, +0xe6, 0x44, 0x02, 0xf6, 0xd2, 0xb0, 0xd2, 0xb1, 0xd2, 0xb3, 0x90, 0xff, 0xa4, 0xe0, 0x90, 0xfa, +0x7a, 0xf0, 0x90, 0xff, 0xb4, 0xe0, 0x90, 0xfa, 0x7b, 0xf0, 0x90, 0xff, 0xa2, 0xe0, 0x90, 0xfa, +0x78, 0xf0, 0x90, 0xff, 0xb2, 0xe0, 0x90, 0xfa, 0x79, 0xf0, 0x90, 0xff, 0xa4, 0x74, 0x30, 0xf0, +0x90, 0xff, 0xb4, 0xf0, 0x90, 0xff, 0xa2, 0x74, 0x40, 0xf0, 0x90, 0xff, 0xb2, 0xf0, 0x90, 0xfa, +0xe3, 0xe5, 0xa8, 0xf0, 0x75, 0xa8, 0x81, 0x90, 0xff, 0x92, 0xe0, 0x60, 0x04, 0xe4, 0xf0, 0x80, +0xf6, 0x90, 0xff, 0xfd, 0x74, 0x3a, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x90, 0xfa, 0x7a, +0xe0, 0x90, 0xff, 0xa4, 0xf0, 0x90, 0xfa, 0x7b, 0xe0, 0x90, 0xff, 0xb4, 0xf0, 0x90, 0xfa, 0x78, +0xe0, 0x90, 0xff, 0xa2, 0xf0, 0x90, 0xfa, 0x79, 0xe0, 0x90, 0xff, 0xb2, 0xf0, 0x90, 0xf9, 0x15, +0xe0, 0x60, 0x02, 0xc2, 0xb3, 0x90, 0xfa, 0xe3, 0xe0, 0xf5, 0xa8, 0x02, 0x10, 0x0c, 0x8b, 0x3c, +0x8a, 0x3d, 0x89, 0x3e, 0x8d, 0x3f, 0xe5, 0x3f, 0x70, 0x03, 0xaf, 0x3f, 0x22, 0x12, 0x2a, 0xa8, +0x70, 0x16, 0x12, 0x2a, 0xc7, 0xe5, 0x40, 0x90, 0xff, 0xf1, 0xf0, 0x12, 0x2e, 0xd4, 0x50, 0xf2, +0x12, 0x24, 0x7b, 0x40, 0x0b, 0x7f, 0x00, 0x22, 0x12, 0x2a, 0xc7, 0x12, 0x24, 0x7b, 0x50, 0xf8, +0x90, 0xff, 0xf3, 0x74, 0xa1, 0xf0, 0xe5, 0x3f, 0xb4, 0x01, 0x07, 0x90, 0xff, 0xf0, 0xe0, 0x44, +0x02, 0xf0, 0x90, 0xff, 0xf1, 0xe4, 0xf0, 0xf5, 0x42, 0xe5, 0x3f, 0x14, 0xff, 0xe5, 0x42, 0xc3, +0x9f, 0x50, 0x2a, 0x12, 0x2e, 0xbd, 0x40, 0x03, 0xaf, 0x42, 0x22, 0xc3, 0xe5, 0x3f, 0x95, 0x42, +0xff, 0xbf, 0x02, 0x07, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x12, 0x2a, 0xba, 0x05, 0x42, +0x74, 0x01, 0x25, 0x3e, 0xf5, 0x3e, 0xe4, 0x35, 0x3d, 0xf5, 0x3d, 0x80, 0xcc, 0x12, 0x2e, 0xbd, +0x40, 0x03, 0x7f, 0x18, 0x22, 0x12, 0x2a, 0xba, 0xaf, 0x3f, 0x22, 0x90, 0xff, 0xf1, 0xe5, 0x41, +0xf0, 0x02, 0x2e, 0xd4, 0x75, 0xa8, 0x40, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x91, +0x02, 0x24, 0xce, 0x02, 0x2e, 0x88, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, +0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, +0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, +0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x28, +0xcb, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, +0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, +0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, +0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, +0xe7, 0x80, 0xbe, 0xe4, 0xf5, 0x36, 0x12, 0x19, 0x21, 0xe0, 0xb4, 0x04, 0x0d, 0xe5, 0x36, 0x24, +0x03, 0xff, 0x12, 0x2d, 0x4f, 0x12, 0x19, 0x21, 0xe4, 0xf0, 0x05, 0x36, 0xe5, 0x36, 0xc3, 0x94, +0x02, 0x40, 0xe3, 0xe4, 0xf5, 0x36, 0x75, 0xf0, 0x02, 0xe5, 0x36, 0x90, 0xfa, 0x90, 0x12, 0x19, +0x62, 0x60, 0x2c, 0x12, 0x29, 0xda, 0xef, 0x60, 0x52, 0x75, 0xf0, 0x02, 0xe5, 0x36, 0x90, 0xfa, +0x90, 0x12, 0x14, 0xdf, 0xe4, 0xf0, 0xa3, 0xf0, 0x75, 0xf0, 0x0a, 0xe5, 0x36, 0x90, 0xfa, 0x9c, +0x12, 0x14, 0xdf, 0xe0, 0xa3, 0x30, 0xe6, 0x33, 0x12, 0x19, 0x21, 0x74, 0x04, 0xf0, 0x22, 0x75, +0xf0, 0x02, 0xe5, 0x36, 0x90, 0xfa, 0x94, 0x12, 0x19, 0x62, 0x60, 0x16, 0x12, 0x29, 0xda, 0xef, +0x60, 0x19, 0x75, 0xf0, 0x02, 0xe5, 0x36, 0x90, 0xfa, 0x94, 0x12, 0x14, 0xdf, 0xe4, 0xf0, 0xa3, +0xf0, 0x22, 0x05, 0x36, 0xe5, 0x36, 0xc3, 0x94, 0x02, 0x40, 0x9b, 0x22, 0xe4, 0xff, 0x90, 0xff, +0x83, 0xe0, 0x54, 0x0f, 0xfe, 0xef, 0xc3, 0x9e, 0x50, 0x17, 0x74, 0xf0, 0x2f, 0xf5, 0x82, 0xe4, +0x34, 0xfe, 0xf5, 0x83, 0xe0, 0x12, 0x18, 0x2a, 0x12, 0x13, 0xfb, 0x0f, 0x12, 0x18, 0x19, 0x80, +0xdd, 0xef, 0xfd, 0xc3, 0xe5, 0x31, 0x9d, 0xf5, 0x31, 0xe5, 0x30, 0x94, 0x00, 0xf5, 0x30, 0xd3, +0xe5, 0x31, 0x94, 0x00, 0xe5, 0x30, 0x94, 0x00, 0x40, 0x06, 0xe4, 0x90, 0xff, 0x83, 0xf0, 0x22, +0x12, 0x19, 0x3e, 0x12, 0x19, 0x92, 0x12, 0x19, 0x8c, 0x12, 0x13, 0xb5, 0x24, 0x6e, 0x60, 0x1e, +0x14, 0x60, 0x1b, 0x24, 0x8e, 0x70, 0x2d, 0x90, 0x00, 0x01, 0x12, 0x13, 0xce, 0xff, 0x24, 0xfc, +0x60, 0x03, 0x04, 0x70, 0x1f, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0d, 0x02, 0x10, 0x9c, 0x12, 0x19, +0x6c, 0x12, 0x22, 0xb8, 0x12, 0x18, 0xe8, 0x12, 0x13, 0xce, 0x60, 0x03, 0x02, 0x2f, 0x76, 0xe4, +0xff, 0x12, 0x2f, 0x6a, 0x22, 0x8b, 0x4b, 0x8a, 0x4c, 0x89, 0x4d, 0x8c, 0x4e, 0x8d, 0x4f, 0xd2, +0x00, 0x12, 0x2a, 0xa8, 0x70, 0x16, 0x12, 0x2a, 0xc7, 0xe5, 0x4e, 0x90, 0xff, 0xf1, 0xf0, 0x12, +0x2e, 0xd4, 0x50, 0xf2, 0x12, 0x26, 0x9a, 0x40, 0x0b, 0x7f, 0x18, 0x22, 0x12, 0x2a, 0xc7, 0x12, +0x26, 0x9a, 0x50, 0xf8, 0xe4, 0xf5, 0x51, 0xe5, 0x50, 0x14, 0xff, 0xe5, 0x51, 0xc3, 0x9f, 0x50, +0x17, 0x12, 0x26, 0x8a, 0x40, 0x03, 0x7f, 0x18, 0x22, 0x05, 0x51, 0x74, 0x01, 0x25, 0x4d, 0xf5, +0x4d, 0xe4, 0x35, 0x4c, 0xf5, 0x4c, 0x80, 0xdf, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x01, 0xf0, 0x12, +0x26, 0x8a, 0x40, 0x03, 0x7f, 0x18, 0x22, 0x7f, 0x00, 0x22, 0xab, 0x4b, 0xaa, 0x4c, 0xa9, 0x4d, +0x12, 0x13, 0xb5, 0x90, 0xff, 0xf1, 0xf0, 0x02, 0x2e, 0xd4, 0x90, 0xff, 0xf1, 0xe5, 0x4f, 0xf0, +0x02, 0x2e, 0xd4, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcb, 0xe4, 0xfd, 0x12, 0x20, 0xc5, 0x90, 0xfa, +0xcb, 0xe4, 0x75, 0xf0, 0x09, 0x12, 0x14, 0x2f, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x37, 0x90, 0xfa, +0xcb, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x14, 0x45, 0x85, 0xf0, 0x41, 0xf5, 0x40, 0x7d, 0x01, 0x12, +0x23, 0xee, 0x90, 0xff, 0xf7, 0xe5, 0x37, 0x12, 0x26, 0xfe, 0x90, 0xff, 0xf6, 0xe5, 0x37, 0xf0, +0x90, 0xfa, 0xcb, 0xe4, 0xf0, 0xa3, 0x74, 0x06, 0x12, 0x26, 0xfe, 0xe5, 0x37, 0x30, 0xe0, 0x07, +0x90, 0xff, 0xfc, 0x74, 0x94, 0xf0, 0x22, 0x90, 0xff, 0xfc, 0x74, 0x90, 0xf0, 0x22, 0xf0, 0x7b, +0x00, 0x7a, 0x00, 0x79, 0x37, 0x90, 0xfa, 0xcb, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x14, 0x45, 0x85, +0xf0, 0x41, 0xf5, 0x40, 0x7d, 0x01, 0x02, 0x23, 0xee, 0x15, 0x6b, 0xa8, 0x6b, 0xa6, 0x07, 0x30, +0x08, 0x05, 0x12, 0x10, 0xec, 0x80, 0xf8, 0xd2, 0x08, 0xa8, 0x6b, 0xe6, 0xff, 0xb4, 0x03, 0x0f, +0x78, 0x82, 0x76, 0xff, 0x08, 0x76, 0xe0, 0x08, 0x76, 0xff, 0x08, 0x76, 0xa0, 0x80, 0x0d, 0x78, +0x82, 0x76, 0xff, 0x08, 0x76, 0xe2, 0x08, 0x76, 0xff, 0x08, 0x76, 0xb0, 0x78, 0x86, 0x76, 0xfa, +0x08, 0x76, 0x9a, 0xef, 0x24, 0xfd, 0x75, 0xf0, 0x0a, 0xa4, 0xae, 0xf0, 0x12, 0x20, 0xb7, 0x7b, +0x01, 0x7a, 0xff, 0x79, 0x48, 0x78, 0x6e, 0x12, 0x14, 0xf4, 0xa8, 0x6b, 0xe6, 0x24, 0xfd, 0x75, +0xf0, 0x08, 0xa4, 0xff, 0xae, 0xf0, 0x78, 0x70, 0x12, 0x20, 0xb7, 0x79, 0x08, 0x78, 0x71, 0x12, +0x14, 0xf4, 0x78, 0x73, 0xef, 0x12, 0x20, 0xb7, 0x05, 0x6b, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, +0xab, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xfa, 0xe2, 0x74, 0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, +0x79, 0xcb, 0xe4, 0xf5, 0x40, 0xf5, 0x41, 0x7d, 0x01, 0x12, 0x23, 0xee, 0x7e, 0x00, 0x90, 0xfa, +0xe0, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x64, 0x01, 0x70, 0x10, 0x90, 0xfa, 0xcb, 0xe0, 0xb4, 0x52, +0x09, 0x90, 0xf9, 0x65, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x29, 0x90, 0xfa, 0xe0, 0xe0, 0x70, 0x04, +0xa3, 0xe0, 0x64, 0x01, 0x70, 0x10, 0x90, 0xfa, 0xcb, 0xe0, 0xb4, 0x10, 0x09, 0x90, 0xf9, 0x65, +0xe0, 0x44, 0x10, 0xf0, 0x80, 0x0d, 0x90, 0xfa, 0xe2, 0x74, 0x03, 0xf0, 0x90, 0xf9, 0x65, 0xe0, +0x54, 0xef, 0xf0, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x22, 0x90, 0xff, 0x93, 0x74, 0x2a, +0xf0, 0x90, 0xff, 0xff, 0xe0, 0x60, 0x06, 0x90, 0xff, 0xfc, 0x74, 0x10, 0xf0, 0x90, 0xff, 0x91, +0xe0, 0x44, 0x90, 0xf0, 0x12, 0x27, 0x8b, 0x12, 0x15, 0x35, 0x12, 0x2d, 0xa5, 0x7e, 0x07, 0x7f, +0xd0, 0x12, 0x11, 0x68, 0x7e, 0x0f, 0x7f, 0xa0, 0x12, 0x11, 0x82, 0xe4, 0x78, 0x7d, 0xf6, 0x78, +0x7d, 0xe6, 0xff, 0xc3, 0x94, 0x06, 0x50, 0x0b, 0x74, 0x74, 0x2f, 0xf8, 0xe4, 0xf6, 0x78, 0x7d, +0x06, 0x80, 0xec, 0x7f, 0x03, 0x12, 0x2c, 0x5b, 0x90, 0xf9, 0x65, 0xe0, 0x20, 0xe4, 0x05, 0x7f, +0x04, 0x12, 0x2c, 0x5b, 0x90, 0xff, 0x9b, 0xe4, 0xf0, 0x90, 0xff, 0x9a, 0xf0, 0x90, 0xff, 0xe8, +0xe0, 0x54, 0x1f, 0xf0, 0xd2, 0xa8, 0x22, 0x12, 0x0f, 0x89, 0x78, 0x90, 0xef, 0xf6, 0x12, 0x27, +0x19, 0x12, 0x20, 0x59, 0x30, 0xe0, 0x25, 0x12, 0x20, 0x2d, 0xe0, 0x54, 0x7f, 0xf0, 0x78, 0x71, +0x12, 0x14, 0xeb, 0x90, 0x00, 0x02, 0x12, 0x13, 0xce, 0x30, 0xe7, 0x09, 0x90, 0x00, 0x02, 0xe4, +0x12, 0x14, 0x0d, 0x80, 0xe9, 0x12, 0x20, 0x2d, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x20, 0x59, 0x30, +0xe1, 0x1e, 0x12, 0x20, 0x1b, 0xe0, 0x54, 0x7f, 0xf0, 0x12, 0x2f, 0x15, 0x78, 0x6e, 0x12, 0x14, +0xeb, 0x90, 0x00, 0x02, 0x74, 0x80, 0x12, 0x14, 0x0d, 0x12, 0x20, 0x1b, 0xe0, 0x44, 0x80, 0xf0, +0x12, 0x2f, 0x80, 0xe4, 0xff, 0x12, 0x2e, 0xa5, 0x02, 0x10, 0x0c, 0x03, 0x6e, 0x01, 0xff, 0x48, +0x03, 0x71, 0x01, 0xff, 0x08, 0x02, 0x6c, 0x00, 0x00, 0x44, 0xfa, 0x94, 0x00, 0x00, 0x00, 0x00, +0x44, 0xfa, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfa, 0xae, 0x00, 0x00, 0x42, 0xfa, 0x7a, 0x00, +0x00, 0x42, 0xfa, 0x78, 0x00, 0x00, 0x42, 0xf9, 0x69, 0xff, 0xff, 0x42, 0xfa, 0x76, 0x00, 0x00, +0x43, 0xf9, 0x16, 0x0a, 0x32, 0x02, 0x41, 0xf9, 0x63, 0x20, 0x41, 0xf9, 0x64, 0x20, 0x41, 0xf9, +0x61, 0x00, 0x41, 0xf9, 0x62, 0x00, 0x44, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf9, 0x65, +0x00, 0x41, 0xf9, 0x15, 0x00, 0x01, 0x20, 0x00, 0x41, 0xf8, 0x04, 0x00, 0x00, 0x12, 0x19, 0x82, +0xe5, 0x31, 0x64, 0x09, 0x70, 0x04, 0xe5, 0x30, 0x64, 0x01, 0x60, 0x48, 0xc3, 0xe5, 0x31, 0x94, +0x08, 0xe5, 0x30, 0x94, 0x00, 0x40, 0x11, 0x7f, 0x08, 0xef, 0xe5, 0x31, 0x94, 0x08, 0xf5, 0x31, +0xe5, 0x30, 0x94, 0x00, 0xf5, 0x30, 0x80, 0x05, 0xaf, 0x31, 0x12, 0x19, 0x92, 0xe4, 0xfe, 0xee, +0xc3, 0x9f, 0x50, 0x19, 0x12, 0x18, 0x2a, 0x12, 0x13, 0xb5, 0xfd, 0x74, 0xf8, 0x2e, 0xf5, 0x82, +0xe4, 0x34, 0xfe, 0xf5, 0x83, 0xed, 0xf0, 0x0e, 0x12, 0x18, 0x19, 0x80, 0xe2, 0xef, 0x54, 0x7f, +0x90, 0xff, 0x81, 0xf0, 0x22, 0x8b, 0x5f, 0x8a, 0x60, 0x89, 0x61, 0x12, 0x2a, 0x6e, 0x70, 0x05, +0xa3, 0x74, 0x08, 0xf0, 0x22, 0xab, 0x5f, 0xaa, 0x60, 0xa9, 0x61, 0x12, 0x2a, 0x62, 0x90, 0xfa, +0xc5, 0x12, 0x15, 0x06, 0xe5, 0x61, 0x24, 0x03, 0xf9, 0xe4, 0x35, 0x60, 0xfa, 0x90, 0xfa, 0xbf, +0x12, 0x15, 0x06, 0xe4, 0x90, 0xfa, 0xbe, 0xf0, 0x78, 0x91, 0xf6, 0x90, 0xfa, 0xbd, 0xe0, 0xff, +0x78, 0x91, 0xe6, 0xc3, 0x9f, 0x50, 0x12, 0x12, 0x2a, 0x40, 0xff, 0x12, 0x2a, 0x49, 0x12, 0x2a, +0x5c, 0x78, 0x91, 0x06, 0x12, 0x2a, 0x58, 0x80, 0xe2, 0x22, 0xad, 0x07, 0xac, 0x06, 0x90, 0x2f, +0x06, 0xe4, 0x93, 0xff, 0x78, 0x7a, 0xf6, 0x54, 0x0f, 0x12, 0x19, 0x07, 0xe0, 0x08, 0x76, 0x00, +0x08, 0xf6, 0x18, 0x12, 0x18, 0x42, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x78, 0x7b, +0xee, 0xf6, 0x08, 0xef, 0xf6, 0xee, 0x44, 0xf8, 0x18, 0xf6, 0xef, 0x08, 0xf6, 0x90, 0xff, 0x7a, +0xe0, 0x20, 0xe7, 0x03, 0x7f, 0x00, 0x22, 0x78, 0x7b, 0xe6, 0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, +0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0x90, 0xff, 0x7a, 0x74, 0x02, 0xf0, 0x7f, 0x01, 0x22, 0xab, +0x5c, 0xaa, 0x5d, 0xa9, 0x5e, 0x90, 0x00, 0x03, 0x12, 0x13, 0xce, 0x54, 0xf0, 0x24, 0xa0, 0x22, +0x90, 0xfa, 0xc5, 0x12, 0x14, 0xfd, 0x02, 0x13, 0xb5, 0x90, 0xfa, 0xbf, 0x12, 0x14, 0xfd, 0xef, +0x12, 0x13, 0xfb, 0x90, 0xfa, 0xc6, 0xe4, 0x22, 0x90, 0xfa, 0xc0, 0xe4, 0x75, 0xf0, 0x01, 0x02, +0x14, 0x2f, 0x90, 0x00, 0x08, 0x12, 0x14, 0x5b, 0xaa, 0xf0, 0xf9, 0x7b, 0x01, 0x22, 0x90, 0x00, +0x05, 0x12, 0x13, 0xce, 0x90, 0xfa, 0xbd, 0xf0, 0x22, 0xab, 0x5c, 0xaa, 0x5d, 0xa9, 0x5e, 0x22, +0x90, 0xfa, 0xd9, 0xe0, 0xff, 0x7e, 0x00, 0xc3, 0x90, 0xfa, 0xd3, 0xe0, 0x9f, 0xf0, 0x90, 0xfa, +0xd2, 0xe0, 0x9e, 0xf0, 0x90, 0xfa, 0xd4, 0xee, 0x8f, 0xf0, 0x12, 0x14, 0x2f, 0xef, 0x25, 0x57, +0xf5, 0x57, 0xee, 0x35, 0x56, 0xf5, 0x56, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, +0x54, 0xfd, 0xf0, 0x90, 0xfa, 0xe2, 0xe0, 0x64, 0x03, 0x22, 0x90, 0xff, 0xf2, 0xe0, 0xab, 0x3c, +0xaa, 0x3d, 0xa9, 0x3e, 0x02, 0x13, 0xfb, 0x90, 0xff, 0xf3, 0x74, 0xa0, 0xf0, 0x22, 0x8f, 0x6a, +0xed, 0x70, 0x0f, 0xe5, 0x6a, 0xb4, 0x03, 0x05, 0x7f, 0x01, 0x02, 0x2e, 0xeb, 0x7f, 0x02, 0x02, +0x2e, 0xeb, 0xaf, 0x6a, 0x12, 0x27, 0x19, 0x74, 0x74, 0x25, 0x6a, 0xf8, 0xe6, 0x30, 0xe2, 0x0b, +0xd2, 0x09, 0x12, 0x18, 0x9b, 0xe0, 0x54, 0x7f, 0xf0, 0x80, 0x02, 0xc2, 0x09, 0xe5, 0x6a, 0xb4, +0x03, 0x07, 0x7f, 0x81, 0x12, 0x2e, 0xeb, 0x80, 0x05, 0x7f, 0x82, 0x12, 0x2e, 0xeb, 0x30, 0x09, +0x07, 0x12, 0x18, 0x9b, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x2f, 0x80, 0x22, 0x12, 0x0f, 0x89, 0x90, +0xff, 0xfd, 0xe0, 0x44, 0x60, 0xf0, 0xd2, 0x01, 0x90, 0xff, 0xfc, 0xe0, 0x44, 0x02, 0xf0, 0x90, +0xff, 0x00, 0xe0, 0x30, 0xe7, 0x13, 0x90, 0xff, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x2c, 0x80, +0x90, 0xff, 0xfc, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x0d, 0x12, 0x19, 0x3e, 0x53, 0x2c, 0x7f, 0x90, +0xff, 0xfc, 0xe0, 0x54, 0xfe, 0xf0, 0x90, 0xff, 0x81, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x02, 0x9f, +0x12, 0x19, 0x46, 0x02, 0x10, 0x0c, 0x12, 0x0f, 0x89, 0x78, 0x8a, 0x12, 0x20, 0x9e, 0x30, 0xe1, +0x07, 0x7f, 0x13, 0x12, 0x2e, 0xa5, 0x80, 0x34, 0x90, 0xf9, 0x65, 0xe0, 0x54, 0x03, 0x60, 0x16, +0x78, 0x8a, 0xe6, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80, 0x07, 0x90, +0xff, 0xb4, 0xe0, 0x54, 0xdf, 0xf0, 0xc2, 0xb3, 0x90, 0xf9, 0x15, 0xe0, 0x04, 0xf0, 0x78, 0x8a, +0xe6, 0xff, 0x12, 0x20, 0x59, 0xfd, 0x12, 0x2d, 0x21, 0x12, 0x2e, 0xa5, 0x02, 0x10, 0x0c, 0x12, +0x0f, 0x89, 0x78, 0x8f, 0xef, 0xf6, 0xd2, 0x00, 0x12, 0x27, 0x19, 0x90, 0xf9, 0x66, 0x12, 0x14, +0xfd, 0xe9, 0x24, 0x03, 0xf9, 0xe4, 0x3a, 0xfa, 0xc0, 0x02, 0x78, 0x86, 0xe6, 0xfe, 0x08, 0xe6, +0xaa, 0x06, 0xf8, 0xac, 0x02, 0x7d, 0x01, 0xd0, 0x02, 0x12, 0x20, 0x4b, 0x12, 0x2f, 0x80, 0x78, +0x8f, 0xe6, 0xff, 0x12, 0x19, 0xbb, 0x12, 0x2e, 0xa5, 0x02, 0x10, 0x0c, 0x12, 0x0f, 0x89, 0x78, +0x8b, 0xef, 0xf6, 0x12, 0x2e, 0x4c, 0x12, 0x2e, 0xa5, 0x90, 0xf9, 0x65, 0xe0, 0x54, 0x03, 0x60, +0x16, 0x78, 0x8b, 0xe6, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x07, +0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xf9, 0x15, 0xe0, 0x14, 0xf0, 0xe0, 0x70, 0x02, +0xd2, 0xb3, 0x02, 0x10, 0x0c, 0x8f, 0x69, 0x12, 0x27, 0x19, 0x12, 0x20, 0x2d, 0xe0, 0x54, 0x3f, +0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x20, 0x25, 0xe0, 0x54, 0x3f, 0xf0, 0x08, 0xe6, 0xfe, 0x08, +0xe6, 0x8e, 0x83, 0x24, 0x0b, 0x12, 0x20, 0x25, 0xe0, 0x54, 0xf8, 0xf0, 0x12, 0x2f, 0x80, 0x74, +0x74, 0x25, 0x69, 0xf8, 0x74, 0xfb, 0x56, 0xf6, 0x7f, 0x00, 0x22, 0x8f, 0x37, 0xc2, 0x08, 0x12, +0x27, 0x19, 0x12, 0x20, 0x38, 0x78, 0x84, 0x12, 0x20, 0x1d, 0xe0, 0x44, 0x01, 0xf0, 0x12, 0x20, +0x70, 0x12, 0x20, 0x21, 0xe0, 0x20, 0xe0, 0xf6, 0xef, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, +0x83, 0xe0, 0x54, 0xf8, 0xf0, 0x12, 0x2f, 0x80, 0xaf, 0x37, 0x12, 0x19, 0xbb, 0x22, 0x12, 0x0f, +0x89, 0x12, 0x27, 0x19, 0x12, 0x20, 0x70, 0x24, 0x06, 0x12, 0x20, 0x23, 0xe0, 0xfd, 0x12, 0x20, +0x53, 0x90, 0x00, 0x03, 0x12, 0x20, 0x78, 0x24, 0x05, 0x12, 0x20, 0x25, 0xe0, 0x90, 0x00, 0x04, +0x12, 0x14, 0x0d, 0x12, 0x2f, 0x80, 0x7d, 0x02, 0xe4, 0xff, 0x12, 0x2c, 0xc0, 0x02, 0x10, 0x0c, +0xae, 0x05, 0x12, 0x18, 0xed, 0xef, 0x12, 0x14, 0x0d, 0x0e, 0x0e, 0x0e, 0xee, 0xd3, 0x95, 0x35, +0xe4, 0x95, 0x34, 0x40, 0x02, 0xae, 0x35, 0xee, 0xd3, 0x94, 0x08, 0x74, 0x80, 0x94, 0x81, 0x40, +0x0a, 0x7e, 0x03, 0x90, 0x00, 0x02, 0x74, 0x02, 0x12, 0x14, 0x0d, 0xaf, 0x06, 0x12, 0x2f, 0x6a, +0x22, 0x12, 0x0f, 0x89, 0x78, 0x8c, 0x12, 0x20, 0x9e, 0x30, 0xe2, 0x07, 0x7f, 0x13, 0x12, 0x2e, +0xa5, 0x80, 0x1b, 0x78, 0x8c, 0xe6, 0x24, 0x74, 0xf8, 0xe6, 0x20, 0xe1, 0x07, 0x7f, 0x12, 0x12, +0x2e, 0xa5, 0x80, 0x0a, 0x78, 0x8c, 0xe6, 0xff, 0x12, 0x21, 0x6e, 0x12, 0x2e, 0xa5, 0x02, 0x10, +0x0c, 0xae, 0x07, 0xed, 0x54, 0x03, 0x64, 0x01, 0x60, 0x03, 0x7f, 0x10, 0x22, 0xed, 0x54, 0x7c, +0xc3, 0x94, 0x04, 0x50, 0x03, 0x7f, 0x0b, 0x22, 0x74, 0x74, 0x2e, 0xf8, 0x74, 0x02, 0x46, 0xf6, +0x74, 0x95, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 0xed, 0xf0, 0x7f, 0x00, 0x22, 0xbf, +0x03, 0x06, 0x7c, 0xff, 0x7d, 0xe0, 0x80, 0x04, 0x7c, 0xff, 0x7d, 0xe2, 0x8d, 0x82, 0x8c, 0x83, +0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x20, 0x25, 0xe0, 0x44, 0x80, 0xf0, 0x74, +0x74, 0x2f, 0xf8, 0x74, 0x04, 0x46, 0xf6, 0x7f, 0x00, 0x22, 0x12, 0x0f, 0x89, 0xe5, 0x31, 0x64, +0x09, 0x70, 0x04, 0xe5, 0x30, 0x64, 0x01, 0x60, 0x16, 0x90, 0xff, 0x83, 0xe0, 0x54, 0x0f, 0xff, +0xc3, 0xe5, 0x31, 0x9f, 0xe5, 0x30, 0x94, 0x00, 0x40, 0x05, 0x12, 0x25, 0x9c, 0x80, 0x03, 0x12, +0x2f, 0x76, 0x02, 0x10, 0x0c, 0x90, 0xff, 0xfc, 0xe0, 0x20, 0xe7, 0x1f, 0xc2, 0xaf, 0x7d, 0xff, +0xac, 0x05, 0x1d, 0xec, 0x60, 0x15, 0x7e, 0x04, 0x7f, 0x00, 0xef, 0x1f, 0xaa, 0x06, 0x70, 0x01, +0x1e, 0x4a, 0x60, 0xec, 0x90, 0xff, 0x92, 0xe4, 0xf0, 0x80, 0xef, 0x22, 0x12, 0x0f, 0x89, 0x78, +0x6c, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x30, 0xe0, 0x12, 0x30, 0xe1, 0x0f, 0x90, 0xff, 0xfc, 0xe0, +0x44, 0x20, 0xf0, 0x7f, 0x04, 0x12, 0x11, 0x9f, 0x12, 0x19, 0x55, 0x02, 0x10, 0x0c, 0x8e, 0x65, +0x8f, 0x66, 0xe5, 0x66, 0x15, 0x66, 0xae, 0x65, 0x70, 0x02, 0x15, 0x65, 0xd3, 0x94, 0x00, 0xee, +0x94, 0x00, 0x40, 0x09, 0x7e, 0x07, 0x7f, 0xd0, 0x12, 0x0f, 0x62, 0x80, 0xe5, 0x22, 0x11, 0x1a, +0x2b, 0x1c, 0x23, 0x56, 0x2f, 0x5c, 0x2d, 0xcc, 0x2d, 0x7a, 0x2e, 0x6b, 0x2c, 0x8e, 0x2b, 0x66, +0x2b, 0xec, 0x2c, 0xf1, 0x2e, 0x2d, 0x1b, 0xe6, 0x2b, 0xaf, 0x28, 0x67, 0x0e, 0x12, 0x0f, 0x89, +0x78, 0x8d, 0x12, 0x20, 0x9e, 0x20, 0xe2, 0x07, 0x7f, 0x11, 0x12, 0x2e, 0xa5, 0x80, 0x0a, 0x78, +0x8d, 0xe6, 0xff, 0x12, 0x2c, 0x25, 0x12, 0x2e, 0xa5, 0x02, 0x10, 0x0c, 0x8f, 0x67, 0x12, 0x2c, +0x25, 0xaf, 0x67, 0x12, 0x27, 0x19, 0x12, 0x20, 0x38, 0x12, 0x2f, 0x80, 0x74, 0x74, 0x25, 0x67, +0xf8, 0x74, 0xfd, 0x56, 0xf6, 0xaf, 0x67, 0x12, 0x19, 0xbb, 0x22, 0x12, 0x0f, 0x89, 0xe5, 0x31, +0x64, 0x09, 0x70, 0x04, 0xe5, 0x30, 0x64, 0x01, 0x60, 0x05, 0x12, 0x29, 0x2d, 0x80, 0x06, 0x12, +0x19, 0x7a, 0x12, 0x19, 0x82, 0x02, 0x10, 0x0c, 0x12, 0x27, 0xfb, 0x12, 0x12, 0x3b, 0x90, 0xf8, +0x04, 0xe0, 0xff, 0x60, 0x05, 0x7d, 0x01, 0x12, 0x11, 0xd8, 0x12, 0x26, 0xa3, 0x12, 0x12, 0x77, +0x12, 0x10, 0xfa, 0x80, 0xe3, 0x12, 0x18, 0xed, 0xef, 0x12, 0x14, 0x0d, 0xe4, 0xf5, 0x2a, 0xf5, +0x2b, 0xef, 0x60, 0x03, 0x02, 0x2f, 0x76, 0xe4, 0xff, 0x12, 0x2f, 0x6a, 0x22, 0x90, 0xff, 0xf0, +0xe0, 0xff, 0x54, 0xa0, 0x60, 0xf7, 0xef, 0x30, 0xe5, 0x08, 0x90, 0xff, 0xf0, 0x44, 0x20, 0xf0, +0xc3, 0x22, 0xd3, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0xff, 0x54, 0x28, 0x60, 0xf7, 0xef, 0x30, 0xe5, +0x08, 0x90, 0xff, 0xf0, 0x44, 0x20, 0xf0, 0xc3, 0x22, 0xd3, 0x22, 0xef, 0x30, 0xe7, 0x08, 0x12, +0x18, 0xad, 0xe0, 0x54, 0xdf, 0xf0, 0x22, 0xef, 0x12, 0x18, 0xf7, 0xe0, 0x54, 0xdf, 0xf0, 0x22, +0x81, 0x01, 0x82, 0x02, 0x83, 0x03, 0x87, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, +0x00, 0x40, 0x00, 0x08, 0x00, 0x78, 0x84, 0x12, 0x20, 0x2f, 0xa3, 0xa3, 0xe0, 0xff, 0x30, 0xe7, +0x06, 0x54, 0x7f, 0xf0, 0x44, 0x80, 0xf0, 0x22, 0x85, 0x34, 0x30, 0x85, 0x35, 0x31, 0x90, 0xff, +0x82, 0xe0, 0x54, 0xf7, 0xf0, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0x22, 0xe4, 0xfe, 0xee, 0x90, 0x2f, +0x00, 0x93, 0xb5, 0x07, 0x02, 0xd3, 0x22, 0x0e, 0xbe, 0x07, 0xf2, 0xc3, 0x22, 0x00, 0x08, 0x18, +0x38, 0x28, 0x01, 0x81, 0x10, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0f, 0x89, 0x7f, +0x02, 0x12, 0x10, 0x18, 0x12, 0x19, 0x55, 0x02, 0x10, 0x0c, 0x75, 0x30, 0x00, 0x8f, 0x31, 0x12, +0x18, 0x49, 0x12, 0x29, 0x2d, 0x22, 0x12, 0x19, 0x82, 0x12, 0x19, 0x3e, 0x12, 0x19, 0x7a, 0x22, +0xc2, 0x08, 0x22, +}; + +#undef IMAGE_VERSION_NAME + +#undef IMAGE_ARRAY_NAME + diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c new file mode 100644 index 000000000000..493ab2518435 --- /dev/null +++ b/drivers/usb/serial/io_ti.c @@ -0,0 +1,2684 @@ +/* + * Edgeport USB Serial Converter driver + * + * Copyright(c) 2000-2002 Inside Out Networks, All rights reserved. + * Copyright(c) 2001-2002 Greg Kroah-Hartman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Supports the following devices: + * EP/1 EP/2 EP/4 + * + * Version history: + * + * July 11, 2002 Removed 4 port device structure since all TI UMP + * chips have only 2 ports + * David Iacovelli (davidi@ionetworks.com) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_SERIAL_DEBUG + static int debug = 1; +#else + static int debug; +#endif + +#include "usb-serial.h" + +#include "io_16654.h" +#include "io_usbvend.h" +#include "io_ti.h" + +/* + * Version Information + */ +#define DRIVER_VERSION "v0.2" +#define DRIVER_AUTHOR "Greg Kroah-Hartman and David Iacovelli" +#define DRIVER_DESC "Edgeport USB Serial Driver" + + +/* firmware image code */ +#define IMAGE_VERSION_NAME PagableOperationalCodeImageVersion +#define IMAGE_ARRAY_NAME PagableOperationalCodeImage +#define IMAGE_SIZE PagableOperationalCodeSize +#include "io_fw_down3.h" /* Define array OperationalCodeImage[] */ + +#define EPROM_PAGE_SIZE 64 + + +struct edgeport_uart_buf_desc { + __u32 count; // Number of bytes currently in buffer +}; + +/* different hardware types */ +#define HARDWARE_TYPE_930 0 +#define HARDWARE_TYPE_TIUMP 1 + +// IOCTL_PRIVATE_TI_GET_MODE Definitions +#define TI_MODE_CONFIGURING 0 // Device has not entered start device +#define TI_MODE_BOOT 1 // Staying in boot mode +#define TI_MODE_DOWNLOAD 2 // Made it to download mode +#define TI_MODE_TRANSITIONING 3 // Currently in boot mode but transitioning to download mode + + +/* Product information read from the Edgeport */ +struct product_info +{ + int TiMode; // Current TI Mode + __u8 hardware_type; // Type of hardware +} __attribute__((packed)); + + +struct edgeport_port { + __u16 uart_base; + __u16 dma_address; + __u8 shadow_msr; + __u8 shadow_mcr; + __u8 shadow_lsr; + __u8 lsr_mask; + __u32 ump_read_timeout; /* Number of miliseconds the UMP will + wait without data before completing + a read short */ + int baud_rate; + int close_pending; + int lsr_event; + struct edgeport_uart_buf_desc tx; + struct async_icount icount; + wait_queue_head_t delta_msr_wait; /* for handling sleeping while + waiting for msr change to + happen */ + struct edgeport_serial *edge_serial; + struct usb_serial_port *port; +}; + +struct edgeport_serial { + struct product_info product_info; + u8 TI_I2C_Type; // Type of I2C in UMP + u8 TiReadI2C; // Set to TRUE if we have read the I2c in Boot Mode + int num_ports_open; + struct usb_serial *serial; +}; + + +/* Devices that this driver supports */ +static struct usb_device_id edgeport_1port_id_table [] = { + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) }, + { } +}; + +static struct usb_device_id edgeport_2port_id_table [] = { + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421_BOOT) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421_DOWN) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21_BOOT) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21_DOWN) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_42) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4I) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22) }, + { } +}; + +/* Devices that this driver supports */ +static __devinitdata struct usb_device_id id_table_combined [] = { + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421_BOOT) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421_DOWN) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21_BOOT) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21_DOWN) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_42) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4I) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22) }, + { } +}; + +MODULE_DEVICE_TABLE (usb, id_table_combined); + + +static struct EDGE_FIRMWARE_VERSION_INFO OperationalCodeImageVersion; + +static int TIStayInBootMode = 0; +static int ignore_cpu_rev = 0; + + + +static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios); + +static int TIReadVendorRequestSync (struct usb_device *dev, + __u8 request, + __u16 value, + __u16 index, + u8 *data, + int size) +{ + int status; + + status = usb_control_msg (dev, + usb_rcvctrlpipe(dev, 0), + request, + (USB_TYPE_VENDOR | + USB_RECIP_DEVICE | + USB_DIR_IN), + value, + index, + data, + size, + HZ); + if (status < 0) + return status; + if (status != size) { + dbg ("%s - wanted to write %d, but only wrote %d", + __FUNCTION__, size, status); + return -ECOMM; + } + return 0; +} + +static int TISendVendorRequestSync (struct usb_device *dev, + __u8 request, + __u16 value, + __u16 index, + u8 *data, + int size) +{ + int status; + + status = usb_control_msg (dev, + usb_sndctrlpipe(dev, 0), + request, + (USB_TYPE_VENDOR | + USB_RECIP_DEVICE | + USB_DIR_OUT), + value, + index, + data, + size, + HZ); + + if (status < 0) + return status; + if (status != size) { + dbg ("%s - wanted to write %d, but only wrote %d", + __FUNCTION__, size, status); + return -ECOMM; + } + return 0; +} + +static int TIWriteCommandSync (struct usb_device *dev, __u8 command, + __u8 moduleid, __u16 value, u8 *data, + int size) +{ + return TISendVendorRequestSync (dev, + command, // Request + value, // wValue + moduleid, // wIndex + data, // TransferBuffer + size); // TransferBufferLength + +} + + +/* clear tx/rx buffers and fifo in TI UMP */ +static int TIPurgeDataSync (struct usb_serial_port *port, __u16 mask) +{ + int port_number = port->number - port->serial->minor; + + dbg ("%s - port %d, mask %x", __FUNCTION__, port_number, mask); + + return TIWriteCommandSync (port->serial->dev, + UMPC_PURGE_PORT, + (__u8)(UMPM_UART1_PORT + port_number), + mask, + NULL, + 0); +} + +/** + * TIReadDownloadMemory - Read edgeport memory from TI chip + * @dev: usb device pointer + * @address: Device CPU address at which to read + * @length: Length of above data + * @address_type: Can read both XDATA and I2C + * @buffer: pointer to input data buffer + */ +int TIReadDownloadMemory (struct usb_device *dev, int start_address, int length, + __u8 address_type, __u8 *buffer) +{ + int status = 0; + __u8 read_length; + __u16 be_start_address; + + dbg ("%s - @ %x for %d", __FUNCTION__, start_address, length); + + /* Read in blocks of 64 bytes + * (TI firmware can't handle more than 64 byte reads) + */ + while (length) { + if (length > 64) + read_length= 64; + else + read_length = (__u8)length; + + if (read_length > 1) { + dbg ("%s - @ %x for %d", __FUNCTION__, + start_address, read_length); + } + be_start_address = cpu_to_be16 (start_address); + status = TIReadVendorRequestSync (dev, + UMPC_MEMORY_READ, // Request + (__u16)address_type, // wValue (Address type) + be_start_address, // wIndex (Address to read) + buffer, // TransferBuffer + read_length); // TransferBufferLength + + if (status) { + dbg ("%s - ERROR %x", __FUNCTION__, status); + return status; + } + + if (read_length > 1) { + usb_serial_debug_data (__FILE__, __FUNCTION__, + read_length, buffer); + } + + /* Update pointers/length */ + start_address += read_length; + buffer += read_length; + length -= read_length; + } + + return status; +} + +int TIReadRam (struct usb_device *dev, int start_address, int length, __u8 *buffer) +{ + return TIReadDownloadMemory (dev, + start_address, + length, + DTK_ADDR_SPACE_XDATA, + buffer); +} + +/* Read edgeport memory to a given block */ +static int TIReadBootMemory (struct edgeport_serial *serial, int start_address, int length, __u8 * buffer) +{ + int status = 0; + int i; + + for (i=0; i< length; i++) { + status = TIReadVendorRequestSync (serial->serial->dev, + UMPC_MEMORY_READ, // Request + serial->TI_I2C_Type, // wValue (Address type) + (__u16)(start_address+i), // wIndex + &buffer[i], // TransferBuffer + 0x01); // TransferBufferLength + if (status) { + dbg ("%s - ERROR %x", __FUNCTION__, status); + return status; + } + } + + dbg ("%s - start_address = %x, length = %d", __FUNCTION__, start_address, length); + usb_serial_debug_data (__FILE__, __FUNCTION__, length, buffer); + + serial->TiReadI2C = 1; + + return status; +} + +/* Write given block to TI EPROM memory */ +static int TIWriteBootMemory (struct edgeport_serial *serial, int start_address, int length, __u8 *buffer) +{ + int status = 0; + int i; + __u8 temp; + + /* Must do a read before write */ + if (!serial->TiReadI2C) { + status = TIReadBootMemory(serial, 0, 1, &temp); + if (status) + return status; + } + + for (i=0; i < length; ++i) { + status = TISendVendorRequestSync (serial->serial->dev, + UMPC_MEMORY_WRITE, // Request + buffer[i], // wValue + (__u16)(i+start_address), // wIndex + NULL, // TransferBuffer + 0); // TransferBufferLength + if (status) + return status; + } + + dbg ("%s - start_sddr = %x, length = %d", __FUNCTION__, start_address, length); + usb_serial_debug_data (__FILE__, __FUNCTION__, length, buffer); + + return status; +} + + +/* Write edgeport I2C memory to TI chip */ +static int TIWriteDownloadI2C (struct edgeport_serial *serial, int start_address, int length, __u8 address_type, __u8 *buffer) +{ + int status = 0; + int write_length; + __u16 be_start_address; + + /* We can only send a maximum of 1 aligned byte page at a time */ + + /* calulate the number of bytes left in the first page */ + write_length = EPROM_PAGE_SIZE - (start_address & (EPROM_PAGE_SIZE - 1)); + + if (write_length > length) + write_length = length; + + dbg ("%s - BytesInFirstPage Addr = %x, length = %d", __FUNCTION__, start_address, write_length); + usb_serial_debug_data (__FILE__, __FUNCTION__, write_length, buffer); + + /* Write first page */ + be_start_address = cpu_to_be16 (start_address); + status = TISendVendorRequestSync (serial->serial->dev, + UMPC_MEMORY_WRITE, // Request + (__u16)address_type, // wValue + be_start_address, // wIndex + buffer, // TransferBuffer + write_length); + if (status) { + dbg ("%s - ERROR %d", __FUNCTION__, status); + return status; + } + + length -= write_length; + start_address += write_length; + buffer += write_length; + + /* We should be aligned now -- can write max page size bytes at a time */ + while (length) { + if (length > EPROM_PAGE_SIZE) + write_length = EPROM_PAGE_SIZE; + else + write_length = length; + + dbg ("%s - Page Write Addr = %x, length = %d", __FUNCTION__, start_address, write_length); + usb_serial_debug_data (__FILE__, __FUNCTION__, write_length, buffer); + + /* Write next page */ + be_start_address = cpu_to_be16 (start_address); + status = TISendVendorRequestSync (serial->serial->dev, + UMPC_MEMORY_WRITE, // Request + (__u16)address_type, // wValue + be_start_address, // wIndex + buffer, // TransferBuffer + write_length); // TransferBufferLength + if (status) { + dbg ("%s - ERROR %d", __FUNCTION__, status); + return status; + } + + length -= write_length; + start_address += write_length; + buffer += write_length; + } + return status; +} + +/* Examine the UMP DMA registers and LSR + * + * Check the MSBit of the X and Y DMA byte count registers. + * A zero in this bit indicates that the TX DMA buffers are empty + * then check the TX Empty bit in the UART. + */ +static int TIIsTxActive (struct edgeport_port *port) +{ + int status; + struct out_endpoint_desc_block *oedb; + __u8 lsr; + int bytes_left = 0; + + oedb = kmalloc (sizeof (* oedb), GFP_KERNEL); + if (!oedb) { + err ("%s - out of memory", __FUNCTION__); + return -ENOMEM; + } + + /* Read the DMA Count Registers */ + status = TIReadRam (port->port->serial->dev, + port->dma_address, + sizeof( *oedb), + (void *)oedb); + + if (status) + goto exit_is_tx_active; + + dbg ("%s - XByteCount 0x%X", __FUNCTION__, oedb->XByteCount); + + /* and the LSR */ + status = TIReadRam (port->port->serial->dev, + port->uart_base + UMPMEM_OFFS_UART_LSR, + 1, + &lsr); + + if (status) + goto exit_is_tx_active; + dbg ("%s - LSR = 0x%X", __FUNCTION__, lsr); + + /* If either buffer has data or we are transmitting then return TRUE */ + if ((oedb->XByteCount & 0x80 ) != 0 ) + bytes_left += 64; + + if ((lsr & UMP_UART_LSR_TX_MASK ) == 0 ) + bytes_left += 1; + + /* We return Not Active if we get any kind of error */ +exit_is_tx_active: + dbg ("%s - return %d", __FUNCTION__, bytes_left ); + return bytes_left; +} + +static void TIChasePort(struct edgeport_port *port) +{ + int loops; + int last_count; + int write_size; + +restart_tx_loop: + // Base the LoopTime on the baud rate + if (port->baud_rate == 0) + port->baud_rate = 1200; + + write_size = port->tx.count; + loops = max(100, (100*write_size)/(port->baud_rate/10)); + dbg ("%s - write_size %d, baud %d loop = %d", __FUNCTION__, + write_size, port->baud_rate, loops); + + while (1) { + // Save Last count + last_count = port->tx.count; + + dbg ("%s - Tx Buffer Size = %d loops = %d", __FUNCTION__, + last_count, loops); + + /* Is the Edgeport Buffer empty? */ + if (port->tx.count == 0) + break; + + /* Block the thread for 10ms */ + wait_ms (10); + + if (last_count == port->tx.count) { + /* No activity.. count down. */ + --loops; + if (loops == 0) { + dbg ("%s - Wait for TxEmpty - TIMEOUT", + __FUNCTION__); + return; + } + } else { + /* Reset timeout value back to a minimum of 1 second */ + dbg ("%s - Wait for TxEmpty Reset Count", __FUNCTION__); + goto restart_tx_loop; + } + } + + dbg ("%s - Local Tx Buffer Empty -- Waiting for TI UMP to EMPTY X/Y and FIFO", + __FUNCTION__); + + write_size = TIIsTxActive (port); + loops = max(50, (100*write_size)/(port->baud_rate/10)); + dbg ("%s - write_size %d, baud %d loop = %d", __FUNCTION__, + write_size, port->baud_rate, loops); + + while (1) { + /* This function takes 4 ms; */ + if (!TIIsTxActive (port)) { + /* Delay a few char times */ + wait_ms (50); + dbg ("%s - Empty", __FUNCTION__); + return; + } + + --loops; + if (loops == 0) { + dbg ("%s - TIMEOUT", __FUNCTION__); + return; + } + } +} + +static int TIChooseConfiguration (struct usb_device *dev) +{ + // There may be multiple configurations on this device, in which case + // we would need to read and parse all of them to find out which one + // we want. However, we just support one config at this point, + // configuration # 1, which is Config Descriptor 0. + + dbg ("%s - Number of Interfaces = %d", __FUNCTION__, dev->config->bNumInterfaces); + dbg ("%s - MAX Power = %d", __FUNCTION__, dev->config->MaxPower*2); + + if (dev->config->bNumInterfaces != 1) { + err ("%s - bNumInterfaces is not 1, ERROR!", __FUNCTION__); + return -ENODEV; + } + + return 0; +} + +int TIReadRom (struct edgeport_serial *serial, int start_address, int length, __u8 *buffer) +{ + int status; + + if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) { + status = TIReadDownloadMemory (serial->serial->dev, + start_address, + length, + serial->TI_I2C_Type, + buffer); + } else { + status = TIReadBootMemory (serial, + start_address, + length, + buffer); + } + + return status; +} + +int TIWriteRom (struct edgeport_serial *serial, int start_address, int length, __u8 *buffer) +{ + if (serial->product_info.TiMode == TI_MODE_BOOT) + return TIWriteBootMemory (serial, + start_address, + length, + buffer); + + if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) + return TIWriteDownloadI2C (serial, + start_address, + length, + serial->TI_I2C_Type, + buffer); + + return -EINVAL; +} + + + +/* Read a descriptor header from I2C based on type */ +static int TIGetDescriptorAddress (struct edgeport_serial *serial, int desc_type, struct ti_i2c_desc *rom_desc) +{ + int start_address; + int status; + + /* Search for requested descriptor in I2C */ + start_address = 2; + do { + status = TIReadRom (serial, + start_address, + sizeof(struct ti_i2c_desc), + (__u8 *)rom_desc ); + if (status) + return 0; + + if (rom_desc->Type == desc_type) + return start_address; + + start_address = start_address + sizeof(struct ti_i2c_desc) + rom_desc->Size; + + } while ((start_address < TI_MAX_I2C_SIZE) && rom_desc->Type); + + return 0; +} + +/* Validate descriptor checksum */ +static int ValidChecksum(struct ti_i2c_desc *rom_desc, __u8 *buffer) +{ + __u16 i; + __u8 cs = 0; + + for (i=0; i < rom_desc->Size; i++) { + cs = (__u8)(cs + buffer[i]); + } + if (cs != rom_desc->CheckSum) { + dbg ("%s - Mismatch %x - %x", __FUNCTION__, rom_desc->CheckSum, cs); + return -EINVAL; + } + return 0; +} + +/* Make sure that the I2C image is good */ +static int TiValidateI2cImage (struct edgeport_serial *serial) +{ + int status = 0; + struct ti_i2c_desc *rom_desc; + int start_address = 2; + __u8 *buffer; + + rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL); + if (!rom_desc) { + err ("%s - out of memory", __FUNCTION__); + return -ENOMEM; + } + buffer = kmalloc (TI_MAX_I2C_SIZE, GFP_KERNEL); + if (!buffer) { + err ("%s - out of memory when allocating buffer", __FUNCTION__); + kfree (rom_desc); + return -ENOMEM; + } + + // Read the first byte (Signature0) must be 0x52 + status = TIReadRom (serial, 0, 1, buffer); + if (status) + goto ExitTiValidateI2cImage; + + if (*buffer != 0x52) { + err ("%s - invalid buffer signature", __FUNCTION__); + status = -ENODEV; + goto ExitTiValidateI2cImage; + } + + do { + // Validate the I2C + status = TIReadRom (serial, + start_address, + sizeof(struct ti_i2c_desc), + (__u8 *)rom_desc); + if (status) + break; + + if ((start_address + sizeof(struct ti_i2c_desc) + rom_desc->Size) > TI_MAX_I2C_SIZE) { + status = -ENODEV; + dbg ("%s - structure too big, erroring out.", __FUNCTION__); + break; + } + + dbg ("%s Type = 0x%x", __FUNCTION__, rom_desc->Type); + + // Skip type 2 record + if ((rom_desc->Type & 0x0f) != I2C_DESC_TYPE_FIRMWARE_BASIC) { + // Read the descriptor data + status = TIReadRom(serial, + start_address+sizeof(struct ti_i2c_desc), + rom_desc->Size, + buffer); + if (status) + break; + + status = ValidChecksum(rom_desc, buffer); + if (status) + break; + } + start_address = start_address + sizeof(struct ti_i2c_desc) + rom_desc->Size; + + } while ((rom_desc->Type != I2C_DESC_TYPE_ION) && (start_address < TI_MAX_I2C_SIZE)); + + if ((rom_desc->Type != I2C_DESC_TYPE_ION) || (start_address > TI_MAX_I2C_SIZE)) + status = -ENODEV; + +ExitTiValidateI2cImage: + kfree (buffer); + kfree (rom_desc); + return status; +} + +static int TIReadManufDescriptor (struct edgeport_serial *serial, __u8 *buffer) +{ + int status; + int start_address; + struct ti_i2c_desc *rom_desc; + struct edge_ti_manuf_descriptor *desc; + + rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL); + if (!rom_desc) { + err ("%s - out of memory", __FUNCTION__); + return -ENOMEM; + } + start_address = TIGetDescriptorAddress (serial, I2C_DESC_TYPE_ION, rom_desc); + + if (!start_address) { + dbg ("%s - Edge Descriptor not found in I2C", __FUNCTION__); + status = -ENODEV; + goto exit; + } + + // Read the descriptor data + status = TIReadRom (serial, + start_address+sizeof(struct ti_i2c_desc), + rom_desc->Size, + buffer); + if (status) + goto exit; + + status = ValidChecksum(rom_desc, buffer); + + desc = (struct edge_ti_manuf_descriptor *)buffer; + dbg ( "%s - IonConfig 0x%x", __FUNCTION__, desc->IonConfig ); + dbg ( "%s - Version %d", __FUNCTION__, desc->Version ); + dbg ( "%s - Cpu/Board 0x%x", __FUNCTION__, desc->CpuRev_BoardRev ); + dbg ( "%s - NumPorts %d", __FUNCTION__, desc->NumPorts ); + dbg ( "%s - NumVirtualPorts %d", __FUNCTION__, desc->NumVirtualPorts ); + dbg ( "%s - TotalPorts %d", __FUNCTION__, desc->TotalPorts ); + +exit: + kfree (rom_desc); + return status; +} + +/* Build firmware header used for firmware update */ +static int BuildI2CFirmwareHeader (__u8 *header) +{ + __u8 *buffer; + int buffer_size; + int i; + __u8 cs = 0; + struct ti_i2c_desc *i2c_header; + struct ti_i2c_image_header *img_header; + struct ti_i2c_firmware_rec *firmware_rec; + + // In order to update the I2C firmware we must change the type 2 record to type 0xF2. + // This will force the UMP to come up in Boot Mode. Then while in boot mode, the driver + // will download the latest firmware (padded to 15.5k) into the UMP ram. + // And finally when the device comes back up in download mode the driver will cause + // the new firmware to be copied from the UMP Ram to I2C and the firmware will update + // the record type from 0xf2 to 0x02. + + // Allocate a 15.5k buffer + 2 bytes for version number (Firmware Record) + buffer_size = (((1024 * 16) - 512 )+ sizeof(struct ti_i2c_firmware_rec)); + + buffer = kmalloc (buffer_size, GFP_KERNEL); + if (!buffer) { + err ("%s - out of memory", __FUNCTION__); + return -ENOMEM; + } + + // Set entire image of 0xffs + memset (buffer, 0xff, buffer_size); + + // Copy version number into firmware record + firmware_rec = (struct ti_i2c_firmware_rec *)buffer; + + firmware_rec->Ver_Major = OperationalCodeImageVersion.MajorVersion; + firmware_rec->Ver_Minor = OperationalCodeImageVersion.MinorVersion; + + // Pointer to fw_down memory image + img_header = (struct ti_i2c_image_header *)&PagableOperationalCodeImage[0]; + + memcpy (buffer + sizeof(struct ti_i2c_firmware_rec), + &PagableOperationalCodeImage[sizeof(struct ti_i2c_image_header)], + img_header->Length); + + for (i=0; i < buffer_size; i++) { + cs = (__u8)(cs + buffer[i]); + } + + kfree (buffer); + + // Build new header + i2c_header = (struct ti_i2c_desc *)header; + firmware_rec = (struct ti_i2c_firmware_rec*)i2c_header->Data; + + i2c_header->Type = I2C_DESC_TYPE_FIRMWARE_BLANK; + i2c_header->Size = (__u16)buffer_size; + i2c_header->CheckSum = cs; + firmware_rec->Ver_Major = OperationalCodeImageVersion.MajorVersion; + firmware_rec->Ver_Minor = OperationalCodeImageVersion.MinorVersion; + + return 0; +} + +/* Try to figure out what type of I2c we have */ +static int TIGetI2cTypeInBootMode (struct edgeport_serial *serial) +{ + int status; + __u8 data; + + // Try to read type 2 + status = TIReadVendorRequestSync (serial->serial->dev, + UMPC_MEMORY_READ, // Request + DTK_ADDR_SPACE_I2C_TYPE_II, // wValue (Address type) + 0, // wIndex + &data, // TransferBuffer + 0x01); // TransferBufferLength + if (status) + dbg ("%s - read 2 status error = %d", __FUNCTION__, status); + else + dbg ("%s - read 2 data = 0x%x", __FUNCTION__, data); + if ((!status) && data == 0x52) { + dbg ("%s - ROM_TYPE_II", __FUNCTION__); + serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; + return 0; + } + + // Try to read type 3 + status = TIReadVendorRequestSync (serial->serial->dev, + UMPC_MEMORY_READ, // Request + DTK_ADDR_SPACE_I2C_TYPE_III, // wValue (Address type) + 0, // wIndex + &data, // TransferBuffer + 0x01); // TransferBufferLength + if (status) + dbg ("%s - read 3 status error = %d", __FUNCTION__, status); + else + dbg ("%s - read 2 data = 0x%x", __FUNCTION__, data); + if ((!status) && data == 0x52) { + dbg ("%s - ROM_TYPE_III", __FUNCTION__); + serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_III; + return 0; + } + + dbg ("%s - Unknown", __FUNCTION__); + serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; + return -ENODEV; +} + +static int TISendBulkTransferSync (struct usb_serial *serial, void *buffer, int length, int *num_sent) +{ + int status; + + status = usb_bulk_msg (serial->dev, + usb_sndbulkpipe(serial->dev, + serial->port[0].bulk_out_endpointAddress), + buffer, + length, + num_sent, + HZ); + return status; +} + +/* Download given firmware image to the device (IN BOOT MODE) */ +static int TIDownloadCodeImage (struct edgeport_serial *serial, __u8 *image, int image_length) +{ + int status = 0; + int pos; + int transfer; + int done; + + // Transfer firmware image + for (pos = 0; pos < image_length; ) { + // Read the next buffer from file + transfer = image_length - pos; + if (transfer > EDGE_FW_BULK_MAX_PACKET_SIZE) + transfer = EDGE_FW_BULK_MAX_PACKET_SIZE; + + // Transfer data + status = TISendBulkTransferSync (serial->serial, &image[pos], transfer, &done); + if (status) + break; + // Advance buffer pointer + pos += done; + } + + return status; +} + +// FIXME!!! +static int TIConfigureBootDevice (struct usb_device *dev) +{ + return 0; +} + +/** + * DownloadTIFirmware - Download run-time operating firmware to the TI5052 + * + * This routine downloads the main operating code into the TI5052, using the + * boot code already burned into E2PROM or ROM. + */ +static int TIDownloadFirmware (struct edgeport_serial *serial) +{ + int status = 0; + int start_address; + struct edge_ti_manuf_descriptor *ti_manuf_desc; + struct usb_interface_descriptor *interface; + int download_cur_ver; + int download_new_ver; + + /* This routine is entered by both the BOOT mode and the Download mode + * We can determine which code is running by the reading the config + * descriptor and if we have only one bulk pipe it is in boot mode + */ + serial->product_info.hardware_type = HARDWARE_TYPE_TIUMP; + + /* Default to type 2 i2c */ + serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; + + status = TIChooseConfiguration (serial->serial->dev); + if (status) + return status; + + interface = serial->serial->dev->config->interface->altsetting; + if (!interface) { + err ("%s - no interface set, error!", __FUNCTION__); + return -ENODEV; + } + + // Setup initial mode -- the default mode 0 is TI_MODE_CONFIGURING + // if we have more than one endpoint we are definitely in download mode + if (interface->bNumEndpoints > 1) + serial->product_info.TiMode = TI_MODE_DOWNLOAD; + else + // Otherwise we will remain in configuring mode + serial->product_info.TiMode = TI_MODE_CONFIGURING; + + // Save Download Version Number + OperationalCodeImageVersion.MajorVersion = PagableOperationalCodeImageVersion.MajorVersion; + OperationalCodeImageVersion.MinorVersion = PagableOperationalCodeImageVersion.MinorVersion; + OperationalCodeImageVersion.BuildNumber = PagableOperationalCodeImageVersion.BuildNumber; + + /********************************************************************/ + /* Download Mode */ + /********************************************************************/ + if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) { + struct ti_i2c_desc *rom_desc; + + dbg ("%s - <<<<<<<<<<<<<<>>>>>>>>>", __FUNCTION__); + + status = TiValidateI2cImage (serial); + if (status) { + dbg ("%s - <<<<<<<<<<<<<<>>>>>>>>>", + __FUNCTION__); + return status; + } + + /* Validate Hardware version number + * Read Manufacturing Descriptor from TI Based Edgeport + */ + ti_manuf_desc = kmalloc (sizeof (*ti_manuf_desc), GFP_KERNEL); + if (!ti_manuf_desc) { + err ("%s - out of memory.", __FUNCTION__); + return -ENOMEM; + } + status = TIReadManufDescriptor (serial, (__u8 *)ti_manuf_desc); + if (status) { + kfree (ti_manuf_desc); + return status; + } + + // Check version number of ION descriptor + if (!ignore_cpu_rev && TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev) < 2) { + dbg ( "%s - Wrong CPU Rev %d (Must be 2)", __FUNCTION__, + TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev)); + kfree (ti_manuf_desc); + return -EINVAL; + } + + rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL); + if (!rom_desc) { + err ("%s - out of memory.", __FUNCTION__); + kfree (ti_manuf_desc); + return -ENOMEM; + } + + // Search for type 2 record (firmware record) + if ((start_address = TIGetDescriptorAddress (serial, I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc)) != 0) { + struct ti_i2c_firmware_rec *firmware_version; + __u8 record; + + dbg ("%s - Found Type FIRMWARE (Type 2) record", __FUNCTION__); + + firmware_version = kmalloc (sizeof (*firmware_version), GFP_KERNEL); + if (!firmware_version) { + err ("%s - out of memory.", __FUNCTION__); + kfree (rom_desc); + kfree (ti_manuf_desc); + return -ENOMEM; + } + + // Validate version number + // Read the descriptor data + status = TIReadRom (serial, + start_address+sizeof(struct ti_i2c_desc), + sizeof(struct ti_i2c_firmware_rec), + (__u8 *)firmware_version); + if (status) { + kfree (firmware_version); + kfree (rom_desc); + kfree (ti_manuf_desc); + return status; + } + + // Check version number of download with current version in I2c + download_cur_ver = (firmware_version->Ver_Major << 8) + + (firmware_version->Ver_Minor); + download_new_ver = (OperationalCodeImageVersion.MajorVersion << 8) + + (OperationalCodeImageVersion.MinorVersion); + + dbg ("%s - >>>Firmware Versions Device %d.%d Driver %d.%d", + __FUNCTION__, + firmware_version->Ver_Major, + firmware_version->Ver_Minor, + OperationalCodeImageVersion.MajorVersion, + OperationalCodeImageVersion.MinorVersion); + + // Check if we have an old version in the I2C and update if necessary + if (download_cur_ver != download_new_ver) { + dbg ("%s - Update I2C Download from %d.%d to %d.%d", + __FUNCTION__, + firmware_version->Ver_Major, + firmware_version->Ver_Minor, + OperationalCodeImageVersion.MajorVersion, + OperationalCodeImageVersion.MinorVersion); + + // In order to update the I2C firmware we must change the type 2 record to type 0xF2. + // This will force the UMP to come up in Boot Mode. Then while in boot mode, the driver + // will download the latest firmware (padded to 15.5k) into the UMP ram. + // And finally when the device comes back up in download mode the driver will cause + // the new firmware to be copied from the UMP Ram to I2C and the firmware will update + // the record type from 0xf2 to 0x02. + + record = I2C_DESC_TYPE_FIRMWARE_BLANK; + + // Change the I2C Firmware record type to 0xf2 to trigger an update + status = TIWriteRom (serial, + start_address, + sizeof(record), + &record); + if (status) { + kfree (firmware_version); + kfree (rom_desc); + kfree (ti_manuf_desc); + return status; + } + + // verify the write -- must do this in order for write to + // complete before we do the hardware reset + status = TIReadRom (serial, + start_address, + sizeof(record), + &record); + + if (status) { + kfree (firmware_version); + kfree (rom_desc); + kfree (ti_manuf_desc); + return status; + } + + if (record != I2C_DESC_TYPE_FIRMWARE_BLANK) { + err ("%s - error resetting device", __FUNCTION__); + kfree (firmware_version); + kfree (rom_desc); + kfree (ti_manuf_desc); + return -ENODEV; + } + + dbg ("%s - HARDWARE RESET", __FUNCTION__); + + // Reset UMP -- Back to BOOT MODE + status = TISendVendorRequestSync (serial->serial->dev, + UMPC_HARDWARE_RESET, // Request + 0, // wValue + 0, // wIndex + NULL, // TransferBuffer + 0); // TransferBufferLength + + dbg ( "%s - HARDWARE RESET return %d", __FUNCTION__, status); + + /* return an error on purpose. */ + return -ENODEV; + } + } + // Search for type 0xF2 record (firmware blank record) + else if ((start_address = TIGetDescriptorAddress (serial, I2C_DESC_TYPE_FIRMWARE_BLANK, rom_desc)) != 0) { + #define HEADER_SIZE (sizeof(struct ti_i2c_desc) + sizeof(struct ti_i2c_firmware_rec)) + __u8 *header; + __u8 *vheader; + + header = kmalloc (HEADER_SIZE, GFP_KERNEL); + if (!header) { + err ("%s - out of memory.", __FUNCTION__); + kfree (rom_desc); + kfree (ti_manuf_desc); + return -ENOMEM; + } + + vheader = kmalloc (HEADER_SIZE, GFP_KERNEL); + if (!vheader) { + err ("%s - out of memory.", __FUNCTION__); + kfree (header); + kfree (rom_desc); + kfree (ti_manuf_desc); + return -ENOMEM; + } + + dbg ("%s - Found Type BLANK FIRMWARE (Type F2) record", __FUNCTION__); + + // In order to update the I2C firmware we must change the type 2 record to type 0xF2. + // This will force the UMP to come up in Boot Mode. Then while in boot mode, the driver + // will download the latest firmware (padded to 15.5k) into the UMP ram. + // And finally when the device comes back up in download mode the driver will cause + // the new firmware to be copied from the UMP Ram to I2C and the firmware will update + // the record type from 0xf2 to 0x02. + status = BuildI2CFirmwareHeader(header); + if (status) { + kfree (vheader); + kfree (header); + kfree (rom_desc); + kfree (ti_manuf_desc); + return status; + } + + // Update I2C with type 0xf2 record with correct size and checksum + status = TIWriteRom (serial, + start_address, + HEADER_SIZE, + header); + if (status) { + kfree (vheader); + kfree (header); + kfree (rom_desc); + kfree (ti_manuf_desc); + return status; + } + + // verify the write -- must do this in order for write to + // complete before we do the hardware reset + status = TIReadRom (serial, + start_address, + HEADER_SIZE, + vheader); + + if (status) { + dbg ("%s - can't read header back", __FUNCTION__); + kfree (vheader); + kfree (header); + kfree (rom_desc); + kfree (ti_manuf_desc); + return status; + } + if (memcmp(vheader, header, HEADER_SIZE)) { + dbg ("%s - write download record failed", __FUNCTION__); + kfree (vheader); + kfree (header); + kfree (rom_desc); + kfree (ti_manuf_desc); + return status; + } + + kfree (vheader); + kfree (header); + + dbg ("%s - Start firmware update", __FUNCTION__); + + // Tell firmware to copy download image into I2C + status = TISendVendorRequestSync (serial->serial->dev, + UMPC_COPY_DNLD_TO_I2C, // Request + 0, // wValue + 0, // wIndex + NULL, // TransferBuffer + 0); // TransferBufferLength + + dbg ("%s - Update complete 0x%x", __FUNCTION__, status); + if (status) { + dbg ("%s - UMPC_COPY_DNLD_TO_I2C failed", __FUNCTION__); + kfree (rom_desc); + kfree (ti_manuf_desc); + return status; + } + } + + // The device is running the download code + kfree (rom_desc); + kfree (ti_manuf_desc); + return 0; + } + + /********************************************************************/ + /* Boot Mode */ + /********************************************************************/ + dbg ("%s - <<<<<<<<<<<<<<>>>>>>>>>>>>>>", + __FUNCTION__); + + // Configure the TI device so we can use the BULK pipes for download + status = TIConfigureBootDevice (serial->serial->dev); + if (status) + return status; + + if (serial->serial->dev->descriptor.idVendor != USB_VENDOR_ID_ION) { + dbg ("%s - VID = 0x%x", __FUNCTION__, + serial->serial->dev->descriptor.idVendor); + serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; + goto StayInBootMode; + } + + // We have an ION device (I2c Must be programmed) + // Determine I2C image type + if (TIGetI2cTypeInBootMode(serial)) { + goto StayInBootMode; + } + + // Registry variable set? + if (TIStayInBootMode) { + dbg ("%s - TIStayInBootMode", __FUNCTION__); + goto StayInBootMode; + } + + // Check for ION Vendor ID and that the I2C is valid + if (!TiValidateI2cImage(serial)) { + struct ti_i2c_image_header *header; + int i; + __u8 cs = 0; + __u8 *buffer; + int buffer_size; + + /* Validate Hardware version number + * Read Manufacturing Descriptor from TI Based Edgeport + */ + ti_manuf_desc = kmalloc (sizeof (*ti_manuf_desc), GFP_KERNEL); + if (!ti_manuf_desc) { + err ("%s - out of memory.", __FUNCTION__); + return -ENOMEM; + } + status = TIReadManufDescriptor (serial, (__u8 *)ti_manuf_desc); + if (status) { + kfree (ti_manuf_desc); + goto StayInBootMode; + } + + // Check for version 2 + if (!ignore_cpu_rev && TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev) < 2) { + dbg ("%s - Wrong CPU Rev %d (Must be 2)", __FUNCTION__, + TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev)); + kfree (ti_manuf_desc); + goto StayInBootMode; + } + + kfree (ti_manuf_desc); + + // In order to update the I2C firmware we must change the type 2 record to type 0xF2. + // This will force the UMP to come up in Boot Mode. Then while in boot mode, the driver + // will download the latest firmware (padded to 15.5k) into the UMP ram. + // And finally when the device comes back up in download mode the driver will cause + // the new firmware to be copied from the UMP Ram to I2C and the firmware will update + // the record type from 0xf2 to 0x02. + + /* + * Do we really have to copy the whole firmware image, + * or could we do this in place! + */ + + // Allocate a 15.5k buffer + 3 byte header + buffer_size = (((1024 * 16) - 512) + sizeof(struct ti_i2c_image_header)); + buffer = kmalloc (buffer_size, GFP_KERNEL); + if (!buffer) { + err ("%s - out of memory", __FUNCTION__); + return -ENOMEM; + } + + // Initialize the buffer to 0xff (pad the buffer) + memset (buffer, 0xff, buffer_size); + + memcpy (buffer, &PagableOperationalCodeImage[0], PagableOperationalCodeSize); + + for(i = sizeof(struct ti_i2c_image_header); i < buffer_size; i++) { + cs = (__u8)(cs + buffer[i]); + } + + header = (struct ti_i2c_image_header *)buffer; + + // update length and checksum after padding + header->Length = (__u16)(buffer_size - sizeof(struct ti_i2c_image_header)); + header->CheckSum = cs; + + // Download the operational code + dbg ("%s - Downloading operational code image (TI UMP)", __FUNCTION__); + status = TIDownloadCodeImage (serial, buffer, buffer_size); + + kfree (buffer); + + if (status) { + dbg ("%s - Error downloading operational code image", __FUNCTION__); + return status; + } + + // Device will reboot + serial->product_info.TiMode = TI_MODE_TRANSITIONING; + + dbg ("%s - Download successful -- Device rebooting...", __FUNCTION__); + + /* return an error on purpose */ + return -ENODEV; + } + +StayInBootMode: + // Eprom is invalid or blank stay in boot mode + dbg ("%s - <<<<<<<<<<<<<<>>>>>>>>>>>", __FUNCTION__); + serial->product_info.TiMode = TI_MODE_BOOT; + + return 0; +} + + +static int TISetDtr (struct edgeport_port *port) +{ + int port_number = port->port->number - port->port->serial->minor; + + dbg ("%s", __FUNCTION__); + port->shadow_mcr |= MCR_DTR; + + return TIWriteCommandSync (port->port->serial->dev, + UMPC_SET_CLR_DTR, + (__u8)(UMPM_UART1_PORT + port_number), + 1, /* set */ + NULL, + 0); +} + +static int TIClearDtr (struct edgeport_port *port) +{ + int port_number = port->port->number - port->port->serial->minor; + + dbg ("%s", __FUNCTION__); + port->shadow_mcr &= ~MCR_DTR; + + return TIWriteCommandSync (port->port->serial->dev, + UMPC_SET_CLR_DTR, + (__u8)(UMPM_UART1_PORT + port_number), + 0, /* clear */ + NULL, + 0); +} + +static int TISetRts (struct edgeport_port *port) +{ + int port_number = port->port->number - port->port->serial->minor; + + dbg ("%s", __FUNCTION__); + port->shadow_mcr |= MCR_RTS; + + return TIWriteCommandSync (port->port->serial->dev, + UMPC_SET_CLR_RTS, + (__u8)(UMPM_UART1_PORT + port_number), + 1, /* set */ + NULL, + 0); +} + +static int TIClearRts (struct edgeport_port *port) +{ + int port_number = port->port->number - port->port->serial->minor; + + dbg ("%s", __FUNCTION__); + port->shadow_mcr &= ~MCR_RTS; + + return TIWriteCommandSync (port->port->serial->dev, + UMPC_SET_CLR_RTS, + (__u8)(UMPM_UART1_PORT + port_number), + 0, /* clear */ + NULL, + 0); +} + +static int TISetLoopBack (struct edgeport_port *port) +{ + int port_number = port->port->number - port->port->serial->minor; + + dbg ("%s", __FUNCTION__); + + return TIWriteCommandSync (port->port->serial->dev, + UMPC_SET_CLR_LOOPBACK, + (__u8)(UMPM_UART1_PORT + port_number), + 1, /* set */ + NULL, + 0); +} + +static int TIClearLoopBack (struct edgeport_port *port) +{ + int port_number = port->port->number - port->port->serial->minor; + + dbg ("%s", __FUNCTION__); + + return TIWriteCommandSync (port->port->serial->dev, + UMPC_SET_CLR_LOOPBACK, + (__u8)(UMPM_UART1_PORT + port_number), + 0, /* clear */ + NULL, + 0); +} + +static int TISetBreak (struct edgeport_port *port) +{ + int port_number = port->port->number - port->port->serial->minor; + + dbg ("%s", __FUNCTION__); + + return TIWriteCommandSync (port->port->serial->dev, + UMPC_SET_CLR_BREAK, + (__u8)(UMPM_UART1_PORT + port_number), + 1, /* set */ + NULL, + 0); +} + +static int TIClearBreak (struct edgeport_port *port) +{ + int port_number = port->port->number - port->port->serial->minor; + + dbg ("%s", __FUNCTION__); + + return TIWriteCommandSync (port->port->serial->dev, + UMPC_SET_CLR_BREAK, + (__u8)(UMPM_UART1_PORT + port_number), + 0, /* clear */ + NULL, + 0); +} + +static int TIRestoreMCR (struct edgeport_port *port, __u8 mcr) +{ + int status = 0; + + dbg ("%s - %x", __FUNCTION__, mcr); + + if (mcr & MCR_DTR) + status = TISetDtr (port); + else + status = TIClearDtr (port); + + if (status) + return status; + + if (mcr & MCR_RTS) + status = TISetRts (port); + else + status = TIClearRts (port); + + if (status) + return status; + + if (mcr & MCR_LOOPBACK) + status = TISetLoopBack (port); + else + status = TIClearLoopBack (port); + + return status; +} + + + +/* Convert TI LSR to standard UART flags */ +static __u8 MapLineStatus (__u8 ti_lsr) +{ + __u8 lsr = 0; + +#define MAP_FLAG(flagUmp, flagUart) \ + if (ti_lsr & flagUmp) lsr |= flagUart; + + MAP_FLAG(UMP_UART_LSR_OV_MASK, LSR_OVER_ERR) /* overrun */ + MAP_FLAG(UMP_UART_LSR_PE_MASK, LSR_PAR_ERR) /* parity error */ + MAP_FLAG(UMP_UART_LSR_FE_MASK, LSR_FRM_ERR) /* framing error */ + MAP_FLAG(UMP_UART_LSR_BR_MASK, LSR_BREAK) /* break detected */ + MAP_FLAG(UMP_UART_LSR_RX_MASK, LSR_RX_AVAIL) /* receive data available */ + MAP_FLAG(UMP_UART_LSR_TX_MASK, LSR_TX_EMPTY) /* transmit holding register empty */ + +#undef MAP_FLAG + + return lsr; +} + +static void handle_new_msr (struct edgeport_port *edge_port, __u8 msr) +{ + struct async_icount *icount; + + dbg ("%s - %02x", __FUNCTION__, msr); + + if (msr & (MSR_DELTA_CTS | MSR_DELTA_DSR | MSR_DELTA_RI | MSR_DELTA_CD)) { + icount = &edge_port->icount; + + /* update input line counters */ + if (msr & MSR_DELTA_CTS) + icount->cts++; + if (msr & MSR_DELTA_DSR) + icount->dsr++; + if (msr & MSR_DELTA_CD) + icount->dcd++; + if (msr & MSR_DELTA_RI) + icount->rng++; + wake_up_interruptible (&edge_port->delta_msr_wait); + } + + /* Save the new modem status */ + edge_port->shadow_msr = msr & 0xf0; + + return; +} + +static void handle_new_lsr (struct edgeport_port *edge_port, int lsr_data, __u8 lsr, __u8 data) +{ + struct async_icount *icount; + __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK)); + + dbg ("%s - %02x", __FUNCTION__, new_lsr); + + edge_port->shadow_lsr = lsr; + + if (new_lsr & LSR_BREAK) { + /* + * Parity and Framing errors only count if they + * occur exclusive of a break being received. + */ + new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK); + } + + /* Place LSR data byte into Rx buffer */ + if (lsr_data && edge_port->port->tty) { + tty_insert_flip_char(edge_port->port->tty, data, 0); + tty_flip_buffer_push(edge_port->port->tty); + } + + /* update input line counters */ + icount = &edge_port->icount; + if (new_lsr & LSR_BREAK) + icount->brk++; + if (new_lsr & LSR_OVER_ERR) + icount->overrun++; + if (new_lsr & LSR_PAR_ERR) + icount->parity++; + if (new_lsr & LSR_FRM_ERR) + icount->frame++; +} + + +static void edge_interrupt_callback (struct urb *urb) +{ + struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context; + struct usb_serial_port *port; + struct edgeport_port *edge_port; + unsigned char *data = urb->transfer_buffer; + int length = urb->actual_length; + int port_number; + int function; + __u8 lsr; + __u8 msr; + + dbg("%s", __FUNCTION__); + + if (serial_paranoia_check (edge_serial->serial, __FUNCTION__)) { + return; + } + + if (urb->status) { + dbg(__FUNCTION__" - nonzero control read status received: %d", urb->status); + return; + } + + if (!length) { + dbg ("%s - no data in urb", __FUNCTION__); + return; + } + + usb_serial_debug_data (__FILE__, __FUNCTION__, length, data); + + if (length != 2) { + dbg ("%s - expecting packet of size 2, got %d", __FUNCTION__, length); + return; + } + + port_number = TIUMP_GET_PORT_FROM_CODE (data[0]); + function = TIUMP_GET_FUNC_FROM_CODE (data[0]); + dbg ("%s - port_number %d, function %d, info 0x%x", + __FUNCTION__, port_number, function, data[1]); + port = &edge_serial->serial->port[port_number]; + if (port_paranoia_check (port, __FUNCTION__)) { + dbg ("%s - change found for port that is not present", + __FUNCTION__); + return; + } + edge_port = port->private; + if (!edge_port) { + dbg ("%s - edge_port not found", __FUNCTION__); + return; + } + switch (function) { + case TIUMP_INTERRUPT_CODE_LSR: + lsr = MapLineStatus(data[1]); + if (lsr & UMP_UART_LSR_DATA_MASK) { + /* Save the LSR event for bulk read completion routine */ + dbg ("%s - LSR Event Port %u LSR Status = %02x", + __FUNCTION__, port_number, lsr); + edge_port->lsr_event = 1; + edge_port->lsr_mask = lsr; + } else { + dbg ("%s - ===== Port %d LSR Status = %02x ======", + __FUNCTION__, port_number, lsr); + handle_new_lsr (edge_port, 0, lsr, 0); + } + break; + + case TIUMP_INTERRUPT_CODE_MSR: // MSR + /* Copy MSR from UMP */ + msr = data[1]; + dbg ("%s - ===== Port %u MSR Status = %02x ======\n", + __FUNCTION__, port_number, msr); + handle_new_msr (edge_port, msr); + break; + + default: + err ("%s - Unknown Interrupt code from UMP %x\n", + __FUNCTION__, data[1]); + break; + + } +} + +static void edge_bulk_in_callback (struct urb *urb) +{ + struct edgeport_port *edge_port = (struct edgeport_port *)urb->context; + unsigned char *data = urb->transfer_buffer; + struct tty_struct *tty; + int status; + int i; + int port_number; + + dbg("%s", __FUNCTION__); + + if (port_paranoia_check (edge_port->port, __FUNCTION__)) + return; + + if (urb->status) { + dbg ("%s - nonzero read bulk status received: %d", + __FUNCTION__, urb->status); + + if (urb->status == -EPIPE) { + /* clear any problem that might have happened on this pipe */ + usb_clear_halt (edge_port->port->serial->dev, urb->pipe); + goto exit; + } + return; + } + + port_number = edge_port->port->number - edge_port->port->serial->minor; + + if (edge_port->lsr_event) { + edge_port->lsr_event = 0; + dbg ("%s ===== Port %u LSR Status = %02x, Data = %02x ======", + __FUNCTION__, port_number, edge_port->lsr_mask, *data); + handle_new_lsr (edge_port, 1, edge_port->lsr_mask, *data); + /* Adjust buffer length/pointer */ + --urb->actual_length; + ++data; + } + + tty = edge_port->port->tty; + if (tty && urb->actual_length) { + usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data); + + if (edge_port->close_pending) { + dbg ("%s - close is pending, dropping data on the floor.", __FUNCTION__); + } else { + for (i = 0; i < urb->actual_length ; ++i) { + /* if we insert more than TTY_FLIPBUF_SIZE characters, + * we drop them. */ + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + tty_flip_buffer_push(tty); + } + /* this doesn't actually push the data through unless + * tty->low_latency is set */ + tty_insert_flip_char(tty, data[i], 0); + } + tty_flip_buffer_push(tty); + } + edge_port->icount.rx += urb->actual_length; + } + +exit: + /* continue always trying to read */ + urb->dev = edge_port->port->serial->dev; + status = usb_submit_urb (urb, GFP_ATOMIC); + if (status) + err ("%s - usb_submit_urb failed with result %d", + __FUNCTION__, status); +} + +static void edge_bulk_out_callback (struct urb *urb) +{ + struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); + struct tty_struct *tty; + + dbg ("%s - port %d", __FUNCTION__, port->number); + + if (!serial) { + dbg ("%s - bad serial pointer, exiting", __FUNCTION__); + return; + } + + if (urb->status) { + dbg ("%s - nonzero write bulk status received: %d", + __FUNCTION__, urb->status); + + if (urb->status == -EPIPE) { + /* clear any problem that might have happened on this pipe */ + usb_clear_halt (serial->dev, urb->pipe); + } + return; + } + + tty = port->tty; + if (tty) { + /* let the tty driver wakeup if it has a special write_wakeup function */ + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { + (tty->ldisc.write_wakeup)(tty); + } + + /* tell the tty driver that something has changed */ + wake_up_interruptible(&tty->write_wait); + } +} + +static int edge_open (struct usb_serial_port *port, struct file * filp) +{ + struct edgeport_port *edge_port = (struct edgeport_port *)port->private; + struct edgeport_serial *edge_serial; + struct usb_device *dev; + struct urb *urb; + int port_number; + int status; + u16 open_settings; + u8 transaction_timeout; + + if (port_paranoia_check (port, __FUNCTION__)) + return -ENODEV; + + dbg("%s - port %d", __FUNCTION__, port->number); + + if (edge_port == NULL) + return -ENODEV; + + /* force low_latency on so that our tty_push actually forces the data through, + otherwise it is scheduled, and with high data rates (like with OHCI) data + can get lost. */ + if (port->tty) + port->tty->low_latency = 1; + + port_number = port->number - port->serial->minor; + switch (port_number) { + case 0: + edge_port->uart_base = UMPMEM_BASE_UART1; + edge_port->dma_address = UMPD_OEDB1_ADDRESS; + break; + case 1: + edge_port->uart_base = UMPMEM_BASE_UART2; + edge_port->dma_address = UMPD_OEDB2_ADDRESS; + break; + default: + err ("Unknown port number!!!"); + return -ENODEV; + } + + dbg ("%s - port_number = %d, uart_base = %04x, dma_address = %04x", + __FUNCTION__, port_number, edge_port->uart_base, edge_port->dma_address); + + dev = port->serial->dev; + + memset (&(edge_port->icount), 0x00, sizeof(edge_port->icount)); + init_waitqueue_head (&edge_port->delta_msr_wait); + + /* turn off loopback */ + status = TIClearLoopBack (edge_port); + if (status) + return status; + + /* set up the port settings */ + edge_set_termios (port, NULL); + + /* open up the port */ + + /* milliseconds to timeout for DMA transfer */ + transaction_timeout = 2; + + edge_port->ump_read_timeout = max (20, ((transaction_timeout * 3) / 2) ); + + // milliseconds to timeout for DMA transfer + open_settings = (u8)(UMP_DMA_MODE_CONTINOUS | + UMP_PIPE_TRANS_TIMEOUT_ENA | + (transaction_timeout << 2)); + + dbg ("%s - Sending UMPC_OPEN_PORT", __FUNCTION__); + + /* Tell TI to open and start the port */ + status = TIWriteCommandSync (dev, + UMPC_OPEN_PORT, + (u8)(UMPM_UART1_PORT + port_number), + open_settings, + NULL, + 0); + if (status) + return status; + + /* Start the DMA? */ + status = TIWriteCommandSync (dev, + UMPC_START_PORT, + (u8)(UMPM_UART1_PORT + port_number), + 0, + NULL, + 0); + if (status) + return status; + + /* Clear TX and RX buffers in UMP */ + status = TIPurgeDataSync (port, UMP_PORT_DIR_OUT | UMP_PORT_DIR_IN); + if (status) + return status; + + /* Read Initial MSR */ + status = TIReadVendorRequestSync (dev, + UMPC_READ_MSR, // Request + 0, // wValue + (__u16)(UMPM_UART1_PORT + port_number), // wIndex (Address) + &edge_port->shadow_msr, // TransferBuffer + 1); // TransferBufferLength + if (status) + return status; + + dbg ("ShadowMSR 0x%X", edge_port->shadow_msr); + + edge_serial = edge_port->edge_serial; + if (edge_serial->num_ports_open == 0) { + /* we are the first port to be opened, let's post the interrupt urb */ + urb = edge_serial->serial->port[0].interrupt_in_urb; + if (!urb) { + err ("%s - no interrupt urb present, exiting", __FUNCTION__); + return -EINVAL; + } + urb->complete = edge_interrupt_callback; + urb->context = edge_serial; + urb->dev = dev; + status = usb_submit_urb (urb, GFP_KERNEL); + if (status) { + err ("%s - usb_submit_urb failed with value %d", __FUNCTION__, status); + return status; + } + } + + /* + * reset the data toggle on the bulk endpoints to work around bug in + * host controllers where things get out of sync some times + */ + usb_clear_halt (dev, port->write_urb->pipe); + usb_clear_halt (dev, port->read_urb->pipe); + + /* start up our bulk read urb */ + urb = port->read_urb; + if (!urb) { + err ("%s - no read urb present, exiting", __FUNCTION__); + return -EINVAL; + } + urb->complete = edge_bulk_in_callback; + urb->context = edge_port; + urb->dev = dev; + status = usb_submit_urb (urb, GFP_KERNEL); + if (status) { + err ("%s - read bulk usb_submit_urb failed with value %d", __FUNCTION__, status); + return status; + } + + ++edge_serial->num_ports_open; + + dbg("%s - exited", __FUNCTION__); + + return 0; +} + +static void edge_close (struct usb_serial_port *port, struct file * filp) +{ + struct usb_serial *serial; + struct edgeport_serial *edge_serial; + struct edgeport_port *edge_port; + int port_number; + int status; + + if (port_paranoia_check (port, __FUNCTION__)) + return; + + dbg(__FUNCTION__ " - port %d", port->number); + + serial = get_usb_serial (port, __FUNCTION__); + if (!serial) + return; + + edge_serial = (struct edgeport_serial *)serial->private; + edge_port = (struct edgeport_port *)port->private; + if ((edge_serial == NULL) || (edge_port == NULL)) + return; + + if (serial->dev) { + /* The bulkreadcompletion routine will check + * this flag and dump add read data */ + edge_port->close_pending = 1; + + /* chase the port close */ + TIChasePort (edge_port); + + usb_unlink_urb (port->read_urb); + + /* assuming we can still talk to the device, + * send a close port command to it */ + dbg("%s - send umpc_close_port", __FUNCTION__); + port_number = port->number - port->serial->minor; + status = TIWriteCommandSync (port->serial->dev, + UMPC_CLOSE_PORT, + (__u8)(UMPM_UART1_PORT + port_number), + 0, + NULL, + 0); + --edge_port->edge_serial->num_ports_open; + if (edge_port->edge_serial->num_ports_open <= 0) { + /* last port is now closed, let's shut down our interrupt urb */ + usb_unlink_urb (serial->port[0].interrupt_in_urb); + edge_port->edge_serial->num_ports_open = 0; + } + edge_port->close_pending = 0; + } + + dbg(__FUNCTION__" exited"); +} + +static int edge_write (struct usb_serial_port *port, int from_user, const unsigned char *data, int count) +{ + struct usb_serial *serial = port->serial; + struct edgeport_port *edge_port = port->private; + int result; + + dbg("%s - port %d", __FUNCTION__, port->number); + + if (count == 0) { + dbg("%s - write request of 0 bytes", __FUNCTION__); + return 0; + } + + if (edge_port == NULL) + return -ENODEV; + if (edge_port->close_pending == 1) + return -ENODEV; + + if (port->write_urb->status == -EINPROGRESS) { + dbg ("%s - already writing", __FUNCTION__); + return 0; + } + + count = min (count, port->bulk_out_size); + + if (from_user) { + if (copy_from_user(port->write_urb->transfer_buffer, data, count)) + return -EFAULT; + } else { + memcpy (port->write_urb->transfer_buffer, data, count); + } + + usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer); + + /* set up our urb */ + usb_fill_bulk_urb (port->write_urb, serial->dev, + usb_sndbulkpipe (serial->dev, + port->bulk_out_endpointAddress), + port->write_urb->transfer_buffer, count, + edge_bulk_out_callback, + port); + + /* send the data out the bulk port */ + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); + if (result) + err(__FUNCTION__ " - failed submitting write urb, error %d", result); + else + result = count; + + if (result > 0) + edge_port->icount.tx += count; + + return result; +} + +static int edge_write_room (struct usb_serial_port *port) +{ + struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); + int room = 0; + + dbg(__FUNCTION__); + + if (edge_port == NULL) + return -ENODEV; + if (edge_port->close_pending == 1) + return -ENODEV; + + dbg(__FUNCTION__" - port %d", port->number); + + if (port->write_urb->status != -EINPROGRESS) + room = port->bulk_out_size; + + dbg(__FUNCTION__ " - returns %d", room); + return room; +} + +static int edge_chars_in_buffer (struct usb_serial_port *port) +{ + struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); + int chars = 0; + + dbg(__FUNCTION__); + + if (edge_port == NULL) + return -ENODEV; + if (edge_port->close_pending == 1) + return -ENODEV; + + dbg("%s - port %d", __FUNCTION__, port->number); + + if (port->write_urb->status == -EINPROGRESS) + chars = port->write_urb->transfer_buffer_length; + + dbg ("%s - returns %d", __FUNCTION__, chars); + return chars; +} + +static void edge_throttle (struct usb_serial_port *port) +{ + struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); + struct tty_struct *tty; + int status; + + dbg("%s - port %d", __FUNCTION__, port->number); + + if (edge_port == NULL) + return; + + tty = port->tty; + if (!tty) { + dbg ("%s - no tty available", __FUNCTION__); + return; + } + /* if we are implementing XON/XOFF, send the stop character */ + if (I_IXOFF(tty)) { + unsigned char stop_char = STOP_CHAR(tty); + status = edge_write (port, 0, &stop_char, 1); + if (status <= 0) { + return; + } + } + + /* if we are implementing RTS/CTS, toggle that line */ + if (tty->termios->c_cflag & CRTSCTS) { + status = TIClearRts (edge_port); + } + + usb_unlink_urb (port->read_urb); +} + +static void edge_unthrottle (struct usb_serial_port *port) +{ + struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); + struct tty_struct *tty; + int status; + + dbg(__FUNCTION__" - port %d", port->number); + + if (edge_port == NULL) + return; + + tty = port->tty; + if (!tty) { + dbg ("%s - no tty available", __FUNCTION__); + return; + } + + /* if we are implementing XON/XOFF, send the start character */ + if (I_IXOFF(tty)) { + unsigned char start_char = START_CHAR(tty); + status = edge_write (port, 0, &start_char, 1); + if (status <= 0) { + return; + } + } + + /* if we are implementing RTS/CTS, toggle that line */ + if (tty->termios->c_cflag & CRTSCTS) { + status = TISetRts (edge_port); + } + + port->read_urb->dev = port->serial->dev; + status = usb_submit_urb (port->read_urb, GFP_ATOMIC); + if (status) { + err ("%s - usb_submit_urb failed with value %d", __FUNCTION__, status); + } +} + + +static void change_port_settings (struct edgeport_port *edge_port, struct termios *old_termios) +{ + struct ump_uart_config *config; + struct tty_struct *tty; + int baud; + int round; + unsigned cflag; + int status; + int port_number = edge_port->port->number - edge_port->port->serial->minor; + + dbg("%s - port %d", __FUNCTION__, edge_port->port->number); + + tty = edge_port->port->tty; + if ((!tty) || + (!tty->termios)) { + dbg("%s - no tty structures", __FUNCTION__); + return; + } + + config = kmalloc (sizeof (*config), GFP_KERNEL); + if (!config) { + err ("%s - out of memory", __FUNCTION__); + return; + } + + cflag = tty->termios->c_cflag; + + config->wFlags = 0; + + /* These flags must be set */ + config->wFlags |= UMP_MASK_UART_FLAGS_RECEIVE_MS_INT; + config->wFlags |= UMP_MASK_UART_FLAGS_AUTO_START_ON_ERR; + config->bUartMode = 0; + + switch (cflag & CSIZE) { + case CS5: + config->bDataBits = UMP_UART_CHAR5BITS; + dbg ("%s - data bits = 5", __FUNCTION__); + break; + case CS6: + config->bDataBits = UMP_UART_CHAR6BITS; + dbg ("%s - data bits = 6", __FUNCTION__); + break; + case CS7: + config->bDataBits = UMP_UART_CHAR7BITS; + dbg ("%s - data bits = 7", __FUNCTION__); + break; + default: + case CS8: + config->bDataBits = UMP_UART_CHAR8BITS; + dbg ("%s - data bits = 8", __FUNCTION__); + break; + } + + if (cflag & PARENB) { + if (cflag & PARODD) { + config->wFlags |= UMP_MASK_UART_FLAGS_PARITY; + config->bParity = UMP_UART_ODDPARITY; + dbg(__FUNCTION__" - parity = odd"); + } else { + config->wFlags |= UMP_MASK_UART_FLAGS_PARITY; + config->bParity = UMP_UART_EVENPARITY; + dbg(__FUNCTION__" - parity = even"); + } + } else { + config->bParity = UMP_UART_NOPARITY; + dbg(__FUNCTION__" - parity = none"); + } + + if (cflag & CSTOPB) { + config->bStopBits = UMP_UART_STOPBIT2; + dbg(__FUNCTION__" - stop bits = 2"); + } else { + config->bStopBits = UMP_UART_STOPBIT1; + dbg(__FUNCTION__" - stop bits = 1"); + } + + /* figure out the flow control settings */ + if (cflag & CRTSCTS) { + config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X_CTS_FLOW; + config->wFlags |= UMP_MASK_UART_FLAGS_RTS_FLOW; + dbg(__FUNCTION__" - RTS/CTS is enabled"); + } else { + dbg(__FUNCTION__" - RTS/CTS is disabled"); + } + + /* if we are implementing XON/XOFF, set the start and stop character in the device */ + if (I_IXOFF(tty) || I_IXON(tty)) { + config->cXon = START_CHAR(tty); + config->cXoff = STOP_CHAR(tty); + + /* if we are implementing INBOUND XON/XOFF */ + if (I_IXOFF(tty)) { + config->wFlags |= UMP_MASK_UART_FLAGS_IN_X; + dbg ("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", + __FUNCTION__, config->cXon, config->cXoff); + } else { + dbg ("%s - INBOUND XON/XOFF is disabled", __FUNCTION__); + } + + /* if we are implementing OUTBOUND XON/XOFF */ + if (I_IXON(tty)) { + config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X; + dbg ("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", + __FUNCTION__, config->cXon, config->cXoff); + } else { + dbg ("%s - OUTBOUND XON/XOFF is disabled", __FUNCTION__); + } + } + + /* Round the baud rate */ + baud = tty_get_baud_rate(tty); + if (!baud) { + /* pick a default, any default... */ + baud = 9600; + } + config->wBaudRate = (__u16)(461550L / baud); + round = 4615500L / baud; + if ((round - (config->wBaudRate * 10)) >= 5) + config->wBaudRate++; + + dbg ("%s - baud rate = %d, wBaudRate = %d", __FUNCTION__, baud, config->wBaudRate); + + dbg ("wBaudRate: %d", (int)(461550L / config->wBaudRate)); + dbg ("wFlags: 0x%x", config->wFlags); + dbg ("bDataBits: %d", config->bDataBits); + dbg ("bParity: %d", config->bParity); + dbg ("bStopBits: %d", config->bStopBits); + dbg ("cXon: %d", config->cXon); + dbg ("cXoff: %d", config->cXoff); + dbg ("bUartMode: %d", config->bUartMode); + + /* move the word values into big endian mode */ + cpu_to_be16s (&config->wFlags); + cpu_to_be16s (&config->wBaudRate); + + status = TIWriteCommandSync (edge_port->port->serial->dev, + UMPC_SET_CONFIG, + (__u8)(UMPM_UART1_PORT + port_number), + 0, + (__u8 *)config, + sizeof(*config)); + if (status) { + dbg ("%s - error %d when trying to write config to device", + __FUNCTION__, status); + } + + kfree (config); + + return; +} + +static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios) +{ + struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); + struct tty_struct *tty = port->tty; + unsigned int cflag; + + if (!port->tty || !port->tty->termios) { + dbg ("%s - no tty or termios", __FUNCTION__); + return; + } + + cflag = tty->termios->c_cflag; + /* check that they really want us to change something */ + if (old_termios) { + if ((cflag == old_termios->c_cflag) && + (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { + dbg ("%s - nothing to change", __FUNCTION__); + return; + } + } + + dbg("%s - clfag %08x iflag %08x", __FUNCTION__, + tty->termios->c_cflag, + RELEVANT_IFLAG(tty->termios->c_iflag)); + if (old_termios) { + dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, + old_termios->c_cflag, + RELEVANT_IFLAG(old_termios->c_iflag)); + } + + dbg("%s - port %d", __FUNCTION__, port->number); + + if (edge_port == NULL) + return; + + /* change the port settings to the new ones specified */ + change_port_settings (edge_port, old_termios); + + return; +} + +static int set_modem_info (struct edgeport_port *edge_port, unsigned int cmd, unsigned int *value) +{ + unsigned int mcr = edge_port->shadow_mcr; + unsigned int arg; + + if (copy_from_user(&arg, value, sizeof(int))) + return -EFAULT; + + switch (cmd) { + case TIOCMBIS: + if (arg & TIOCM_RTS) + mcr |= MCR_RTS; + if (arg & TIOCM_DTR) + mcr |= MCR_RTS; + if (arg & TIOCM_LOOP) + mcr |= MCR_LOOPBACK; + break; + + case TIOCMBIC: + if (arg & TIOCM_RTS) + mcr &= ~MCR_RTS; + if (arg & TIOCM_DTR) + mcr &= ~MCR_RTS; + if (arg & TIOCM_LOOP) + mcr &= ~MCR_LOOPBACK; + break; + + case TIOCMSET: + /* turn off the RTS and DTR and LOOPBACK + * and then only turn on what was asked to */ + mcr &= ~(MCR_RTS | MCR_DTR | MCR_LOOPBACK); + mcr |= ((arg & TIOCM_RTS) ? MCR_RTS : 0); + mcr |= ((arg & TIOCM_DTR) ? MCR_DTR : 0); + mcr |= ((arg & TIOCM_LOOP) ? MCR_LOOPBACK : 0); + break; + } + + edge_port->shadow_mcr = mcr; + + TIRestoreMCR (edge_port, mcr); + + return 0; +} + +static int get_modem_info (struct edgeport_port *edge_port, unsigned int *value) +{ + unsigned int result = 0; + unsigned int msr = edge_port->shadow_msr; + unsigned int mcr = edge_port->shadow_mcr; + + result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ + | ((mcr & MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */ + | ((msr & MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ + | ((msr & MSR_CD) ? TIOCM_CAR: 0) /* 0x040 */ + | ((msr & MSR_RI) ? TIOCM_RI: 0) /* 0x080 */ + | ((msr & MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ + + + dbg(__FUNCTION__" -- %x", result); + + if (copy_to_user(value, &result, sizeof(int))) + return -EFAULT; + return 0; +} + +static int get_serial_info (struct edgeport_port *edge_port, struct serial_struct * retinfo) +{ + struct serial_struct tmp; + + if (!retinfo) + return -EFAULT; + + memset(&tmp, 0, sizeof(tmp)); + + tmp.type = PORT_16550A; + tmp.line = edge_port->port->serial->minor; + tmp.port = edge_port->port->number; + tmp.irq = 0; + tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; + tmp.xmit_fifo_size = edge_port->port->bulk_out_size; + tmp.baud_base = 9600; + tmp.close_delay = 5*HZ; + tmp.closing_wait = 30*HZ; +// tmp.custom_divisor = state->custom_divisor; +// tmp.hub6 = state->hub6; +// tmp.io_type = state->io_type; + + + if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) + return -EFAULT; + return 0; +} + +static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); + struct async_icount cnow; + struct async_icount cprev; + + dbg(__FUNCTION__" - port %d, cmd = 0x%x", port->number, cmd); + + switch (cmd) { + case TIOCINQ: + dbg(__FUNCTION__" (%d) TIOCINQ", port->number); +// return get_number_bytes_avail(edge_port, (unsigned int *) arg); + break; + + case TIOCSERGETLSR: + dbg(__FUNCTION__" (%d) TIOCSERGETLSR", port->number); +// return get_lsr_info(edge_port, (unsigned int *) arg); + break; + + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + dbg(__FUNCTION__" (%d) TIOCMSET/TIOCMBIC/TIOCMSET", port->number); + return set_modem_info(edge_port, cmd, (unsigned int *) arg); + break; + + case TIOCMGET: + dbg(__FUNCTION__" (%d) TIOCMGET", port->number); + return get_modem_info(edge_port, (unsigned int *) arg); + break; + + case TIOCGSERIAL: + dbg(__FUNCTION__" (%d) TIOCGSERIAL", port->number); + return get_serial_info(edge_port, (struct serial_struct *) arg); + break; + + case TIOCSSERIAL: + dbg(__FUNCTION__" (%d) TIOCSSERIAL", port->number); + break; + + case TIOCMIWAIT: + dbg(__FUNCTION__" (%d) TIOCMIWAIT", port->number); + cprev = edge_port->icount; + while (1) { + interruptible_sleep_on(&edge_port->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + cnow = edge_port->icount; + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) + return -EIO; /* no change => error */ + if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { + return 0; + } + cprev = cnow; + } + /* not reached */ + break; + + case TIOCGICOUNT: + dbg ("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, + port->number, edge_port->icount.rx, edge_port->icount.tx); + if (copy_to_user((void *)arg, &edge_port->icount, sizeof(edge_port->icount))) + return -EFAULT; + return 0; + } + + return -ENOIOCTLCMD; +} + +static void edge_break (struct usb_serial_port *port, int break_state) +{ + struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); + int status; + + dbg ("%s - state = %d", __FUNCTION__, break_state); + + /* chase the port close */ + TIChasePort (edge_port); + + if (break_state == -1) { + status = TISetBreak (edge_port); + } else { + status = TIClearBreak (edge_port); + } + if (status) { + dbg ("%s - error %d sending break set/clear command.", + __FUNCTION__, status); + } +} + +static int edge_startup (struct usb_serial *serial) +{ + struct edgeport_serial *edge_serial; + struct edgeport_port *edge_port; + struct usb_device *dev; + int status; + int i; + + dev = serial->dev; + + /* create our private serial structure */ + edge_serial = kmalloc (sizeof(struct edgeport_serial), GFP_KERNEL); + if (edge_serial == NULL) { + err(__FUNCTION__" - Out of memory"); + return -ENOMEM; + } + memset (edge_serial, 0, sizeof(struct edgeport_serial)); + edge_serial->serial = serial; + serial->private = edge_serial; + + status = TIDownloadFirmware (edge_serial); + if (status) { + kfree (edge_serial); + return status; + } + + /* set up our port private structures */ + for (i = 0; i < serial->num_ports; ++i) { + edge_port = kmalloc (sizeof(struct edgeport_port), GFP_KERNEL); + if (edge_port == NULL) { + err(__FUNCTION__" - Out of memory"); + return -ENOMEM; + } + memset (edge_port, 0, sizeof(struct edgeport_port)); + edge_port->port = &serial->port[i]; + edge_port->edge_serial = edge_serial; + serial->port[i].private = edge_port; + } + + return 0; +} + +static void edge_shutdown (struct usb_serial *serial) +{ + int i; + + dbg (__FUNCTION__); + + for (i=0; i < serial->num_ports; ++i) { + kfree (serial->port[i].private); + serial->port[i].private = NULL; + } + kfree (serial->private); + serial->private = NULL; +} + + +static struct usb_serial_device_type edgeport_1port_device = { + owner: THIS_MODULE, + name: "Edgeport TI 1 port adapter", + id_table: edgeport_1port_id_table, + num_interrupt_in: 1, + num_bulk_in: 1, + num_bulk_out: 1, + num_ports: 1, + open: edge_open, + close: edge_close, + throttle: edge_throttle, + unthrottle: edge_unthrottle, + attach: edge_startup, + shutdown: edge_shutdown, + ioctl: edge_ioctl, + set_termios: edge_set_termios, + write: edge_write, + write_room: edge_write_room, + chars_in_buffer: edge_chars_in_buffer, + break_ctl: edge_break, +}; + +static struct usb_serial_device_type edgeport_2port_device = { + owner: THIS_MODULE, + name: "Edgeport TI 2 port adapter", + id_table: edgeport_2port_id_table, + num_interrupt_in: 1, + num_bulk_in: 2, + num_bulk_out: 2, + num_ports: 2, + open: edge_open, + close: edge_close, + throttle: edge_throttle, + unthrottle: edge_unthrottle, + attach: edge_startup, + shutdown: edge_shutdown, + ioctl: edge_ioctl, + set_termios: edge_set_termios, + write: edge_write, + write_room: edge_write_room, + chars_in_buffer: edge_chars_in_buffer, + break_ctl: edge_break, +}; + + +static int __init edgeport_init(void) +{ + usb_serial_register (&edgeport_1port_device); + usb_serial_register (&edgeport_2port_device); + info(DRIVER_DESC " " DRIVER_VERSION); + return 0; +} + +static void __exit edgeport_exit (void) +{ + usb_serial_deregister (&edgeport_1port_device); + usb_serial_deregister (&edgeport_2port_device); +} + +module_init(edgeport_init); +module_exit(edgeport_exit); + +/* Module information */ +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +MODULE_PARM(debug, "i"); +MODULE_PARM_DESC(debug, "Debug enabled or not"); + +MODULE_PARM(ignore_cpu_rev, "i"); +MODULE_PARM_DESC(ignore_cpu_rev, "Ignore the cpu revision when connecting to a device"); + diff --git a/drivers/usb/serial/io_ti.h b/drivers/usb/serial/io_ti.h new file mode 100644 index 000000000000..82a06c8b444c --- /dev/null +++ b/drivers/usb/serial/io_ti.h @@ -0,0 +1,180 @@ +/***************************************************************************** + * + * Copyright (c) 1997-2002 Inside Out Networks, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * + * Feb-16-2001 DMI Added I2C structure definitions + * May-29-2002 gkh Ported to Linux + * + * + ******************************************************************************/ + +#ifndef _IO_TI_H_ +#define _IO_TI_H_ + +/* Address Space */ +#define DTK_ADDR_SPACE_XDATA 0x03 /* Addr is placed in XDATA space */ +#define DTK_ADDR_SPACE_I2C_TYPE_II 0x82 /* Addr is placed in I2C area */ +#define DTK_ADDR_SPACE_I2C_TYPE_III 0x83 /* Addr is placed in I2C area */ + +// UART Defines +#define UMPMEM_BASE_UART1 0xFFA0 /* UMP UART1 base address */ +#define UMPMEM_BASE_UART2 0xFFB0 /* UMP UART2 base address */ +#define UMPMEM_OFFS_UART_LSR 0x05 /* UMP UART LSR register offset */ + +/* Bits per character */ +#define UMP_UART_CHAR5BITS 0x00 +#define UMP_UART_CHAR6BITS 0x01 +#define UMP_UART_CHAR7BITS 0x02 +#define UMP_UART_CHAR8BITS 0x03 + +/* Parity */ +#define UMP_UART_NOPARITY 0x00 +#define UMP_UART_ODDPARITY 0x01 +#define UMP_UART_EVENPARITY 0x02 +#define UMP_UART_MARKPARITY 0x03 +#define UMP_UART_SPACEPARITY 0x04 + +/* Stop bits */ +#define UMP_UART_STOPBIT1 0x00 +#define UMP_UART_STOPBIT15 0x01 +#define UMP_UART_STOPBIT2 0x02 + +/* Line status register masks */ +#define UMP_UART_LSR_OV_MASK 0x01 +#define UMP_UART_LSR_PE_MASK 0x02 +#define UMP_UART_LSR_FE_MASK 0x04 +#define UMP_UART_LSR_BR_MASK 0x08 +#define UMP_UART_LSR_ER_MASK 0x0F +#define UMP_UART_LSR_RX_MASK 0x10 +#define UMP_UART_LSR_TX_MASK 0x20 + +#define UMP_UART_LSR_DATA_MASK ( LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK ) + +/* Port Settings Constants) */ +#define UMP_MASK_UART_FLAGS_RTS_FLOW 0x0001 +#define UMP_MASK_UART_FLAGS_RTS_DISABLE 0x0002 +#define UMP_MASK_UART_FLAGS_PARITY 0x0008 +#define UMP_MASK_UART_FLAGS_OUT_X_DSR_FLOW 0x0010 +#define UMP_MASK_UART_FLAGS_OUT_X_CTS_FLOW 0x0020 +#define UMP_MASK_UART_FLAGS_OUT_X 0x0040 +#define UMP_MASK_UART_FLAGS_OUT_XA 0x0080 +#define UMP_MASK_UART_FLAGS_IN_X 0x0100 +#define UMP_MASK_UART_FLAGS_DTR_FLOW 0x0800 +#define UMP_MASK_UART_FLAGS_DTR_DISABLE 0x1000 +#define UMP_MASK_UART_FLAGS_RECEIVE_MS_INT 0x2000 +#define UMP_MASK_UART_FLAGS_AUTO_START_ON_ERR 0x4000 + +#define UMP_DMA_MODE_CONTINOUS 0x01 +#define UMP_PIPE_TRANS_TIMEOUT_ENA 0x80 +#define UMP_PIPE_TRANSFER_MODE_MASK 0x03 +#define UMP_PIPE_TRANS_TIMEOUT_MASK 0x7C + +/* Purge port Direction Mask Bits */ +#define UMP_PORT_DIR_OUT 0x01 +#define UMP_PORT_DIR_IN 0x02 + +// Address of Port 0 +#define UMPM_UART1_PORT 0x03 + +// Commands +#define UMPC_SET_CONFIG 0x05 +#define UMPC_OPEN_PORT 0x06 +#define UMPC_CLOSE_PORT 0x07 +#define UMPC_START_PORT 0x08 +#define UMPC_STOP_PORT 0x09 +#define UMPC_TEST_PORT 0x0A +#define UMPC_PURGE_PORT 0x0B + +#define UMPC_COMPLETE_READ 0x80 // Force the Firmware to complete the current Read +#define UMPC_HARDWARE_RESET 0x81 // Force UMP back into BOOT Mode +#define UMPC_COPY_DNLD_TO_I2C 0x82 // Copy current download image to type 0xf2 record in 16k I2C + // firmware will change 0xff record to type 2 record when complete + + // Special function register commands + // wIndex is register address + // wValue is MSB/LSB mask/data +#define UMPC_WRITE_SFR 0x83 // Write SFR Register + + // wIndex is register address +#define UMPC_READ_SFR 0x84 // Read SRF Register + + // Set or Clear DTR (wValue bit 0 Set/Clear) wIndex ModuleID (port) +#define UMPC_SET_CLR_DTR 0x85 + + // Set or Clear RTS (wValue bit 0 Set/Clear) wIndex ModuleID (port) +#define UMPC_SET_CLR_RTS 0x86 + + // Set or Clear LOOPBACK (wValue bit 0 Set/Clear) wIndex ModuleID (port) +#define UMPC_SET_CLR_LOOPBACK 0x87 + + // Set or Clear BREAK (wValue bit 0 Set/Clear) wIndex ModuleID (port) +#define UMPC_SET_CLR_BREAK 0x88 + + // Read MSR wIndex ModuleID (port) +#define UMPC_READ_MSR 0x89 + + /* Toolkit commands */ + /* Read-write group */ +#define UMPC_MEMORY_READ 0x92 +#define UMPC_MEMORY_WRITE 0x93 + +/* + * UMP DMA Definitions + */ +#define UMPD_OEDB1_ADDRESS 0xFF08 +#define UMPD_OEDB2_ADDRESS 0xFF10 + +struct out_endpoint_desc_block +{ + __u8 Configuration; + __u8 XBufAddr; + __u8 XByteCount; + __u8 Unused1; + __u8 Unused2; + __u8 YBufAddr; + __u8 YByteCount; + __u8 BufferSize; +} __attribute__((packed)); + + +/* + * TYPE DEFINITIONS + * Structures for Firmware commands + */ +struct ump_uart_config /* UART settings */ +{ + __u16 wBaudRate; /* Baud rate */ + __u16 wFlags; /* Bitmap mask of flags */ + __u8 bDataBits; /* 5..8 - data bits per character */ + __u8 bParity; /* Parity settings */ + __u8 bStopBits; /* Stop bits settings */ + char cXon; /* XON character */ + char cXoff; /* XOFF character */ + __u8 bUartMode; /* Will be updated when a user */ + /* interface is defined */ +} __attribute__((packed)); + + +/* + * TYPE DEFINITIONS + * Structures for USB interrupts + */ +struct ump_interrupt /* Interrupt packet structure */ +{ + __u8 bICode; /* Interrupt code (interrupt num) */ + __u8 bIInfo; /* Interrupt information */ +} __attribute__((packed)); + + +#define TIUMP_GET_PORT_FROM_CODE(c) (((c) >> 4) - 3) +#define TIUMP_GET_FUNC_FROM_CODE(c) ((c) & 0x0f) +#define TIUMP_INTERRUPT_CODE_LSR 0x03 +#define TIUMP_INTERRUPT_CODE_MSR 0x04 + +#endif diff --git a/drivers/usb/serial/io_usbvend.h b/drivers/usb/serial/io_usbvend.h index 068066e821e8..37fe6744a92c 100644 --- a/drivers/usb/serial/io_usbvend.h +++ b/drivers/usb/serial/io_usbvend.h @@ -106,11 +106,23 @@ #define ION_DEVICE_ID_BB_EDGEPORT_4_DIN 0x011 // Edgeport/4 RS232 with Apple DIN connector #define ION_DEVICE_ID_BB_EDGEPORT_16_DUAL_CPU 0x012 // Half of an Edgeport/16 (the kind with 2 EP/8s) #define ION_DEVICE_ID_BB_EDGEPORT_8I 0x014 // Edgeport/8 RS422 (single-CPU) -// These IDs are used by the Edgeport.exe program for uninstalling. -// -#define EDGEPORT_DEVICE_IDS {0x001, 0x003, 0x004, 0x005, 0x006, 0x007, 0x00B, \ - 0x00C, 0x00D, 0x00E, 0x00F, 0x010, 0x011, 0x012, \ - 0x013, 0x014 } + + +/* Edgeport TI based devices */ +#define ION_DEVICE_ID_TI_EDGEPORT_4 0x0201 /* Edgeport/4 RS232 */ +#define ION_DEVICE_ID_TI_EDGEPORT_2 0x0205 /* Edgeport/2 RS232 */ +#define ION_DEVICE_ID_TI_EDGEPORT_4I 0x0206 /* Edgeport/4i RS422 */ +#define ION_DEVICE_ID_TI_EDGEPORT_2I 0x0207 /* Edgeport/2i RS422/RS485 */ +#define ION_DEVICE_ID_TI_EDGEPORT_421 0x020C /* Edgeport/421 4 hub 2 RS232 + Parallel (lucent on a different hub port) */ +#define ION_DEVICE_ID_TI_EDGEPORT_21 0x020D /* Edgeport/21 2 RS232 + Parallel (lucent on a different hub port) */ +#define ION_DEVICE_ID_TI_EDGEPORT_1 0x0215 /* Edgeport/1 RS232 */ +#define ION_DEVICE_ID_TI_EDGEPORT_42 0x0217 /* Edgeport/42 4 hub 2 RS232 */ +#define ION_DEVICE_ID_TI_EDGEPORT_22 0x021A /* Edgeport/22 Edgeport/22I is an Edgeport/4 with ports 1&2 RS422 and ports 3&4 RS232 */ + +#define ION_DEVICE_ID_TI_EDGEPORT_421_BOOT 0x0240 /* Edgeport/421 in boot mode */ +#define ION_DEVICE_ID_TI_EDGEPORT_421_DOWN 0x0241 /* Edgeport/421 in download mode first interface is 2 RS232 (Note that the second interface of this multi interface device should be a standard USB class 7 printer port) */ +#define ION_DEVICE_ID_TI_EDGEPORT_21_BOOT 0x0242 /* Edgeport/21 in boot mode */ +#define ION_DEVICE_ID_TI_EDGEPORT_21_DOWN 0x0243 /*Edgeport/42 in download mode: first interface is 2 RS232 (Note that the second interface of this multi interface device should be a standard USB class 7 printer port) */ #define MAKE_USB_PRODUCT_ID( OemId, DeviceId ) \ @@ -217,7 +229,7 @@ // descriptor format, so that they may be separately retrieved, // if necessary, with a minimum of work on the 930. This also // requires them to be in UNICODE format, which, for English at -// least, simply means extending each UCHAR into a USHORT. +// least, simply means extending each __u8 into a __u16. // 3. For all fields, 00 means 'uninitialized'. // 4. All unused areas should be set to 00 for future expansion. // @@ -384,5 +396,92 @@ struct edge_boot_descriptor { #define BOOT_CAP_RESET_CMD 0x0001 // If set, boot correctly supports ION_RESET_DEVICE -#endif // if !defined() + +/************************************************************************ + T I U M P D E F I N I T I O N S + ***********************************************************************/ + +//************************************************************************ +// TI I2C Format Definitions +//************************************************************************ +#define I2C_DESC_TYPE_INFO_BASIC 1 +#define I2C_DESC_TYPE_FIRMWARE_BASIC 2 +#define I2C_DESC_TYPE_DEVICE 3 +#define I2C_DESC_TYPE_CONFIG 4 +#define I2C_DESC_TYPE_STRING 5 +#define I2C_DESC_TYPE_FIRMWARE_BLANK 0xf2 + +#define I2C_DESC_TYPE_MAX 5 +// 3410 may define types 6, 7 for other firmware downloads + +// Special section defined by ION +#define I2C_DESC_TYPE_ION 0 // Not defined by TI + + +struct ti_i2c_desc +{ + __u8 Type; // Type of descriptor + __u16 Size; // Size of data only not including header + __u8 CheckSum; // Checksum (8 bit sum of data only) + __u8 Data[0]; // Data starts here +}__attribute__((packed)); + +struct ti_i2c_firmware_rec +{ + __u8 Ver_Major; // Firmware Major version number + __u8 Ver_Minor; // Firmware Minor version number + __u8 Data[0]; // Download starts here +}__attribute__((packed)); + + +// Structure of header of download image in fw_down.h +struct ti_i2c_image_header +{ + __u16 Length; + __u8 CheckSum; +}__attribute__((packed)); + +struct ti_basic_descriptor +{ + __u8 Power; // Self powered + // bit 7: 1 - power switching supported + // 0 - power switching not supported + // + // bit 0: 1 - self powered + // 0 - bus powered + // + // + __u16 HubVid; // VID HUB + __u16 HubPid; // PID HUB + __u16 DevPid; // PID Edgeport + __u8 HubTime; // Time for power on to power good + __u8 HubCurrent; // HUB Current = 100ma +} __attribute__((packed)); + + +#define TI_GET_CPU_REVISION(x) (__u8)((((x)>>4)&0x0f)) +#define TI_GET_BOARD_REVISION(x) (__u8)(((x)&0x0f)) + +#define TI_I2C_SIZE_MASK 0x1f // 5 bits +#define TI_GET_I2C_SIZE(x) ((((x) & TI_I2C_SIZE_MASK)+1)*256) + +#define TI_MAX_I2C_SIZE ( 16 * 1024 ) + +/* TI USB 5052 definitions */ +struct edge_ti_manuf_descriptor +{ + __u8 IonConfig; // Config byte for ION manufacturing use + __u8 IonConfig2; // Expansion + __u8 Version; // Verqsion + __u8 CpuRev_BoardRev; // CPU revision level (0xF0) and Board Rev Level (0x0F) + __u8 NumPorts; // Number of ports for this UMP + __u8 NumVirtualPorts; // Number of Virtual ports + __u8 HubConfig1; // Used to configure the Hub + __u8 HubConfig2; // Used to configure the Hub + __u8 TotalPorts; // Total Number of Com Ports for the entire device (All UMPs) + __u8 Reserved; +}__attribute__((packed)); + + +#endif // if !defined() -- cgit v1.2.3 From d33c76ad1843260c6cd4df2dbc32b0939a9c1b3b Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 25 Jul 2002 22:08:37 -0700 Subject: [PATCH] ACPI compile fix This fixes the ACPI_DEBUG compile issue that turned up. --- drivers/acpi/include/aclocal.h | 4 ++-- drivers/acpi/include/acmacros.h | 10 +++++++--- drivers/acpi/parser/psutils.c | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/include/aclocal.h b/drivers/acpi/include/aclocal.h index d97fc5e8f8ab..f9d6e2f1f031 100644 --- a/drivers/acpi/include/aclocal.h +++ b/drivers/acpi/include/aclocal.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: aclocal.h - Internal data types used across the ACPI subsystem - * $Revision: 172 $ + * $Revision: 173 $ * *****************************************************************************/ @@ -567,7 +567,7 @@ acpi_status (*ACPI_EXECUTE_OP) ( */ typedef struct acpi_opcode_info { -#ifdef ACPI_DISASSEMBLER +#if defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUG) NATIVE_CHAR *name; /* Opcode name (disassembler/debug only) */ #endif u32 parse_args; /* Grammar/Parse time arguments */ diff --git a/drivers/acpi/include/acmacros.h b/drivers/acpi/include/acmacros.h index c8e79b0f76d4..57452f9b6cbf 100644 --- a/drivers/acpi/include/acmacros.h +++ b/drivers/acpi/include/acmacros.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acmacros.h - C macros for the entire subsystem. - * $Revision: 125 $ + * $Revision: 126 $ * *****************************************************************************/ @@ -287,11 +287,15 @@ /* * Macros for the master AML opcode table */ -#ifdef ACPI_DISASSEMBLER +#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG) #define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags) {name,Pargs,Iargs,flags,obj_type,class,type} -#define ACPI_DISASM_ONLY_MEMBERS(a) a; #else #define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags) {Pargs,Iargs,flags,obj_type,class,type} +#endif + +#ifdef ACPI_DISASSEMBLER +#define ACPI_DISASM_ONLY_MEMBERS(a) a; +#else #define ACPI_DISASM_ONLY_MEMBERS(a) #endif diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c index 7605080eeb62..7c8950786d35 100644 --- a/drivers/acpi/parser/psutils.c +++ b/drivers/acpi/parser/psutils.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psutils - Parser miscellaneous utilities (Parser only) - * $Revision: 53 $ + * $Revision: 54 $ * *****************************************************************************/ @@ -88,7 +88,7 @@ acpi_ps_init_op ( op->common.data_type = ACPI_DESC_TYPE_PARSER; op->common.aml_opcode = opcode; - ACPI_DEBUG_ONLY_MEMBERS (ACPI_STRNCPY (op->common.aml_op_name, + ACPI_DISASM_ONLY_MEMBERS (ACPI_STRNCPY (op->common.aml_op_name, (acpi_ps_get_opcode_info (opcode))->name, sizeof (op->common.aml_op_name))); } -- cgit v1.2.3 From 180bc55f027518b44d4176b7d3f998abf43c06a7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 26 Jul 2002 12:48:36 +0100 Subject: [SERIAL] Stop open() looping while opening a non-present port Trying to open a non-present port (for configuration) causes us to to endlessly loop (by returning -ERESTARTSYS). We should be returning success. This cset fixes this. --- drivers/serial/core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/core.c b/drivers/serial/core.c index fec9988ad959..6dd36a75bdde 100644 --- a/drivers/serial/core.c +++ b/drivers/serial/core.c @@ -1450,6 +1450,9 @@ uart_block_til_ready(struct file *filp, struct uart_info *info) if (signal_pending(current)) return -ERESTARTSYS; + if (info->tty->flags & (1 << TTY_IO_ERROR)) + return 0; + if (tty_hung_up_p(filp) || !(info->flags & UIF_INITIALIZED)) return (port->flags & UPF_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS; -- cgit v1.2.3 From 493a06f472e212289179225d5aefbcbae251975a Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 26 Jul 2002 14:27:23 +0100 Subject: [SERIAL] Turn on 8250 framing/parity error reporting on INPCK not IGNPAR --- drivers/serial/8250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 51836215e1c3..5ee576a93794 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -1336,7 +1336,7 @@ serial8250_change_speed(struct uart_port *port, unsigned int cflag, fcr |= UART_FCR7_64BYTE; up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (iflag & IGNPAR) + if (iflag & INPCK) up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; if (iflag & (BRKINT | PARMRK)) up->port.read_status_mask |= UART_LSR_BI; -- cgit v1.2.3 From b35451b51006e1c7081890979fbf0a5787352054 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 26 Jul 2002 22:58:27 +0100 Subject: [PATCH] designated initalizers for serial/ The old form of designated initializers are obsolete: we need to replace them with the ISO C forms before 2.6. Gcc has always supported both forms anyway. From Rusty's Trivial Patch - thanks. --- drivers/serial/21285.c | 88 +++++++++++++++++----------------- drivers/serial/8250.c | 62 ++++++++++++------------ drivers/serial/8250_pci.c | 8 ++-- drivers/serial/amba.c | 108 +++++++++++++++++++++--------------------- drivers/serial/anakin.c | 118 +++++++++++++++++++++++----------------------- drivers/serial/clps711x.c | 80 +++++++++++++++---------------- drivers/serial/sa1100.c | 60 +++++++++++------------ drivers/serial/uart00.c | 74 ++++++++++++++--------------- 8 files changed, 299 insertions(+), 299 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 369e6cceb574..cc0b6ef0f1d1 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c @@ -344,33 +344,33 @@ static int serial21285_verify_port(struct uart_port *port, struct serial_struct } static struct uart_ops serial21285_ops = { - tx_empty: serial21285_tx_empty, - get_mctrl: serial21285_get_mctrl, - set_mctrl: serial21285_set_mctrl, - stop_tx: serial21285_stop_tx, - start_tx: serial21285_start_tx, - stop_rx: serial21285_stop_rx, - enable_ms: serial21285_enable_ms, - break_ctl: serial21285_break_ctl, - startup: serial21285_startup, - shutdown: serial21285_shutdown, - change_speed: serial21285_change_speed, - type: serial21285_type, - release_port: serial21285_release_port, - request_port: serial21285_request_port, - config_port: serial21285_config_port, - verify_port: serial21285_verify_port, + .tx_empty = serial21285_tx_empty, + .get_mctrl = serial21285_get_mctrl, + .set_mctrl = serial21285_set_mctrl, + .stop_tx = serial21285_stop_tx, + .start_tx = serial21285_start_tx, + .stop_rx = serial21285_stop_rx, + .enable_ms = serial21285_enable_ms, + .break_ctl = serial21285_break_ctl, + .startup = serial21285_startup, + .shutdown = serial21285_shutdown, + .change_speed = serial21285_change_speed, + .type = serial21285_type, + .release_port = serial21285_release_port, + .request_port = serial21285_request_port, + .config_port = serial21285_config_port, + .verify_port = serial21285_verify_port, }; static struct uart_port serial21285_port = { - membase: 0, - mapbase: 0x42000160, - iotype: SERIAL_IO_MEM, - irq: NO_IRQ, - uartclk: 0, - fifosize: 16, - ops: &serial21285_ops, - flags: ASYNC_BOOT_AUTOCONF, + .membase = 0, + .mapbase = 0x42000160, + .iotype = SERIAL_IO_MEM, + .irq = NO_IRQ, + .uartclk = 0, + .fifosize = 16, + .ops = &serial21285_ops, + .flags = ASYNC_BOOT_AUTOCONF, }; static void serial21285_setup_ports(void) @@ -466,23 +466,23 @@ static int __init serial21285_console_setup(struct console *co, char *options) #ifdef CONFIG_SERIAL_21285_OLD static struct console serial21285_old_cons = { - name: SERIAL_21285_OLD_NAME, - write: serial21285_console_write, - device: serial21285_console_device, - setup: serial21285_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = SERIAL_21285_OLD_NAME, + .write = serial21285_console_write, + .device = serial21285_console_device, + .setup = serial21285_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; #endif static struct console serial21285_console = { - name: SERIAL_21285_NAME, - write: serial21285_console_write, - device: serial21285_console_device, - setup: serial21285_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = SERIAL_21285_NAME, + .write = serial21285_console_write, + .device = serial21285_console_device, + .setup = serial21285_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; void __init rs285_console_init(void) @@ -497,17 +497,17 @@ void __init rs285_console_init(void) #endif static struct uart_driver serial21285_reg = { - owner: THIS_MODULE, - driver_name: "ttyFB", + .owner = THIS_MODULE, + .driver_name = "ttyFB", #ifdef CONFIG_DEVFS_FS - dev_name: "ttyFB%d", + .dev_name = "ttyFB%d", #else - dev_name: "ttyFB", + .dev_name = "ttyFB", #endif - major: SERIAL_21285_MAJOR, - minor: SERIAL_21285_MINOR, - nr: 1, - cons: SERIAL_21285_CONSOLE, + .major = SERIAL_21285_MAJOR, + .minor = SERIAL_21285_MINOR, + .nr = 1, + .cons = SERIAL_21285_CONSOLE, }; static int __init serial21285_init(void) diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 5ee576a93794..141aa7c49718 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -1672,23 +1672,23 @@ serial8250_type(struct uart_port *port) } static struct uart_ops serial8250_pops = { - tx_empty: serial8250_tx_empty, - set_mctrl: serial8250_set_mctrl, - get_mctrl: serial8250_get_mctrl, - stop_tx: serial8250_stop_tx, - start_tx: serial8250_start_tx, - stop_rx: serial8250_stop_rx, - enable_ms: serial8250_enable_ms, - break_ctl: serial8250_break_ctl, - startup: serial8250_startup, - shutdown: serial8250_shutdown, - change_speed: serial8250_change_speed, - pm: serial8250_pm, - type: serial8250_type, - release_port: serial8250_release_port, - request_port: serial8250_request_port, - config_port: serial8250_config_port, - verify_port: serial8250_verify_port, + .tx_empty = serial8250_tx_empty, + .set_mctrl = serial8250_set_mctrl, + .get_mctrl = serial8250_get_mctrl, + .stop_tx = serial8250_stop_tx, + .start_tx = serial8250_start_tx, + .stop_rx = serial8250_stop_rx, + .enable_ms = serial8250_enable_ms, + .break_ctl = serial8250_break_ctl, + .startup = serial8250_startup, + .shutdown = serial8250_shutdown, + .change_speed = serial8250_change_speed, + .pm = serial8250_pm, + .type = serial8250_type, + .release_port = serial8250_release_port, + .request_port = serial8250_request_port, + .config_port = serial8250_config_port, + .verify_port = serial8250_verify_port, }; static struct uart_8250_port serial8250_ports[UART_NR]; @@ -1836,12 +1836,12 @@ static int __init serial8250_console_setup(struct console *co, char *options) } static struct console serial8250_console = { - name: "ttyS", - write: serial8250_console_write, - device: serial8250_console_device, - setup: serial8250_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = "ttyS", + .write = serial8250_console_write, + .device = serial8250_console_device, + .setup = serial8250_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; void __init serial8250_console_init(void) @@ -1856,17 +1856,17 @@ void __init serial8250_console_init(void) #endif static struct uart_driver serial8250_reg = { - owner: THIS_MODULE, - driver_name: "serial", + .owner = THIS_MODULE, + .driver_name = "serial", #ifdef CONFIG_DEVFS_FS - dev_name: "tts/%d", + .dev_name = "tts/%d", #else - dev_name: "ttyS", + .dev_name = "ttyS", #endif - major: TTY_MAJOR, - minor: 64, - nr: UART_NR, - cons: SERIAL8250_CONSOLE, + .major = TTY_MAJOR, + .minor = 64, + .nr = UART_NR, + .cons = SERIAL8250_CONSOLE, }; /* diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index ef925d32febe..d6dcbcff8680 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -1112,10 +1112,10 @@ static struct pci_device_id serial_pci_tbl[] __devinitdata = { #endif static struct pci_driver serial_pci_driver = { - name: "serial", - probe: pci_init_one, - remove: __devexit_p(pci_remove_one), - id_table: serial_pci_tbl, + .name = "serial", + .probe = pci_init_one, + .remove = __devexit_p(pci_remove_one), + .id_table = serial_pci_tbl, }; static int __init serial8250_pci_init(void) diff --git a/drivers/serial/amba.c b/drivers/serial/amba.c index c5d3157db265..b350a5598663 100644 --- a/drivers/serial/amba.c +++ b/drivers/serial/amba.c @@ -557,54 +557,54 @@ static int ambauart_verify_port(struct uart_port *port, struct serial_struct *se } static struct uart_ops amba_pops = { - tx_empty: ambauart_tx_empty, - set_mctrl: ambauart_set_mctrl, - get_mctrl: ambauart_get_mctrl, - stop_tx: ambauart_stop_tx, - start_tx: ambauart_start_tx, - stop_rx: ambauart_stop_rx, - enable_ms: ambauart_enable_ms, - break_ctl: ambauart_break_ctl, - startup: ambauart_startup, - shutdown: ambauart_shutdown, - change_speed: ambauart_change_speed, - type: ambauart_type, - release_port: ambauart_release_port, - request_port: ambauart_request_port, - config_port: ambauart_config_port, - verify_port: ambauart_verify_port, + .tx_empty = ambauart_tx_empty, + .set_mctrl = ambauart_set_mctrl, + .get_mctrl = ambauart_get_mctrl, + .stop_tx = ambauart_stop_tx, + .start_tx = ambauart_start_tx, + .stop_rx = ambauart_stop_rx, + .enable_ms = ambauart_enable_ms, + .break_ctl = ambauart_break_ctl, + .startup = ambauart_startup, + .shutdown = ambauart_shutdown, + .change_speed = ambauart_change_speed, + .type = ambauart_type, + .release_port = ambauart_release_port, + .request_port = ambauart_request_port, + .config_port = ambauart_config_port, + .verify_port = ambauart_verify_port, }; static struct uart_amba_port amba_ports[UART_NR] = { { - port: { - membase: (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), - mapbase: INTEGRATOR_UART0_BASE, - iotype: SERIAL_IO_MEM, - irq: IRQ_UARTINT0, - uartclk: 14745600, - fifosize: 16, - ops: &amba_pops, - flags: ASYNC_BOOT_AUTOCONF, - line: 0, + .port = { + .membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), + .mapbase = INTEGRATOR_UART0_BASE, + .iotype = SERIAL_IO_MEM, + .irq = IRQ_UARTINT0, + .uartclk = 14745600, + .fifosize = 16, + .ops = &amba_pops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, }, - dtr_mask: 1 << 5, - rts_mask: 1 << 4, + .dtr_mask = 1 << 5, + .rts_mask = 1 << 4, }, { - port: { - membase: (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), - mapbase: INTEGRATOR_UART1_BASE, - iotype: SERIAL_IO_MEM, - irq: IRQ_UARTINT1, - uartclk: 14745600, - fifosize: 16, - ops: &amba_pops, - flags: ASYNC_BOOT_AUTOCONF, - line: 1, + .port = { + .membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), + .mapbase = INTEGRATOR_UART1_BASE, + .iotype = SERIAL_IO_MEM, + .irq = IRQ_UARTINT1, + .uartclk = 14745600, + .fifosize = 16, + .ops = &amba_pops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 1, }, - dtr_mask: 1 << 7, - rts_mask: 1 << 6, + .dtr_mask = 1 << 7, + .rts_mask = 1 << 6, } }; @@ -706,12 +706,12 @@ static int __init ambauart_console_setup(struct console *co, char *options) } static struct console amba_console = { - name: "ttyAM", - write: ambauart_console_write, - device: ambauart_console_device, - setup: ambauart_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = "ttyAM", + .write = ambauart_console_write, + .device = ambauart_console_device, + .setup = ambauart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; void __init ambauart_console_init(void) @@ -725,17 +725,17 @@ void __init ambauart_console_init(void) #endif static struct uart_driver amba_reg = { - owner: THIS_MODULE, - driver_name: "ttyAM", + .owner = THIS_MODULE, + .driver_name = "ttyAM", #ifdef CONFIG_DEVFS_FS - dev_name: "ttyAM%d", + .dev_name = "ttyAM%d", #else - dev_name: "ttyAM", + .dev_name = "ttyAM", #endif - major: SERIAL_AMBA_MAJOR, - minor: SERIAL_AMBA_MINOR, - nr: UART_NR, - cons: AMBA_CONSOLE, + .major = SERIAL_AMBA_MAJOR, + .minor = SERIAL_AMBA_MINOR, + .nr = UART_NR, + .cons = AMBA_CONSOLE, }; static int __init ambauart_init(void) diff --git a/drivers/serial/anakin.c b/drivers/serial/anakin.c index f01e383a2624..dcb19b6630c9 100644 --- a/drivers/serial/anakin.c +++ b/drivers/serial/anakin.c @@ -322,65 +322,65 @@ static const char *anakin_type(struct port *port) } static struct uart_ops anakin_pops = { - tx_empty: anakin_tx_empty, - set_mctrl: anakin_set_mctrl, - get_mctrl: anakin_get_mctrl, - stop_tx: anakin_stop_tx, - start_tx: anakin_start_tx, - stop_rx: anakin_stop_rx, - enable_ms: anakin_enable_ms, - break_ctl: anakin_break_ctl, - startup: anakin_startup, - shutdown: anakin_shutdown, - change_speed: anakin_change_speed, - type: anakin_type, + .tx_empty = anakin_tx_empty, + .set_mctrl = anakin_set_mctrl, + .get_mctrl = anakin_get_mctrl, + .stop_tx = anakin_stop_tx, + .start_tx = anakin_start_tx, + .stop_rx = anakin_stop_rx, + .enable_ms = anakin_enable_ms, + .break_ctl = anakin_break_ctl, + .startup = anakin_startup, + .shutdown = anakin_shutdown, + .change_speed = anakin_change_speed, + .type = anakin_type, }; static struct uart_port anakin_ports[UART_NR] = { { - base: IO_BASE + UART0, - irq: IRQ_UART0, - uartclk: 3686400, - fifosize: 0, - ops: &anakin_pops, - flags: ASYNC_BOOT_AUTOCONF, - line: 0, + .base = IO_BASE + UART0, + .irq = IRQ_UART0, + .uartclk = 3686400, + .fifosize = 0, + .ops = &anakin_pops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, }, { - base: IO_BASE + UART1, - irq: IRQ_UART1, - uartclk: 3686400, - fifosize: 0, - ops: &anakin_pops, - flags: ASYNC_BOOT_AUTOCONF, - line: 1, + .base = IO_BASE + UART1, + .irq = IRQ_UART1, + .uartclk = 3686400, + .fifosize = 0, + .ops = &anakin_pops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 1, }, { - base: IO_BASE + UART2, - irq: IRQ_UART2, - uartclk: 3686400, - fifosize: 0, - ops: &anakin_pops, - flags: ASYNC_BOOT_AUTOCONF, - line: 2, + .base = IO_BASE + UART2, + .irq = IRQ_UART2, + .uartclk = 3686400, + .fifosize = 0, + .ops = &anakin_pops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 2, }, { - base: IO_BASE + UART3, - irq: IRQ_UART3, - uartclk: 3686400, - fifosize: 0, - ops: &anakin_pops, - flags: ASYNC_BOOT_AUTOCONF, - line: 3, + .base = IO_BASE + UART3, + .irq = IRQ_UART3, + .uartclk = 3686400, + .fifosize = 0, + .ops = &anakin_pops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 3, }, { - base: IO_BASE + UART4, - irq: IRQ_UART4, - uartclk: 3686400, - fifosize: 0, - ops: &anakin_pops, - flags: ASYNC_BOOT_AUTOCONF, - line: 4, + .base = IO_BASE + UART4, + .irq = IRQ_UART4, + .uartclk = 3686400, + .fifosize = 0, + .ops = &anakin_pops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 4, }, }; @@ -485,12 +485,12 @@ anakin_console_setup(struct console *co, char *options) } static struct console anakin_console = { - name: SERIAL_ANAKIN_NAME, - write: anakin_console_write, - device: anakin_console_device, - setup: anakin_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = SERIAL_ANAKIN_NAME, + .write = anakin_console_write, + .device = anakin_console_device, + .setup = anakin_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; void __init @@ -505,12 +505,12 @@ anakin_console_init(void) #endif static struct uart_register anakin_reg = { - driver_name: SERIAL_ANAKIN_NAME, - dev_name: SERIAL_ANAKIN_NAME, - major: SERIAL_ANAKIN_MAJOR, - minor: SERIAL_ANAKIN_MINOR, - nr: UART_NR, - cons: ANAKIN_CONSOLE, + .driver_name = SERIAL_ANAKIN_NAME, + .dev_name = SERIAL_ANAKIN_NAME, + .major = SERIAL_ANAKIN_MAJOR, + .minor = SERIAL_ANAKIN_MINOR, + .nr = UART_NR, + .cons = ANAKIN_CONSOLE, }; static int __init diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c index bc79f73a6a16..b67f857fa588 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/serial/clps711x.c @@ -418,39 +418,39 @@ static int clps711xuart_request_port(struct uart_port *port) } static struct uart_ops clps711x_pops = { - tx_empty: clps711xuart_tx_empty, - set_mctrl: clps711xuart_set_mctrl_null, - get_mctrl: clps711xuart_get_mctrl, - stop_tx: clps711xuart_stop_tx, - start_tx: clps711xuart_start_tx, - stop_rx: clps711xuart_stop_rx, - enable_ms: clps711xuart_enable_ms, - break_ctl: clps711xuart_break_ctl, - startup: clps711xuart_startup, - shutdown: clps711xuart_shutdown, - change_speed: clps711xuart_change_speed, - type: clps711xuart_type, - config_port: clps711xuart_config_port, - release_port: clps711xuart_release_port, - request_port: clps711xuart_request_port, + .tx_empty = clps711xuart_tx_empty, + .set_mctrl = clps711xuart_set_mctrl_null, + .get_mctrl = clps711xuart_get_mctrl, + .stop_tx = clps711xuart_stop_tx, + .start_tx = clps711xuart_start_tx, + .stop_rx = clps711xuart_stop_rx, + .enable_ms = clps711xuart_enable_ms, + .break_ctl = clps711xuart_break_ctl, + .startup = clps711xuart_startup, + .shutdown = clps711xuart_shutdown, + .change_speed = clps711xuart_change_speed, + .type = clps711xuart_type, + .config_port = clps711xuart_config_port, + .release_port = clps711xuart_release_port, + .request_port = clps711xuart_request_port, }; static struct uart_port clps711x_ports[UART_NR] = { { - iobase: SYSCON1, - irq: IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */ - uartclk: 3686400, - fifosize: 16, - ops: &clps711x_pops, - flags: ASYNC_BOOT_AUTOCONF, + .iobase = SYSCON1, + .irq = IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */ + .uartclk = 3686400, + .fifosize = 16, + .ops = &clps711x_pops, + .flags = ASYNC_BOOT_AUTOCONF, }, { - iobase: SYSCON2, - irq: IRQ_UTXINT2, /* IRQ_URXINT2 */ - uartclk: 3686400, - fifosize: 16, - ops: &clps711x_pops, - flags: ASYNC_BOOT_AUTOCONF, + .iobase = SYSCON2, + .irq = IRQ_UTXINT2, /* IRQ_URXINT2 */ + .uartclk = 3686400, + .fifosize = 16, + .ops = &clps711x_pops, + .flags = ASYNC_BOOT_AUTOCONF, } }; @@ -560,12 +560,12 @@ static int __init clps711xuart_console_setup(struct console *co, char *options) } static struct console clps711x_console = { - name: SERIAL_CLPS711X_NAME, - write: clps711xuart_console_write, - device: clps711xuart_console_device, - setup: clps711xuart_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = SERIAL_CLPS711X_NAME, + .write = clps711xuart_console_write, + .device = clps711xuart_console_device, + .setup = clps711xuart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; void __init clps711xuart_console_init(void) @@ -579,18 +579,18 @@ void __init clps711xuart_console_init(void) #endif static struct uart_driver clps711x_reg = { - driver_name: "ttyCL", + .driver_name = "ttyCL", #ifdef CONFIG_DEVFS_FS - dev_name: SERIAL_CLPS711X_NAME, + .dev_name = SERIAL_CLPS711X_NAME, #else - dev_name: SERIAL_CLPS711X_NAME, + .dev_name = SERIAL_CLPS711X_NAME, #endif - major: SERIAL_CLPS711X_MAJOR, - minor: SERIAL_CLPS711X_MINOR, - nr: UART_NR, + .major = SERIAL_CLPS711X_MAJOR, + .minor = SERIAL_CLPS711X_MINOR, + .nr = UART_NR, - cons: CLPS711X_CONSOLE, + .cons = CLPS711X_CONSOLE, }; static int __init clps711xuart_init(void) diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index b10ad6329dbe..aced0fa1b70b 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c @@ -602,22 +602,22 @@ sa1100_verify_port(struct uart_port *port, struct serial_struct *ser) } static struct uart_ops sa1100_pops = { - tx_empty: sa1100_tx_empty, - set_mctrl: sa1100_set_mctrl, - get_mctrl: sa1100_get_mctrl, - stop_tx: sa1100_stop_tx, - start_tx: sa1100_start_tx, - stop_rx: sa1100_stop_rx, - enable_ms: sa1100_enable_ms, - break_ctl: sa1100_break_ctl, - startup: sa1100_startup, - shutdown: sa1100_shutdown, - change_speed: sa1100_change_speed, - type: sa1100_type, - release_port: sa1100_release_port, - request_port: sa1100_request_port, - config_port: sa1100_config_port, - verify_port: sa1100_verify_port, + .tx_empty = sa1100_tx_empty, + .set_mctrl = sa1100_set_mctrl, + .get_mctrl = sa1100_get_mctrl, + .stop_tx = sa1100_stop_tx, + .start_tx = sa1100_start_tx, + .stop_rx = sa1100_stop_rx, + .enable_ms = sa1100_enable_ms, + .break_ctl = sa1100_break_ctl, + .startup = sa1100_startup, + .shutdown = sa1100_shutdown, + .change_speed = sa1100_change_speed, + .type = sa1100_type, + .release_port = sa1100_release_port, + .request_port = sa1100_request_port, + .config_port = sa1100_config_port, + .verify_port = sa1100_verify_port, }; static struct sa1100_port sa1100_ports[NR_PORTS]; @@ -820,12 +820,12 @@ sa1100_console_setup(struct console *co, char *options) } static struct console sa1100_console = { - name: "ttySA", - write: sa1100_console_write, - device: sa1100_console_device, - setup: sa1100_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = "ttySA", + .write = sa1100_console_write, + .device = sa1100_console_device, + .setup = sa1100_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; void __init sa1100_rs_console_init(void) @@ -840,17 +840,17 @@ void __init sa1100_rs_console_init(void) #endif static struct uart_driver sa1100_reg = { - owner: THIS_MODULE, - driver_name: "ttySA", + .owner = THIS_MODULE, + .driver_name = "ttySA", #ifdef CONFIG_DEVFS_FS - dev_name: "ttySA%d", + .dev_name = "ttySA%d", #else - dev_name: "ttySA", + .dev_name = "ttySA", #endif - major: SERIAL_SA1100_MAJOR, - minor: MINOR_START, - nr: NR_PORTS, - cons: SA1100_CONSOLE, + .major = SERIAL_SA1100_MAJOR, + .minor = MINOR_START, + .nr = NR_PORTS, + .cons = SA1100_CONSOLE, }; static int __init sa1100_serial_init(void) diff --git a/drivers/serial/uart00.c b/drivers/serial/uart00.c index 41f09f633e55..18cdd391e82f 100644 --- a/drivers/serial/uart00.c +++ b/drivers/serial/uart00.c @@ -498,35 +498,35 @@ static int uart00_verify_port(struct uart_port *port, struct serial_struct *ser) } static struct uart_ops uart00_pops = { - tx_empty: uart00_tx_empty, - set_mctrl: uart00_set_mctrl_null, - get_mctrl: uart00_get_mctrl, - stop_tx: uart00_stop_tx, - start_tx: uart00_start_tx, - stop_rx: uart00_stop_rx, - enable_ms: uart00_enable_ms, - break_ctl: uart00_break_ctl, - startup: uart00_startup, - shutdown: uart00_shutdown, - change_speed: uart00_change_speed, - type: uart00_type, - release_port: uart00_release_port, - request_port: uart00_request_port, - config_port: uart00_config_port, - verify_port: uart00_verify_port, + .tx_empty = uart00_tx_empty, + .set_mctrl = uart00_set_mctrl_null, + .get_mctrl = uart00_get_mctrl, + .stop_tx = uart00_stop_tx, + .start_tx = uart00_start_tx, + .stop_rx = uart00_stop_rx, + .enable_ms = uart00_enable_ms, + .break_ctl = uart00_break_ctl, + .startup = uart00_startup, + .shutdown = uart00_shutdown, + .change_speed = uart00_change_speed, + .type = uart00_type, + .release_port = uart00_release_port, + .request_port = uart00_request_port, + .config_port = uart00_config_port, + .verify_port = uart00_verify_port, }; #ifdef CONFIG_ARCH_CAMELOT static struct uart_port epxa10db_port = { - membase: (void*)IO_ADDRESS(EXC_UART00_BASE), - mapbase: EXC_UART00_BASE, - iotype: SERIAL_IO_MEM, - irq: IRQ_UART, - uartclk: EXC_AHB2_CLK_FREQUENCY, - fifosize: 16, - ops: &uart00_pops, - flags: ASYNC_BOOT_AUTOCONF, + .membase = (void*)IO_ADDRESS(EXC_UART00_BASE), + .mapbase = EXC_UART00_BASE, + .iotype = SERIAL_IO_MEM, + .irq = IRQ_UART, + .uartclk = EXC_AHB2_CLK_FREQUENCY, + .fifosize = 16, + .ops = &uart00_pops, + .flags = ASYNC_BOOT_AUTOCONF, }; #endif @@ -633,12 +633,12 @@ static int __init uart00_console_setup(struct console *co, char *options) } static struct console uart00_console = { - name: SERIAL_UART00_NAME, - write: uart00_console_write, - device: uart00_console_device, - setup: uart00_console_setup, - flags: CON_PRINTBUFFER, - index: 0, + .name = SERIAL_UART00_NAME, + .write = uart00_console_write, + .device = uart00_console_device, + .setup = uart00_console_setup, + .flags = CON_PRINTBUFFER, + .index = 0, }; void __init uart00_console_init(void) @@ -652,13 +652,13 @@ void __init uart00_console_init(void) #endif static struct uart_driver uart00_reg = { - owner: NULL, - driver_name: SERIAL_UART00_NAME, - dev_name: SERIAL_UART00_NAME, - major: SERIAL_UART00_MAJOR, - minor: SERIAL_UART00_MINOR, - nr: UART_NR, - cons: UART00_CONSOLE, + .owner = NULL, + .driver_name = SERIAL_UART00_NAME, + .dev_name = SERIAL_UART00_NAME, + .major = SERIAL_UART00_MAJOR, + .minor = SERIAL_UART00_MINOR, + .nr = UART_NR, + .cons = UART00_CONSOLE, }; struct dev_port_entry{ -- cgit v1.2.3 From c249c322954f73ec72bae6cc6646ffabc3b19ece Mon Sep 17 00:00:00 2001 From: Craig Kulesa Date: Sat, 27 Jul 2002 00:44:24 +0100 Subject: [PATCH] fix unresolved syms for serial drivers The following two patches seem to be needed to export the requisite symbols needed for fully modular builds of the new serial drivers in 2.5.28. --- drivers/char/tty_io.c | 1 + drivers/serial/core.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 269abc090514..62ecb5df63fe 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -545,6 +545,7 @@ void tty_vhangup(struct tty_struct * tty) #endif do_tty_hangup((void *) tty); } +EXPORT_SYMBOL(tty_vhangup); int tty_hung_up_p(struct file * filp) { diff --git a/drivers/serial/core.c b/drivers/serial/core.c index 6dd36a75bdde..b5910ea9d868 100644 --- a/drivers/serial/core.c +++ b/drivers/serial/core.c @@ -2472,6 +2472,8 @@ EXPORT_SYMBOL(uart_register_driver); EXPORT_SYMBOL(uart_unregister_driver); EXPORT_SYMBOL(uart_register_port); EXPORT_SYMBOL(uart_unregister_port); +EXPORT_SYMBOL(uart_add_one_port); +EXPORT_SYMBOL(uart_remove_one_port); MODULE_DESCRIPTION("Serial driver core"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From cc1d784041442a6eb4d5b0fadf2fcb095c093e89 Mon Sep 17 00:00:00 2001 From: Martin Dalecki Date: Fri, 26 Jul 2002 01:14:19 -0700 Subject: [PATCH] 2.5.28 small REQ_SPECIAL abstraction The attached patch does the following: 1. Remove blkdev_release_request(Request); it was an unnecessary wrapper around blk_put_request(Request). Likely some leftover from pre-BIO time... 2. Abstract out the fine __scsi_insert_special() function out from the SCSI code. Now that I have finally managed to kill all those IDE 'specific' REQ_BLAH request types, we can do this final step, and it will be used soon at least by ATA code as well. The goal is that scsi_request_fn and do_ide_request should start to look similar like silblings. Its called blk_insert_request() now and even documented in code. 3. Change some stuff over from extern inline to static inline in blkdev.h. (trivia...) This patch doesn't change *any* functionality, so its not exposing SCSI to any danger :-). --- drivers/block/DAC960.c | 2 +- drivers/block/ll_rw_blk.c | 52 ++++++++++++++++++++++++++++++++++++++++------- drivers/scsi/scsi_lib.c | 51 ++-------------------------------------------- include/linux/blkdev.h | 31 ++++++++++++++-------------- include/linux/nbd.h | 2 +- 5 files changed, 64 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index dc372aa4dbb1..59e4b53dfce5 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -2884,7 +2884,7 @@ static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller, Command->BufferHeader = Request->bio; Command->RequestBuffer = Request->buffer; blkdev_dequeue_request(Request); - blkdev_release_request(Request); + blk_put_request(Request); DAC960_QueueReadWriteCommand(Command); return true; } diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index e73c1d823428..53f1706d2877 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1233,9 +1233,47 @@ struct request *__blk_get_request(request_queue_t *q, int rw) return rq; } -void blk_put_request(struct request *rq) +/** + * blk_insert_request - insert a special request in to a request queue + * @q: request queue where request should be inserted + * @rq: request to be inserted + * @at_head: insert request at head or tail of queue + * @data: private data + * + * Description: + * Many block devices need to execute commands asynchronously, so they don't + * block the whole kernel from preemption during request execution. This is + * accomplished normally by inserting aritficial requests tagged as + * REQ_SPECIAL in to the corresponding request queue, and letting them be + * scheduled for actual execution by the request queue. + * + * We have the option of inserting the head or the tail of the queue. + * Typically we use the tail for new ioctls and so forth. We use the head + * of the queue for things like a QUEUE_FULL message from a device, or a + * host that is unable to accept a particular command. + */ +void blk_insert_request(request_queue_t *q, struct request *rq, + int at_head, void *data) { - blkdev_release_request(rq); + unsigned long flags; + + /* + * tell I/O scheduler that this isn't a regular read/write (ie it + * must not attempt merges on this) and that it acts as a soft + * barrier + */ + rq->flags &= REQ_QUEUED; + rq->flags |= REQ_SPECIAL | REQ_BARRIER; + + rq->special = data; + + spin_lock_irqsave(q->queue_lock, flags); + /* If command is tagged, release the tag */ + if(blk_rq_tagged(rq)) + blk_queue_end_tag(q, rq); + _elv_add_request(q, rq, !at_head, 0); + q->request_fn(q); + spin_unlock_irqrestore(q->queue_lock, flags); } /* RO fail safe mechanism */ @@ -1307,7 +1345,7 @@ static inline void add_request(request_queue_t * q, struct request * req, /* * Must be called with queue lock held and interrupts disabled */ -void blkdev_release_request(struct request *req) +void blk_put_request(struct request *req) { struct request_list *rl = req->rl; request_queue_t *q = req->q; @@ -1370,7 +1408,7 @@ static void attempt_merge(request_queue_t *q, struct request *req, req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors; - blkdev_release_request(next); + blk_put_request(next); } } @@ -1568,7 +1606,7 @@ get_rq: add_request(q, req, insert_here); out: if (freereq) - blkdev_release_request(freereq); + blk_put_request(freereq); spin_unlock_irq(q->queue_lock); return 0; @@ -2003,7 +2041,7 @@ void end_that_request_last(struct request *req) if (req->waiting) complete(req->waiting); - blkdev_release_request(req); + blk_put_request(req); } #define MB(kb) ((kb) << 10) @@ -2064,7 +2102,6 @@ EXPORT_SYMBOL(blk_cleanup_queue); EXPORT_SYMBOL(blk_queue_make_request); EXPORT_SYMBOL(blk_queue_bounce_limit); EXPORT_SYMBOL(generic_make_request); -EXPORT_SYMBOL(blkdev_release_request); EXPORT_SYMBOL(generic_unplug_device); EXPORT_SYMBOL(blk_plug_device); EXPORT_SYMBOL(blk_remove_plug); @@ -2088,6 +2125,7 @@ EXPORT_SYMBOL(blk_hw_contig_segment); EXPORT_SYMBOL(blk_get_request); EXPORT_SYMBOL(__blk_get_request); EXPORT_SYMBOL(blk_put_request); +EXPORT_SYMBOL(blk_insert_request); EXPORT_SYMBOL(blk_queue_prep_rq); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 0bbb215e7a8d..9f516d0d204d 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -50,53 +50,6 @@ * This entire source file deals with the new queueing code. */ -/* - * Function: __scsi_insert_special() - * - * Purpose: worker for scsi_insert_special_*() - * - * Arguments: q - request queue where request should be inserted - * rq - request to be inserted - * data - private data - * at_head - insert request at head or tail of queue - * - * Lock status: Assumed that queue lock is not held upon entry. - * - * Returns: Nothing - */ -static void __scsi_insert_special(request_queue_t *q, struct request *rq, - void *data, int at_head) -{ - unsigned long flags; - - ASSERT_LOCK(q->queue_lock, 0); - - /* - * tell I/O scheduler that this isn't a regular read/write (ie it - * must not attempt merges on this) and that it acts as a soft - * barrier - */ - rq->flags &= REQ_QUEUED; - rq->flags |= REQ_SPECIAL | REQ_BARRIER; - - rq->special = data; - - /* - * We have the option of inserting the head or the tail of the queue. - * Typically we use the tail for new ioctls and so forth. We use the - * head of the queue for things like a QUEUE_FULL message from a - * device, or a host that is unable to accept a particular command. - */ - spin_lock_irqsave(q->queue_lock, flags); - /* If command is tagged, release the tag */ - if(blk_rq_tagged(rq)) - blk_queue_end_tag(q, rq); - _elv_add_request(q, rq, !at_head, 0); - q->request_fn(q); - spin_unlock_irqrestore(q->queue_lock, flags); -} - - /* * Function: scsi_insert_special_cmd() * @@ -121,7 +74,7 @@ int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head) { request_queue_t *q = &SCpnt->device->request_queue; - __scsi_insert_special(q, SCpnt->request, SCpnt, at_head); + blk_insert_request(q, SCpnt->request, at_head, SCpnt); return 0; } @@ -149,7 +102,7 @@ int scsi_insert_special_req(Scsi_Request * SRpnt, int at_head) { request_queue_t *q = &SRpnt->sr_device->request_queue; - __scsi_insert_special(q, SRpnt->sr_request, SRpnt, at_head); + blk_insert_request(q, SRpnt->sr_request, at_head, SRpnt); return 0; } diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 726492d4c45a..f83c52f82ab0 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -281,12 +281,13 @@ extern int wipe_partitions(kdev_t dev); extern void register_disk(struct gendisk *dev, kdev_t first, unsigned minors, struct block_device_operations *ops, long size); extern void generic_make_request(struct bio *bio); extern inline request_queue_t *bdev_get_queue(struct block_device *bdev); -extern void blkdev_release_request(struct request *); +extern void blk_put_request(struct request *); extern void blk_attempt_remerge(request_queue_t *, struct request *); extern void __blk_attempt_remerge(request_queue_t *, struct request *); extern struct request *blk_get_request(request_queue_t *, int, int); extern struct request *__blk_get_request(request_queue_t *, int); extern void blk_put_request(struct request *); +extern void blk_insert_request(request_queue_t *, struct request *, int, void *); extern void blk_plug_device(request_queue_t *); extern int blk_remove_plug(request_queue_t *); extern void blk_recount_segments(request_queue_t *, struct bio *); @@ -309,20 +310,21 @@ extern int blk_init_queue(request_queue_t *, request_fn_proc *, spinlock_t *); extern void blk_cleanup_queue(request_queue_t *); extern void blk_queue_make_request(request_queue_t *, make_request_fn *); extern void blk_queue_bounce_limit(request_queue_t *, u64); -extern void blk_queue_max_sectors(request_queue_t *q, unsigned short); -extern void blk_queue_max_phys_segments(request_queue_t *q, unsigned short); -extern void blk_queue_max_hw_segments(request_queue_t *q, unsigned short); -extern void blk_queue_max_segment_size(request_queue_t *q, unsigned int); -extern void blk_queue_hardsect_size(request_queue_t *q, unsigned short); -extern void blk_queue_segment_boundary(request_queue_t *q, unsigned long); -extern void blk_queue_assign_lock(request_queue_t *q, spinlock_t *); -extern void blk_queue_prep_rq(request_queue_t *q, prep_rq_fn *pfn); +extern void blk_queue_max_sectors(request_queue_t *, unsigned short); +extern void blk_queue_max_phys_segments(request_queue_t *, unsigned short); +extern void blk_queue_max_hw_segments(request_queue_t *, unsigned short); +extern void blk_queue_max_segment_size(request_queue_t *, unsigned int); +extern void blk_queue_hardsect_size(request_queue_t *, unsigned short); +extern void blk_queue_segment_boundary(request_queue_t *, unsigned long); +extern void blk_queue_assign_lock(request_queue_t *, spinlock_t *); +extern void blk_queue_prep_rq(request_queue_t *, prep_rq_fn *pfn); extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); extern int blk_rq_map_sg(request_queue_t *, struct request *, struct scatterlist *); extern void blk_dump_rq_flags(struct request *, char *); extern void generic_unplug_device(void *); + /* * tag stuff */ @@ -348,15 +350,12 @@ extern int * blk_size[MAX_BLKDEV]; /* in units of 1024 bytes */ extern void drive_stat_acct(struct request *, int, int); -extern inline void blk_clear(int major) +static inline void blk_clear(int major) { blk_size[major] = NULL; -#if 0 - blk_size_in_bytes[major] = NULL; -#endif } -extern inline int queue_hardsect_size(request_queue_t *q) +static inline int queue_hardsect_size(request_queue_t *q) { int retval = 512; @@ -366,7 +365,7 @@ extern inline int queue_hardsect_size(request_queue_t *q) return retval; } -extern inline int bdev_hardsect_size(struct block_device *bdev) +static inline int bdev_hardsect_size(struct block_device *bdev) { return queue_hardsect_size(bdev_get_queue(bdev)); } @@ -375,7 +374,7 @@ extern inline int bdev_hardsect_size(struct block_device *bdev) #define blk_started_io(nsects) do { } while (0) /* assumes size > 256 */ -extern inline unsigned int blksize_bits(unsigned int size) +static inline unsigned int blksize_bits(unsigned int size) { unsigned int bits = 8; do { diff --git a/include/linux/nbd.h b/include/linux/nbd.h index eae4f5bbb65a..e2c507ba6b08 100644 --- a/include/linux/nbd.h +++ b/include/linux/nbd.h @@ -61,7 +61,7 @@ nbd_end_request(struct request *req) bio->bi_next = NULL; bio_endio(bio, uptodate); } - blkdev_release_request(req); + blk_put_request(req); spin_unlock_irqrestore(q->queue_lock, flags); } -- cgit v1.2.3 From 72b6c89355f2270e22b5aee2938bb9821a48f6f8 Mon Sep 17 00:00:00 2001 From: Martin Dalecki Date: Fri, 26 Jul 2002 01:14:32 -0700 Subject: [PATCH] 2.5.28 IDE 102 Just getting trivia out of the way, so the interresting parts don't get burried by them: - Sanitize the menu configuration system. - Allow to compile atapi.c as a "foundation module" for the consuming device type drivers. --- arch/alpha/config.in | 4 +-- arch/arm/config.in | 4 +-- arch/i386/config.in | 42 ++++++++++++++++---------------- arch/ia64/config.in | 4 +-- arch/m68k/config.in | 8 +++--- arch/mips/config.in | 4 +-- arch/mips64/config.in | 4 +-- arch/ppc64/config.in | 4 +-- arch/sh/config.in | 4 +-- arch/sparc/config.in | 4 +-- arch/sparc64/config.in | 4 +-- arch/x86_64/config.in | 4 +-- drivers/ide/Config.help | 10 ++++++++ drivers/ide/Config.in | 65 ++++++++++++++++++++++--------------------------- drivers/ide/Makefile | 4 +-- 15 files changed, 86 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/arch/alpha/config.in b/arch/alpha/config.in index b12f8b7b38ed..4050a48ceb3a 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -283,9 +283,9 @@ if [ "$CONFIG_NET" = "y" ]; then fi mainmenu_option next_comment -comment 'ATA/IDE/MFM/RLL support' +comment 'ATA/ATAPI/MFM/RLL support' -tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE +tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in diff --git a/arch/arm/config.in b/arch/arm/config.in index 583485356034..8e5d6d652075 100644 --- a/arch/arm/config.in +++ b/arch/arm/config.in @@ -529,9 +529,9 @@ if [ "$CONFIG_NET" = "y" ]; then fi mainmenu_option next_comment -comment 'ATA/IDE/MFM/RLL support' +comment 'ATA/ATAPI/MFM/RLL support' -tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE +tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in diff --git a/arch/i386/config.in b/arch/i386/config.in index d1c238813604..de59f559ee7b 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -298,18 +298,10 @@ source drivers/pnp/Config.in source drivers/block/Config.in -source drivers/md/Config.in - -if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in -fi - -source drivers/telephony/Config.in - mainmenu_option next_comment -comment 'ATA/IDE/MFM/RLL support' +comment 'ATA/ATAPI/MFM/RLL device support' -tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE +tristate 'ATA/ATAPI/MFM/RLL device support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in @@ -319,15 +311,32 @@ fi endmenu mainmenu_option next_comment -comment 'SCSI support' +comment 'SCSI device support' -tristate 'SCSI support' CONFIG_SCSI +tristate 'SCSI device support' CONFIG_SCSI if [ "$CONFIG_SCSI" != "n" ]; then source drivers/scsi/Config.in fi endmenu +mainmenu_option next_comment +comment 'Old non-SCSI/ATAPI CD-ROM drives' + +bool 'Support non-SCSI/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI +if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then + source drivers/cdrom/Config.in +fi +endmenu + +source drivers/md/Config.in + +if [ "$CONFIG_NET" = "y" ]; then + source net/Config.in +fi + +source drivers/telephony/Config.in + source drivers/message/fusion/Config.in source drivers/ieee1394/Config.in @@ -354,15 +363,6 @@ source net/irda/Config.in source drivers/isdn/Config.in -mainmenu_option next_comment -comment 'Old CD-ROM drivers (not SCSI, not IDE)' - -bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI -if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then - source drivers/cdrom/Config.in -fi -endmenu - # # input before char - char/joystick depends on it. As does USB. # diff --git a/arch/ia64/config.in b/arch/ia64/config.in index 882be867a289..0313d39a1131 100644 --- a/arch/ia64/config.in +++ b/arch/ia64/config.in @@ -133,9 +133,9 @@ source drivers/md/Config.in source drivers/message/fusion/Config.in mainmenu_option next_comment -comment 'ATA/IDE/MFM/RLL support' +comment 'ATA/ATAPI/MFM/RLL support' -tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE +tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in diff --git a/arch/m68k/config.in b/arch/m68k/config.in index 5d737dc1fa9d..a5f1c4bd88ae 100644 --- a/arch/m68k/config.in +++ b/arch/m68k/config.in @@ -160,9 +160,9 @@ if [ "$CONFIG_MAC" = "y" ]; then fi mainmenu_option next_comment -comment 'ATA/IDE/MFM/RLL support' +comment 'ATA/ATAPI/MFM/RLL device support' -tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE +tristate 'ATA/ATAPI/MFM/RLL device support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in @@ -172,9 +172,9 @@ fi endmenu mainmenu_option next_comment -comment 'SCSI support' +comment 'SCSI device support' -tristate 'SCSI support' CONFIG_SCSI +tristate 'SCSI device support' CONFIG_SCSI if [ "$CONFIG_SCSI" != "n" ]; then diff --git a/arch/mips/config.in b/arch/mips/config.in index d90ee3b08d68..b585724bbf03 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -343,9 +343,9 @@ if [ "$CONFIG_SGI_IP22" != "y" -a \ "$CONFIG_DECSTATION" != "y" ]; then mainmenu_option next_comment - comment 'ATA/IDE/MFM/RLL support' + comment 'ATA/ATAPI/MFM/RLL support' - tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE + tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in diff --git a/arch/mips64/config.in b/arch/mips64/config.in index ad8c17e3cc30..0e369d91dee8 100644 --- a/arch/mips64/config.in +++ b/arch/mips64/config.in @@ -138,9 +138,9 @@ fi source drivers/telephony/Config.in mainmenu_option next_comment -comment 'ATA/IDE/MFM/RLL support' +comment 'ATA/ATAPI/MFM/RLL support' -tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE +tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in diff --git a/arch/ppc64/config.in b/arch/ppc64/config.in index e90f9da20015..1590def66395 100644 --- a/arch/ppc64/config.in +++ b/arch/ppc64/config.in @@ -92,9 +92,9 @@ if [ "$CONFIG_NET" = "y" ]; then fi mainmenu_option next_comment -comment 'ATA/IDE/MFM/RLL support' +comment 'ATA/ATAPI/MFM/RLL support' -tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE +tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in diff --git a/arch/sh/config.in b/arch/sh/config.in index 07681448d732..34814b8098a6 100644 --- a/arch/sh/config.in +++ b/arch/sh/config.in @@ -211,9 +211,9 @@ if [ "$CONFIG_NET" = "y" ]; then fi mainmenu_option next_comment -comment 'ATA/IDE/MFM/RLL support' +comment 'ATA/ATAPI/MFM/RLL support' -tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE +tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in diff --git a/arch/sparc/config.in b/arch/sparc/config.in index fb11163e0502..06e635833b19 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -104,9 +104,9 @@ fi if [ "$CONFIG_PCI" = "y" ]; then mainmenu_option next_comment - comment 'ATA/IDE/MFM/RLL support' + comment 'ATA/ATAPI/MFM/RLL support' - tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE + tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index 5b251158cdcc..265b34dbfa01 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -105,9 +105,9 @@ if [ "$CONFIG_NET" = "y" ]; then fi mainmenu_option next_comment -comment 'ATA/IDE/MFM/RLL support' +comment 'ATA/ATAPI/MFM/RLL device support' -tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE +tristate 'ATA/ATAPI/MFM/RLL device support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in diff --git a/arch/x86_64/config.in b/arch/x86_64/config.in index 829a74f439ad..d2cabfdc56b1 100644 --- a/arch/x86_64/config.in +++ b/arch/x86_64/config.in @@ -126,9 +126,9 @@ fi source drivers/telephony/Config.in mainmenu_option next_comment -comment 'ATA/IDE/MFM/RLL support' +comment 'ATA/ATAPI/MFM/RLL support' -tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE +tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in diff --git a/drivers/ide/Config.help b/drivers/ide/Config.help index 74668ed23673..3375dee859dc 100644 --- a/drivers/ide/Config.help +++ b/drivers/ide/Config.help @@ -84,6 +84,16 @@ CONFIG_BLK_DEV_IDECS Support for outboard IDE disks, tape drives, and CD-ROM drives connected through a PCMCIA card. +CONFIG_ATAPI + If you wish to enable basic support for devices attached to the system + through the ATA interface, and which are using using the ATAPI protocol + (CD-ROM, CD-RW, DVD, DVD-RW, LS120, ZIP, ...), say Y. + + If you want to compile the driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The module + will be called atapi.o. + CONFIG_BLK_DEV_IDECD If you have a CD-ROM drive using the ATAPI protocol, say Y. ATAPI is a newer protocol used by IDE CD-ROM and TAPE drives, similar to the diff --git a/drivers/ide/Config.in b/drivers/ide/Config.in index f2c8fe680de1..5a48bc9a7b78 100644 --- a/drivers/ide/Config.in +++ b/drivers/ide/Config.in @@ -1,40 +1,37 @@ # -# IDE ATA ATAPI Block device driver configuration +# ATA/ATAPI block device driver configuration # -# Andre Hedrick -# -mainmenu_option next_comment -comment 'ATA and ATAPI Block devices' - -dep_tristate 'Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support' CONFIG_BLK_DEV_IDE $CONFIG_IDE -comment 'Please see Documentation/ide.txt for help/info on IDE drives' +dep_tristate 'Enhanced ATA/ATAPI device (disk,cdrom,...) support' CONFIG_BLK_DEV_IDE $CONFIG_IDE if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then dep_bool ' Use old disk-only driver on primary interface' CONFIG_BLK_DEV_HD_IDE $CONFIG_X86 define_bool CONFIG_BLK_DEV_HD $CONFIG_BLK_DEV_HD_IDE - dep_tristate ' Include IDE/ATA-2 DISK support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE - dep_mbool ' Use multi-mode by default' CONFIG_IDEDISK_MULTI_MODE $CONFIG_BLK_DEV_IDEDISK - dep_mbool ' Auto-Geometry Resizing support' CONFIG_IDEDISK_STROKE $CONFIG_BLK_DEV_IDEDISK - dep_tristate ' PCMCIA IDE support' CONFIG_BLK_DEV_IDECS $CONFIG_BLK_DEV_IDE $CONFIG_PCMCIA - dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE - dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE - dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE - dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE $CONFIG_SCSI + dep_tristate ' ATA disk support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE + dep_bool ' Use multi-mode by default' CONFIG_IDEDISK_MULTI_MODE $CONFIG_BLK_DEV_IDEDISK + dep_bool ' Auto-Geometry Resizing support' CONFIG_IDEDISK_STROKE $CONFIG_BLK_DEV_IDEDISK + + dep_tristate ' ATAPI device support (CD-ROM, floppy)' CONFIG_ATAPI $CONFIG_BLK_DEV_IDE + dep_tristate ' CD-ROM support' CONFIG_BLK_DEV_IDECD $CONFIG_ATAPI $CONFIG_BLK_DEV_IDE + dep_tristate ' Tape support' CONFIG_BLK_DEV_IDETAPE $CONFIG_ATAPI $CONFIG_BLK_DEV_IDE + dep_tristate ' Floppy support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_ATAPI $CONFIG_BLK_DEV_IDE + dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_ATAPI $CONFIG_BLK_DEV_IDE $CONFIG_SCSI + + dep_tristate ' PCMCIA/CardBus support' CONFIG_BLK_DEV_IDECS $CONFIG_BLK_DEV_IDE $CONFIG_PCMCIA - comment 'ATA host chip set support' - dep_bool ' CMD640 chip set bugfix/support' CONFIG_BLK_DEV_CMD640 $CONFIG_X86 + comment 'ATA host controller support' + dep_bool ' RZ1000 bugfix/support' CONFIG_BLK_DEV_RZ1000 $CONFIG_X86 + dep_bool ' CMD640 bugfix/support' CONFIG_BLK_DEV_CMD640 $CONFIG_X86 dep_bool ' CMD640 enhanced support' CONFIG_BLK_DEV_CMD640_ENHANCED $CONFIG_BLK_DEV_CMD640 dep_bool ' ISA-PNP support' CONFIG_BLK_DEV_ISAPNP $CONFIG_ISAPNP - if [ "$CONFIG_PCI" = "y" ]; then - dep_bool ' RZ1000 chip set bugfix/support' CONFIG_BLK_DEV_RZ1000 $CONFIG_X86 - comment ' PCI host chip set support' - dep_bool ' Boot off-board chip sets first support' CONFIG_BLK_DEV_OFFBOARD $CONFIG_PCI - dep_bool ' Sharing PCI ATA interrupts support' CONFIG_IDEPCI_SHARE_IRQ $CONFIG_PCI + if [ "$CONFIG_PCI" != "n" ]; then + comment ' PCI host controller support' + dep_bool ' Boot off-board controllers first' CONFIG_BLK_DEV_OFFBOARD $CONFIG_PCI + dep_bool ' Sharing PCI ATA interrupts' CONFIG_IDEPCI_SHARE_IRQ $CONFIG_PCI dep_bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_PCI dep_bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI - dep_bool ' ATA tagged command queueing (DANGEROUS)' CONFIG_BLK_DEV_IDE_TCQ $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL + dep_bool ' Tagged command queueing (DANGEROUS)' CONFIG_BLK_DEV_IDE_TCQ $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL dep_bool ' TCQ on by default' CONFIG_BLK_DEV_IDE_TCQ_DEFAULT $CONFIG_BLK_DEV_IDE_TCQ if [ "$CONFIG_BLK_DEV_IDE_TCQ" != "n" ]; then int ' Default queue depth' CONFIG_BLK_DEV_IDE_TCQ_DEPTH 32 @@ -110,7 +107,7 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then fi # assume no ISA -> also no VLB - dep_bool ' Other ISA/VLB IDE chipset support' CONFIG_IDE_CHIPSETS $CONFIG_ISA + dep_bool ' ISA/VLB IDE chipset support' CONFIG_IDE_CHIPSETS $CONFIG_ISA if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then comment 'Note: most of these also require special kernel boot parameters' bool ' ALI M14xx support' CONFIG_BLK_DEV_ALI14XX @@ -122,15 +119,13 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then dep_tristate ' QDI QD65xx support' CONFIG_BLK_DEV_QD65XX $CONFIG_BLK_DEV_IDE bool ' UMC-8672 support' CONFIG_BLK_DEV_UMC8672 fi - if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" -o \ - "$CONFIG_BLK_DEV_IDEDMA_PMAC" = "y" -o \ - "$CONFIG_BLK_DEV_IDEDMA_ICS" = "y" ]; then + if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" != "n" -o \ + "$CONFIG_BLK_DEV_IDEDMA_PMAC" != "n" -o \ + "$CONFIG_BLK_DEV_IDEDMA_ICS" != "n" ]; then bool ' IGNORE word93 Validation BITS' CONFIG_IDEDMA_IVB fi - - define_bool CONFIG_ATAPI y else - bool 'Old hard disk (MFM/RLL/IDE) driver' CONFIG_BLK_DEV_HD_ONLY + bool 'Old disk only (MFM/RLL/IDE) driver' CONFIG_BLK_DEV_HD_ONLY define_bool CONFIG_BLK_DEV_HD $CONFIG_BLK_DEV_HD_ONLY fi @@ -142,8 +137,6 @@ else define_bool CONFIG_IDEDMA_AUTO n fi -dep_tristate 'Support for IDE Raid controllers (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL -dep_tristate ' Support Promise software RAID (Fasttrak(tm)) (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_PDC $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID -dep_tristate ' Highpoint 370 software RAID (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_HPT $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID - -endmenu +dep_tristate 'Support for software RAID controllers (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL +dep_tristate ' Support Promise (Fasttrak(tm)) (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_PDC $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID +dep_tristate ' Highpoint 370 EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_HPT $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 010311bd8fec..57aaeb7a3ce8 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_BLK_DEV_HD) += hd.o obj-$(CONFIG_BLK_DEV_IDE) += ide-mod.o obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o -# obj-$(CONFIG_ATAPI) += atapi.o +obj-$(CONFIG_ATAPI) += atapi.o obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o @@ -69,6 +69,6 @@ obj-$(CONFIG_BLK_DEV_ATARAID_PDC) += pdcraid.o obj-$(CONFIG_BLK_DEV_ATARAID_HPT) += hptraid.o ide-mod-objs := device.o ide-taskfile.o main.o ide.o probe.o \ - ioctl.o atapi.o ata-timing.o $(ide-obj-y) + ioctl.o ata-timing.o $(ide-obj-y) include $(TOPDIR)/Rules.make -- cgit v1.2.3 From e7a6bdfdb183ba2e3985fe874eef3992505ad0d2 Mon Sep 17 00:00:00 2001 From: Martin Dalecki Date: Fri, 26 Jul 2002 01:16:19 -0700 Subject: [PATCH] IDE 105 - Rename ata-timings.h to timings.h. Same arguments as for agp. - Always include hdparm.h just before ide.h. Include them last where used. This is preparing to split out the IDE register declarations out of this file, since many other files in the kernel include it, which don't have anything to do with IDE. - Don't use the "IDE special" data type "byte". Just use the u8 data type for consistency with the rest of the kernel where applicable. --- drivers/ide/aec62xx.c | 5 ++- drivers/ide/ali14xx.c | 5 ++- drivers/ide/alim15x3.c | 34 ++++++++--------- drivers/ide/amd74xx.c | 5 ++- drivers/ide/ata-timing.c | 5 ++- drivers/ide/ata-timing.h | 95 ----------------------------------------------- drivers/ide/cmd640.c | 10 ++--- drivers/ide/cmd64x.c | 34 ++++++++--------- drivers/ide/cs5530.c | 14 +++---- drivers/ide/cy82c693.c | 13 ++++--- drivers/ide/dtc2278.c | 6 +-- drivers/ide/hpt34x.c | 4 +- drivers/ide/hpt366.c | 5 +-- drivers/ide/hptraid.c | 4 +- drivers/ide/ht6560b.c | 20 +++++----- drivers/ide/icside.c | 2 +- drivers/ide/ide-cd.c | 4 +- drivers/ide/ide-cd.h | 26 ++++++------- drivers/ide/ide-disk.c | 3 +- drivers/ide/ide-floppy.c | 4 +- drivers/ide/ide-m8xx.c | 9 +++-- drivers/ide/ide-pci.c | 3 +- drivers/ide/ide-pmac.c | 28 +++++++------- drivers/ide/ide-tape.c | 6 +-- drivers/ide/ide.c | 7 ++-- drivers/ide/ioctl.c | 16 ++++---- drivers/ide/it8172.c | 5 +-- drivers/ide/main.c | 5 ++- drivers/ide/ns87415.c | 2 +- drivers/ide/opti621.c | 16 ++++---- drivers/ide/pcidma.c | 5 ++- drivers/ide/pdc202xx.c | 14 +++---- drivers/ide/pdc4030.c | 4 +- drivers/ide/pdcraid.c | 4 +- drivers/ide/piix.c | 5 ++- drivers/ide/probe.c | 11 +++--- drivers/ide/qd65xx.c | 47 +++++++++++------------ drivers/ide/qd65xx.h | 4 +- drivers/ide/quirks.c | 7 ++-- drivers/ide/serverworks.c | 4 +- drivers/ide/sis5513.c | 34 +++++++++-------- drivers/ide/sl82c105.c | 10 ++--- drivers/ide/tcq.c | 1 + drivers/ide/timing.h | 83 +++++++++++++++++++++++++++++++++++++++++ drivers/ide/trm290.c | 2 +- drivers/ide/umc8672.c | 18 ++++----- drivers/ide/via82cxxx.c | 5 ++- fs/partitions/msdos.c | 1 + include/linux/ide.h | 61 +++++++++++++++--------------- 49 files changed, 359 insertions(+), 356 deletions(-) delete mode 100644 drivers/ide/ata-timing.h create mode 100644 drivers/ide/timing.h (limited to 'drivers') diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c index d2dca5e1a1a4..468a4b788644 100644 --- a/drivers/ide/aec62xx.c +++ b/drivers/ide/aec62xx.c @@ -42,10 +42,11 @@ #include #include #include +#include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" #define AEC_DRIVE_TIMING 0x40 @@ -167,7 +168,7 @@ static void aec62xx_tune_drive(struct ata_device *drive, unsigned char pio) return; } - aec_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5)); + aec_set_drive(drive, XFER_PIO_0 + min_t(u8, pio, 5)); } #ifdef CONFIG_BLK_DEV_IDEDMA diff --git a/drivers/ide/ali14xx.c b/drivers/ide/ali14xx.c index 33f175c92e0b..9d2e97c47d36 100644 --- a/drivers/ide/ali14xx.c +++ b/drivers/ide/ali14xx.c @@ -37,12 +37,13 @@ #include #include -#include #include +#include +#include #include -#include "ata-timing.h" +#include "timing.h" /* port addresses for auto-detection */ #define ALI_NUM_PORTS 4 diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index f8422ad5e897..e862b5c98dfd 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c @@ -26,30 +26,30 @@ #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" -static byte m5229_revision; -static byte chip_is_1543c_e; +static u8 m5229_revision; +static int chip_is_1543c_e; static struct pci_dev *isa_dev; -static void ali15x3_tune_drive(struct ata_device *drive, byte pio) +static void ali15x3_tune_drive(struct ata_device *drive, u8 pio) { struct ata_timing *t; struct ata_channel *hwif = drive->channel; struct pci_dev *dev = hwif->pci_dev; int s_time, a_time, c_time; - byte s_clc, a_clc, r_clc; + u8 s_clc, a_clc, r_clc; unsigned long flags; int port = hwif->unit ? 0x5c : 0x58; int portFIFO = hwif->unit ? 0x55 : 0x54; - byte cd_dma_fifo = 0; + u8 cd_dma_fifo = 0; if (pio == 255) pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO); else - pio = XFER_PIO_0 + min_t(byte, pio, 4); + pio = XFER_PIO_0 + min_t(u8, pio, 4); t = ata_timing_data(pio); @@ -100,15 +100,15 @@ static void ali15x3_tune_drive(struct ata_device *drive, byte pio) local_irq_restore(flags); } -static int ali15x3_tune_chipset(struct ata_device *drive, byte speed) +static int ali15x3_tune_chipset(struct ata_device *drive, u8 speed) { struct pci_dev *dev = drive->channel->pci_dev; - byte unit = (drive->select.b.unit & 0x01); - byte tmpbyte = 0x00; - int m5229_udma = drive->channel->unit ? 0x57 : 0x56; + u8 unit = (drive->select.b.unit & 0x01); + u8 tmpbyte = 0x00; + int m5229_udma = drive->channel->unit ? 0x57 : 0x56; if (speed < XFER_UDMA_0) { - byte ultra_enable = (unit) ? 0x7f : 0xf7; + u8 ultra_enable = unit ? 0x7f : 0xf7; /* * clear "ultra enable" bit */ @@ -135,7 +135,7 @@ static int ali15x3_tune_chipset(struct ata_device *drive, byte speed) pci_write_config_byte(dev, 0x4b, tmpbyte); } } -#endif /* CONFIG_BLK_DEV_IDEDMA */ +#endif return ide_config_drive_speed(drive, speed); } @@ -212,10 +212,10 @@ static unsigned int __init ali15x3_ata66_check(struct ata_channel *hwif) { struct pci_dev *dev = hwif->pci_dev; unsigned int ata66 = 0; - byte cable_80_pin[2] = { 0, 0 }; + u8 cable_80_pin[2] = { 0, 0 }; unsigned long flags; - byte tmpbyte; + u8 tmpbyte; local_irq_save(flags); @@ -305,8 +305,8 @@ static unsigned int __init ali15x3_ata66_check(struct ata_channel *hwif) static void __init ali15x3_init_channel(struct ata_channel *hwif) { #ifndef CONFIG_SPARC64 - byte ideic, inmir; - byte irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6, + u8 ideic, inmir; + u8 irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; hwif->irq = hwif->unit ? 15 : 14; diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c index 485f31e3f4cb..5e2e1e27e850 100644 --- a/drivers/ide/amd74xx.c +++ b/drivers/ide/amd74xx.c @@ -42,11 +42,12 @@ #include #include #include +#include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" #define AMD_IDE_ENABLE (0x00 + amd_config->base) @@ -171,7 +172,7 @@ static void amd74xx_tune_drive(struct ata_device *drive, u8 pio) return; } - amd_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5)); + amd_set_drive(drive, XFER_PIO_0 + min_t(u8, pio, 5)); } #ifdef CONFIG_BLK_DEV_IDEDMA diff --git a/drivers/ide/ata-timing.c b/drivers/ide/ata-timing.c index 01a312044242..f713a15b047a 100644 --- a/drivers/ide/ata-timing.c +++ b/drivers/ide/ata-timing.c @@ -23,7 +23,10 @@ */ #include -#include "ata-timing.h" +#include +#include + +#include "timing.h" /* * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). These were taken diff --git a/drivers/ide/ata-timing.h b/drivers/ide/ata-timing.h deleted file mode 100644 index 9f01f07e8329..000000000000 --- a/drivers/ide/ata-timing.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef _ATA_TIMING_H -#define _ATA_TIMING_H - -/* - * $Id: ata-timing.h,v 2.0 2002/03/12 13:02:22 vojtech Exp $ - * - * Copyright (C) 1996 Linus Torvalds, Igor Abramov, and Mark Lord - * Copyright (C) 1999-2001 Vojtech Pavlik - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#define XFER_PIO_5 0x0d -#define XFER_UDMA_SLOW 0x4f - -struct ata_timing { - short mode; - short setup; /* t1 */ - short act8b; /* t2 for 8-bit io */ - short rec8b; /* t2i for 8-bit io */ - short cyc8b; /* t0 for 8-bit io */ - short active; /* t2 or tD */ - short recover; /* t2i or tK */ - short cycle; /* t0 */ - short udma; /* t2CYCTYP/2 */ -}; - -extern struct ata_timing ata_timing[]; - -#define IDE_TIMING_SETUP 0x01 -#define IDE_TIMING_ACT8B 0x02 -#define IDE_TIMING_REC8B 0x04 -#define IDE_TIMING_CYC8B 0x08 -#define IDE_TIMING_8BIT 0x0e -#define IDE_TIMING_ACTIVE 0x10 -#define IDE_TIMING_RECOVER 0x20 -#define IDE_TIMING_CYCLE 0x40 -#define IDE_TIMING_UDMA 0x80 -#define IDE_TIMING_ALL 0xff - -#define FIT(v,x,y) max_t(int,min_t(int,v,y),x) -#define ENOUGH(v,unit) (((v)-1)/(unit)+1) -#define EZ(v,unit) ((v)?ENOUGH(v,unit):0) - -/* see hpt366.c for details */ -#define XFER_UDMA_66_3 0x100 -#define XFER_UDMA_66_4 0x200 - -#define XFER_MODE 0xff0 -#define XFER_UDMA_133 0x800 -#define XFER_UDMA_100 0x400 -#define XFER_UDMA_66 0x300 -#define XFER_UDMA 0x040 -#define XFER_MWDMA 0x020 -#define XFER_SWDMA 0x010 -#define XFER_EPIO 0x001 -#define XFER_PIO 0x000 - -#define XFER_UDMA_ALL 0xf40 -#define XFER_UDMA_80W 0xf00 - -/* External interface to host chips channel timing setup. - * - * It's a bit elaborate due to the legacy we have to bear. - */ - -extern short ata_timing_mode(struct ata_device *drive, int map); -extern void ata_timing_quantize(struct ata_timing *t, struct ata_timing *q, - int T, int UT); -extern void ata_timing_merge(struct ata_timing *a, struct ata_timing *b, - struct ata_timing *m, unsigned int what); -void ata_timing_merge_8bit(struct ata_timing *t); -extern struct ata_timing* ata_timing_data(short speed); -extern int ata_timing_compute(struct ata_device *drive, - short speed, struct ata_timing *t, int T, int UT); -extern u8 ata_best_pio_mode(struct ata_device *drive); - -#endif diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c index 742f8c7a54f3..e8325b9e7690 100644 --- a/drivers/ide/cmd640.c +++ b/drivers/ide/cmd640.c @@ -106,13 +106,13 @@ #include #include #include +#include #include #include -#include #include -#include "ata-timing.h" +#include "timing.h" /* * This flag is set in ide.c by the parameter: ide0=cmd640_vlb @@ -200,7 +200,7 @@ static struct ata_device *cmd_drives[4]; * Interface to access cmd640x registers */ static unsigned int cmd640_key; -static void (*put_cmd640_reg)(unsigned short reg, byte val); +static void (*put_cmd640_reg)(unsigned short reg, u8 val); static u8 (*get_cmd640_reg)(unsigned short reg); /* @@ -219,7 +219,7 @@ static spinlock_t cmd640_lock = SPIN_LOCK_UNLOCKED; /* PCI method 1 access */ -static void put_cmd640_reg_pci1 (unsigned short reg, byte val) +static void put_cmd640_reg_pci1 (unsigned short reg, u8 val) { unsigned long flags; @@ -641,7 +641,7 @@ static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle /* * Drive PIO mode selection: */ -static void cmd640_tune_drive(struct ata_device *drive, byte mode_wanted) +static void cmd640_tune_drive(struct ata_device *drive, u8 mode_wanted) { u8 b; struct ata_timing *t; diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 188aeac9074c..0d6c087b361f 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c @@ -18,13 +18,13 @@ #include #include #include -#include #include +#include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" #define CMD_DEBUG 0 @@ -81,8 +81,8 @@ * Registers and masks for easy access by drive index: */ #if 0 -static byte prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23}; -static byte prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3}; +static u8 prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23}; +static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3}; #endif /* @@ -93,15 +93,15 @@ static void program_drive_counts(struct ata_device *drive, int setup_count, int { unsigned long flags; struct ata_device *drives = drive->channel->drives; - byte temp_b; - static const byte setup_counts[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; - static const byte recovery_counts[] = + u8 temp_b; + static const u8 setup_counts[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; + static const u8 recovery_counts[] = {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; - static const byte arttim_regs[2][2] = { + static const u8 arttim_regs[2][2] = { { ARTTIM0, ARTTIM1 }, { ARTTIM23, ARTTIM23 } }; - static const byte drwtim_regs[2][2] = { + static const u8 drwtim_regs[2][2] = { { DRWTIM0, DRWTIM1 }, { DRWTIM2, DRWTIM3 } }; @@ -142,11 +142,11 @@ static void program_drive_counts(struct ata_device *drive, int setup_count, int */ (void) pci_read_config_byte(drive->channel->pci_dev, arttim_regs[channel][slave], &temp_b); (void) pci_write_config_byte(drive->channel->pci_dev, arttim_regs[channel][slave], - ((byte) setup_count) | (temp_b & 0x3f)); + ((u8) setup_count) | (temp_b & 0x3f)); (void) pci_write_config_byte(drive->channel->pci_dev, drwtim_regs[channel][slave], - (byte) ((active_count << 4) | recovery_count)); - cmdprintk ("Write %x to %x\n", ((byte) setup_count) | (temp_b & 0x3f), arttim_regs[channel][slave]); - cmdprintk ("Write %x to %x\n", (byte) ((active_count << 4) | recovery_count), drwtim_regs[channel][slave]); + (u8) ((active_count << 4) | recovery_count)); + cmdprintk ("Write %x to %x\n", ((u8) setup_count) | (temp_b & 0x3f), arttim_regs[channel][slave]); + cmdprintk ("Write %x to %x\n", (u8) ((active_count << 4) | recovery_count), drwtim_regs[channel][slave]); local_irq_restore(flags); } @@ -405,7 +405,7 @@ static int cmd64x_tune_chipset(struct ata_device *drive, u8 speed) return ide_config_drive_speed(drive, speed); } -static int cmd680_tune_chipset(struct ata_device *drive, byte speed) +static int cmd680_tune_chipset(struct ata_device *drive, u8 speed) { struct ata_channel *hwif = drive->channel; struct pci_dev *dev = hwif->pci_dev; @@ -520,9 +520,9 @@ static int cmd64x_udma_stop(struct ata_device *drive) dma_stat = inb(dma_base+2); /* get DMA status */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ if (jack_slap) { - byte dma_intr = 0; - byte dma_mask = (ch->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; - byte dma_reg = (ch->unit) ? ARTTIM2 : CFR; + u8 dma_intr = 0; + u8 dma_mask = (ch->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; + u8 dma_reg = (ch->unit) ? ARTTIM2 : CFR; (void) pci_read_config_byte(dev, dma_reg, &dma_intr); /* * DAMN BMIDE is not connected to PCI space! diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c index b761e7896385..89ee79cfcda3 100644 --- a/drivers/ide/cs5530.c +++ b/drivers/ide/cs5530.c @@ -20,22 +20,22 @@ #include #include #include -#include #include #include #include +#include #include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" /* * Set a new transfer mode at the drive */ -int cs5530_set_xfer_mode(struct ata_device *drive, byte mode) +int cs5530_set_xfer_mode(struct ata_device *drive, u8 mode) { int error = 0; @@ -67,7 +67,7 @@ static unsigned int cs5530_pio_timings[2][5] = * The ide_init_cs5530() routine guarantees that all drives * will have valid default PIO timings set up before we get here. */ -static void cs5530_tuneproc(struct ata_device *drive, byte pio) /* pio=255 means "autotune" */ +static void cs5530_tuneproc(struct ata_device *drive, u8 pio) { struct ata_channel *hwif = drive->channel; unsigned int format, basereg = CS5530_BASEREG(hwif); @@ -75,7 +75,7 @@ static void cs5530_tuneproc(struct ata_device *drive, byte pio) /* pio=255 means if (pio == 255) pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO); else - pio = XFER_PIO_0 + min_t(byte, pio, 4); + pio = XFER_PIO_0 + min_t(u8, pio, 4); if (!cs5530_set_xfer_mode(drive, pio)) { format = (inl(basereg+4) >> 31) & 1; @@ -206,7 +206,7 @@ static unsigned int __init pci_init_cs5530(struct pci_dev *dev) unsigned short pcicmd = 0; unsigned long flags; - pci_for_each_dev (dev) { + pci_for_each_dev(dev) { if (dev->vendor == PCI_VENDOR_ID_CYRIX) { switch (dev->device) { case PCI_DEVICE_ID_CYRIX_PCI_MASTER: @@ -256,7 +256,7 @@ static unsigned int __init pci_init_cs5530(struct pci_dev *dev) */ pci_write_config_byte(master_0, 0x40, 0x1e); - /* + /* * Set max PCI burst size (16-bytes seems to work best): * 16bytes: set bit-1 at 0x41 (reg value of 0x16) * all others: clear bit-1 at 0x41, and do: diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c index 297b55d18ce2..acf889aad4dd 100644 --- a/drivers/ide/cy82c693.c +++ b/drivers/ide/cy82c693.c @@ -47,11 +47,12 @@ #include #include #include +#include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" /* the current version */ @@ -141,7 +142,7 @@ static u8 calc_clk(int time, int bus_speed) * for mode 3 and 4 drives 8 and 16-bit timings are the same * */ -/* FIXME: use generic ata-timings library --bkz */ +/* FIXME: use generic timings library --bkz */ static void compute_clocks(u8 pio, pio_clocks_t *p_pclk) { struct ata_timing *t; @@ -186,8 +187,8 @@ static void compute_clocks(u8 pio, pio_clocks_t *p_pclk) */ static void cy82c693_dma_enable(struct ata_device *drive, int mode, int single) { - byte index; - byte data; + u8 index; + u8 data; if (mode>2) /* make sure we set a valid mode */ mode = 2; @@ -206,7 +207,7 @@ static void cy82c693_dma_enable(struct ata_device *drive, int mode, int single) printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", drive->name, drive->channel->unit, drive->select.b.unit, (data&0x3), ((data>>2)&1)); #endif - data = (byte)mode|(byte)(single<<2); + data = (u8) mode | (u8) (single << 2); OUT_BYTE(index, CY82_INDEX_PORT); OUT_BYTE(data, CY82_DATA_PORT); @@ -271,7 +272,7 @@ static int cy82c693_udma_setup(struct ata_device *drive, int map) /* * tune ide drive - set PIO mode */ -static void cy82c693_tune_drive(struct ata_device *drive, byte pio) +static void cy82c693_tune_drive(struct ata_device *drive, u8 pio) { struct ata_channel *hwif = drive->channel; struct pci_dev *dev = hwif->pci_dev; diff --git a/drivers/ide/dtc2278.c b/drivers/ide/dtc2278.c index 45cd4d9c7f81..8d947231d2ab 100644 --- a/drivers/ide/dtc2278.c +++ b/drivers/ide/dtc2278.c @@ -9,13 +9,13 @@ #include #include #include +#include #include #include -#include #include -#include "ata-timing.h" +#include "timing.h" /* * Changing this #undef to #define may solve start up problems in some systems. @@ -66,7 +66,7 @@ static void sub22 (char b, char c) } } -static void tune_dtc2278(struct ata_device *drive, byte pio) +static void tune_dtc2278(struct ata_device *drive, u8 pio) { unsigned long flags; diff --git a/drivers/ide/hpt34x.c b/drivers/ide/hpt34x.c index 9f5d08d42f2c..8fb181800602 100644 --- a/drivers/ide/hpt34x.c +++ b/drivers/ide/hpt34x.c @@ -21,16 +21,16 @@ #include #include #include -#include #include #include #include +#include #include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" #define HPT343_DEBUG_DRIVE_INFO 0 diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index a24e170bee2e..c2204b5b7ef4 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c @@ -53,18 +53,17 @@ #include #include #include -#include - #include #include #include +#include #include #include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" diff --git a/drivers/ide/hptraid.c b/drivers/ide/hptraid.c index 43b45c6e06eb..d4742834b864 100644 --- a/drivers/ide/hptraid.c +++ b/drivers/ide/hptraid.c @@ -105,10 +105,10 @@ static int hptraid_ioctl(struct inode *inode, struct file *file, if (!loc) return -EINVAL; val = 255; - if (put_user(val, (byte *) & loc->heads)) + if (put_user(val, (u8 *) & loc->heads)) return -EFAULT; val = 63; - if (put_user(val, (byte *) & loc->sectors)) + if (put_user(val, (u8 *) & loc->sectors)) return -EFAULT; bios_cyl = raid[minor].sectors / 63 / 255; if (put_user diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c index 55f39b8c506e..34207cd5d911 100644 --- a/drivers/ide/ht6560b.c +++ b/drivers/ide/ht6560b.c @@ -38,13 +38,13 @@ #include #include #include +#include #include #include -#include #include -#include "ata-timing.h" +#include "timing.h" /* #define DEBUG */ /* remove comments for DEBUG messages */ @@ -61,7 +61,7 @@ * bit3 (0x08): "1" 3 cycle time, "0" 2 cycle time (?) */ #define HT_CONFIG_PORT 0x3e6 -#define HT_CONFIG(drivea) (byte)(((drivea)->drive_data & 0xff00) >> 8) +#define HT_CONFIG(drivea) (u8)(((drivea)->drive_data & 0xff00) >> 8) /* * FIFO + PREFETCH (both a/b-model) */ @@ -107,7 +107,7 @@ * Active Time for each drive. Smaller value gives higher speed. * In case of failures you should probably fall back to a higher value. */ -#define HT_TIMING(drivea) (byte)((drivea)->drive_data & 0x00ff) +#define HT_TIMING(drivea) (u8)((drivea)->drive_data & 0x00ff) #define HT_TIMING_DEFAULT 0xff /* @@ -194,7 +194,7 @@ static int __init try_to_init_ht6560b(void) return 1; } -static byte ht_pio2timings(struct ata_device *drive, byte pio) +static u8 ht_pio2timings(struct ata_device *drive, u8 pio) { int active_time, recovery_time; int active_cycles, recovery_cycles; @@ -204,7 +204,7 @@ static byte ht_pio2timings(struct ata_device *drive, byte pio) if (pio == 255) pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO); else - pio = XFER_PIO_0 + min_t(byte, pio, 4); + pio = XFER_PIO_0 + min_t(u8, pio, 4); t = ata_timing_data(pio); @@ -233,7 +233,7 @@ static byte ht_pio2timings(struct ata_device *drive, byte pio) drive->name, pio - XFER_PIO_0, recovery_cycles, recovery_time, active_cycles, active_time); #endif - return (byte)((recovery_cycles << 4) | active_cycles); + return (u8)((recovery_cycles << 4) | active_cycles); } else { #ifdef DEBUG @@ -247,7 +247,7 @@ static byte ht_pio2timings(struct ata_device *drive, byte pio) /* * Enable/Disable so called prefetch mode */ -static void ht_set_prefetch(struct ata_device *drive, byte state) +static void ht_set_prefetch(struct ata_device *drive, u8 state) { unsigned long flags; int t = HT_PREFETCH_MODE << 8; @@ -274,10 +274,10 @@ static void ht_set_prefetch(struct ata_device *drive, byte state) #endif } -static void tune_ht6560b(struct ata_device *drive, byte pio) +static void tune_ht6560b(struct ata_device *drive, u8 pio) { unsigned long flags; - byte timing; + u8 timing; switch (pio) { case 8: /* set prefetch off */ diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index cd2af4ca8faa..a93846b806a6 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c @@ -377,7 +377,7 @@ icside_config_if(struct ata_device *drive, int xfer_mode) return on; } -static int icside_set_speed(struct ata_device *drive, byte speed) +static int icside_set_speed(struct ata_device *drive, u8 speed) { return icside_config_if(drive, speed); } diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 166971c7307d..1e4dbbebcec7 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1716,7 +1716,7 @@ void msf_from_bcd (struct atapi_msf *msf) static inline -void lba_to_msf (int lba, byte *m, byte *s, byte *f) +void lba_to_msf(int lba, u8 *m, u8 *s, u8 *f) { lba += CD_MSF_OFFSET; lba &= 0xffffff; /* negative lbas use only 24 bits */ @@ -1728,7 +1728,7 @@ void lba_to_msf (int lba, byte *m, byte *s, byte *f) static inline -int msf_to_lba (byte m, byte s, byte f) +int msf_to_lba(u8 m, u8 s, u8 f) { return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET; } diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index dcd660ce6ce1..7f4ac20a5b5a 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -80,7 +80,7 @@ struct ide_cd_config_flags { __u8 close_tray : 1; /* can close the tray */ __u8 writing : 1; /* pseudo write in progress */ __u8 reserved : 3; - byte max_speed; /* Max speed of the drive */ + u8 max_speed; /* Max speed of the drive */ }; #define CDROM_CONFIG_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->config_flags)) @@ -92,7 +92,7 @@ struct ide_cd_state_flags { __u8 door_locked : 1; /* We think that the drive door is locked. */ __u8 writing : 1; /* the drive is currently writing */ __u8 reserved : 4; - byte current_speed; /* Current speed of the drive */ + u8 current_speed; /* Current speed of the drive */ }; #define CDROM_STATE_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->state_flags)) @@ -132,7 +132,7 @@ struct atapi_toc_header { } __attribute__((packed)); struct atapi_toc_entry { - byte reserved1; + u8 reserved1; #if defined(__BIG_ENDIAN_BITFIELD) __u8 adr : 4; __u8 control : 4; @@ -142,8 +142,8 @@ struct atapi_toc_entry { #else #error "Please fix " #endif - byte track; - byte reserved2; + u8 track; + u8 reserved2; union { unsigned lba; struct atapi_msf msf; @@ -176,8 +176,8 @@ struct atapi_cdrom_subchnl { #else #error "Please fix " #endif - u_char acdsc_trk; - u_char acdsc_ind; + u8 acdsc_trk; + u8 acdsc_ind; union { struct atapi_msf msf; int lba; @@ -207,7 +207,7 @@ struct atapi_capabilities_page { #error "Please fix " #endif - byte page_length; + u8 page_length; #if defined(__BIG_ENDIAN_BITFIELD) __u8 reserved2 : 2; @@ -435,8 +435,8 @@ struct atapi_mechstat_header { #error "Please fix " #endif - byte curlba[3]; - byte nslots; + u8 curlba[3]; + u8 nslots; __u16 slot_tablelen; }; @@ -454,7 +454,7 @@ struct atapi_slot { #error "Please fix " #endif - byte reserved2[3]; + u8 reserved2[3]; }; struct atapi_changer_info { @@ -514,13 +514,11 @@ struct cdrom_info { #define ABORTED_COMMAND 0x0b #define MISCOMPARE 0x0e - - /* This stuff should be in cdrom.h, since it is now generic... */ #if VERBOSE_IDE_CD_ERRORS /* The generic packet command opcodes for CD/DVD Logical Units, - * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */ + * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */ const struct { unsigned short packet_command; const char * const text; diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index cd3fd43b4b23..4070de3d2832 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -24,8 +24,9 @@ #include #include #include -#include #include /* for invalidate_bdev() */ +#include +#include #include #include diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index a05c8b00c9ce..e346d1d12b58 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -245,8 +245,8 @@ typedef struct { /* * Last error information */ - byte sense_key, asc, ascq; - byte ticks; /* delay this long before sending packet command */ + u8 sense_key, asc, ascq; + u8 ticks; /* delay this long before sending packet command */ int progress_indication; /* diff --git a/drivers/ide/ide-m8xx.c b/drivers/ide/ide-m8xx.c index a04398c9e12c..c842699af329 100644 --- a/drivers/ide/ide-m8xx.c +++ b/drivers/ide/ide-m8xx.c @@ -29,8 +29,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -43,7 +44,7 @@ #include #include -#include "ata-timing.h" +#include "timing.h" static int identify (volatile unsigned char *p); static void print_fixed (volatile unsigned char *p); @@ -51,7 +52,7 @@ static void print_funcid (int func); static int check_ide_device (unsigned long base); static int ide_interrupt_ack(struct ata_channel *); -static void m8xx_ide_tuneproc(struct ata_device *drive, byte pio); +static void m8xx_ide_tuneproc(struct ata_device *drive, u8 pio); typedef struct ide_ioport_desc { unsigned long base_off; /* Offset to PCMCIA memory */ @@ -437,7 +438,7 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw, /* Calculate PIO timings */ static void -m8xx_ide_tuneproc(struct ata_device *drive, byte pio) +m8xx_ide_tuneproc(struct ata_device *drive, u8 pio) { #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT) volatile pcmconf8xx_t *pcmp; diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c index e9076cb4869c..a9173ffad2dd 100644 --- a/drivers/ide/ide-pci.c +++ b/drivers/ide/ide-pci.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -30,7 +31,7 @@ /* * This is the list of registered PCI chipset driver data structures. */ -static struct ata_pci_device *ata_pci_device_list = NULL; +static struct ata_pci_device *ata_pci_device_list; /* = NULL */ /* * This function supplies the data necessary to detect the particular chipset. diff --git a/drivers/ide/ide-pmac.c b/drivers/ide/ide-pmac.c index 5a52c4fa4169..4630dbc4fe5d 100644 --- a/drivers/ide/ide-pmac.c +++ b/drivers/ide/ide-pmac.c @@ -34,8 +34,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -51,7 +52,7 @@ #include #include #endif -#include "ata-timing.h" +#include "timing.h" #undef IDE_PMAC_DEBUG @@ -262,8 +263,8 @@ static int pmac_udma_init(struct ata_device *drive, struct request *rq); static int pmac_udma_irq_status(struct ata_device *drive); static int pmac_udma_setup(struct ata_device *drive, int map); static int pmac_ide_build_dmatable(struct ata_device *drive, struct request *rq, int ix, int wr); -static int pmac_ide_tune_chipset(struct ata_device *drive, byte speed); -static void pmac_ide_tuneproc(struct ata_device *drive, byte pio); +static int pmac_ide_tune_chipset(struct ata_device *drive, u8 speed); +static void pmac_ide_tuneproc(struct ata_device *drive, u8 pio); static void pmac_ide_selectproc(struct ata_device *drive); #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ @@ -457,7 +458,7 @@ out: /* Calculate PIO timings */ static void __pmac -pmac_ide_tuneproc(struct ata_device *drive, byte pio) +pmac_ide_tuneproc(struct ata_device *drive, u8 pio) { struct ata_timing *t; int i; @@ -472,7 +473,7 @@ pmac_ide_tuneproc(struct ata_device *drive, byte pio) if (pio == 255) pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO); else - pio = XFER_PIO_0 + min_t(byte, pio, 4); + pio = XFER_PIO_0 + min_t(u8, pio, 4); t = ata_timing_data(pio); @@ -523,8 +524,7 @@ pmac_ide_tuneproc(struct ata_device *drive, byte pio) } #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC -static int __pmac -set_timings_udma(u32 *timings, byte speed) +static int __pmac set_timings_udma(u32 *timings, u8 speed) { unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks; @@ -546,7 +546,7 @@ set_timings_udma(u32 *timings, byte speed) } static int __pmac -set_timings_mdma(int intf_type, u32 *timings, byte speed, int drive_cycle_time) +set_timings_mdma(int intf_type, u32 *timings, u8 speed, int drive_cycle_time) { int cycleTime, accessTime, recTime; unsigned accessTicks, recTicks; @@ -659,7 +659,7 @@ set_timings_mdma(int intf_type, u32 *timings, byte speed, int drive_cycle_time) * our, normal mdma function is supposed to be more precise */ static int __pmac -pmac_ide_tune_chipset (struct ata_device *drive, byte speed) +pmac_ide_tune_chipset (struct ata_device *drive, u8 speed) { int intf = pmac_ide_find(drive); int unit = (drive->select.b.unit & 0x01); @@ -1211,8 +1211,8 @@ udma_bits_to_command(unsigned char bits, int high_speed) static int __pmac pmac_ide_mdma_enable(struct ata_device *drive, int idx) { - byte bits = drive->id->dma_mword & 0x07; - byte feature = dma_bits_to_command(bits); + u8 bits = drive->id->dma_mword & 0x07; + u8 feature = dma_bits_to_command(bits); u32 *timings; int drive_cycle_time; struct hd_driveid *id = drive->id; @@ -1249,8 +1249,8 @@ pmac_ide_mdma_enable(struct ata_device *drive, int idx) static int __pmac pmac_ide_udma_enable(struct ata_device *drive, int idx, int high_speed) { - byte bits = drive->id->dma_ultra & 0x1f; - byte feature = udma_bits_to_command(bits, high_speed); + u8 bits = drive->id->dma_ultra & 0x1f; + u8 feature = udma_bits_to_command(bits, high_speed); u32 *timings; int ret; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 2c1fe77c4cb2..4dc463ba33fa 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -827,7 +827,7 @@ typedef struct { /* * Read position information */ - byte partition; + u8 partition; unsigned int first_frame_position; /* Current block */ unsigned int last_frame_position; unsigned int blocks_in_buffer; @@ -835,7 +835,7 @@ typedef struct { /* * Last error information */ - byte sense_key, asc, ascq; + u8 sense_key, asc, ascq; /* * Character device operation @@ -1237,7 +1237,7 @@ static int idetape_chrdev_present = 0; * DO NOT REMOVE, BUILDING A VERBOSE DEBUG SCHEME FOR ATAPI */ -char *idetape_sense_key_verbose (byte idetape_sense_key) +char *idetape_sense_key_verbose(u8 idetape_sense_key) { switch (idetape_sense_key) { default: { diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 230bad45d91d..3b776c4dae02 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -49,12 +49,13 @@ #endif #include #include -#include #include #include #include #include #include +#include +#include #include #include @@ -62,7 +63,7 @@ #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" #include "ioctl.h" @@ -258,7 +259,7 @@ static struct ata_bit_messages ata_error_msgs[] = { { MARK_ERR, MARK_ERR, "addr mark not found" } }; -static void dump_bits(struct ata_bit_messages *msgs, int nr, byte bits) +static void dump_bits(struct ata_bit_messages *msgs, int nr, u8 bits) { int i; int first = 1; diff --git a/drivers/ide/ioctl.c b/drivers/ide/ioctl.c index 003b743b4772..d1b5f6f8d4ad 100644 --- a/drivers/ide/ioctl.c +++ b/drivers/ide/ioctl.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include #include @@ -230,13 +230,13 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned if (!loc || (drive->type != ATA_DISK && drive->type != ATA_FLOPPY)) return -EINVAL; - if (put_user(drive->bios_head, (byte *) &loc->heads)) + if (put_user(drive->bios_head, (u8 *) &loc->heads)) return -EFAULT; - if (put_user(drive->bios_sect, (byte *) &loc->sectors)) + if (put_user(drive->bios_sect, (u8 *) &loc->sectors)) return -EFAULT; - if (put_user(bios_cyl, (unsigned short *) &loc->cylinders)) + if (put_user(bios_cyl, (u16 *) &loc->cylinders)) return -EFAULT; if (put_user((unsigned)drive->part[minor(inode->i_rdev)&PARTN_MASK].start_sect, @@ -283,18 +283,18 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned case HDIO_GET_NICE: - return put_user(drive->dsc_overlap << IDE_NICE_DSC_OVERLAP | - drive->atapi_overlap << IDE_NICE_ATAPI_OVERLAP, + return put_user(drive->dsc_overlap | drive->atapi_overlap << 1, (long *) arg); case HDIO_SET_NICE: if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP)))) + if (arg != (arg & 1)) return -EPERM; - drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1; + drive->dsc_overlap = arg & 1; + /* Only CD-ROM's and tapes support DSC overlap. */ if (drive->dsc_overlap && !(drive->type == ATA_ROM || drive->type == ATA_TAPE)) { drive->dsc_overlap = 0; diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c index 002dc1766fd0..838718764c4f 100644 --- a/drivers/ide/it8172.c +++ b/drivers/ide/it8172.c @@ -33,16 +33,15 @@ #include #include #include -#include -#include #include #include +#include #include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" diff --git a/drivers/ide/main.c b/drivers/ide/main.c index a3e134deef6b..c59fe6307400 100644 --- a/drivers/ide/main.c +++ b/drivers/ide/main.c @@ -35,12 +35,13 @@ #endif #include #include -#include #include #include #include #include #include +#include +#include #include #include @@ -48,7 +49,7 @@ #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" #include "ioctl.h" diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c index 379bde73032d..61f9b75eef67 100644 --- a/drivers/ide/ns87415.c +++ b/drivers/ide/ns87415.c @@ -126,7 +126,7 @@ static void __init ide_init_ns87415(struct ata_channel *hwif) { struct pci_dev *dev = hwif->pci_dev; unsigned int ctrl, using_inta; - byte progif; + u8 progif; /* Set a good latency timer and cache line size value. */ (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); diff --git a/drivers/ide/opti621.c b/drivers/ide/opti621.c index 6b025f3e93ce..c141def6663d 100644 --- a/drivers/ide/opti621.c +++ b/drivers/ide/opti621.c @@ -99,7 +99,7 @@ #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" #define OPTI621_MAX_PIO 3 @@ -137,7 +137,7 @@ int reg_base; /* there are stored pio numbers from other calls of opti621_tune_drive */ -static void compute_pios(struct ata_device *drive, byte pio) +static void compute_pios(struct ata_device *drive, u8 pio) /* Store values into drive->drive_data * second_contr - 0 for primary controller, 1 for secondary * slave_drive - 0 -> pio is for master, 1 -> pio is for slave @@ -178,7 +178,7 @@ static int cmpt_clk(int time, int bus_speed) return ((time*bus_speed+999999)/1000000); } -static void write_reg(byte value, int reg) +static void write_reg(u8 value, int reg) /* Write value to register reg, base of register * is at reg_base (0x1f0 primary, 0x170 secondary, * if not changed by PCI configuration). @@ -192,14 +192,14 @@ static void write_reg(byte value, int reg) outb(0x83, reg_base+2); } -static byte read_reg(int reg) +static u8 read_reg(int reg) /* Read value from register reg, base of register * is at reg_base (0x1f0 primary, 0x170 secondary, * if not changed by PCI configuration). * This is from setupvic.exe program. */ { - byte ret; + u8 ret; inw(reg_base+1); inw(reg_base+1); outb(3, reg_base+2); @@ -245,16 +245,16 @@ static void compute_clocks(int pio, pio_clocks_t *clks) } /* Main tune procedure, called from tuneproc. */ -static void opti621_tune_drive(struct ata_device *drive, byte pio) +static void opti621_tune_drive(struct ata_device *drive, u8 pio) { /* primary and secondary drives share some registers, * so we have to program both drives */ unsigned long flags; - byte pio1, pio2; + u8 pio1, pio2; pio_clocks_t first, second; int ax, drdy; - byte cycle1, cycle2, misc; + u8 cycle1, cycle2, misc; struct ata_channel *hwif = drive->channel; /* sets drive->drive_data for both drives */ diff --git a/drivers/ide/pcidma.c b/drivers/ide/pcidma.c index a476693a3820..2674e69327dc 100644 --- a/drivers/ide/pcidma.c +++ b/drivers/ide/pcidma.c @@ -24,10 +24,11 @@ #include #include #include -#include #include +#include +#include -#include "ata-timing.h" +#include "timing.h" #include #include diff --git a/drivers/ide/pdc202xx.c b/drivers/ide/pdc202xx.c index 28f888d4a9c4..1d871fdcc1d2 100644 --- a/drivers/ide/pdc202xx.c +++ b/drivers/ide/pdc202xx.c @@ -48,16 +48,16 @@ #include #include #include -#include #include #include #include +#include #include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" #define PDC202XX_DEBUG_DRIVE_INFO 0 @@ -105,7 +105,7 @@ static struct pdc_bit_messages pdc_reg_C[] = { /* MC3-MC0 - DMA "C" timing */ }; -static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits) +static void pdc_dump_bits(struct pdc_bit_messages *msgs, u8 bits) { int i; @@ -174,7 +174,7 @@ static int __init pdc202xx_modes_map(struct ata_channel *ch) return map; } -static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed) +static int pdc202xx_tune_chipset(struct ata_device *drive, u8 speed) { struct pci_dev *dev = drive->channel->pci_dev; u32 drive_conf; @@ -315,7 +315,7 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed) OUT_BYTE(value, reg); \ mdelay(delay); -static int pdc202xx_new_tune_chipset(struct ata_device *drive, byte speed) +static int pdc202xx_new_tune_chipset(struct ata_device *drive, u8 speed) { struct ata_channel *hwif = drive->channel; u32 high_16 = pci_resource_start(hwif->pci_dev, 4); @@ -453,7 +453,7 @@ static void pdc202xx_tune_drive(struct ata_device *drive, u8 pio) if (pio == 255) speed = ata_best_pio_mode(drive); else - speed = XFER_PIO_0 + min_t(byte, pio, 4); + speed = XFER_PIO_0 + min_t(u8, pio, 4); pdc202xx_tune_chipset(drive, speed); } @@ -695,7 +695,7 @@ static unsigned int __init pdc202xx_init_chipset(struct pci_dev *dev) break; default: if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { - byte irq = 0, irq2 = 0; + u8 irq = 0, irq2 = 0; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); pci_read_config_byte(dev, (PCI_INTERRUPT_LINE) | 0x80, &irq2); /* 0xbc */ diff --git a/drivers/ide/pdc4030.c b/drivers/ide/pdc4030.c index 323be48b0e30..c08a6914c7ff 100644 --- a/drivers/ide/pdc4030.c +++ b/drivers/ide/pdc4030.c @@ -175,10 +175,10 @@ static void promise_selectproc(struct ata_device *drive) * by command F0. They all have the same success/failure notification - * 'P' (=0x50) on success, 'p' (=0x70) on failure. */ -int pdc4030_cmd(struct ata_device *drive, byte cmd) +int pdc4030_cmd(struct ata_device *drive, u8 cmd) { unsigned long timeout, timer; - byte status_val; + u8 status_val; promise_selectproc(drive); /* redundant? */ outb(0xF3, IDE_SECTOR_REG); diff --git a/drivers/ide/pdcraid.c b/drivers/ide/pdcraid.c index d1bd67ba7f45..f4b7fc0f82e1 100644 --- a/drivers/ide/pdcraid.c +++ b/drivers/ide/pdcraid.c @@ -135,11 +135,11 @@ static int pdcraid_ioctl(struct inode *inode, struct file *file, return -EINVAL; if (put_user (raid[minor].geom.heads, - (byte *) & loc->heads)) + (u8 *) & loc->heads)) return -EFAULT; if (put_user (raid[minor].geom.sectors, - (byte *) & loc->sectors)) + (u8 *) & loc->sectors)) return -EFAULT; if (put_user (bios_cyl, (unsigned short *) &loc->cylinders)) diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index a5fb9998bf56..b56759830069 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c @@ -45,11 +45,12 @@ #include #include #include +#include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" #define PIIX_IDETIM0 0x40 @@ -240,7 +241,7 @@ static void piix_tune_drive(struct ata_device *drive, unsigned char pio) return; } - piix_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5)); + piix_set_drive(drive, XFER_PIO_0 + min_t(u8, pio, 5)); } #ifdef CONFIG_BLK_DEV_IDEDMA diff --git a/drivers/ide/probe.c b/drivers/ide/probe.c index abe93fece6cf..3766b7531c78 100644 --- a/drivers/ide/probe.c +++ b/drivers/ide/probe.c @@ -28,9 +28,10 @@ #include #include #include -#include #include #include +#include +#include #include #include @@ -302,18 +303,18 @@ void ide_fixstring(char *s, const int bytecount, const int byteswap) /* * All hosts that use the 80c ribbon must use this! */ -byte eighty_ninty_three(struct ata_device *drive) +int eighty_ninty_three(struct ata_device *drive) { - return ((u8) ((drive->channel->udma_four) && + return ((drive->channel->udma_four) && #ifndef CONFIG_IDEDMA_IVB (drive->id->hw_config & 0x4000) && #endif - (drive->id->hw_config & 0x6000)) ? 1 : 0); + (drive->id->hw_config & 0x6000)) ? 1 : 0; } /* FIXME: Channel lock should be held. */ -int ide_config_drive_speed(struct ata_device *drive, byte speed) +int ide_config_drive_speed(struct ata_device *drive, u8 speed) { struct ata_channel *ch = drive->channel; int ret; diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c index 6fce3b4bf491..633a75950d60 100644 --- a/drivers/ide/qd65xx.c +++ b/drivers/ide/qd65xx.c @@ -29,12 +29,13 @@ #include #include #include +#include #include #include -#include + #include -#include "ata-timing.h" +#include "timing.h" #include "qd65xx.h" /* @@ -85,7 +86,7 @@ static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */ -static void qd_write_reg(byte content, byte reg) +static void qd_write_reg(u8 content, unsigned int reg) { unsigned long flags; @@ -95,10 +96,10 @@ static void qd_write_reg(byte content, byte reg) restore_flags(flags); /* all CPUs */ } -byte __init qd_read_reg(byte reg) +static u8 __init qd_read_reg(unsigned int reg) { unsigned long flags; - byte read; + u8 read; save_flags(flags); /* all CPUs */ cli(); /* all CPUs */ @@ -115,8 +116,8 @@ byte __init qd_read_reg(byte reg) static void qd_select(struct ata_device *drive) { - byte index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) | - (QD_TIMREG(drive) & 0x02); + u8 index = (((QD_TIMREG(drive)) & 0x80 ) >> 7) | + (QD_TIMREG(drive) & 0x02); if (timings[index] != QD_TIMING(drive)) qd_write_reg(timings[index] = QD_TIMING(drive), QD_TIMREG(drive)); @@ -130,9 +131,9 @@ static void qd_select(struct ata_device *drive) * upper nibble represents recovery time, in count of VLB clocks */ -static byte qd6500_compute_timing(struct ata_channel *hwif, int active_time, int recovery_time) +static u8 qd6500_compute_timing(struct ata_channel *hwif, int active_time, int recovery_time) { - byte active_cycle,recovery_cycle; + u8 active_cycle,recovery_cycle; if (system_bus_speed <= 33333) { active_cycle = 9 - IDE_IN(active_time * system_bus_speed / 1000000 + 1, 2, 9); @@ -151,12 +152,12 @@ static byte qd6500_compute_timing(struct ata_channel *hwif, int active_time, int * idem for qd6580 */ -static byte qd6580_compute_timing(int active_time, int recovery_time) +static u8 qd6580_compute_timing(int active_time, int recovery_time) { - byte active_cycle = 17 - IDE_IN(active_time * system_bus_speed / 1000000 + 1, 2, 17); - byte recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_speed / 1000000 + 1, 2, 15); + u8 active_cycle = 17 - IDE_IN(active_time * system_bus_speed / 1000000 + 1, 2, 17); + u8 recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_speed / 1000000 + 1, 2, 15); - return((recovery_cycle<<4) | active_cycle); + return (recovery_cycle<<4) | active_cycle; } /* @@ -205,7 +206,7 @@ static int qd_timing_ok(struct ata_device drives[]) * records the timing, and enables selectproc as needed */ -static void qd_set_timing(struct ata_device *drive, byte timing) +static void qd_set_timing(struct ata_device *drive, u8 timing) { struct ata_channel *hwif = drive->channel; @@ -224,7 +225,7 @@ static void qd_set_timing(struct ata_device *drive, byte timing) * qd6500_tune_drive */ -static void qd6500_tune_drive(struct ata_device *drive, byte pio) +static void qd6500_tune_drive(struct ata_device *drive, u8 pio) { int active_time = 175; int recovery_time = 415; /* worst case values from the dos driver */ @@ -245,7 +246,7 @@ static void qd6500_tune_drive(struct ata_device *drive, byte pio) * qd6580_tune_drive */ -static void qd6580_tune_drive(struct ata_device *drive, byte pio) +static void qd6580_tune_drive(struct ata_device *drive, u8 pio) { struct ata_timing *t; int base = drive->channel->select_data; @@ -257,7 +258,7 @@ static void qd6580_tune_drive(struct ata_device *drive, byte pio) if (pio == 255) pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO); else - pio = XFER_PIO_0 + min_t(byte, pio, 4); + pio = XFER_PIO_0 + min_t(u8, pio, 4); t = ata_timing_data(pio); @@ -305,8 +306,8 @@ static void qd6580_tune_drive(struct ata_device *drive, byte pio) static int __init qd_testreg(int port) { - byte savereg; - byte readreg; + u8 savereg; + u8 readreg; unsigned long flags; save_flags(flags); /* all CPUs */ @@ -333,7 +334,7 @@ static int __init qd_testreg(int port) * called to setup an ata channel : adjusts attributes & links for tuning */ -void __init qd_setup(int unit, int base, int config, unsigned int data0, unsigned int data1, void (*tuneproc) (struct ata_device *, byte pio)) +void __init qd_setup(int unit, int base, int config, unsigned int data0, unsigned int data1, void (*tuneproc) (struct ata_device *, u8 pio)) { struct ata_channel *hwif = &ide_hwifs[unit]; @@ -354,7 +355,7 @@ void __init qd_setup(int unit, int base, int config, unsigned int data0, unsigne */ void __init qd_unsetup(int unit) { struct ata_channel *hwif = &ide_hwifs[unit]; - byte config = hwif->config_data; + u8 config = hwif->config_data; int base = hwif->select_data; void *tuneproc = (void *) hwif->tuneproc; @@ -390,7 +391,7 @@ void __init qd_unsetup(int unit) { int __init qd_probe(int base) { - byte config; + u8 config; int unit; config = qd_read_reg(QD_CONFIG_PORT); @@ -417,7 +418,7 @@ int __init qd_probe(int base) } if (((config & 0xf0) == QD_CONFIG_QD6580_A) || ((config & 0xf0) == QD_CONFIG_QD6580_B)) { - byte control; + u8 control; if (qd_testreg(base) || qd_testreg(base+0x02)) return 1; /* bad registers */ diff --git a/drivers/ide/qd65xx.h b/drivers/ide/qd65xx.h index 73a7d76bbf6e..e0136907954c 100644 --- a/drivers/ide/qd65xx.h +++ b/drivers/ide/qd65xx.h @@ -34,8 +34,8 @@ #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) #define QD_CONTROL(hwif) (((hwif)->config_data & 0xff00) >> 8) -#define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff) -#define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8) +#define QD_TIMING(drive) (u8)(((drive)->drive_data) & 0x00ff) +#define QD_TIMREG(drive) (u8)((((drive)->drive_data) & 0xff00) >> 8) #define QD6500_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08)) #define QD6580_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00)) diff --git a/drivers/ide/quirks.c b/drivers/ide/quirks.c index d4cd05578193..740cfe5632fe 100644 --- a/drivers/ide/quirks.c +++ b/drivers/ide/quirks.c @@ -24,8 +24,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -153,14 +154,14 @@ int check_drive_lists(struct ata_device *drive, int good_bad) /* Consult the list of known "good" drives */ list = good_dma_drives; while (*list) { - if (!strcmp(*list++,id->model)) + if (!strcmp(*list++, id->model)) return 1; } } else { /* Consult the list of known "bad" drives */ list = bad_dma_drives; while (*list) { - if (!strcmp(*list++,id->model)) { + if (!strcmp(*list++, id->model)) { printk("%s: Disabling (U)DMA for %s\n", drive->name, id->model); return 1; diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c index ff8e39ef3b9f..1aa9c7199d71 100644 --- a/drivers/ide/serverworks.c +++ b/drivers/ide/serverworks.c @@ -85,14 +85,14 @@ #include #include #include -#include #include #include +#include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" #undef SVWKS_DEBUG_DRIVE_INFO diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c index fb1a56cd0140..efe3d4a882ad 100644 --- a/drivers/ide/sis5513.c +++ b/drivers/ide/sis5513.c @@ -44,13 +44,13 @@ #include #include #include -#include #include +#include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" /* When DEBUG is defined it outputs initial PCI config register @@ -84,7 +84,7 @@ static unsigned char chipset_family; Fewer might be used depending on the actual chipset */ static unsigned char ide_regs_copy[0x58]; -static byte sis5513_max_config_register(void) { +static u8 sis5513_max_config_register(void) { switch(chipset_family) { case ATA_00: case ATA_16: return 0x4f; @@ -100,9 +100,9 @@ static byte sis5513_max_config_register(void) { /* Read config registers, print differences from previous read */ static void sis5513_load_verify_registers(struct pci_dev* dev, char* info) { int i; - byte reg_val; - byte changed=0; - byte max = sis5513_max_config_register(); + u8 reg_val; + u8 changed = 0; + u8 max = sis5513_max_config_register(); printk("SIS5513: %s, changed registers:\n", info); for(i=0; i<=max; i++) { @@ -121,9 +121,10 @@ static void sis5513_load_verify_registers(struct pci_dev* dev, char* info) { } /* Load config registers, no printing */ -static void sis5513_load_registers(struct pci_dev* dev) { +static void sis5513_load_registers(struct pci_dev* dev) +{ int i; - byte max = sis5513_max_config_register(); + u8 max = sis5513_max_config_register(); for(i=0; i<=max; i++) { pci_read_config_byte(dev, i, &(ide_regs_copy[i])); @@ -131,14 +132,15 @@ static void sis5513_load_registers(struct pci_dev* dev) { } /* Print a register */ -static void sis5513_print_register(int reg) { +static void sis5513_print_register(int reg) +{ printk(" %0#x:%0#x", reg, ide_regs_copy[reg]); } /* Print valuable registers */ static void sis5513_print_registers(struct pci_dev* dev, char* marker) { int i; - byte max = sis5513_max_config_register(); + u8 max = sis5513_max_config_register(); sis5513_load_registers(dev); printk("SIS5513 %s\n", marker); @@ -193,9 +195,9 @@ static const struct { /* Cycle time bits and values vary accross chip dma capabilities These three arrays hold the register layout and the values to set. Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */ -static byte cycle_time_offset[] = {0,0,5,4,4,0,0}; -static byte cycle_time_range[] = {0,0,2,3,3,4,4}; -static byte cycle_time_value[][XFER_UDMA_5 - XFER_UDMA_0 + 1] = { +static u8 cycle_time_offset[] = {0,0,5,4,4,0,0}; +static u8 cycle_time_range[] = {0,0,2,3,3,4,4}; +static u8 cycle_time_value[][XFER_UDMA_5 - XFER_UDMA_0 + 1] = { {0,0,0,0,0,0}, /* no udma */ {0,0,0,0,0,0}, /* no udma */ {3,2,1,0,0,0}, @@ -317,7 +319,7 @@ static int sis5513_tune_chipset(struct ata_device *drive, u8 speed) struct ata_channel *hwif = drive->channel; struct pci_dev *dev = hwif->pci_dev; - byte drive_pci, reg; + u8 drive_pci, reg; #ifdef DEBUG sis5513_load_verify_registers(dev, "sis5513_tune_chipset start"); @@ -418,7 +420,7 @@ static unsigned int __init pci_init_sis5513(struct pci_dev *dev) #endif if (SiSHostChipInfo[i].flags & SIS5513_LATENCY) { - byte latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */ + u8 latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */ pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency); } } @@ -427,7 +429,7 @@ static unsigned int __init pci_init_sis5513(struct pci_dev *dev) 1/ tell IDE channels to operate in Compabitility mode only 2/ tell old chips to allow per drive IDE timings */ if (host_dev) { - byte reg; + u8 reg; switch(chipset_family) { case ATA_133: case ATA_100: diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c index 488b0018bb43..d348331d2006 100644 --- a/drivers/ide/sl82c105.c +++ b/drivers/ide/sl82c105.c @@ -19,14 +19,14 @@ #include #include #include -#include #include +#include #include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" /* @@ -82,7 +82,7 @@ static void config_for_pio(struct ata_device *drive, int pio, int report) if (pio == 255) xfer_mode = ata_timing_mode(drive, XFER_PIO | XFER_EPIO); else - xfer_mode = XFER_PIO_0 + min_t(byte, pio, 4); + xfer_mode = XFER_PIO_0 + min_t(u8, pio, 4); t = ata_timing_data(xfer_mode); @@ -258,7 +258,7 @@ static void sl82c105_lostirq(struct ata_device *drive) * We only deal with PIO mode here - DMA mode 'using_dma' is not * initialised at the point that this function is called. */ -static void tune_sl82c105(struct ata_device *drive, byte pio) +static void tune_sl82c105(struct ata_device *drive, u8 pio) { config_for_pio(drive, pio, 1); @@ -320,7 +320,7 @@ static unsigned int __init sl82c105_init_chipset(struct pci_dev *dev) static void __init sl82c105_init_dma(struct ata_channel *ch, unsigned long dma_base) { unsigned int bridge_rev; - byte dma_state; + u8 dma_state; dma_state = inb(dma_base + 2); bridge_rev = sl82c105_bridge_revision(ch->pci_dev); diff --git a/drivers/ide/tcq.c b/drivers/ide/tcq.c index 83c63ff13f7d..f6ce02e194e2 100644 --- a/drivers/ide/tcq.c +++ b/drivers/ide/tcq.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ide/timing.h b/drivers/ide/timing.h new file mode 100644 index 000000000000..f413a85723d0 --- /dev/null +++ b/drivers/ide/timing.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 1996 Linus Torvalds, Igor Abramov, and Mark Lord + * Copyright (C) 1999-2001 Vojtech Pavlik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define XFER_PIO_5 0x0d +#define XFER_UDMA_SLOW 0x4f + +struct ata_timing { + short mode; + short setup; /* t1 */ + short act8b; /* t2 for 8-bit io */ + short rec8b; /* t2i for 8-bit io */ + short cyc8b; /* t0 for 8-bit io */ + short active; /* t2 or tD */ + short recover; /* t2i or tK */ + short cycle; /* t0 */ + short udma; /* t2CYCTYP/2 */ +}; + +extern struct ata_timing ata_timing[]; + +#define IDE_TIMING_SETUP 0x01 +#define IDE_TIMING_ACT8B 0x02 +#define IDE_TIMING_REC8B 0x04 +#define IDE_TIMING_CYC8B 0x08 +#define IDE_TIMING_8BIT 0x0e +#define IDE_TIMING_ACTIVE 0x10 +#define IDE_TIMING_RECOVER 0x20 +#define IDE_TIMING_CYCLE 0x40 +#define IDE_TIMING_UDMA 0x80 +#define IDE_TIMING_ALL 0xff + +#define FIT(v,x,y) max_t(int,min_t(int,v,y),x) +#define ENOUGH(v,unit) (((v)-1)/(unit)+1) +#define EZ(v,unit) ((v)?ENOUGH(v,unit):0) + +/* see hpt366.c for details */ +#define XFER_UDMA_66_3 0x100 +#define XFER_UDMA_66_4 0x200 + +#define XFER_MODE 0xff0 +#define XFER_UDMA_133 0x800 +#define XFER_UDMA_100 0x400 +#define XFER_UDMA_66 0x300 +#define XFER_UDMA 0x040 +#define XFER_MWDMA 0x020 +#define XFER_SWDMA 0x010 +#define XFER_EPIO 0x001 +#define XFER_PIO 0x000 + +#define XFER_UDMA_ALL 0xf40 +#define XFER_UDMA_80W 0xf00 + +/* External interface to host chips channel timing setup. + * + * It's a bit elaborate due to the legacy we have to bear. + */ + +extern short ata_timing_mode(struct ata_device *drive, int map); +extern void ata_timing_quantize(struct ata_timing *t, struct ata_timing *q, + int T, int UT); +extern void ata_timing_merge(struct ata_timing *a, struct ata_timing *b, + struct ata_timing *m, unsigned int what); +void ata_timing_merge_8bit(struct ata_timing *t); +extern struct ata_timing* ata_timing_data(short speed); +extern int ata_timing_compute(struct ata_device *drive, + short speed, struct ata_timing *t, int T, int UT); +extern u8 ata_best_pio_mode(struct ata_device *drive); diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c index 4e1995b62a47..d37b405e4759 100644 --- a/drivers/ide/trm290.c +++ b/drivers/ide/trm290.c @@ -251,7 +251,7 @@ static void __init trm290_init_channel(struct ata_channel *hwif) { unsigned int cfgbase = 0; unsigned long flags; - byte reg; + u8 reg; struct pci_dev *dev = hwif->pci_dev; hwif->chipset = ide_trm290; diff --git a/drivers/ide/umc8672.c b/drivers/ide/umc8672.c index fb7f1a6116b9..61c986d226b3 100644 --- a/drivers/ide/umc8672.c +++ b/drivers/ide/umc8672.c @@ -46,13 +46,13 @@ #include #include #include +#include #include #include -#include #include -#include "ata-timing.h" +#include "timing.h" /* * Default speeds. These can be changed with "auto-tune" and/or hdparm. @@ -62,11 +62,11 @@ #define UMC_DRIVE2 1 /* 11 = Fastest Speed */ #define UMC_DRIVE3 1 /* In case of crash reduce speed */ -static byte current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3}; -static const byte pio_to_umc [5] = {0,3,7,10,11}; /* rough guesses */ +static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3}; +static const u8 pio_to_umc[5] = {0,3,7,10,11}; /* rough guesses */ /* 0 1 2 3 4 5 6 7 8 9 10 11 */ -static const byte speedtab [3][12] = { +static const u8 speedtab[3][12] = { {0xf, 0xb, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }, {0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }, {0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}}; @@ -77,13 +77,13 @@ static void out_umc (char port,char wert) outb_p (wert,0x109); } -static inline byte in_umc (char port) +static inline u8 in_umc (char port) { outb_p (port,0x108); return inb_p (0x109); } -static void umc_set_speeds (byte speeds[]) +static void umc_set_speeds(u8 speeds[]) { int i, tmp; @@ -106,14 +106,14 @@ static void umc_set_speeds (byte speeds[]) speeds[0], speeds[1], speeds[2], speeds[3]); } -static void tune_umc(struct ata_device *drive, byte pio) +static void tune_umc(struct ata_device *drive, u8 pio) { unsigned long flags; if (pio == 255) pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; else - pio = min_t(byte, pio, 4); + pio = min_t(u8, pio, 4); printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", drive->name, pio, pio_to_umc[pio]); save_flags(flags); /* all CPUs */ diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index 54838f9a8975..45cc8fd3fa80 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -65,11 +65,12 @@ #include #include #include +#include #include #include -#include "ata-timing.h" +#include "timing.h" #include "pcihost.h" #define VIA_IDE_ENABLE 0x40 @@ -217,7 +218,7 @@ static void via82cxxx_tune_drive(struct ata_device *drive, unsigned char pio) return; } - via_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5)); + via_set_drive(drive, XFER_PIO_0 + min_t(u8, pio, 5)); } #ifdef CONFIG_BLK_DEV_IDEDMA diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index f06e68e07cce..5d0bb6074fe4 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -23,6 +23,7 @@ #include /* for invalidate_bdev() */ #ifdef CONFIG_BLK_DEV_IDE +#include #include /* IDE xlate */ #elif defined(CONFIG_BLK_DEV_IDE_MODULE) #include diff --git a/include/linux/ide.h b/include/linux/ide.h index 7b9c5cce01cf..8a41b3b2e74a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -285,8 +285,8 @@ struct ata_device { unsigned long sleep; /* sleep until this time */ - byte retry_pio; /* retrying dma capable host in pio */ - byte state; /* retry state */ + u8 retry_pio; /* retrying dma capable host in pio */ + u8 state; /* retry state */ unsigned using_dma : 1; /* disk is using dma for read/write */ unsigned using_tcq : 1; /* disk is using queueing */ @@ -307,20 +307,20 @@ struct ata_device { unsigned remap_0_to_1 : 2; /* 0=remap if ezdrive, 1=remap, 2=noremap */ unsigned ata_flash : 1; /* 1=present, 0=default */ unsigned addressing; /* : 2; 0=28-bit, 1=48-bit, 2=64-bit */ - byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */ + u8 scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */ select_t select; /* basic drive/head select reg value */ u8 status; /* last retrived status value for device */ - byte ready_stat; /* min status value for drive ready */ - byte mult_count; /* current multiple sector setting */ - byte bad_wstat; /* used for ignoring WRERR_STAT */ - byte nowerr; /* used for ignoring WRERR_STAT */ - byte sect0; /* offset of first sector for DM6:DDO */ - byte head; /* "real" number of heads */ - byte sect; /* "real" sectors per track */ - byte bios_head; /* BIOS/fdisk/LILO number of heads */ - byte bios_sect; /* BIOS/fdisk/LILO sectors per track */ + u8 ready_stat; /* min status value for drive ready */ + u8 mult_count; /* current multiple sector setting */ + u8 bad_wstat; /* used for ignoring WRERR_STAT */ + u8 nowerr; /* used for ignoring WRERR_STAT */ + u8 sect0; /* offset of first sector for DM6:DDO */ + u8 head; /* "real" number of heads */ + u8 sect; /* "real" sectors per track */ + u8 bios_head; /* BIOS/fdisk/LILO number of heads */ + u8 bios_sect; /* BIOS/fdisk/LILO sectors per track */ unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */ unsigned int cyl; /* "real" number of cyls */ u64 capacity; /* total number of sectors */ @@ -343,13 +343,12 @@ struct ata_device { int lun; /* logical unit */ int crc_count; /* crc counter to reduce drive speed */ - byte quirk_list; /* drive is considered quirky if set for a specific host */ - byte suspend_reset; /* drive suspend mode flag, soft-reset recovers */ - byte current_speed; /* current transfer rate set */ - byte dn; /* now wide spread use */ - byte wcache; /* status of write cache */ - byte acoustic; /* acoustic management */ - byte queue_depth; /* max queue depth */ + int quirk_list; /* drive is considered quirky if set for a specific host */ + u8 current_speed; /* current transfer rate set */ + u8 dn; /* now wide spread use */ + u8 wcache; /* status of write cache */ + u8 acoustic; /* acoustic management */ + unsigned int queue_depth; /* max queue depth */ unsigned int failures; /* current failure count */ unsigned int max_failures; /* maximum allowed failure count */ struct device dev; /* global device tree handle */ @@ -370,7 +369,7 @@ typedef enum { ATA_OP_FINISHED, /* no drive operation was started */ ATA_OP_CONTINUES, /* a drive operation was started, and a handler was set */ ATA_OP_RELEASED, /* started and released bus */ - ATA_OP_READY, /* indicate status poll finished fine */ + ATA_OP_READY /* indicate status poll finished fine */ } ide_startstop_t; /* @@ -428,10 +427,10 @@ struct ata_channel { */ /* setup disk on a channel for a particular PIO transfer mode */ - void (*tuneproc) (struct ata_device *, byte pio); + void (*tuneproc) (struct ata_device *, u8 pio); /* setup the chipset timing for a particular transfer mode */ - int (*speedproc) (struct ata_device *, byte pio); + int (*speedproc) (struct ata_device *, u8 pio); /* tweaks hardware to select drive */ void (*selectproc) (struct ata_device *); @@ -640,10 +639,8 @@ extern void ata_read(struct ata_device *, void *, unsigned int); extern void ata_write(struct ata_device *, void *, unsigned int); extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *, char *); -extern int ide_config_drive_speed(struct ata_device *, byte); -extern byte eighty_ninty_three(struct ata_device *); - -extern void ide_stall_queue(struct ata_device *, unsigned long); +extern int ide_config_drive_speed(struct ata_device *, u8); +extern int eighty_ninty_three(struct ata_device *); extern int system_bus_speed; @@ -656,11 +653,11 @@ extern int system_bus_speed; extern int drive_is_flashcard(struct ata_device *); -int ide_spin_wait_hwgroup(struct ata_device *); -void ide_timer_expiry (unsigned long data); +extern int ide_spin_wait_hwgroup(struct ata_device *); +extern void ide_timer_expiry(unsigned long data); extern void ata_irq_request(int irq, void *data, struct pt_regs *regs); -void do_ide_request (request_queue_t * q); -void ide_init_subdrivers (void); +extern void do_ide_request(request_queue_t * q); +extern void ide_init_subdrivers(void); extern struct block_device_operations ide_fops[]; @@ -742,12 +739,12 @@ static inline int udma_irq_status(struct ata_device *drive) static inline void udma_timeout(struct ata_device *drive) { - return drive->channel->udma_timeout(drive); + drive->channel->udma_timeout(drive); } static inline void udma_irq_lost(struct ata_device *drive) { - return drive->channel->udma_irq_lost(drive); + drive->channel->udma_irq_lost(drive); } #ifdef CONFIG_BLK_DEV_IDEDMA -- cgit v1.2.3 From 2993fd69dc04a62f672c889254d72ad123f5ef1a Mon Sep 17 00:00:00 2001 From: Martin Dalecki Date: Fri, 26 Jul 2002 01:18:01 -0700 Subject: [PATCH] IDE 106 Small missing notch. --- drivers/ide/main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/main.c b/drivers/ide/main.c index c59fe6307400..50bc8732e38b 100644 --- a/drivers/ide/main.c +++ b/drivers/ide/main.c @@ -1069,7 +1069,6 @@ int ide_register_subdriver(struct ata_device *drive, struct ata_operations *driv } drive->revalidate = 1; - drive->suspend_reset = 0; return 0; } -- cgit v1.2.3 From e1eec525be1b708894650a4573d6d7f61e96c4fa Mon Sep 17 00:00:00 2001 From: Martin Dalecki Date: Fri, 26 Jul 2002 01:18:14 -0700 Subject: [PATCH] IDE 107 - Fix "temporal anomaly" in do_ide_request pointed out by Petr Vandrovec. Thanks Petr! --- drivers/ide/ide.c | 391 +++++++++++++++++++++++++++--------------------------- 1 file changed, 193 insertions(+), 198 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 3b776c4dae02..0c9d9a41b390 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -517,49 +517,21 @@ void ide_stall_queue(struct ata_device *drive, unsigned long timeout) * Issue a new request. * Caller must have already done spin_lock_irqsave(channel->lock, ...) */ -static void do_request(struct ata_channel *channel) +void do_ide_request(request_queue_t *q) { - struct ata_channel *ch; - struct ata_device *drive = NULL; - unsigned int unit; - ide_startstop_t ret; - - local_irq_disable(); /* necessary paranoia */ - - /* - * Select the next device which will be serviced. This selects - * only between devices on the same channel, since everything - * else will be scheduled on the queue level. - */ - - for (unit = 0; unit < MAX_DRIVES; ++unit) { - struct ata_device *tmp = &channel->drives[unit]; - - if (!tmp->present) - continue; - - /* There are no requests pending for this device. - */ - if (blk_queue_empty(&tmp->queue)) - continue; - + struct ata_channel *channel = q->queuedata; - /* This device still wants to remain idle. - */ - if (tmp->sleep && time_after(tmp->sleep, jiffies)) - continue; + while (!test_and_set_bit(IDE_BUSY, channel->active)) { + struct ata_channel *ch; + struct ata_device *drive = NULL; + unsigned int unit; + ide_startstop_t ret; - /* Take this device, if there is no device choosen thus - * far or which is more urgent. + /* + * Select the next device which will be serviced. This selects + * only between devices on the same channel, since everything + * else will be scheduled on the queue level. */ - if (!drive || (tmp->sleep && (!drive->sleep || time_after(drive->sleep, tmp->sleep)))) { - if (!blk_queue_plugged(&tmp->queue)) - drive = tmp; - } - } - - if (!drive) { - unsigned long sleep = 0; for (unit = 0; unit < MAX_DRIVES; ++unit) { struct ata_device *tmp = &channel->drives[unit]; @@ -567,208 +539,229 @@ static void do_request(struct ata_channel *channel) if (!tmp->present) continue; - /* This device is sleeping and waiting to be serviced - * earlier than any other device we checked thus far. - */ - if (tmp->sleep && (!sleep || time_after(sleep, tmp->sleep))) - sleep = tmp->sleep; - } - - if (sleep) { - /* - * Take a short snooze, and then wake up again. Just - * in case there are big differences in relative - * throughputs.. don't want to hog the cpu too much. + /* There are no requests pending for this device. */ + if (blk_queue_empty(&tmp->queue)) + continue; - if (time_after(jiffies, sleep - WAIT_MIN_SLEEP)) - sleep = jiffies + WAIT_MIN_SLEEP; -#if 1 - if (timer_pending(&channel->timer)) - printk(KERN_ERR "%s: timer already active\n", __FUNCTION__); -#endif - set_bit(IDE_SLEEP, channel->active); - mod_timer(&channel->timer, sleep); - /* - * We purposely leave us busy while sleeping becouse we - * are prepared to handle the IRQ from it. - * - * FIXME: Make sure sleeping can't interferre with - * operations of other devices on the same channel. - */ - } else { - /* FIXME: use queue plugging instead of active to block - * upper layers from stomping on us */ - /* Ugly, but how can we sleep for the lock otherwise? - * */ - - ide_release_lock(&ide_irq_lock);/* for atari only */ - clear_bit(IDE_BUSY, channel->active); - - /* All requests are done. - * - * Disable IRQs from the last drive on this channel, to - * make sure that it wan't throw stones at us when we - * are not prepared to take them. + /* This device still wants to remain idle. */ + if (tmp->sleep && time_after(tmp->sleep, jiffies)) + continue; - if (channel->drive && !channel->drive->using_tcq) - ata_irq_enable(channel->drive, 0); + /* Take this device, if there is no device choosen thus + * far or which is more urgent. + */ + if (!drive || (tmp->sleep && (!drive->sleep || time_after(drive->sleep, tmp->sleep)))) { + if (!blk_queue_plugged(&tmp->queue)) + drive = tmp; + } } - return; - } - - /* Remember the last drive we where acting on. - */ - ch = drive->channel; - ch->drive = drive; + if (!drive) { + unsigned long sleep = 0; - /* Feed commands to a drive until it barfs. - */ - do { - struct request *rq = NULL; - sector_t block; + for (unit = 0; unit < MAX_DRIVES; ++unit) { + struct ata_device *tmp = &channel->drives[unit]; - /* Abort early if we can't queue another command. for non tcq, - * ata_can_queue is always 1 since we never get here unless the - * drive is idle. - */ + if (!tmp->present) + continue; - if (!ata_can_queue(drive)) { - if (!ata_pending_commands(drive)) { - clear_bit(IDE_BUSY, ch->active); - if (drive->using_tcq) - ata_irq_enable(drive, 0); + /* This device is sleeping and waiting to be serviced + * earlier than any other device we checked thus far. + */ + if (tmp->sleep && (!sleep || time_after(sleep, tmp->sleep))) + sleep = tmp->sleep; } - break; - } - drive->sleep = 0; + if (sleep) { + /* + * Take a short snooze, and then wake up again. Just + * in case there are big differences in relative + * throughputs.. don't want to hog the cpu too much. + */ + + if (time_after(jiffies, sleep - WAIT_MIN_SLEEP)) + sleep = jiffies + WAIT_MIN_SLEEP; +#if 1 + if (timer_pending(&channel->timer)) + printk(KERN_ERR "%s: timer already active\n", __FUNCTION__); +#endif + set_bit(IDE_SLEEP, channel->active); + mod_timer(&channel->timer, sleep); + + /* + * We purposely leave us busy while sleeping becouse we + * are prepared to handle the IRQ from it. + * + * FIXME: Make sure sleeping can't interferre with + * operations of other devices on the same channel. + */ + } else { + /* FIXME: use queue plugging instead of active to block + * upper layers from stomping on us */ + /* Ugly, but how can we sleep for the lock otherwise? + * */ + + ide_release_lock(&ide_irq_lock);/* for atari only */ + clear_bit(IDE_BUSY, channel->active); + + /* All requests are done. + * + * Disable IRQs from the last drive on this channel, to + * make sure that it wan't throw stones at us when we + * are not prepared to take them. + */ + + if (channel->drive && !channel->drive->using_tcq) + ata_irq_enable(channel->drive, 0); + } - if (test_bit(IDE_DMA, ch->active)) { - printk(KERN_ERR "%s: error: DMA in progress...\n", drive->name); - break; + return; } - /* There's a small window between where the queue could be - * replugged while we are in here when using tcq (in which case - * the queue is probably empty anyways...), so check and leave - * if appropriate. When not using tcq, this is still a severe - * BUG! + /* Remember the last drive we where acting on. */ + ch = drive->channel; + ch->drive = drive; - if (blk_queue_plugged(&drive->queue)) { - BUG_ON(!drive->using_tcq); - break; - } + /* Feed commands to a drive until it barfs. + */ + do { + struct request *rq = NULL; + sector_t block; + + /* Abort early if we can't queue another command. for non tcq, + * ata_can_queue is always 1 since we never get here unless the + * drive is idle. + */ + + if (!ata_can_queue(drive)) { + if (!ata_pending_commands(drive)) { + clear_bit(IDE_BUSY, ch->active); + if (drive->using_tcq) + ata_irq_enable(drive, 0); + } + break; + } + + drive->sleep = 0; - if (!(rq = elv_next_request(&drive->queue))) { - if (!ata_pending_commands(drive)) { - clear_bit(IDE_BUSY, ch->active); - if (drive->using_tcq) - ata_irq_enable(drive, 0); + if (test_bit(IDE_DMA, ch->active)) { + printk(KERN_ERR "%s: error: DMA in progress...\n", drive->name); + break; } - drive->rq = NULL; - break; - } + /* There's a small window between where the queue could be + * replugged while we are in here when using tcq (in which case + * the queue is probably empty anyways...), so check and leave + * if appropriate. When not using tcq, this is still a severe + * BUG! + */ - /* If there are queued commands, we can't start a - * non-fs request (really, a non-queuable command) - * until the queue is empty. - */ - if (!(rq->flags & REQ_CMD) && ata_pending_commands(drive)) - break; + if (blk_queue_plugged(&drive->queue)) { + BUG_ON(!drive->using_tcq); + break; + } - drive->rq = rq; + if (!(rq = elv_next_request(&drive->queue))) { + if (!ata_pending_commands(drive)) { + clear_bit(IDE_BUSY, ch->active); + if (drive->using_tcq) + ata_irq_enable(drive, 0); + } + drive->rq = NULL; - spin_unlock(ch->lock); - /* allow other IRQs while we start this request */ - local_irq_enable(); + break; + } - /* - * This initiates handling of a new I/O request. - */ + /* If there are queued commands, we can't start a + * non-fs request (really, a non-queuable command) + * until the queue is empty. + */ + if (!(rq->flags & REQ_CMD) && ata_pending_commands(drive)) + break; + + drive->rq = rq; + + spin_unlock(ch->lock); + /* allow other IRQs while we start this request */ + local_irq_enable(); + + /* + * This initiates handling of a new I/O request. + */ - BUG_ON(!(rq->flags & REQ_STARTED)); + BUG_ON(!(rq->flags & REQ_STARTED)); #ifdef DEBUG - printk("%s: %s: current=0x%08lx\n", ch->name, __FUNCTION__, (unsigned long) rq); + printk("%s: %s: current=0x%08lx\n", ch->name, __FUNCTION__, (unsigned long) rq); #endif - /* bail early if we've exceeded max_failures */ - if (drive->max_failures && (drive->failures > drive->max_failures)) - goto kill_rq; + /* bail early if we've exceeded max_failures */ + if (drive->max_failures && (drive->failures > drive->max_failures)) + goto kill_rq; - block = rq->sector; + block = rq->sector; - /* Strange disk manager remap. - */ - if (rq->flags & REQ_CMD) - if (drive->type == ATA_DISK || drive->type == ATA_FLOPPY) - block += drive->sect0; + /* Strange disk manager remap. + */ + if (rq->flags & REQ_CMD) + if (drive->type == ATA_DISK || drive->type == ATA_FLOPPY) + block += drive->sect0; - /* Yecch - this will shift the entire interval, possibly killing some - * innocent following sector. - */ - if (block == 0 && drive->remap_0_to_1 == 1) - block = 1; /* redirect MBR access to EZ-Drive partn table */ + /* Yecch - this will shift the entire interval, possibly killing some + * innocent following sector. + */ + if (block == 0 && drive->remap_0_to_1 == 1) + block = 1; /* redirect MBR access to EZ-Drive partn table */ - ata_select(drive, 0); - ret = ata_status_poll(drive, drive->ready_stat, BUSY_STAT | DRQ_STAT, - WAIT_READY, rq); + ata_select(drive, 0); + ret = ata_status_poll(drive, drive->ready_stat, BUSY_STAT | DRQ_STAT, + WAIT_READY, rq); - if (ret != ATA_OP_READY) { - printk(KERN_ERR "%s: drive not ready for command\n", drive->name); + if (ret != ATA_OP_READY) { + printk(KERN_ERR "%s: drive not ready for command\n", drive->name); - goto kill_rq; - } + goto kill_rq; + } - if (!ata_ops(drive)) { - printk(KERN_WARNING "%s: device type %d not supported\n", - drive->name, drive->type); - goto kill_rq; - } + if (!ata_ops(drive)) { + printk(KERN_WARNING "%s: device type %d not supported\n", + drive->name, drive->type); + goto kill_rq; + } - /* The normal way of execution is to pass and execute the request - * handler down to the device type driver. - */ + /* The normal way of execution is to pass and execute the request + * handler down to the device type driver. + */ - if (ata_ops(drive)->do_request) { - ret = ata_ops(drive)->do_request(drive, rq, block); - } else { + if (ata_ops(drive)->do_request) { + ret = ata_ops(drive)->do_request(drive, rq, block); + } else { kill_rq: - if (ata_ops(drive) && ata_ops(drive)->end_request) - ata_ops(drive)->end_request(drive, rq, 0); - else - ata_end_request(drive, rq, 0, 0); - ret = ATA_OP_FINISHED; + if (ata_ops(drive) && ata_ops(drive)->end_request) + ata_ops(drive)->end_request(drive, rq, 0); + else + ata_end_request(drive, rq, 0, 0); + ret = ATA_OP_FINISHED; - } - spin_lock_irq(ch->lock); - - /* continue if command started, so we are busy */ - } while (ret != ATA_OP_CONTINUES); - /* make sure the BUSY bit is set */ - /* FIXME: perhaps there is some place where we miss to set it? */ -// set_bit(IDE_BUSY, ch->active); -} - -void do_ide_request(request_queue_t *q) -{ - struct ata_channel *ch = q->queuedata; + } + spin_lock_irq(ch->lock); - while (!test_and_set_bit(IDE_BUSY, ch->active)) { - do_request(ch); + /* continue if command started, so we are busy */ + } while (ret != ATA_OP_CONTINUES); + /* make sure the BUSY bit is set */ + /* FIXME: perhaps there is some place where we miss to set it? */ + // set_bit(IDE_BUSY, ch->active); } } /* * This is our timeout function for all drive operations. But note that it can * also be invoked as a result of a "sleep" operation triggered by the - * mod_timer() call in do_request. + * mod_timer() call in do_ide_request. * * FIXME: This should take a drive context instead of a channel. * FIXME: This should not explicitly reenter the request handling engine. @@ -893,7 +886,8 @@ void ide_timer_expiry(unsigned long data) if (ret == ATA_OP_FINISHED) { /* Reenter the request handling engine. */ - do_request(ch); + clear_bit(IDE_BUSY, ch->active); + do_ide_request(&drive->queue); } } spin_unlock_irqrestore(ch->lock, flags); @@ -1050,9 +1044,10 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs) * another interrupt. */ - if (!ch->handler) - do_request(ch); - else + if (!ch->handler) { + clear_bit(IDE_BUSY, ch->active); + do_ide_request(&drive->queue); + } else printk("%s: %s: huh? expected NULL handler on exit\n", drive->name, __FUNCTION__); } -- cgit v1.2.3