From 07145ea97e91066ce04c7a389d44eee78a6d3fcb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 1 May 2008 01:12:40 -0700 Subject: [PATCH] --- yaml --- r: 95858 b: refs/heads/master c: c26d3c0138970778fabe114df99dffb34a04b1d7 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/lguest/lguest.c | 62 +- .../powerpc/mpc52xx-device-tree-bindings.txt | 11 - .../Documentation/scsi/ChangeLog.megaraid_sas | 22 - trunk/MAINTAINERS | 6 - trunk/arch/alpha/kernel/osf_sys.c | 69 +- trunk/arch/ia64/ia32/ia32_signal.c | 2 +- trunk/arch/ia64/kernel/acpi.c | 2 +- trunk/arch/ia64/kernel/irq.c | 4 +- trunk/arch/ia64/kernel/palinfo.c | 2 +- trunk/arch/ia64/kernel/perfmon.c | 199 +- trunk/arch/ia64/kernel/signal.c | 15 +- trunk/arch/ia64/kernel/smp.c | 68 +- trunk/arch/ia64/kernel/time.c | 5 + trunk/arch/ia64/kernel/topology.c | 16 +- trunk/arch/m32r/Makefile | 2 - trunk/arch/m32r/defconfig | 863 ++++++ trunk/arch/m32r/kernel/vmlinux.lds.S | 3 + trunk/arch/mips/kernel/irixioctl.c | 55 +- trunk/arch/mips/kernel/kspd.c | 1 - trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts | 23 +- trunk/arch/powerpc/configs/ps3_defconfig | 132 +- trunk/arch/powerpc/kernel/smp.c | 2 - trunk/arch/powerpc/mm/slb.c | 27 +- .../powerpc/platforms/cell/spufs/coredump.c | 1 - trunk/arch/powerpc/platforms/ps3/interrupt.c | 6 +- trunk/arch/powerpc/sysdev/fsl_rio.c | 9 +- trunk/arch/powerpc/sysdev/fsl_soc.c | 4 +- trunk/arch/powerpc/sysdev/xilinx_intc.c | 2 +- trunk/arch/sparc64/kernel/pci.c | 130 +- trunk/arch/sparc64/kernel/pci_common.c | 6 - trunk/arch/sparc64/kernel/pci_impl.h | 9 - trunk/block/bsg.c | 12 +- trunk/block/scsi_ioctl.c | 5 +- trunk/drivers/block/ub.c | 63 +- trunk/drivers/block/virtio_blk.c | 44 +- trunk/drivers/char/tty_audit.c | 1 - trunk/drivers/char/tty_io.c | 1 - .../char/xilinx_hwicap/xilinx_hwicap.c | 6 +- trunk/drivers/firewire/fw-sbp2.c | 2 +- trunk/drivers/lguest/lguest_device.c | 68 +- trunk/drivers/lguest/lguest_user.c | 4 +- trunk/drivers/net/fec_mpc52xx.c | 97 +- trunk/drivers/net/fec_mpc52xx.h | 19 + trunk/drivers/net/virtio_net.c | 96 +- trunk/drivers/ps3/ps3-lpm.c | 1 - trunk/drivers/ps3/ps3-sys-manager.c | 7 +- trunk/drivers/s390/scsi/zfcp_dbf.c | 2 +- trunk/drivers/s390/scsi/zfcp_fsf.c | 2 +- trunk/drivers/scsi/53c700.c | 6 +- trunk/drivers/scsi/Kconfig | 3 +- trunk/drivers/scsi/a100u2w.c | 2 +- trunk/drivers/scsi/aacraid/aachba.c | 133 +- trunk/drivers/scsi/aacraid/aacraid.h | 28 +- trunk/drivers/scsi/aacraid/comminit.c | 2 - trunk/drivers/scsi/aacraid/commsup.c | 34 +- trunk/drivers/scsi/aacraid/linit.c | 22 +- trunk/drivers/scsi/aic94xx/aic94xx_init.c | 6 +- trunk/drivers/scsi/constants.c | 10 +- trunk/drivers/scsi/dpt/dpti_ioctl.h | 16 +- trunk/drivers/scsi/dpt/dptsig.h | 8 +- trunk/drivers/scsi/dpt/sys_info.h | 4 +- trunk/drivers/scsi/dpt_i2o.c | 640 ++--- trunk/drivers/scsi/dpti.h | 15 +- trunk/drivers/scsi/gdth.c | 2 +- trunk/drivers/scsi/hptiop.c | 6 +- trunk/drivers/scsi/ibmvscsi/ibmvscsi.c | 7 +- trunk/drivers/scsi/ibmvscsi/viosrp.h | 9 - trunk/drivers/scsi/initio.c | 2 +- trunk/drivers/scsi/ipr.c | 2 +- trunk/drivers/scsi/megaraid/megaraid_mbox.c | 17 - trunk/drivers/scsi/megaraid/megaraid_mbox.h | 1 - trunk/drivers/scsi/megaraid/megaraid_sas.c | 13 +- trunk/drivers/scsi/megaraid/megaraid_sas.h | 6 +- trunk/drivers/scsi/qla1280.c | 4 +- trunk/drivers/scsi/scsi.c | 23 +- trunk/drivers/scsi/scsi_error.c | 15 +- trunk/drivers/scsi/scsi_lib.c | 7 +- trunk/drivers/scsi/scsi_tgt_lib.c | 2 - trunk/drivers/scsi/u14-34f.c | 6 +- trunk/drivers/serial/mpc52xx_uart.c | 2 - trunk/drivers/usb/Makefile | 2 - trunk/drivers/usb/atm/Kconfig | 4 + trunk/drivers/usb/c67x00/Makefile | 9 - trunk/drivers/usb/c67x00/c67x00-drv.c | 243 -- trunk/drivers/usb/c67x00/c67x00-hcd.c | 412 --- trunk/drivers/usb/c67x00/c67x00-hcd.h | 133 - trunk/drivers/usb/c67x00/c67x00-ll-hpi.c | 480 ---- trunk/drivers/usb/c67x00/c67x00-sched.c | 1170 -------- trunk/drivers/usb/c67x00/c67x00.h | 294 -- trunk/drivers/usb/core/message.c | 4 +- trunk/drivers/usb/gadget/Kconfig | 20 - trunk/drivers/usb/gadget/Makefile | 1 - trunk/drivers/usb/gadget/ether.c | 8 +- trunk/drivers/usb/gadget/file_storage.c | 25 +- trunk/drivers/usb/gadget/pxa27x_udc.c | 2404 ----------------- trunk/drivers/usb/gadget/pxa27x_udc.h | 487 ---- trunk/drivers/usb/gadget/serial.c | 90 +- trunk/drivers/usb/gadget/zero.c | 370 +-- trunk/drivers/usb/host/Kconfig | 39 - trunk/drivers/usb/host/Makefile | 4 +- trunk/drivers/usb/host/isp1760-hcd.c | 2231 --------------- trunk/drivers/usb/host/isp1760-hcd.h | 206 -- trunk/drivers/usb/host/isp1760-if.c | 298 -- trunk/drivers/usb/host/ohci-hub.c | 2 +- trunk/drivers/usb/host/uhci-hcd.c | 74 +- trunk/drivers/usb/host/uhci-hcd.h | 5 +- trunk/drivers/usb/misc/ldusb.c | 28 +- trunk/drivers/usb/misc/usbtest.c | 276 +- trunk/drivers/usb/serial/aircable.c | 98 +- trunk/drivers/usb/serial/airprime.c | 63 +- trunk/drivers/usb/serial/ark3116.c | 54 +- trunk/drivers/usb/serial/ch341.c | 2 +- trunk/drivers/usb/serial/ftdi_sio.c | 8 - trunk/drivers/usb/serial/ftdi_sio.h | 11 - trunk/drivers/usb/serial/mos7840.c | 5 +- trunk/drivers/usb/storage/Kconfig | 3 +- trunk/drivers/usb/storage/cypress_atacb.c | 2 +- trunk/drivers/usb/storage/isd200.c | 2 - trunk/drivers/usb/storage/libusual.c | 2 +- trunk/drivers/usb/storage/onetouch.c | 4 +- trunk/drivers/usb/storage/unusual_devs.h | 28 +- trunk/drivers/usb/storage/usb.c | 3 +- trunk/drivers/virtio/virtio.c | 38 +- trunk/drivers/virtio/virtio_balloon.c | 12 +- trunk/drivers/virtio/virtio_pci.c | 34 +- trunk/drivers/virtio/virtio_ring.c | 5 - trunk/fs/anon_inodes.c | 13 +- trunk/fs/compat.c | 1 - trunk/fs/dnotify.c | 2 +- trunk/fs/eventfd.c | 15 +- trunk/fs/eventpoll.c | 23 +- trunk/fs/exec.c | 1 - trunk/fs/fcntl.c | 1 - trunk/fs/file.c | 23 +- trunk/fs/file_table.c | 1 - trunk/fs/locks.c | 1 - trunk/fs/ocfs2/cluster/sys.c | 2 +- trunk/fs/ocfs2/dlm/dlmdebug.c | 8 +- trunk/fs/ocfs2/file.c | 4 - trunk/fs/ocfs2/localalloc.c | 4 +- trunk/fs/ocfs2/stack_o2cb.c | 2 +- trunk/fs/ocfs2/stack_user.c | 2 +- trunk/fs/ocfs2/symlink.c | 2 - trunk/fs/open.c | 1 - trunk/fs/proc/array.c | 1 - trunk/fs/proc/base.c | 1 - trunk/fs/select.c | 3 +- trunk/fs/signalfd.c | 17 +- trunk/fs/timerfd.c | 11 +- trunk/include/asm-ia64/cpu.h | 2 +- trunk/include/asm-ia64/thread_info.h | 13 +- trunk/include/asm-powerpc/ps3.h | 3 + trunk/include/linux/Kbuild | 5 - trunk/include/linux/anon_inodes.h | 3 +- trunk/include/linux/device.h | 8 +- trunk/include/linux/fdtable.h | 99 - trunk/include/linux/file.h | 86 +- trunk/include/linux/init_task.h | 2 +- trunk/include/linux/irq.h | 1 - trunk/include/linux/poll.h | 2 - trunk/include/linux/rio.h | 2 - trunk/include/linux/usb/c67x00.h | 48 - trunk/include/linux/usb/ch9.h | 12 +- trunk/include/linux/usb/gadget.h | 21 - trunk/include/linux/virtio.h | 7 - trunk/include/linux/virtio_blk.h | 14 +- trunk/include/linux/virtio_config.h | 81 +- trunk/include/linux/virtio_net.h | 13 +- trunk/include/scsi/scsi.h | 40 +- trunk/include/scsi/scsi_cmnd.h | 23 +- trunk/include/scsi/scsi_eh.h | 4 +- trunk/include/scsi/scsi_host.h | 8 +- trunk/kernel/exit.c | 1 - trunk/kernel/fork.c | 1 - trunk/kernel/irq/manage.c | 49 +- trunk/kernel/irq/spurious.c | 4 +- trunk/kernel/kmod.c | 1 - trunk/security/selinux/hooks.c | 1 - trunk/virt/kvm/kvm_main.c | 21 +- 180 files changed, 2482 insertions(+), 11168 deletions(-) create mode 100644 trunk/arch/m32r/defconfig delete mode 100644 trunk/drivers/usb/c67x00/Makefile delete mode 100644 trunk/drivers/usb/c67x00/c67x00-drv.c delete mode 100644 trunk/drivers/usb/c67x00/c67x00-hcd.c delete mode 100644 trunk/drivers/usb/c67x00/c67x00-hcd.h delete mode 100644 trunk/drivers/usb/c67x00/c67x00-ll-hpi.c delete mode 100644 trunk/drivers/usb/c67x00/c67x00-sched.c delete mode 100644 trunk/drivers/usb/c67x00/c67x00.h delete mode 100644 trunk/drivers/usb/gadget/pxa27x_udc.c delete mode 100644 trunk/drivers/usb/gadget/pxa27x_udc.h delete mode 100644 trunk/drivers/usb/host/isp1760-hcd.c delete mode 100644 trunk/drivers/usb/host/isp1760-hcd.h delete mode 100644 trunk/drivers/usb/host/isp1760-if.c delete mode 100644 trunk/include/linux/fdtable.h delete mode 100644 trunk/include/linux/usb/c67x00.h diff --git a/[refs] b/[refs] index 41f33bfbcd0c..cfb6fd8d8144 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c36c804559d3a891a2e655ba8185b4fa7eaee156 +refs/heads/master: c26d3c0138970778fabe114df99dffb34a04b1d7 diff --git a/trunk/Documentation/lguest/lguest.c b/trunk/Documentation/lguest/lguest.c index 3be8ab2a886a..4c1fc65a8b3d 100644 --- a/trunk/Documentation/lguest/lguest.c +++ b/trunk/Documentation/lguest/lguest.c @@ -131,9 +131,6 @@ struct device /* Any queues attached to this device */ struct virtqueue *vq; - /* Handle status being finalized (ie. feature bits stable). */ - void (*ready)(struct device *me); - /* Device-specific data. */ void *priv; }; @@ -928,40 +925,24 @@ static void enable_fd(int fd, struct virtqueue *vq) write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd)); } -/* When the Guest tells us they updated the status field, we handle it. */ -static void update_device_status(struct device *dev) +/* When the Guest asks us to reset a device, it's is fairly easy. */ +static void reset_device(struct device *dev) { struct virtqueue *vq; - /* This is a reset. */ - if (dev->desc->status == 0) { - verbose("Resetting device %s\n", dev->name); + verbose("Resetting device %s\n", dev->name); + /* Clear the status. */ + dev->desc->status = 0; - /* Clear any features they've acked. */ - memset(get_feature_bits(dev) + dev->desc->feature_len, 0, - dev->desc->feature_len); + /* Clear any features they've acked. */ + memset(get_feature_bits(dev) + dev->desc->feature_len, 0, + dev->desc->feature_len); - /* Zero out the virtqueues. */ - for (vq = dev->vq; vq; vq = vq->next) { - memset(vq->vring.desc, 0, - vring_size(vq->config.num, getpagesize())); - vq->last_avail_idx = 0; - } - } else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) { - warnx("Device %s configuration FAILED", dev->name); - } else if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) { - unsigned int i; - - verbose("Device %s OK: offered", dev->name); - for (i = 0; i < dev->desc->feature_len; i++) - verbose(" %08x", get_feature_bits(dev)[i]); - verbose(", accepted"); - for (i = 0; i < dev->desc->feature_len; i++) - verbose(" %08x", get_feature_bits(dev) - [dev->desc->feature_len+i]); - - if (dev->ready) - dev->ready(dev); + /* Zero out the virtqueues. */ + for (vq = dev->vq; vq; vq = vq->next) { + memset(vq->vring.desc, 0, + vring_size(vq->config.num, getpagesize())); + vq->last_avail_idx = 0; } } @@ -973,9 +954,9 @@ static void handle_output(int fd, unsigned long addr) /* Check each device and virtqueue. */ for (i = devices.dev; i; i = i->next) { - /* Notifications to device descriptors update device status. */ + /* Notifications to device descriptors reset the device. */ if (from_guest_phys(addr) == i->desc) { - update_device_status(i); + reset_device(i); return; } @@ -1189,7 +1170,6 @@ static struct device *new_device(const char *name, u16 type, int fd, dev->handle_input = handle_input; dev->name = name; dev->vq = NULL; - dev->ready = NULL; /* Append to device list. Prepending to a single-linked list is * easier, but the user expects the devices to be arranged on the bus @@ -1418,7 +1398,7 @@ static bool service_io(struct device *dev) struct vblk_info *vblk = dev->priv; unsigned int head, out_num, in_num, wlen; int ret; - u8 *in; + struct virtio_blk_inhdr *in; struct virtio_blk_outhdr *out; struct iovec iov[dev->vq->vring.num]; off64_t off; @@ -1436,7 +1416,7 @@ static bool service_io(struct device *dev) head, out_num, in_num); out = convert(&iov[0], struct virtio_blk_outhdr); - in = convert(&iov[out_num+in_num-1], u8); + in = convert(&iov[out_num+in_num-1], struct virtio_blk_inhdr); off = out->sector * 512; /* The block device implements "barriers", where the Guest indicates @@ -1450,7 +1430,7 @@ static bool service_io(struct device *dev) * It'd be nice if we supported eject, for example, but we don't. */ if (out->type & VIRTIO_BLK_T_SCSI_CMD) { fprintf(stderr, "Scsi commands unsupported\n"); - *in = VIRTIO_BLK_S_UNSUPP; + in->status = VIRTIO_BLK_S_UNSUPP; wlen = sizeof(*in); } else if (out->type & VIRTIO_BLK_T_OUT) { /* Write */ @@ -1473,7 +1453,7 @@ static bool service_io(struct device *dev) errx(1, "Write past end %llu+%u", off, ret); } wlen = sizeof(*in); - *in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); + in->status = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); } else { /* Read */ @@ -1486,10 +1466,10 @@ static bool service_io(struct device *dev) verbose("READ from sector %llu: %i\n", out->sector, ret); if (ret >= 0) { wlen = sizeof(*in) + ret; - *in = VIRTIO_BLK_S_OK; + in->status = VIRTIO_BLK_S_OK; } else { wlen = sizeof(*in); - *in = VIRTIO_BLK_S_IOERR; + in->status = VIRTIO_BLK_S_IOERR; } } diff --git a/trunk/Documentation/powerpc/mpc52xx-device-tree-bindings.txt b/trunk/Documentation/powerpc/mpc52xx-device-tree-bindings.txt index 6f12f1c79c0c..cda7a7dffa6d 100644 --- a/trunk/Documentation/powerpc/mpc52xx-device-tree-bindings.txt +++ b/trunk/Documentation/powerpc/mpc52xx-device-tree-bindings.txt @@ -237,17 +237,6 @@ Each GPIO controller node should have the empty property gpio-controller and according to the bit numbers in the GPIO control registers. The second cell is for flags which is currently unsused. -8) FEC nodes -The FEC node can specify one of the following properties to configure -the MII link: -"fsl,7-wire-mode" - An empty property that specifies the link uses 7-wire - mode instead of MII -"current-speed" - Specifies that the MII should be configured for a fixed - speed. This property should contain two cells. The - first cell specifies the speed in Mbps and the second - should be '0' for half duplex and '1' for full duplex -"phy-handle" - Contains a phandle to an Ethernet PHY. - IV - Extra Notes ================ diff --git a/trunk/Documentation/scsi/ChangeLog.megaraid_sas b/trunk/Documentation/scsi/ChangeLog.megaraid_sas index 716fcc1cafb5..91c81db0ba71 100644 --- a/trunk/Documentation/scsi/ChangeLog.megaraid_sas +++ b/trunk/Documentation/scsi/ChangeLog.megaraid_sas @@ -1,25 +1,3 @@ -1 Release Date : Mon. March 10 11:02:31 PDT 2008 - - (emaild-id:megaraidlinux@lsi.com) - Sumant Patro - Bo Yang - -2 Current Version : 00.00.03.20-RC1 -3 Older Version : 00.00.03.16 - -1. Rollback the sense info implementation - Sense buffer ptr data type in the ioctl path is reverted back - to u32 * as in previous versions of driver. - -2. Fixed the driver frame count. - When Driver sent wrong frame count to firmware. As this - particular command is sent to drive, FW is seeing continuous - chip resets and so the command will timeout. - -3. Add the new controller(1078DE) support to the driver - and Increase the max_wait to 60 from 10 in the controller - operational status. With this max_wait increase, driver will - make sure the FW will finish the pending cmd for KDUMP case. - 1 Release Date : Thur. Nov. 07 16:30:43 PST 2007 - (emaild-id:megaraidlinux@lsi.com) Sumant Patro diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 93547d3d04b9..cae9001a670d 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -4051,12 +4051,6 @@ L: linux-usb@vger.kernel.org S: Maintained W: http://www.kroah.com/linux-usb/ -USB CYPRESS C67X00 DRIVER -P: Peter Korsgaard -M: jacmet@sunsite.dk -L: linux-usb@vger.kernel.org -S: Maintained - USB DAVICOM DM9601 DRIVER P: Peter Korsgaard M: jacmet@sunsite.dk diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index 32ca1b927307..9fee37e2596f 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -981,18 +981,27 @@ asmlinkage int osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval32 __user *tvp) { - s64 timeout = MAX_SCHEDULE_TIMEOUT; + fd_set_bits fds; + char *bits; + size_t size; + long timeout; + int ret = -EINVAL; + struct fdtable *fdt; + int max_fds; + + timeout = MAX_SCHEDULE_TIMEOUT; if (tvp) { time_t sec, usec; if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp)) || __get_user(sec, &tvp->tv_sec) || __get_user(usec, &tvp->tv_usec)) { - return -EFAULT; + ret = -EFAULT; + goto out_nofds; } if (sec < 0 || usec < 0) - return -EINVAL; + goto out_nofds; if ((unsigned long) sec < MAX_SELECT_SECONDS) { timeout = (usec + 1000000/HZ - 1) / (1000000/HZ); @@ -1000,8 +1009,60 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, } } + rcu_read_lock(); + fdt = files_fdtable(current->files); + max_fds = fdt->max_fds; + rcu_read_unlock(); + if (n < 0 || n > max_fds) + goto out_nofds; + + /* + * We need 6 bitmaps (in/out/ex for both incoming and outgoing), + * since we used fdset we need to allocate memory in units of + * long-words. + */ + ret = -ENOMEM; + size = FDS_BYTES(n); + bits = kmalloc(6 * size, GFP_KERNEL); + if (!bits) + goto out_nofds; + fds.in = (unsigned long *) bits; + fds.out = (unsigned long *) (bits + size); + fds.ex = (unsigned long *) (bits + 2*size); + fds.res_in = (unsigned long *) (bits + 3*size); + fds.res_out = (unsigned long *) (bits + 4*size); + fds.res_ex = (unsigned long *) (bits + 5*size); + + if ((ret = get_fd_set(n, inp->fds_bits, fds.in)) || + (ret = get_fd_set(n, outp->fds_bits, fds.out)) || + (ret = get_fd_set(n, exp->fds_bits, fds.ex))) + goto out; + zero_fd_set(n, fds.res_in); + zero_fd_set(n, fds.res_out); + zero_fd_set(n, fds.res_ex); + + ret = do_select(n, &fds, &timeout); + /* OSF does not copy back the remaining time. */ - return core_sys_select(n, inp, outp, exp, &timeout); + + if (ret < 0) + goto out; + if (!ret) { + ret = -ERESTARTNOHAND; + if (signal_pending(current)) + goto out; + ret = 0; + } + + if (set_fd_set(n, inp->fds_bits, fds.res_in) || + set_fd_set(n, outp->fds_bits, fds.res_out) || + set_fd_set(n, exp->fds_bits, fds.res_ex)) + ret = -EFAULT; + + out: + kfree(bits); + out_nofds: + return ret; } struct rusage32 { diff --git a/trunk/arch/ia64/ia32/ia32_signal.c b/trunk/arch/ia64/ia32/ia32_signal.c index b763ca19ef17..256a7faeda07 100644 --- a/trunk/arch/ia64/ia32/ia32_signal.c +++ b/trunk/arch/ia64/ia32/ia32_signal.c @@ -463,7 +463,7 @@ sys32_sigsuspend (int history0, int history1, old_sigset_t mask) current->state = TASK_INTERRUPTIBLE; schedule(); - set_restore_sigmask(); + set_thread_flag(TIF_RESTORE_SIGMASK); return -ERESTARTNOHAND; } diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index 19709a079635..c7467f863c7a 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -966,7 +966,7 @@ acpi_map_iosapics (void) fs_initcall(acpi_map_iosapics); #endif /* CONFIG_ACPI_NUMA */ -int __ref acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) +int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) { int err; diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index 7fd18f54c056..6dee579f205f 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -183,10 +183,10 @@ void fixup_irqs(void) { unsigned int irq; extern void ia64_process_pending_intr(void); + extern void ia64_disable_timer(void); extern volatile int time_keeper_id; - /* Mask ITV to disable timer */ - ia64_set_itv(1 << 16); + ia64_disable_timer(); /* * Find a new timesync master diff --git a/trunk/arch/ia64/kernel/palinfo.c b/trunk/arch/ia64/kernel/palinfo.c index 4547a2092af9..396004e8cd14 100644 --- a/trunk/arch/ia64/kernel/palinfo.c +++ b/trunk/arch/ia64/kernel/palinfo.c @@ -1053,7 +1053,7 @@ static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __refdata palinfo_cpu_notifier = +static struct notifier_block palinfo_cpu_notifier __cpuinitdata = { .notifier_call = palinfo_cpu_callback, .priority = 0, diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index c1ad27de2dd2..7fbb51e10bbe 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -867,7 +867,7 @@ pfm_rvfree(void *mem, unsigned long size) } static pfm_context_t * -pfm_context_alloc(int ctx_flags) +pfm_context_alloc(void) { pfm_context_t *ctx; @@ -878,46 +878,6 @@ pfm_context_alloc(int ctx_flags) ctx = kzalloc(sizeof(pfm_context_t), GFP_KERNEL); if (ctx) { DPRINT(("alloc ctx @%p\n", ctx)); - - /* - * init context protection lock - */ - spin_lock_init(&ctx->ctx_lock); - - /* - * context is unloaded - */ - ctx->ctx_state = PFM_CTX_UNLOADED; - - /* - * initialization of context's flags - */ - ctx->ctx_fl_block = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0; - ctx->ctx_fl_system = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0; - ctx->ctx_fl_no_msg = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0; - /* - * will move to set properties - * ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0; - */ - - /* - * init restart semaphore to locked - */ - init_completion(&ctx->ctx_restart_done); - - /* - * activation is used in SMP only - */ - ctx->ctx_last_activation = PFM_INVALID_ACTIVATION; - SET_LAST_CPU(ctx, -1); - - /* - * initialize notification message queue - */ - ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0; - init_waitqueue_head(&ctx->ctx_msgq_wait); - init_waitqueue_head(&ctx->ctx_zombieq); - } return ctx; } @@ -2205,21 +2165,28 @@ static struct dentry_operations pfmfs_dentry_operations = { }; -static struct file * -pfm_alloc_file(pfm_context_t *ctx) +static int +pfm_alloc_fd(struct file **cfile) { - struct file *file; - struct inode *inode; - struct dentry *dentry; + int fd, ret = 0; + struct file *file = NULL; + struct inode * inode; char name[32]; struct qstr this; + fd = get_unused_fd(); + if (fd < 0) return -ENFILE; + + ret = -ENFILE; + + file = get_empty_filp(); + if (!file) goto out; + /* * allocate a new inode */ inode = new_inode(pfmfs_mnt->mnt_sb); - if (!inode) - return ERR_PTR(-ENOMEM); + if (!inode) goto out; DPRINT(("new inode ino=%ld @%p\n", inode->i_ino, inode)); @@ -2232,28 +2199,59 @@ pfm_alloc_file(pfm_context_t *ctx) this.len = strlen(name); this.hash = inode->i_ino; + ret = -ENOMEM; + /* * allocate a new dcache entry */ - dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this); - if (!dentry) { - iput(inode); - return ERR_PTR(-ENOMEM); - } + file->f_path.dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this); + if (!file->f_path.dentry) goto out; - dentry->d_op = &pfmfs_dentry_operations; - d_add(dentry, inode); + file->f_path.dentry->d_op = &pfmfs_dentry_operations; - file = alloc_file(pfmfs_mnt, dentry, FMODE_READ, &pfm_file_ops); - if (!file) { - dput(dentry); - return ERR_PTR(-ENFILE); - } + d_add(file->f_path.dentry, inode); + file->f_path.mnt = mntget(pfmfs_mnt); + file->f_mapping = inode->i_mapping; + file->f_op = &pfm_file_ops; + file->f_mode = FMODE_READ; file->f_flags = O_RDONLY; - file->private_data = ctx; + file->f_pos = 0; + + /* + * may have to delay until context is attached? + */ + fd_install(fd, file); + + /* + * the file structure we will use + */ + *cfile = file; + + return fd; +out: + if (file) put_filp(file); + put_unused_fd(fd); + return ret; +} + +static void +pfm_free_fd(int fd, struct file *file) +{ + struct files_struct *files = current->files; + struct fdtable *fdt; - return file; + /* + * there ie no fd_uninstall(), so we do it here + */ + spin_lock(&files->file_lock); + fdt = files_fdtable(files); + rcu_assign_pointer(fdt->fd[fd], NULL); + spin_unlock(&files->file_lock); + + if (file) + put_filp(file); + put_unused_fd(fd); } static int @@ -2477,7 +2475,6 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t /* link buffer format and context */ ctx->ctx_buf_fmt = fmt; - ctx->ctx_fl_is_sampling = 1; /* assume record() is defined */ /* * check if buffer format wants to use perfmon buffer allocation/mapping service @@ -2672,45 +2669,78 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg { pfarg_context_t *req = (pfarg_context_t *)arg; struct file *filp; - struct path path; int ctx_flags; - int fd; int ret; /* let's check the arguments first */ ret = pfarg_is_sane(current, req); - if (ret < 0) - return ret; + if (ret < 0) return ret; ctx_flags = req->ctx_flags; ret = -ENOMEM; - fd = get_unused_fd(); - if (fd < 0) - return fd; + ctx = pfm_context_alloc(); + if (!ctx) goto error; - ctx = pfm_context_alloc(ctx_flags); - if (!ctx) - goto error; + ret = pfm_alloc_fd(&filp); + if (ret < 0) goto error_file; - filp = pfm_alloc_file(ctx); - if (IS_ERR(filp)) { - ret = PTR_ERR(filp); - goto error_file; - } + req->ctx_fd = ctx->ctx_fd = ret; - req->ctx_fd = ctx->ctx_fd = fd; + /* + * attach context to file + */ + filp->private_data = ctx; /* * does the user want to sample? */ if (pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) { ret = pfm_setup_buffer_fmt(current, filp, ctx, ctx_flags, 0, req); - if (ret) - goto buffer_error; + if (ret) goto buffer_error; } + /* + * init context protection lock + */ + spin_lock_init(&ctx->ctx_lock); + + /* + * context is unloaded + */ + ctx->ctx_state = PFM_CTX_UNLOADED; + + /* + * initialization of context's flags + */ + ctx->ctx_fl_block = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0; + ctx->ctx_fl_system = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0; + ctx->ctx_fl_is_sampling = ctx->ctx_buf_fmt ? 1 : 0; /* assume record() is defined */ + ctx->ctx_fl_no_msg = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0; + /* + * will move to set properties + * ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0; + */ + + /* + * init restart semaphore to locked + */ + init_completion(&ctx->ctx_restart_done); + + /* + * activation is used in SMP only + */ + ctx->ctx_last_activation = PFM_INVALID_ACTIVATION; + SET_LAST_CPU(ctx, -1); + + /* + * initialize notification message queue + */ + ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0; + init_waitqueue_head(&ctx->ctx_msgq_wait); + init_waitqueue_head(&ctx->ctx_zombieq); + DPRINT(("ctx=%p flags=0x%x system=%d notify_block=%d excl_idle=%d no_msg=%d ctx_fd=%d \n", ctx, ctx_flags, @@ -2725,14 +2755,10 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg */ pfm_reset_pmu_state(ctx); - fd_install(fd, filp); - return 0; buffer_error: - path = filp->f_path; - put_filp(filp); - path_put(&path); + pfm_free_fd(ctx->ctx_fd, filp); if (ctx->ctx_buf_fmt) { pfm_buf_fmt_exit(ctx->ctx_buf_fmt, current, NULL, regs); @@ -2741,7 +2767,6 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg pfm_context_free(ctx); error: - put_unused_fd(fd); return ret; } diff --git a/trunk/arch/ia64/kernel/signal.c b/trunk/arch/ia64/kernel/signal.c index 19c5a78636fc..5740296c35af 100644 --- a/trunk/arch/ia64/kernel/signal.c +++ b/trunk/arch/ia64/kernel/signal.c @@ -464,7 +464,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) if (!user_mode(&scr->pt)) return; - if (current_thread_info()->status & TS_RESTORE_SIGMASK) + if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; @@ -530,13 +530,12 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) * continue to iterate in this loop so we can deliver the SIGSEGV... */ if (handle_signal(signr, &ka, &info, oldset, scr)) { - /* - * A signal was successfully delivered; the saved + /* a signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply - * clear the TS_RESTORE_SIGMASK flag. - */ - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; + * clear the TIF_RESTORE_SIGMASK flag */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + clear_thread_flag(TIF_RESTORE_SIGMASK); return; } } @@ -567,8 +566,8 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) /* if there's no signal to deliver, we just put the saved sigmask * back */ - if (current_thread_info()->status & TS_RESTORE_SIGMASK) { - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } diff --git a/trunk/arch/ia64/kernel/smp.c b/trunk/arch/ia64/kernel/smp.c index 983296f1c813..9a9d4c489330 100644 --- a/trunk/arch/ia64/kernel/smp.c +++ b/trunk/arch/ia64/kernel/smp.c @@ -98,33 +98,8 @@ unlock_ipi_calllock(void) spin_unlock_irq(&call_lock); } -static inline void -handle_call_data(void) -{ - struct call_data_struct *data; - void (*func)(void *info); - void *info; - int wait; - - /* release the 'pointer lock' */ - data = (struct call_data_struct *)call_data; - func = data->func; - info = data->info; - wait = data->wait; - - mb(); - atomic_inc(&data->started); - /* At this point the structure may be gone unless wait is true. */ - (*func)(info); - - /* Notify the sending CPU that the task is done. */ - mb(); - if (wait) - atomic_inc(&data->finished); -} - static void -stop_this_cpu(void) +stop_this_cpu (void) { /* * Remove this CPU: @@ -163,21 +138,44 @@ handle_IPI (int irq, void *dev_id) ops &= ~(1 << which); switch (which) { - case IPI_CALL_FUNC: - handle_call_data(); - break; - - case IPI_CPU_STOP: + case IPI_CALL_FUNC: + { + struct call_data_struct *data; + void (*func)(void *info); + void *info; + int wait; + + /* release the 'pointer lock' */ + data = (struct call_data_struct *) call_data; + func = data->func; + info = data->info; + wait = data->wait; + + mb(); + atomic_inc(&data->started); + /* + * At this point the structure may be gone unless + * wait is true. + */ + (*func)(info); + + /* Notify the sending CPU that the task is done. */ + mb(); + if (wait) + atomic_inc(&data->finished); + } + break; + + case IPI_CPU_STOP: stop_this_cpu(); break; #ifdef CONFIG_KEXEC - case IPI_KDUMP_CPU_STOP: + case IPI_KDUMP_CPU_STOP: unw_init_running(kdump_cpu_freeze, NULL); break; #endif - default: - printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", - this_cpu, which); + default: + printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which); break; } } while (ops); diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index 8c73643f2d66..48e15a51782f 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -379,6 +379,11 @@ static struct irqaction timer_irqaction = { .name = "timer" }; +void __devinit ia64_disable_timer(void) +{ + ia64_set_itv(1 << 16); +} + void __init time_init (void) { diff --git a/trunk/arch/ia64/kernel/topology.c b/trunk/arch/ia64/kernel/topology.c index 26228e2d01ae..abb17a613b17 100644 --- a/trunk/arch/ia64/kernel/topology.c +++ b/trunk/arch/ia64/kernel/topology.c @@ -36,11 +36,9 @@ void arch_fix_phys_package_id(int num, u32 slot) } EXPORT_SYMBOL_GPL(arch_fix_phys_package_id); - -#ifdef CONFIG_HOTPLUG_CPU -int __ref arch_register_cpu(int num) +int arch_register_cpu(int num) { -#ifdef CONFIG_ACPI +#if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU) /* * If CPEI can be re-targetted or if this is not * CPEI target, then it is hotpluggable @@ -49,21 +47,19 @@ int __ref arch_register_cpu(int num) sysfs_cpus[num].cpu.hotpluggable = 1; map_cpu_to_node(num, node_cpuid[num].nid); #endif + return register_cpu(&sysfs_cpus[num].cpu, num); } -EXPORT_SYMBOL(arch_register_cpu); + +#ifdef CONFIG_HOTPLUG_CPU void arch_unregister_cpu(int num) { unregister_cpu(&sysfs_cpus[num].cpu); unmap_cpu_from_node(num, cpu_to_node(num)); } +EXPORT_SYMBOL(arch_register_cpu); EXPORT_SYMBOL(arch_unregister_cpu); -#else -static int __init arch_register_cpu(int num) -{ - return register_cpu(&sysfs_cpus[num].cpu, num); -} #endif /*CONFIG_HOTPLUG_CPU*/ diff --git a/trunk/arch/m32r/Makefile b/trunk/arch/m32r/Makefile index 469766b24e22..4072a07ebf8e 100644 --- a/trunk/arch/m32r/Makefile +++ b/trunk/arch/m32r/Makefile @@ -5,8 +5,6 @@ # architecture-specific flags and dependencies. # -KBUILD_DEFCONFIG := m32700ut.smp_defconfig - LDFLAGS := OBJCOPYFLAGS := -O binary -R .note -R .comment -S LDFLAGS_vmlinux := diff --git a/trunk/arch/m32r/defconfig b/trunk/arch/m32r/defconfig new file mode 100644 index 000000000000..af3b98179113 --- /dev/null +++ b/trunk/arch/m32r/defconfig @@ -0,0 +1,863 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.23-rc1 +# Wed Aug 1 17:22:35 2007 +# +CONFIG_M32R=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_NO_IOPORT=y +CONFIG_NO_DMA=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_CPUSETS is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +# CONFIG_KALLSYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +# CONFIG_FUTEX is not set +CONFIG_ANON_INODES=y +# CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# Processor type and features +# +# CONFIG_PLAT_MAPPI is not set +# CONFIG_PLAT_USRV is not set +CONFIG_PLAT_M32700UT=y +# CONFIG_PLAT_OPSPUT is not set +# CONFIG_PLAT_OAKS32R is not set +# CONFIG_PLAT_MAPPI2 is not set +# CONFIG_PLAT_MAPPI3 is not set +# CONFIG_PLAT_M32104UT is not set +CONFIG_CHIP_M32700=y +# CONFIG_CHIP_M32102 is not set +# CONFIG_CHIP_M32104 is not set +# CONFIG_CHIP_VDEC2 is not set +# CONFIG_CHIP_OPSP is not set +CONFIG_MMU=y +CONFIG_TLB_ENTRIES=32 +CONFIG_ISA_M32R2=y +CONFIG_ISA_DSP_LEVEL2=y +CONFIG_ISA_DUAL_ISSUE=y +CONFIG_BUS_CLOCK=50000000 +CONFIG_TIMER_DIVIDE=128 +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_MEMORY_START=0x08000000 +CONFIG_MEMORY_SIZE=0x01000000 +CONFIG_NOHIGHMEM=y +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_DISCONTIGMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_DISCONTIGMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_NEED_MULTIPLE_NODES=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_IRAM_START=0x00f00000 +CONFIG_IRAM_SIZE=0x00080000 +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_PREEMPT=y +CONFIG_SMP=y +# CONFIG_CHIP_M32700_TS1 is not set +CONFIG_NR_CPUS=2 +CONFIG_NODES_SHIFT=1 + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_ISA is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_CFI_ADV_OPTIONS=y +# CONFIG_MTD_CFI_NOSWAP is not set +CONFIG_MTD_CFI_BE_BYTE_SWAP=y +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=m +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=m +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +CONFIG_IDE=y +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=m +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y +# CONFIG_NE2000 is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_M32R_SIO=y +CONFIG_SERIAL_M32R_SIO_CONSOLE=y +CONFIG_SERIAL_M32R_PLDSIO=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_RTC is not set +CONFIG_DS1302=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_CPIA is not set +CONFIG_VIDEO_M32R_AR=m +CONFIG_VIDEO_M32R_AR_M64278=m +CONFIG_RADIO_ADAPTERS=y +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_S1D13XXX=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_LOGO_M32R_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +CONFIG_USB_SUPPORT=y +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set +CONFIG_MMC=y +CONFIG_MMC_DEBUG=y +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y + +# +# MMC/SD Host Controller Drivers +# +# CONFIG_NEW_LEDS is not set + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +CONFIG_JBD_DEBUG=y +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=y + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_FRAME_POINTER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_HAS_IOMEM=y diff --git a/trunk/arch/m32r/kernel/vmlinux.lds.S b/trunk/arch/m32r/kernel/vmlinux.lds.S index 15a6f36c06db..41b07854fcc6 100644 --- a/trunk/arch/m32r/kernel/vmlinux.lds.S +++ b/trunk/arch/m32r/kernel/vmlinux.lds.S @@ -60,6 +60,9 @@ SECTIONS . = ALIGN(4096); __nosave_end = .; + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + . = ALIGN(32); .data.cacheline_aligned : { *(.data.cacheline_aligned) } diff --git a/trunk/arch/mips/kernel/irixioctl.c b/trunk/arch/mips/kernel/irixioctl.c index b39bdba82e02..2bde200d5ad0 100644 --- a/trunk/arch/mips/kernel/irixioctl.c +++ b/trunk/arch/mips/kernel/irixioctl.c @@ -27,6 +27,33 @@ struct irix_termios { cc_t c_cc[NCCS]; }; +extern void start_tty(struct tty_struct *tty); +static struct tty_struct *get_tty(int fd) +{ + struct file *filp; + struct tty_struct *ttyp = NULL; + + rcu_read_lock(); + filp = fcheck(fd); + if(filp && filp->private_data) { + ttyp = (struct tty_struct *) filp->private_data; + + if(ttyp->magic != TTY_MAGIC) + ttyp =NULL; + } + rcu_read_unlock(); + return ttyp; +} + +static struct tty_struct *get_real_tty(struct tty_struct *tp) +{ + if (tp->driver->type == TTY_DRIVER_TYPE_PTY && + tp->driver->subtype == PTY_TYPE_MASTER) + return tp->link; + else + return tp; +} + asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg) { struct tty_struct *tp, *rtp; @@ -119,24 +146,34 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg) error = sys_ioctl(fd, TIOCNOTTY, arg); break; - case 0x00007416: { - pid_t pid; + case 0x00007416: #ifdef DEBUG_IOCTLS printk("TIOCGSID, %08lx) ", arg); #endif - old_fs = get_fs(); set_fs(get_ds()); - error = sys_ioctl(fd, TIOCGSID, (unsigned long)&pid); - set_fs(old_fs); - if (!error) - error = put_user(pid, (unsigned long __user *) arg); + tp = get_tty(fd); + if(!tp) { + error = -EINVAL; + break; + } + rtp = get_real_tty(tp); +#ifdef DEBUG_IOCTLS + printk("rtp->session=%d ", rtp->session); +#endif + error = put_user(rtp->session, (unsigned long __user *) arg); break; - } + case 0x746e: /* TIOCSTART, same effect as hitting ^Q */ #ifdef DEBUG_IOCTLS printk("TIOCSTART, %08lx) ", arg); #endif - error = sys_ioctl(fd, TCXONC, TCOON); + tp = get_tty(fd); + if(!tp) { + error = -EINVAL; + break; + } + rtp = get_real_tty(tp); + start_tty(rtp); break; case 0x20006968: diff --git a/trunk/arch/mips/kernel/kspd.c b/trunk/arch/mips/kernel/kspd.c index ceb62dce1c9c..998c4efcce88 100644 --- a/trunk/arch/mips/kernel/kspd.c +++ b/trunk/arch/mips/kernel/kspd.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts index bba234eb14a9..1f2f1e0a5571 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts @@ -21,7 +21,6 @@ serial1 = &serial1; pci0 = &pci0; pci1 = &pci1; - pci2 = &pci2; }; cpus { @@ -106,7 +105,7 @@ compatible = "ns16550"; reg = <0x4600 0x100>; clock-frequency = <0>; - interrupts = <42 2>; + interrupts = <28 2>; interrupt-parent = <&mpic>; }; @@ -323,24 +322,4 @@ }; }; }; - - pci2: pcie@e0009000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8641-pcie"; - reg = <0xe0009000 0x00001000>; - ranges = <0x02000000 0 0x90000000 0x90000000 0 0x10000000 - 0x01000000 0 0x00000000 0xe2000000 0 0x00100000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0x0000 0 0 1 &mpic 4 1 - 0x0000 0 0 2 &mpic 5 1 - 0x0000 0 0 3 &mpic 6 1 - 0x0000 0 0 4 &mpic 7 1>; - interrupt-parent = <&mpic>; - interrupts = <25 2>; - clock-frequency = <33333333>; - }; }; diff --git a/trunk/arch/powerpc/configs/ps3_defconfig b/trunk/arch/powerpc/configs/ps3_defconfig index 71d79e428d20..7a64c564f6e6 100644 --- a/trunk/arch/powerpc/configs/ps3_defconfig +++ b/trunk/arch/powerpc/configs/ps3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25 -# Mon Apr 28 12:39:10 2008 +# Linux kernel version: 2.6.25-rc6 +# Thu Mar 20 11:07:04 2008 # CONFIG_PPC64=y @@ -30,9 +30,6 @@ CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y CONFIG_ARCH_HAS_ILOG2_U64=y @@ -76,6 +73,8 @@ CONFIG_POSIX_MQUEUE=y CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_USER_SCHED is not set +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -162,6 +161,7 @@ CONFIG_PPC_MULTIPLATFORM=y # CONFIG_PPC_PMAC is not set # CONFIG_PPC_MAPLE is not set # CONFIG_PPC_PASEMI is not set +# CONFIG_PPC_CELLEB is not set CONFIG_PPC_PS3=y # @@ -181,7 +181,6 @@ CONFIG_PS3_LPM=m CONFIG_PPC_CELL=y # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_IBM_CELL_BLADE is not set -# CONFIG_PPC_CELLEB is not set # # Cell Broadband Engine options @@ -206,9 +205,9 @@ CONFIG_SPU_BASE=y # # Kernel options # -CONFIG_TICK_ONESHOT=y +# CONFIG_TICK_ONESHOT is not set # CONFIG_NO_HZ is not set -CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HIGH_RES_TIMERS is not set CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # CONFIG_HZ_100 is not set CONFIG_HZ_250=y @@ -222,6 +221,7 @@ CONFIG_PREEMPT_NONE=y CONFIG_BINFMT_ELF=y CONFIG_COMPAT_BINFMT_ELF=y CONFIG_BINFMT_MISC=y +CONFIG_FORCE_MAX_ZONEORDER=13 # CONFIG_IOMMU_VMERGE is not set CONFIG_IOMMU_HELPER=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y @@ -255,7 +255,6 @@ CONFIG_BOUNCE=y CONFIG_ARCH_MEMORY_PROBE=y # CONFIG_PPC_HAS_HASH_64K is not set # CONFIG_PPC_64K_PAGES is not set -CONFIG_FORCE_MAX_ZONEORDER=13 # CONFIG_SCHED_SMT is not set CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set @@ -273,9 +272,7 @@ CONFIG_GENERIC_ISA_DMA=y # CONFIG_PCI_SYSCALL is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCCARD is not set -CONFIG_PAGE_OFFSET=0xc000000000000000 CONFIG_KERNEL_START=0xc000000000000000 -CONFIG_PHYSICAL_START=0x00000000 # # Networking @@ -295,7 +292,7 @@ CONFIG_XFRM=y # CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y -CONFIG_IP_MULTICAST=y +# CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y @@ -304,7 +301,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set @@ -336,10 +332,8 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y CONFIG_INET6_XFRM_MODE_BEET=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=y -CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set @@ -398,6 +392,8 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -511,7 +507,6 @@ CONFIG_WLAN_80211=y # CONFIG_LIBERTAS is not set # CONFIG_USB_ZD1201 is not set # CONFIG_USB_NET_RNDIS_WLAN is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_HOSTAP is not set # @@ -583,7 +578,6 @@ CONFIG_INPUT_JOYSTICK=y # CONFIG_JOYSTICK_SPACEBALL is not set # CONFIG_JOYSTICK_STINGER is not set # CONFIG_JOYSTICK_TWIDJOY is not set -# CONFIG_JOYSTICK_ZHENHUA is not set # CONFIG_JOYSTICK_JOYDUMP is not set # CONFIG_JOYSTICK_XPAD is not set # CONFIG_INPUT_TABLET is not set @@ -647,7 +641,6 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set # # Multimedia devices @@ -767,6 +760,10 @@ CONFIG_SND_PS3_DEFAULT_START_DELAY=2000 # # CONFIG_SND_SOC is not set +# +# SoC Audio support for SuperH +# + # # ALSA SoC audio for Freescale SOCs # @@ -852,7 +849,6 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_ALAUDA is not set # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set # @@ -897,6 +893,10 @@ CONFIG_USB_MON=y # CONFIG_EDAC is not set # CONFIG_RTC_CLASS is not set # CONFIG_DMADEVICES is not set + +# +# Userspace I/O +# # CONFIG_UIO is not set # @@ -986,6 +986,7 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y @@ -1058,10 +1059,9 @@ CONFIG_NLS_ISO8859_1=y # Library routines # CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set -CONFIG_CRC_ITU_T=m +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set @@ -1071,7 +1071,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y # # Kernel hacking @@ -1079,7 +1078,6 @@ CONFIG_HAVE_LMB=y # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -1095,16 +1093,12 @@ CONFIG_SCHED_DEBUG=y # CONFIG_RT_MUTEX_TESTER is not set CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set CONFIG_DEBUG_LIST=y # CONFIG_DEBUG_SG is not set # CONFIG_BOOT_PRINTK_DELAY is not set @@ -1127,81 +1121,51 @@ CONFIG_IRQSTACKS=y # CONFIG_SECURITY is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y - -# -# Crypto core or helper -# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_GF128MUL=m -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_SEQIV=m - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_CTR=m -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# +CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=m # CONFIG_CRYPTO_SHA1 is not set # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set # CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=m -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_CCM=m +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=m # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=m # CONFIG_CRYPTO_KHAZAD is not set -CONFIG_CRYPTO_SALSA20=m +# CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# +CONFIG_CRYPTO_SALSA20=m # CONFIG_CRYPTO_DEFLATE is not set +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_HW=y # CONFIG_PPC_CLOCK is not set -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index 1457aa0a08f1..be35ffae10f0 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -386,8 +386,6 @@ static void __init smp_create_idle(unsigned int cpu) panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p)); #ifdef CONFIG_PPC64 paca[cpu].__current = p; - paca[cpu].kstack = (unsigned long) task_thread_info(p) - + THREAD_SIZE - STACK_FRAME_OVERHEAD; #endif current_set[cpu] = task_thread_info(p); task_thread_info(p)->cpu = cpu; diff --git a/trunk/arch/powerpc/mm/slb.c b/trunk/arch/powerpc/mm/slb.c index cf8705e32d60..906daeda59a8 100644 --- a/trunk/arch/powerpc/mm/slb.c +++ b/trunk/arch/powerpc/mm/slb.c @@ -30,7 +30,7 @@ #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) #else -#define DBG pr_debug +#define DBG(fmt...) #endif extern void slb_allocate_realmode(unsigned long ea); @@ -44,13 +44,13 @@ static void slb_allocate(unsigned long ea) slb_allocate_realmode(ea); } -#define slb_esid_mask(ssize) \ - (((ssize) == MMU_SEGSIZE_256M)? ESID_MASK: ESID_MASK_1T) - static inline unsigned long mk_esid_data(unsigned long ea, int ssize, unsigned long slot) { - return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | slot; + unsigned long mask; + + mask = (ssize == MMU_SEGSIZE_256M)? ESID_MASK: ESID_MASK_1T; + return (ea & mask) | SLB_ESID_V | slot; } #define slb_vsid_shift(ssize) \ @@ -279,8 +279,8 @@ void slb_initialize(void) patch_slb_encoding(slb_compare_rr_to_size, mmu_slb_size); - DBG("SLB: linear LLP = %04lx\n", linear_llp); - DBG("SLB: io LLP = %04lx\n", io_llp); + DBG("SLB: linear LLP = %04x\n", linear_llp); + DBG("SLB: io LLP = %04x\n", io_llp); } get_paca()->stab_rr = SLB_NUM_BOLTED; @@ -301,16 +301,11 @@ void slb_initialize(void) create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, 1); - /* For the boot cpu, we're running on the stack in init_thread_union, - * which is in the first segment of the linear mapping, and also - * get_paca()->kstack hasn't been initialized yet. - * For secondary cpus, we need to bolt the kernel stack entry now. - */ slb_shadow_clear(2); - if (raw_smp_processor_id() != boot_cpuid && - (get_paca()->kstack & slb_esid_mask(mmu_kernel_ssize)) > PAGE_OFFSET) - create_shadowed_slbe(get_paca()->kstack, - mmu_kernel_ssize, lflags, 2); + /* We don't bolt the stack for the time being - we're in boot, + * so the stack is in the bolted segment. By the time it goes + * elsewhere, we'll call _switch() which will bolt in the new + * one. */ asm volatile("isync":::"memory"); } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/coredump.c b/trunk/arch/powerpc/platforms/cell/spufs/coredump.c index af116aadba10..b962c3ab470c 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/coredump.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/ps3/interrupt.c b/trunk/arch/powerpc/platforms/ps3/interrupt.c index e59634f7af96..a14e5cdc2fed 100644 --- a/trunk/arch/powerpc/platforms/ps3/interrupt.c +++ b/trunk/arch/powerpc/platforms/ps3/interrupt.c @@ -167,8 +167,8 @@ static struct irq_chip ps3_irq_chip = { * ps3_private data. */ -static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, - unsigned int *virq) +int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, + unsigned int *virq) { int result; struct ps3_private *pd; @@ -217,7 +217,7 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, * Clears chip data and calls irq_dispose_mapping() for the virq. */ -static int ps3_virq_destroy(unsigned int virq) +int ps3_virq_destroy(unsigned int virq) { const struct ps3_private *pd = get_irq_chip_data(virq); diff --git a/trunk/arch/powerpc/sysdev/fsl_rio.c b/trunk/arch/powerpc/sysdev/fsl_rio.c index a0fa4ebb39c6..3d920376f58e 100644 --- a/trunk/arch/powerpc/sysdev/fsl_rio.c +++ b/trunk/arch/powerpc/sysdev/fsl_rio.c @@ -176,7 +176,6 @@ struct rio_priv { /** * fsl_rio_doorbell_send - Send a MPC85xx doorbell message - * @mport: RapidIO master port info * @index: ID of RapidIO interface * @destid: Destination ID of target device * @data: 16-bit info field of RapidIO doorbell message @@ -212,7 +211,6 @@ static int fsl_rio_doorbell_send(struct rio_mport *mport, /** * fsl_local_config_read - Generate a MPC85xx local config space read - * @mport: RapidIO master port info * @index: ID of RapdiIO interface * @offset: Offset into configuration space * @len: Length (in bytes) of the maintenance transaction @@ -234,7 +232,6 @@ static int fsl_local_config_read(struct rio_mport *mport, /** * fsl_local_config_write - Generate a MPC85xx local config space write - * @mport: RapidIO master port info * @index: ID of RapdiIO interface * @offset: Offset into configuration space * @len: Length (in bytes) of the maintenance transaction @@ -257,7 +254,6 @@ static int fsl_local_config_write(struct rio_mport *mport, /** * fsl_rio_config_read - Generate a MPC85xx read maintenance transaction - * @mport: RapidIO master port info * @index: ID of RapdiIO interface * @destid: Destination ID of transaction * @hopcount: Number of hops to target device @@ -299,7 +295,6 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, /** * fsl_rio_config_write - Generate a MPC85xx write maintenance transaction - * @mport: RapidIO master port info * @index: ID of RapdiIO interface * @destid: Destination ID of transaction * @hopcount: Number of hops to target device @@ -990,8 +985,8 @@ static inline void fsl_rio_info(struct device *dev, u32 ccsr) } /** - * fsl_rio_setup - Setup Freescale PowerPC RapidIO interface - * @dev: of_device pointer + * fsl_rio_setup - Setup MPC85xx RapidIO interface + * @fsl_rio_setup - Setup Freescale PowerPC RapidIO interface * * Initializes MPC85xx RapidIO hardware interface, configures * master port with system-specific info, and registers the diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.c b/trunk/arch/powerpc/sysdev/fsl_soc.c index 3a7054e2bb75..324c01b70ddd 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.c +++ b/trunk/arch/powerpc/sysdev/fsl_soc.c @@ -389,8 +389,8 @@ static int __init gfar_of_init(void) } gfar_data.phy_id = *id; - snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%llx", - (unsigned long long)res.start); + snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%x", + res.start); of_node_put(phy); of_node_put(mdio); diff --git a/trunk/arch/powerpc/sysdev/xilinx_intc.c b/trunk/arch/powerpc/sysdev/xilinx_intc.c index b7aefd0d45cb..ba8eea2bcce0 100644 --- a/trunk/arch/powerpc/sysdev/xilinx_intc.c +++ b/trunk/arch/powerpc/sysdev/xilinx_intc.c @@ -107,7 +107,7 @@ xilinx_intc_init(struct device_node *np) } regs = ioremap(res.start, 32); - printk(KERN_INFO "Xilinx intc at 0x%08LX mapped to 0x%p\n", + printk(KERN_INFO "Xilinx intc at 0x%08X mapped to 0x%p\n", res.start, regs); /* Setup interrupt controller */ diff --git a/trunk/arch/sparc64/kernel/pci.c b/trunk/arch/sparc64/kernel/pci.c index dbf2fc2f4d87..112b09f16f36 100644 --- a/trunk/arch/sparc64/kernel/pci.c +++ b/trunk/arch/sparc64/kernel/pci.c @@ -350,8 +350,7 @@ static void pci_parse_of_addrs(struct of_device *op, struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, struct device_node *node, - struct pci_bus *bus, int devfn, - int host_controller) + struct pci_bus *bus, int devfn) { struct dev_archdata *sd; struct pci_dev *dev; @@ -390,43 +389,28 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->devfn = devfn; dev->multifunction = 0; /* maybe a lie? */ - if (host_controller) { - if (tlb_type != hypervisor) { - pci_read_config_word(dev, PCI_VENDOR_ID, - &dev->vendor); - pci_read_config_word(dev, PCI_DEVICE_ID, - &dev->device); - } else { - dev->vendor = PCI_VENDOR_ID_SUN; - dev->device = 0x80f0; - } - dev->cfg_size = 256; - dev->class = PCI_CLASS_BRIDGE_HOST << 8; - sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), - 0x00, PCI_SLOT(devfn), PCI_FUNC(devfn)); - } else { - dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); - dev->device = of_getintprop_default(node, "device-id", 0xffff); - dev->subsystem_vendor = - of_getintprop_default(node, "subsystem-vendor-id", 0); - dev->subsystem_device = - of_getintprop_default(node, "subsystem-id", 0); - - dev->cfg_size = pci_cfg_space_size(dev); - - /* We can't actually use the firmware value, we have - * to read what is in the register right now. One - * reason is that in the case of IDE interfaces the - * firmware can sample the value before the the IDE - * interface is programmed into native mode. - */ - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); - dev->class = class >> 8; - dev->revision = class & 0xff; + dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); + dev->device = of_getintprop_default(node, "device-id", 0xffff); + dev->subsystem_vendor = + of_getintprop_default(node, "subsystem-vendor-id", 0); + dev->subsystem_device = + of_getintprop_default(node, "subsystem-id", 0); + + dev->cfg_size = pci_cfg_space_size(dev); + + /* We can't actually use the firmware value, we have + * to read what is in the register right now. One + * reason is that in the case of IDE interfaces the + * firmware can sample the value before the the IDE + * interface is programmed into native mode. + */ + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); + dev->class = class >> 8; + dev->revision = class & 0xff; + + sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), + dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); - sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), - dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); - } if (ofpci_verbose) printk(" class: 0x%x device name: %s\n", dev->class, pci_name(dev)); @@ -441,26 +425,21 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; - if (host_controller) { + if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { + /* a PCI-PCI bridge */ dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; dev->rom_base_reg = PCI_ROM_ADDRESS1; - dev->irq = PCI_IRQ_NONE; + } else if (!strcmp(type, "cardbus")) { + dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; } else { - if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { - /* a PCI-PCI bridge */ - dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; - dev->rom_base_reg = PCI_ROM_ADDRESS1; - } else if (!strcmp(type, "cardbus")) { - dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; - } else { - dev->hdr_type = PCI_HEADER_TYPE_NORMAL; - dev->rom_base_reg = PCI_ROM_ADDRESS; + dev->hdr_type = PCI_HEADER_TYPE_NORMAL; + dev->rom_base_reg = PCI_ROM_ADDRESS; - dev->irq = sd->op->irqs[0]; - if (dev->irq == 0xffffffff) - dev->irq = PCI_IRQ_NONE; - } + dev->irq = sd->op->irqs[0]; + if (dev->irq == 0xffffffff) + dev->irq = PCI_IRQ_NONE; } + pci_parse_of_addrs(sd->op, node, dev); if (ofpci_verbose) @@ -749,7 +728,7 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, prev_devfn = devfn; /* create a new pci_dev for this device */ - dev = of_create_pci_dev(pbm, child, bus, devfn, 0); + dev = of_create_pci_dev(pbm, child, bus, devfn); if (!dev) continue; if (ofpci_verbose) @@ -796,48 +775,9 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) pci_bus_register_of_sysfs(child_bus); } -int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, - unsigned int devfn, - int where, int size, - u32 *value) -{ - static u8 fake_pci_config[] = { - 0x8e, 0x10, /* Vendor: 0x108e (Sun) */ - 0xf0, 0x80, /* Device: 0x80f0 (Fire) */ - 0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */ - 0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */ - 0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */ - 0x00, /* Cacheline: 0x00 */ - 0x40, /* Latency: 0x40 */ - 0x00, /* Header-Type: 0x00 normal */ - }; - - *value = 0; - if (where >= 0 && where < sizeof(fake_pci_config) && - (where + size) >= 0 && - (where + size) < sizeof(fake_pci_config) && - size <= sizeof(u32)) { - while (size--) { - *value <<= 8; - *value |= fake_pci_config[where + size]; - } - } - - return PCIBIOS_SUCCESSFUL; -} - -int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, - unsigned int devfn, - int where, int size, - u32 value) -{ - return PCIBIOS_SUCCESSFUL; -} - struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) { struct device_node *node = pbm->prom_node; - struct pci_dev *host_pdev; struct pci_bus *bus; printk("PCI: Scanning PBM %s\n", node->full_name); @@ -855,10 +795,6 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) bus->resource[0] = &pbm->io_space; bus->resource[1] = &pbm->mem_space; - /* Create the dummy host bridge and link it in. */ - host_pdev = of_create_pci_dev(pbm, node, bus, 0x00, 1); - bus->self = host_pdev; - pci_of_scan_bus(pbm, node, bus); pci_bus_add_devices(bus); pci_bus_register_of_sysfs(bus); diff --git a/trunk/arch/sparc64/kernel/pci_common.c b/trunk/arch/sparc64/kernel/pci_common.c index 923e0bcc3bfd..19fa621d6a60 100644 --- a/trunk/arch/sparc64/kernel/pci_common.c +++ b/trunk/arch/sparc64/kernel/pci_common.c @@ -264,9 +264,6 @@ static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned int func = PCI_FUNC(devfn); unsigned long ret; - if (!bus && devfn == 0x00) - return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, - size, value); if (config_out_of_range(pbm, bus, devfn, where)) { ret = ~0UL; } else { @@ -300,9 +297,6 @@ static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned int func = PCI_FUNC(devfn); unsigned long ret; - if (!bus && devfn == 0x00) - return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, - size, value); if (config_out_of_range(pbm, bus, devfn, where)) { /* Do nothing. */ } else { diff --git a/trunk/arch/sparc64/kernel/pci_impl.h b/trunk/arch/sparc64/kernel/pci_impl.h index 218bac4ff79b..c385d126be11 100644 --- a/trunk/arch/sparc64/kernel/pci_impl.h +++ b/trunk/arch/sparc64/kernel/pci_impl.h @@ -167,15 +167,6 @@ extern void pci_get_pbm_props(struct pci_pbm_info *pbm); extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); -extern int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, - unsigned int devfn, - int where, int size, - u32 *value); -extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, - unsigned int devfn, - int where, int size, - u32 value); - /* Error reporting support. */ extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *); extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *); diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c index f0b7cd343216..fa796b605f55 100644 --- a/trunk/block/bsg.c +++ b/trunk/block/bsg.c @@ -174,11 +174,7 @@ static int bsg_io_schedule(struct bsg_device *bd) static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, struct sg_io_v4 *hdr, int has_write_perm) { - if (hdr->request_len > BLK_MAX_CDB) { - rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); - if (!rq->cmd) - return -ENOMEM; - } + memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request, hdr->request_len)) @@ -215,6 +211,8 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw) if (hdr->guard != 'Q') return -EINVAL; + if (hdr->request_len > BLK_MAX_CDB) + return -EINVAL; if (hdr->dout_xfer_len > (q->max_sectors << 9) || hdr->din_xfer_len > (q->max_sectors << 9)) return -EIO; @@ -304,8 +302,6 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr) } return rq; out: - if (rq->cmd != rq->__cmd) - kfree(rq->cmd); blk_put_request(rq); if (next_rq) { blk_rq_unmap_user(next_rq->bio); @@ -459,8 +455,6 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, ret = rq->errors; blk_rq_unmap_user(bio); - if (rq->cmd != rq->__cmd) - kfree(rq->cmd); blk_put_request(rq); return ret; diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 78199c08ec92..ffa3720e6ca0 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -33,12 +33,13 @@ #include /* Command group 3 is reserved and should never be used. */ -const unsigned char scsi_command_size_tbl[8] = +const unsigned char scsi_command_size[8] = { 6, 10, 10, 12, 16, 12, 10, 10 }; -EXPORT_SYMBOL(scsi_command_size_tbl); + +EXPORT_SYMBOL(scsi_command_size); #include diff --git a/trunk/drivers/block/ub.c b/trunk/drivers/block/ub.c index 3a281ef11ffa..e322cce8c12d 100644 --- a/trunk/drivers/block/ub.c +++ b/trunk/drivers/block/ub.c @@ -205,7 +205,6 @@ struct ub_scsi_cmd { unsigned char key, asc, ascq; /* May be valid if error==-EIO */ int stat_count; /* Retries getting status. */ - unsigned int timeo; /* jiffies until rq->timeout changes */ unsigned int len; /* Requested length */ unsigned int current_sg; @@ -319,7 +318,6 @@ struct ub_dev { int openc; /* protected by ub_lock! */ /* kref is too implicit for our taste */ int reset; /* Reset is running */ - int bad_resid; unsigned int tagcnt; char name[12]; struct usb_device *dev; @@ -766,12 +764,6 @@ static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, cmd->cdb_len = rq->cmd_len; cmd->len = rq->data_len; - - /* - * To reapply this to every URB is not as incorrect as it looks. - * In return, we avoid any complicated tracking calculations. - */ - cmd->timeo = rq->timeout; } static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) @@ -793,6 +785,10 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) scsi_status = 0; } else { if (cmd->act_len != cmd->len) { + if ((cmd->key == MEDIUM_ERROR || + cmd->key == UNIT_ATTENTION) && + ub_rw_cmd_retry(sc, lun, urq, cmd) == 0) + return; scsi_status = SAM_STAT_CHECK_CONDITION; } else { scsi_status = 0; @@ -808,10 +804,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) else scsi_status = DID_ERROR << 16; } else { - if (cmd->error == -EIO && - (cmd->key == 0 || - cmd->key == MEDIUM_ERROR || - cmd->key == UNIT_ATTENTION)) { + if (cmd->error == -EIO) { if (ub_rw_cmd_retry(sc, lun, urq, cmd) == 0) return; } @@ -1266,19 +1259,14 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) return; } - if (!sc->bad_resid) { - len = le32_to_cpu(bcs->Residue); - if (len != cmd->len - cmd->act_len) { - /* - * Only start ignoring if this cmd ended well. - */ - if (cmd->len == cmd->act_len) { - printk(KERN_NOTICE "%s: " - "bad residual %d of %d, ignoring\n", - sc->name, len, cmd->len); - sc->bad_resid = 1; - } - } + len = le32_to_cpu(bcs->Residue); + if (len != cmd->len - cmd->act_len) { + /* + * It is all right to transfer less, the caller has + * to check. But it's not all right if the device + * counts disagree with our counts. + */ + goto Bad_End; } switch (bcs->Status) { @@ -1309,7 +1297,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) ub_state_done(sc, cmd, -EIO); } else { - printk(KERN_WARNING "%s: wrong command state %d\n", + printk(KERN_WARNING "%s: " + "wrong command state %d\n", sc->name, cmd->state); ub_state_done(sc, cmd, -EINVAL); return; @@ -1347,10 +1336,7 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) return; } - if (cmd->timeo) - sc->work_timer.expires = jiffies + cmd->timeo; - else - sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT; + sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT; add_timer(&sc->work_timer); cmd->state = UB_CMDST_DATA; @@ -1390,10 +1376,7 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) return -1; } - if (cmd->timeo) - sc->work_timer.expires = jiffies + cmd->timeo; - else - sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT; + sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT; add_timer(&sc->work_timer); return 0; } @@ -1532,7 +1515,8 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) return; } if (cmd->state != UB_CMDST_SENSE) { - printk(KERN_WARNING "%s: sense done with bad cmd state %d\n", + printk(KERN_WARNING "%s: " + "sense done with bad cmd state %d\n", sc->name, cmd->state); return; } @@ -1736,7 +1720,7 @@ static int ub_bd_ioctl(struct inode *inode, struct file *filp, } /* - * This is called by check_disk_change if we reported a media change. + * This is called once a new disk was seen by the block layer or by ub_probe(). * The main onjective here is to discover the features of the media such as * the capacity, read-only status, etc. USB storage generally does not * need to be spun up, but if we needed it, this would be the place. @@ -2152,7 +2136,8 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev, } if (ep_in == NULL || ep_out == NULL) { - printk(KERN_NOTICE "%s: failed endpoint check\n", sc->name); + printk(KERN_NOTICE "%s: failed endpoint check\n", + sc->name); return -ENODEV; } @@ -2369,7 +2354,7 @@ static void ub_disconnect(struct usb_interface *intf) spin_unlock_irqrestore(&ub_lock, flags); /* - * Fence stall clearings, operations triggered by unlinkings and so on. + * Fence stall clearnings, operations triggered by unlinkings and so on. * We do not attempt to unlink any URBs, because we do not trust the * unlink paths in HC drivers. Also, we get -84 upon disconnect anyway. */ @@ -2432,7 +2417,7 @@ static void ub_disconnect(struct usb_interface *intf) spin_unlock_irqrestore(sc->lock, flags); /* - * There is virtually no chance that other CPU runs a timeout so long + * There is virtually no chance that other CPU runs times so long * after ub_urb_complete should have called del_timer, but only if HCD * didn't forget to deliver a callback on unlink. */ diff --git a/trunk/drivers/block/virtio_blk.c b/trunk/drivers/block/virtio_blk.c index 84e064ffee52..0cfbe8c594a5 100644 --- a/trunk/drivers/block/virtio_blk.c +++ b/trunk/drivers/block/virtio_blk.c @@ -35,7 +35,7 @@ struct virtblk_req struct list_head list; struct request *req; struct virtio_blk_outhdr out_hdr; - u8 status; + struct virtio_blk_inhdr in_hdr; }; static void blk_done(struct virtqueue *vq) @@ -48,7 +48,7 @@ static void blk_done(struct virtqueue *vq) spin_lock_irqsave(&vblk->lock, flags); while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) { int uptodate; - switch (vbr->status) { + switch (vbr->in_hdr.status) { case VIRTIO_BLK_S_OK: uptodate = 1; break; @@ -101,7 +101,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, sg_init_table(vblk->sg, VIRTIO_MAX_SG); sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr)); num = blk_rq_map_sg(q, vbr->req, vblk->sg+1); - sg_set_buf(&vblk->sg[num+1], &vbr->status, sizeof(vbr->status)); + sg_set_buf(&vblk->sg[num+1], &vbr->in_hdr, sizeof(vbr->in_hdr)); if (rq_data_dir(vbr->req) == WRITE) { vbr->out_hdr.type |= VIRTIO_BLK_T_OUT; @@ -157,25 +157,10 @@ static int virtblk_ioctl(struct inode *inode, struct file *filp, /* We provide getgeo only to please some old bootloader/partitioning tools */ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) { - struct virtio_blk *vblk = bd->bd_disk->private_data; - struct virtio_blk_geometry vgeo; - int err; - - /* see if the host passed in geometry config */ - err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY, - offsetof(struct virtio_blk_config, geometry), - &vgeo); - - if (!err) { - geo->heads = vgeo.heads; - geo->sectors = vgeo.sectors; - geo->cylinders = vgeo.cylinders; - } else { - /* some standard values, similar to sd */ - geo->heads = 1 << 6; - geo->sectors = 1 << 5; - geo->cylinders = get_capacity(bd->bd_disk) >> 11; - } + /* some standard values, similar to sd */ + geo->heads = 1 << 6; + geo->sectors = 1 << 5; + geo->cylinders = get_capacity(bd->bd_disk) >> 11; return 0; } @@ -257,12 +242,12 @@ static int virtblk_probe(struct virtio_device *vdev) index++; /* If barriers are supported, tell block layer that queue is ordered */ - if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) + if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); /* Host must always specify the capacity. */ - vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), - &cap, sizeof(cap)); + __virtio_config_val(vdev, offsetof(struct virtio_blk_config, capacity), + &cap); /* If capacity is too big, truncate with warning. */ if ((sector_t)cap != cap) { @@ -304,6 +289,7 @@ static int virtblk_probe(struct virtio_device *vdev) static void virtblk_remove(struct virtio_device *vdev) { struct virtio_blk *vblk = vdev->priv; + int major = vblk->disk->major; /* Nothing should be pending. */ BUG_ON(!list_empty(&vblk->reqs)); @@ -313,6 +299,7 @@ static void virtblk_remove(struct virtio_device *vdev) blk_cleanup_queue(vblk->disk->queue); put_disk(vblk->disk); + unregister_blkdev(major, "virtblk"); mempool_destroy(vblk->pool); vdev->config->del_vq(vblk->vq); kfree(vblk); @@ -323,14 +310,7 @@ static struct virtio_device_id id_table[] = { { 0 }, }; -static unsigned int features[] = { - VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, - VIRTIO_BLK_F_GEOMETRY, -}; - static struct virtio_driver virtio_blk = { - .feature_table = features, - .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, .driver.owner = THIS_MODULE, .id_table = id_table, diff --git a/trunk/drivers/char/tty_audit.c b/trunk/drivers/char/tty_audit.c index 3582f43345a8..6342b0534f4d 100644 --- a/trunk/drivers/char/tty_audit.c +++ b/trunk/drivers/char/tty_audit.c @@ -11,7 +11,6 @@ #include #include -#include #include struct tty_audit_buf { diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 49c1a2267a55..1d298c2cf930 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -78,7 +78,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 3edf1fc12963..dfe6907ae15b 100644 --- a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -623,8 +623,8 @@ static int __devinit hwicap_setup(struct device *dev, int id, if (!request_mem_region(drvdata->mem_start, drvdata->mem_size, DRIVER_NAME)) { - dev_err(dev, "Couldn't lock memory region at %Lx\n", - regs_res->start); + dev_err(dev, "Couldn't lock memory region at %p\n", + (void *)regs_res->start); retval = -EBUSY; goto failed1; } @@ -643,7 +643,7 @@ static int __devinit hwicap_setup(struct device *dev, int id, mutex_init(&drvdata->sem); drvdata->is_open = 0; - dev_info(dev, "ioremap %lx to %p with size %Lx\n", + dev_info(dev, "ioremap %lx to %p with size %x\n", (unsigned long int)drvdata->mem_start, drvdata->base_address, drvdata->mem_size); diff --git a/trunk/drivers/firewire/fw-sbp2.c b/trunk/drivers/firewire/fw-sbp2.c index b2458bb8e9ca..62e3c9190983 100644 --- a/trunk/drivers/firewire/fw-sbp2.c +++ b/trunk/drivers/firewire/fw-sbp2.c @@ -1487,7 +1487,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0) goto out; - memcpy(orb->request.command_block, cmd->cmnd, cmd->cmd_len); + memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); orb->base.callback = complete_command_orb; orb->base.request_bus = diff --git a/trunk/drivers/lguest/lguest_device.c b/trunk/drivers/lguest/lguest_device.c index 8080249957af..2bc9bf7e88e5 100644 --- a/trunk/drivers/lguest/lguest_device.c +++ b/trunk/drivers/lguest/lguest_device.c @@ -85,34 +85,27 @@ static unsigned desc_size(const struct lguest_device_desc *desc) + desc->config_len; } -/* This gets the device's feature bits. */ -static u32 lg_get_features(struct virtio_device *vdev) +/* This tests (and acknowleges) a feature bit. */ +static bool lg_feature(struct virtio_device *vdev, unsigned fbit) { - unsigned int i; - u32 features = 0; struct lguest_device_desc *desc = to_lgdev(vdev)->desc; - u8 *in_features = lg_features(desc); - - /* We do this the slow but generic way. */ - for (i = 0; i < min(desc->feature_len * 8, 32); i++) - if (in_features[i / 8] & (1 << (i % 8))) - features |= (1 << i); - - return features; -} - -static void lg_set_features(struct virtio_device *vdev, u32 features) -{ - unsigned int i; - struct lguest_device_desc *desc = to_lgdev(vdev)->desc; - /* Second half of bitmap is features we accept. */ - u8 *out_features = lg_features(desc) + desc->feature_len; - - memset(out_features, 0, desc->feature_len); - for (i = 0; i < min(desc->feature_len * 8, 32); i++) { - if (features & (1 << i)) - out_features[i / 8] |= (1 << (i % 8)); - } + u8 *features; + + /* Obviously if they ask for a feature off the end of our feature + * bitmap, it's not set. */ + if (fbit / 8 > desc->feature_len) + return false; + + /* The feature bitmap comes after the virtqueues. */ + features = lg_features(desc); + if (!(features[fbit / 8] & (1 << (fbit % 8)))) + return false; + + /* We set the matching bit in the other half of the bitmap to tell the + * Host we want to use this feature. We don't use this yet, but we + * could in future. */ + features[desc->feature_len + fbit / 8] |= (1 << (fbit % 8)); + return true; } /* Once they've found a field, getting a copy of it is easy. */ @@ -144,26 +137,20 @@ static u8 lg_get_status(struct virtio_device *vdev) return to_lgdev(vdev)->desc->status; } -/* To notify on status updates, we (ab)use the NOTIFY hypercall, with the - * descriptor address of the device. A zero status means "reset". */ -static void set_status(struct virtio_device *vdev, u8 status) -{ - unsigned long offset = (void *)to_lgdev(vdev)->desc - lguest_devices; - - /* We set the status. */ - to_lgdev(vdev)->desc->status = status; - hcall(LHCALL_NOTIFY, (max_pfn<desc->status = status; } +/* To reset the device, we (ab)use the NOTIFY hypercall, with the descriptor + * address of the device. The Host will zero the status and all the + * features. */ static void lg_reset(struct virtio_device *vdev) { - set_status(vdev, 0); + unsigned long offset = (void *)to_lgdev(vdev)->desc - lguest_devices; + + hcall(LHCALL_NOTIFY, (max_pfn<= ARRAY_SIZE(cpu->lg->cpus)) + if (id >= NR_CPUS) return -EINVAL; /* Set up this CPU's id, and pointer back to the lguest struct. */ @@ -251,6 +251,8 @@ static ssize_t write(struct file *file, const char __user *in, if (!lg || (cpu_id >= lg->nr_cpus)) return -EINVAL; cpu = &lg->cpus[cpu_id]; + if (!cpu) + return -EINVAL; /* Once the Guest is dead, you can only read() why it died. */ if (lg->dead) diff --git a/trunk/drivers/net/fec_mpc52xx.c b/trunk/drivers/net/fec_mpc52xx.c index 5f9c42e7a7f1..d21b7ab64bd1 100644 --- a/trunk/drivers/net/fec_mpc52xx.c +++ b/trunk/drivers/net/fec_mpc52xx.c @@ -43,29 +43,6 @@ #define DRIVER_NAME "mpc52xx-fec" -#define FEC5200_PHYADDR_NONE (-1) -#define FEC5200_PHYADDR_7WIRE (-2) - -/* Private driver data structure */ -struct mpc52xx_fec_priv { - int duplex; - int speed; - int r_irq; - int t_irq; - struct mpc52xx_fec __iomem *fec; - struct bcom_task *rx_dmatsk; - struct bcom_task *tx_dmatsk; - spinlock_t lock; - int msg_enable; - - /* MDIO link details */ - int phy_addr; - unsigned int phy_speed; - struct phy_device *phydev; - enum phy_state link; -}; - - static irqreturn_t mpc52xx_fec_interrupt(int, void *); static irqreturn_t mpc52xx_fec_rx_interrupt(int, void *); static irqreturn_t mpc52xx_fec_tx_interrupt(int, void *); @@ -246,7 +223,7 @@ static int mpc52xx_fec_phy_start(struct net_device *dev) struct mpc52xx_fec_priv *priv = netdev_priv(dev); int err; - if (priv->phy_addr < 0) + if (!priv->has_phy) return 0; err = mpc52xx_fec_init_phy(dev); @@ -266,7 +243,7 @@ static void mpc52xx_fec_phy_stop(struct net_device *dev) { struct mpc52xx_fec_priv *priv = netdev_priv(dev); - if (!priv->phydev) + if (!priv->has_phy) return; phy_disconnect(priv->phydev); @@ -278,7 +255,7 @@ static void mpc52xx_fec_phy_stop(struct net_device *dev) static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv, struct mii_ioctl_data *mii_data, int cmd) { - if (!priv->phydev) + if (!priv->has_phy) return -ENOTSUPP; return phy_mii_ioctl(priv->phydev, mii_data, cmd); @@ -288,7 +265,7 @@ static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv) { struct mpc52xx_fec __iomem *fec = priv->fec; - if (priv->phydev) + if (!priv->has_phy) return; out_be32(&fec->mii_speed, priv->phy_speed); @@ -727,7 +704,7 @@ static void mpc52xx_fec_start(struct net_device *dev) rcntrl = FEC_RX_BUFFER_SIZE << 16; /* max frame length */ rcntrl |= FEC_RCNTRL_FCE; - if (priv->phy_addr != FEC5200_PHYADDR_7WIRE) + if (priv->has_phy) rcntrl |= FEC_RCNTRL_MII_MODE; if (priv->duplex == DUPLEX_FULL) @@ -887,10 +864,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) struct net_device *ndev; struct mpc52xx_fec_priv *priv = NULL; struct resource mem; - struct device_node *phy_node; - const phandle *phy_handle; - const u32 *prop; - int prop_size; + const phandle *ph; phys_addr_t rx_fifo; phys_addr_t tx_fifo; @@ -974,37 +948,26 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) mpc52xx_fec_get_paddr(ndev, ndev->dev_addr); priv->msg_enable = netif_msg_init(debug, MPC52xx_MESSAGES_DEFAULT); + priv->duplex = DUPLEX_FULL; - /* - * Link mode configuration - */ + /* is the phy present in device tree? */ + ph = of_get_property(op->node, "phy-handle", NULL); + if (ph) { + const unsigned int *prop; + struct device_node *phy_dn; + priv->has_phy = 1; - /* Start with safe defaults for link connection */ - priv->phy_addr = FEC5200_PHYADDR_NONE; - priv->speed = 100; - priv->duplex = DUPLEX_HALF; - priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1; - - /* the 7-wire property means don't use MII mode */ - if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) - priv->phy_addr = FEC5200_PHYADDR_7WIRE; - - /* The current speed preconfigures the speed of the MII link */ - prop = of_get_property(op->node, "current-speed", &prop_size); - if (prop && (prop_size >= sizeof(u32) * 2)) { - priv->speed = prop[0]; - priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF; - } + phy_dn = of_find_node_by_phandle(*ph); + prop = of_get_property(phy_dn, "reg", NULL); + priv->phy_addr = *prop; + + of_node_put(phy_dn); - /* If there is a phy handle, setup link to that phy */ - phy_handle = of_get_property(op->node, "phy-handle", &prop_size); - if (phy_handle && (prop_size >= sizeof(phandle))) { - phy_node = of_find_node_by_phandle(*phy_handle); - prop = of_get_property(phy_node, "reg", &prop_size); - if (prop && (prop_size >= sizeof(u32))) - if ((*prop >= 0) && (*prop < PHY_MAX_ADDR)) - priv->phy_addr = *prop; - of_node_put(phy_node); + /* Phy speed */ + priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1; + } else { + dev_info(&ndev->dev, "can't find \"phy-handle\" in device" + " tree, using 7-wire mode\n"); } /* Hardware init */ @@ -1019,20 +982,6 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) if (rv < 0) goto probe_error; - /* Now report the link setup */ - switch (priv->phy_addr) { - case FEC5200_PHYADDR_NONE: - dev_info(&ndev->dev, "Fixed speed MII link: %i%cD\n", - priv->speed, priv->duplex ? 'F' : 'H'); - break; - case FEC5200_PHYADDR_7WIRE: - dev_info(&ndev->dev, "using 7-wire PHY mode\n"); - break; - default: - dev_info(&ndev->dev, "Using PHY at MDIO address %i\n", - priv->phy_addr); - } - /* We're done ! */ dev_set_drvdata(&op->dev, ndev); diff --git a/trunk/drivers/net/fec_mpc52xx.h b/trunk/drivers/net/fec_mpc52xx.h index a227a525bdbb..8b1f75397b9a 100644 --- a/trunk/drivers/net/fec_mpc52xx.h +++ b/trunk/drivers/net/fec_mpc52xx.h @@ -26,6 +26,25 @@ #define FEC_WATCHDOG_TIMEOUT ((400*HZ)/1000) +struct mpc52xx_fec_priv { + int duplex; + int r_irq; + int t_irq; + struct mpc52xx_fec __iomem *fec; + struct bcom_task *rx_dmatsk; + struct bcom_task *tx_dmatsk; + spinlock_t lock; + int msg_enable; + + int has_phy; + unsigned int phy_speed; + unsigned int phy_addr; + struct phy_device *phydev; + enum phy_state link; + int speed; +}; + + /* ======================================================================== */ /* Hardware register sets & bits */ /* ======================================================================== */ diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index f926b5ab3d09..555b70c8b863 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -41,9 +41,6 @@ struct virtnet_info struct net_device *dev; struct napi_struct napi; - /* The skb we couldn't send because buffers were full. */ - struct sk_buff *last_xmit_skb; - /* Number of input buffers, and max we've ever had. */ unsigned int num, max; @@ -145,10 +142,10 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, static void try_fill_recv(struct virtnet_info *vi) { struct sk_buff *skb; - struct scatterlist sg[2+MAX_SKB_FRAGS]; + struct scatterlist sg[1+MAX_SKB_FRAGS]; int num, err; - sg_init_table(sg, 2+MAX_SKB_FRAGS); + sg_init_table(sg, 1+MAX_SKB_FRAGS); for (;;) { skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN); if (unlikely(!skb)) @@ -224,22 +221,23 @@ static void free_old_xmit_skbs(struct virtnet_info *vi) while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) { pr_debug("Sent skb %p\n", skb); __skb_unlink(skb, &vi->send); - vi->dev->stats.tx_bytes += skb->len; + vi->dev->stats.tx_bytes += len; vi->dev->stats.tx_packets++; kfree_skb(skb); } } -static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) +static int start_xmit(struct sk_buff *skb, struct net_device *dev) { - int num; - struct scatterlist sg[2+MAX_SKB_FRAGS]; + struct virtnet_info *vi = netdev_priv(dev); + int num, err; + struct scatterlist sg[1+MAX_SKB_FRAGS]; struct virtio_net_hdr *hdr; const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; - sg_init_table(sg, 2+MAX_SKB_FRAGS); + sg_init_table(sg, 1+MAX_SKB_FRAGS); - pr_debug("%s: xmit %p " MAC_FMT "\n", vi->dev->name, skb, + pr_debug("%s: xmit %p " MAC_FMT "\n", dev->name, skb, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5]); @@ -274,51 +272,30 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) vnet_hdr_to_sg(sg, skb); num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; - - return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); -} - -static int start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct virtnet_info *vi = netdev_priv(dev); + __skb_queue_head(&vi->send, skb); again: /* Free up any pending old buffers before queueing new ones. */ free_old_xmit_skbs(vi); - - /* If we has a buffer left over from last time, send it now. */ - if (vi->last_xmit_skb) { - if (xmit_skb(vi, vi->last_xmit_skb) != 0) { - /* Drop this skb: we only queue one. */ - vi->dev->stats.tx_dropped++; - kfree_skb(skb); - goto stop_queue; + err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); + if (err) { + pr_debug("%s: virtio not prepared to send\n", dev->name); + netif_stop_queue(dev); + + /* Activate callback for using skbs: if this returns false it + * means some were used in the meantime. */ + if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { + vi->svq->vq_ops->disable_cb(vi->svq); + netif_start_queue(dev); + goto again; } - vi->last_xmit_skb = NULL; - } + __skb_unlink(skb, &vi->send); - /* Put new one in send queue and do transmit */ - __skb_queue_head(&vi->send, skb); - if (xmit_skb(vi, skb) != 0) { - vi->last_xmit_skb = skb; - goto stop_queue; + return NETDEV_TX_BUSY; } -done: vi->svq->vq_ops->kick(vi->svq); - return NETDEV_TX_OK; - -stop_queue: - pr_debug("%s: virtio not prepared to send\n", dev->name); - netif_stop_queue(dev); - - /* Activate callback for using skbs: if this returns false it - * means some were used in the meantime. */ - if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { - vi->svq->vq_ops->disable_cb(vi->svq); - netif_start_queue(dev); - goto again; - } - goto done; + + return 0; } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -378,26 +355,17 @@ static int virtnet_probe(struct virtio_device *vdev) SET_NETDEV_DEV(dev, &vdev->dev); /* Do we support "hardware" checksums? */ - if (csum && virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) { + if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) { /* This opens up the world of extra features. */ dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { + if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) { dev->features |= NETIF_F_TSO | NETIF_F_UFO | NETIF_F_TSO_ECN | NETIF_F_TSO6; } - /* Individual feature bits: what can host handle? */ - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4)) - dev->features |= NETIF_F_TSO; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6)) - dev->features |= NETIF_F_TSO6; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) - dev->features |= NETIF_F_TSO_ECN; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) - dev->features |= NETIF_F_UFO; } /* Configuration may specify what MAC to use. Otherwise random. */ - if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) { + if (vdev->config->feature(vdev, VIRTIO_NET_F_MAC)) { vdev->config->get(vdev, offsetof(struct virtio_net_config, mac), dev->dev_addr, dev->addr_len); @@ -486,15 +454,7 @@ static struct virtio_device_id id_table[] = { { 0 }, }; -static unsigned int features[] = { - VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, - VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, - VIRTIO_NET_F_HOST_ECN, -}; - static struct virtio_driver virtio_net = { - .feature_table = features, - .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, .driver.owner = THIS_MODULE, .id_table = id_table, diff --git a/trunk/drivers/ps3/ps3-lpm.c b/trunk/drivers/ps3/ps3-lpm.c index 85edf945ab86..6c9592ce4996 100644 --- a/trunk/drivers/ps3/ps3-lpm.c +++ b/trunk/drivers/ps3/ps3-lpm.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/ps3/ps3-sys-manager.c b/trunk/drivers/ps3/ps3-sys-manager.c index f17513dd9d4b..7605453b74fd 100644 --- a/trunk/drivers/ps3/ps3-sys-manager.c +++ b/trunk/drivers/ps3/ps3-sys-manager.c @@ -184,7 +184,10 @@ enum ps3_sys_manager_next_op { /** * enum ps3_sys_manager_wake_source - Next-op wakeup source (bit position mask). - * @PS3_SM_WAKE_DEFAULT: Disk insert, power button, eject button. + * @PS3_SM_WAKE_DEFAULT: Disk insert, power button, eject button, IR + * controller, and bluetooth controller. + * @PS3_SM_WAKE_RTC: + * @PS3_SM_WAKE_RTC_ERROR: * @PS3_SM_WAKE_W_O_L: Ether or wireless LAN. * @PS3_SM_WAKE_P_O_R: Power on reset. * @@ -197,6 +200,8 @@ enum ps3_sys_manager_next_op { enum ps3_sys_manager_wake_source { /* version 3 */ PS3_SM_WAKE_DEFAULT = 0, + PS3_SM_WAKE_RTC = 0x00000040, + PS3_SM_WAKE_RTC_ERROR = 0x00000080, PS3_SM_WAKE_W_O_L = 0x00000400, PS3_SM_WAKE_P_O_R = 0x80000000, }; diff --git a/trunk/drivers/s390/scsi/zfcp_dbf.c b/trunk/drivers/s390/scsi/zfcp_dbf.c index c8bad675dbd1..37b85c67b11d 100644 --- a/trunk/drivers/s390/scsi/zfcp_dbf.c +++ b/trunk/drivers/s390/scsi/zfcp_dbf.c @@ -1055,7 +1055,7 @@ static void zfcp_scsi_dbf_event(const char *tag, const char *tag2, int level, rec->scsi_result = scsi_cmnd->result; rec->scsi_cmnd = (unsigned long)scsi_cmnd; rec->scsi_serial = scsi_cmnd->serial_number; - memcpy(rec->scsi_opcode, scsi_cmnd->cmnd, + memcpy(rec->scsi_opcode, &scsi_cmnd->cmnd, min((int)scsi_cmnd->cmd_len, ZFCP_DBF_SCSI_OPCODE)); rec->scsi_retries = scsi_cmnd->retries; diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.c b/trunk/drivers/s390/scsi/zfcp_fsf.c index b2ea4ea051f5..9af2330f07a2 100644 --- a/trunk/drivers/s390/scsi/zfcp_fsf.c +++ b/trunk/drivers/s390/scsi/zfcp_fsf.c @@ -4014,7 +4014,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) ZFCP_LOG_TRACE("scpnt->result =0x%x, command was:\n", scpnt->result); ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, - scpnt->cmnd, scpnt->cmd_len); + (void *) &scpnt->cmnd, scpnt->cmd_len); ZFCP_LOG_TRACE("%i bytes sense data provided by FCP\n", fcp_rsp_iu->fcp_sns_len); diff --git a/trunk/drivers/scsi/53c700.c b/trunk/drivers/scsi/53c700.c index f5a9addb7050..f4c4fe90240a 100644 --- a/trunk/drivers/scsi/53c700.c +++ b/trunk/drivers/scsi/53c700.c @@ -599,7 +599,7 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, (struct NCR_700_command_slot *)SCp->host_scribble; dma_unmap_single(hostdata->dev, slot->pCmd, - MAX_COMMAND_SIZE, DMA_TO_DEVICE); + sizeof(SCp->cmnd), DMA_TO_DEVICE); if (slot->flags == NCR_700_FLAG_AUTOSENSE) { char *cmnd = NCR_700_get_sense_cmnd(SCp->device); #ifdef NCR_700_DEBUG @@ -1004,7 +1004,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, * here */ NCR_700_unmap(hostdata, SCp, slot); dma_unmap_single(hostdata->dev, slot->pCmd, - MAX_COMMAND_SIZE, + sizeof(SCp->cmnd), DMA_TO_DEVICE); cmnd[0] = REQUEST_SENSE; @@ -1901,7 +1901,7 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) } slot->resume_offset = 0; slot->pCmd = dma_map_single(hostdata->dev, SCp->cmnd, - MAX_COMMAND_SIZE, DMA_TO_DEVICE); + sizeof(SCp->cmnd), DMA_TO_DEVICE); NCR_700_start_command(SCp); return 0; } diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index 46d7e400c8be..99c57b0c1d54 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -504,9 +504,10 @@ config SCSI_AIC7XXX_OLD source "drivers/scsi/aic7xxx/Kconfig.aic79xx" source "drivers/scsi/aic94xx/Kconfig" +# All the I2O code and drivers do not seem to be 64bit safe. config SCSI_DPT_I2O tristate "Adaptec I2O RAID support " - depends on SCSI && PCI && VIRT_TO_BUS + depends on !64BIT && SCSI && PCI && VIRT_TO_BUS help This driver supports all of Adaptec's I2O based RAID controllers as well as the DPT SmartRaid V cards. This is an Adaptec maintained diff --git a/trunk/drivers/scsi/a100u2w.c b/trunk/drivers/scsi/a100u2w.c index ced3eebe252c..792b2e807bf3 100644 --- a/trunk/drivers/scsi/a100u2w.c +++ b/trunk/drivers/scsi/a100u2w.c @@ -895,7 +895,7 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru } else { scb->tag_msg = 0; /* No tag support */ } - memcpy(scb->cdb, cmd->cmnd, scb->cdb_len); + memcpy(&scb->cdb[0], &cmd->cmnd, scb->cdb_len); } /** diff --git a/trunk/drivers/scsi/aacraid/aachba.c b/trunk/drivers/scsi/aacraid/aachba.c index aa4e77c25273..460d4024c46c 100644 --- a/trunk/drivers/scsi/aacraid/aachba.c +++ b/trunk/drivers/scsi/aacraid/aachba.c @@ -498,11 +498,6 @@ static void _aac_probe_container2(void * context, struct fib * fibptr) (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { fsa_dev_ptr->valid = 1; - /* sense_key holds the current state of the spin-up */ - if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY)) - fsa_dev_ptr->sense_data.sense_key = NOT_READY; - else if (fsa_dev_ptr->sense_data.sense_key == NOT_READY) - fsa_dev_ptr->sense_data.sense_key = NO_SENSE; fsa_dev_ptr->type = le32_to_cpu(dresp->mnt[0].vol); fsa_dev_ptr->size = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + @@ -1514,35 +1509,20 @@ static void io_callback(void *context, struct fib * fibptr) scsi_dma_unmap(scsicmd); readreply = (struct aac_read_reply *)fib_data(fibptr); - switch (le32_to_cpu(readreply->status)) { - case ST_OK: - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_GOOD; - dev->fsa_dev[cid].sense_data.sense_key = NO_SENSE; - break; - case ST_NOT_READY: - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_CHECK_CONDITION; - set_sense(&dev->fsa_dev[cid].sense_data, NOT_READY, - SENCODE_BECOMING_READY, ASENCODE_BECOMING_READY, 0, 0); - memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, - min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), - SCSI_SENSE_BUFFERSIZE)); - break; - default: + if (le32_to_cpu(readreply->status) == ST_OK) + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; + else { #ifdef AAC_DETAILED_STATUS_INFO printk(KERN_WARNING "io_callback: io failed, status = %d\n", le32_to_cpu(readreply->status)); #endif - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_CHECK_CONDITION; + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; set_sense(&dev->fsa_dev[cid].sense_data, HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0); memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), SCSI_SENSE_BUFFERSIZE)); - break; } aac_fib_complete(fibptr); aac_fib_free(fibptr); @@ -1883,84 +1863,6 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd) return SCSI_MLQUEUE_HOST_BUSY; } -static void aac_start_stop_callback(void *context, struct fib *fibptr) -{ - struct scsi_cmnd *scsicmd = context; - - if (!aac_valid_context(scsicmd, fibptr)) - return; - - BUG_ON(fibptr == NULL); - - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; - - aac_fib_complete(fibptr); - aac_fib_free(fibptr); - scsicmd->scsi_done(scsicmd); -} - -static int aac_start_stop(struct scsi_cmnd *scsicmd) -{ - int status; - struct fib *cmd_fibcontext; - struct aac_power_management *pmcmd; - struct scsi_device *sdev = scsicmd->device; - struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; - - if (!(aac->supplement_adapter_info.SupportedOptions2 & - AAC_OPTION_POWER_MANAGEMENT)) { - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_GOOD; - scsicmd->scsi_done(scsicmd); - return 0; - } - - if (aac->in_reset) - return SCSI_MLQUEUE_HOST_BUSY; - - /* - * Allocate and initialize a Fib - */ - cmd_fibcontext = aac_fib_alloc(aac); - if (!cmd_fibcontext) - return SCSI_MLQUEUE_HOST_BUSY; - - aac_fib_init(cmd_fibcontext); - - pmcmd = fib_data(cmd_fibcontext); - pmcmd->command = cpu_to_le32(VM_ContainerConfig); - pmcmd->type = cpu_to_le32(CT_POWER_MANAGEMENT); - /* Eject bit ignored, not relevant */ - pmcmd->sub = (scsicmd->cmnd[4] & 1) ? - cpu_to_le32(CT_PM_START_UNIT) : cpu_to_le32(CT_PM_STOP_UNIT); - pmcmd->cid = cpu_to_le32(sdev_id(sdev)); - pmcmd->parm = (scsicmd->cmnd[1] & 1) ? - cpu_to_le32(CT_PM_UNIT_IMMEDIATE) : 0; - - /* - * Now send the Fib to the adapter - */ - status = aac_fib_send(ContainerCommand, - cmd_fibcontext, - sizeof(struct aac_power_management), - FsaNormal, - 0, 1, - (fib_callback)aac_start_stop_callback, - (void *)scsicmd); - - /* - * Check that the command queued to the controller - */ - if (status == -EINPROGRESS) { - scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; - return 0; - } - - aac_fib_complete(cmd_fibcontext); - aac_fib_free(cmd_fibcontext); - return SCSI_MLQUEUE_HOST_BUSY; -} - /** * aac_scsi_cmd() - Process SCSI command * @scsicmd: SCSI command block @@ -1997,9 +1899,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) * If the target container doesn't exist, it may have * been newly created */ - if (((fsa_dev_ptr[cid].valid & 1) == 0) || - (fsa_dev_ptr[cid].sense_data.sense_key == - NOT_READY)) { + if ((fsa_dev_ptr[cid].valid & 1) == 0) { switch (scsicmd->cmnd[0]) { case SERVICE_ACTION_IN: if (!(dev->raw_io_interface) || @@ -2191,8 +2091,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp)); /* Do not cache partition table for arrays */ scsicmd->device->removable = 1; - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_GOOD; + + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; scsicmd->scsi_done(scsicmd); return 0; @@ -2287,32 +2187,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) * These commands are all No-Ops */ case TEST_UNIT_READY: - if (fsa_dev_ptr[cid].sense_data.sense_key == NOT_READY) { - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_CHECK_CONDITION; - set_sense(&dev->fsa_dev[cid].sense_data, - NOT_READY, SENCODE_BECOMING_READY, - ASENCODE_BECOMING_READY, 0, 0); - memcpy(scsicmd->sense_buffer, - &dev->fsa_dev[cid].sense_data, - min_t(size_t, - sizeof(dev->fsa_dev[cid].sense_data), - SCSI_SENSE_BUFFERSIZE)); - scsicmd->scsi_done(scsicmd); - return 0; - } - /* FALLTHRU */ case RESERVE: case RELEASE: case REZERO_UNIT: case REASSIGN_BLOCKS: case SEEK_10: + case START_STOP: scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; scsicmd->scsi_done(scsicmd); return 0; - - case START_STOP: - return aac_start_stop(scsicmd); } switch (scsicmd->cmnd[0]) diff --git a/trunk/drivers/scsi/aacraid/aacraid.h b/trunk/drivers/scsi/aacraid/aacraid.h index 73916adb8f80..113ca9c8934c 100644 --- a/trunk/drivers/scsi/aacraid/aacraid.h +++ b/trunk/drivers/scsi/aacraid/aacraid.h @@ -12,7 +12,7 @@ *----------------------------------------------------------------------------*/ #ifndef AAC_DRIVER_BUILD -# define AAC_DRIVER_BUILD 2456 +# define AAC_DRIVER_BUILD 2455 # define AAC_DRIVER_BRANCH "-ms" #endif #define MAXIMUM_NUM_CONTAINERS 32 @@ -34,8 +34,8 @@ #define CONTAINER_TO_ID(cont) (cont) #define CONTAINER_TO_LUN(cont) (0) -#define aac_phys_to_logical(x) ((x)+1) -#define aac_logical_to_phys(x) ((x)?(x)-1:0) +#define aac_phys_to_logical(x) (x+1) +#define aac_logical_to_phys(x) (x?x-1:0) /* #define AAC_DETAILED_STATUS_INFO */ @@ -424,8 +424,6 @@ struct aac_init */ __le32 InitFlags; /* flags for supported features */ #define INITFLAGS_NEW_COMM_SUPPORTED 0x00000001 -#define INITFLAGS_DRIVER_USES_UTC_TIME 0x00000010 -#define INITFLAGS_DRIVER_SUPPORTS_PM 0x00000020 __le32 MaxIoCommands; /* max outstanding commands */ __le32 MaxIoSize; /* largest I/O command */ __le32 MaxFibSize; /* largest FIB to adapter */ @@ -869,10 +867,8 @@ struct aac_supplement_adapter_info }; #define AAC_FEATURE_FALCON cpu_to_le32(0x00000010) #define AAC_FEATURE_JBOD cpu_to_le32(0x08000000) -/* SupportedOptions2 */ -#define AAC_OPTION_MU_RESET cpu_to_le32(0x00000001) -#define AAC_OPTION_IGNORE_RESET cpu_to_le32(0x00000002) -#define AAC_OPTION_POWER_MANAGEMENT cpu_to_le32(0x00000004) +#define AAC_OPTION_MU_RESET cpu_to_le32(0x00000001) +#define AAC_OPTION_IGNORE_RESET cpu_to_le32(0x00000002) #define AAC_SIS_VERSION_V3 3 #define AAC_SIS_SLOT_UNKNOWN 0xFF @@ -1152,7 +1148,6 @@ struct aac_dev #define ST_DQUOT 69 #define ST_STALE 70 #define ST_REMOTE 71 -#define ST_NOT_READY 72 #define ST_BADHANDLE 10001 #define ST_NOT_SYNC 10002 #define ST_BAD_COOKIE 10003 @@ -1274,18 +1269,6 @@ struct aac_synchronize_reply { u8 data[16]; }; -#define CT_POWER_MANAGEMENT 245 -#define CT_PM_START_UNIT 2 -#define CT_PM_STOP_UNIT 3 -#define CT_PM_UNIT_IMMEDIATE 1 -struct aac_power_management { - __le32 command; /* VM_ContainerConfig */ - __le32 type; /* CT_POWER_MANAGEMENT */ - __le32 sub; /* CT_PM_* */ - __le32 cid; - __le32 parm; /* CT_PM_sub_* */ -}; - #define CT_PAUSE_IO 65 #define CT_RELEASE_IO 66 struct aac_pause { @@ -1553,7 +1536,6 @@ struct aac_mntent { #define FSCS_NOTCLEAN 0x0001 /* fsck is necessary before mounting */ #define FSCS_READONLY 0x0002 /* possible result of broken mirror */ #define FSCS_HIDDEN 0x0004 /* should be ignored - set during a clear */ -#define FSCS_NOT_READY 0x0008 /* Array spinning up to fulfil request */ struct aac_query_mount { __le32 command; diff --git a/trunk/drivers/scsi/aacraid/comminit.c b/trunk/drivers/scsi/aacraid/comminit.c index cbac06355107..294a802450be 100644 --- a/trunk/drivers/scsi/aacraid/comminit.c +++ b/trunk/drivers/scsi/aacraid/comminit.c @@ -97,8 +97,6 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED); dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n")); } - init->InitFlags |= cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME | - INITFLAGS_DRIVER_SUPPORTS_PM); init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9); init->MaxFibSize = cpu_to_le32(dev->max_fib_size); diff --git a/trunk/drivers/scsi/aacraid/commsup.c b/trunk/drivers/scsi/aacraid/commsup.c index 289304aab690..ef67816a6fe5 100644 --- a/trunk/drivers/scsi/aacraid/commsup.c +++ b/trunk/drivers/scsi/aacraid/commsup.c @@ -515,7 +515,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, } udelay(5); } - } else if (down_interruptible(&fibptr->event_wait)) { + } else if (down_interruptible(&fibptr->event_wait) == 0) { fibptr->done = 2; up(&fibptr->event_wait); } @@ -906,22 +906,15 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) case AifEnAddJBOD: case AifEnDeleteJBOD: container = le32_to_cpu(((__le32 *)aifcmd->data)[1]); - if ((container >> 28)) { - container = (u32)-1; + if ((container >> 28)) break; - } channel = (container >> 24) & 0xF; - if (channel >= dev->maximum_num_channels) { - container = (u32)-1; + if (channel >= dev->maximum_num_channels) break; - } id = container & 0xFFFF; - if (id >= dev->maximum_num_physicals) { - container = (u32)-1; + if (id >= dev->maximum_num_physicals) break; - } lun = (container >> 16) & 0xFF; - container = (u32)-1; channel = aac_phys_to_logical(channel); device_config_needed = (((__le32 *)aifcmd->data)[0] == @@ -940,18 +933,13 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) case EM_DRIVE_REMOVAL: container = le32_to_cpu( ((__le32 *)aifcmd->data)[2]); - if ((container >> 28)) { - container = (u32)-1; + if ((container >> 28)) break; - } channel = (container >> 24) & 0xF; - if (channel >= dev->maximum_num_channels) { - container = (u32)-1; + if (channel >= dev->maximum_num_channels) break; - } id = container & 0xFFFF; lun = (container >> 16) & 0xFF; - container = (u32)-1; if (id >= dev->maximum_num_physicals) { /* legacy dev_t ? */ if ((0x2000 <= id) || lun || channel || @@ -1037,10 +1025,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) break; } - container = 0; -retry_next: if (device_config_needed == NOTHING) - for (; container < dev->maximum_num_containers; ++container) { + for (container = 0; container < dev->maximum_num_containers; + ++container) { if ((dev->fsa_dev[container].config_waiting_on == 0) && (dev->fsa_dev[container].config_needed != NOTHING) && time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) { @@ -1123,11 +1110,6 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) } if (device_config_needed == ADD) scsi_add_device(dev->scsi_host_ptr, channel, id, lun); - if (channel == CONTAINER_CHANNEL) { - container++; - device_config_needed = NOTHING; - goto retry_next; - } } static int _aac_reset_adapter(struct aac_dev *aac, int forced) diff --git a/trunk/drivers/scsi/aacraid/linit.c b/trunk/drivers/scsi/aacraid/linit.c index 1f7c83607f84..c109f63f8279 100644 --- a/trunk/drivers/scsi/aacraid/linit.c +++ b/trunk/drivers/scsi/aacraid/linit.c @@ -401,8 +401,6 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, static int aac_slave_configure(struct scsi_device *sdev) { struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; - if (aac->jbod && (sdev->type == TYPE_DISK)) - sdev->removable = 1; if ((sdev->type == TYPE_DISK) && (sdev_channel(sdev) != CONTAINER_CHANNEL) && (!aac->jbod || sdev->inq_periph_qual) && @@ -811,12 +809,6 @@ static ssize_t aac_show_flags(struct device *cdev, "SAI_READ_CAPACITY_16\n"); if (dev->jbod) len += snprintf(buf + len, PAGE_SIZE - len, "SUPPORTED_JBOD\n"); - if (dev->supplement_adapter_info.SupportedOptions2 & - AAC_OPTION_POWER_MANAGEMENT) - len += snprintf(buf + len, PAGE_SIZE - len, - "SUPPORTED_POWER_MANAGEMENT\n"); - if (dev->msi) - len += snprintf(buf + len, PAGE_SIZE - len, "PCI_HAS_MSI\n"); return len; } @@ -1114,7 +1106,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, aac->pdev = pdev; aac->name = aac_driver_template.name; aac->id = shost->unique_id; - aac->cardtype = index; + aac->cardtype = index; INIT_LIST_HEAD(&aac->entry); aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL); @@ -1154,19 +1146,19 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, goto out_deinit; /* - * Lets override negotiations and drop the maximum SG limit to 34 - */ + * Lets override negotiations and drop the maximum SG limit to 34 + */ if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) && (shost->sg_tablesize > 34)) { shost->sg_tablesize = 34; shost->max_sectors = (shost->sg_tablesize * 8) + 112; - } + } - if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) && + if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) && (shost->sg_tablesize > 17)) { shost->sg_tablesize = 17; shost->max_sectors = (shost->sg_tablesize * 8) + 112; - } + } error = pci_set_dma_max_seg_size(pdev, (aac->adapter_info.options & AAC_OPT_NEW_COMM) ? @@ -1182,7 +1174,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, else aac->printf_enabled = 0; - /* + /* * max channel will be the physical channels plus 1 virtual channel * all containers are on the virtual channel 0 (CONTAINER_CHANNEL) * physical channels are address by their actual physical number+1 diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_init.c b/trunk/drivers/scsi/aic94xx/aic94xx_init.c index 2a730c470f62..90f5e0a6f2e3 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_init.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_init.c @@ -529,10 +529,10 @@ static void asd_remove_dev_attrs(struct asd_ha_struct *asd_ha) /* The first entry, 0, is used for dynamic ids, the rest for devices * we know about. */ -static const struct asd_pcidev_struct { +static struct asd_pcidev_struct { const char * name; int (*setup)(struct asd_ha_struct *asd_ha); -} asd_pcidev_data[] __devinitconst = { +} asd_pcidev_data[] = { /* Id 0 is used for dynamic ids. */ { .name = "Adaptec AIC-94xx SAS/SATA Host Adapter", .setup = asd_aic9410_setup @@ -735,7 +735,7 @@ static int asd_unregister_sas_ha(struct asd_ha_struct *asd_ha) static int __devinit asd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { - const struct asd_pcidev_struct *asd_dev; + struct asd_pcidev_struct *asd_dev; unsigned asd_id = (unsigned) id->driver_data; struct asd_ha_struct *asd_ha; struct Scsi_Host *shost; diff --git a/trunk/drivers/scsi/constants.c b/trunk/drivers/scsi/constants.c index 9785d7384199..403a7f2d8f9b 100644 --- a/trunk/drivers/scsi/constants.c +++ b/trunk/drivers/scsi/constants.c @@ -28,6 +28,7 @@ #define SERVICE_ACTION_OUT_12 0xa9 #define SERVICE_ACTION_IN_16 0x9e #define SERVICE_ACTION_OUT_16 0x9f +#define VARIABLE_LENGTH_CMD 0x7f @@ -209,7 +210,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) cdb0 = cdbp[0]; switch(cdb0) { case VARIABLE_LENGTH_CMD: - len = scsi_varlen_cdb_length(cdbp); + len = cdbp[7] + 8; if (len < 10) { printk("short variable length command, " "len=%d ext_len=%d", len, cdb_len); @@ -299,7 +300,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) cdb0 = cdbp[0]; switch(cdb0) { case VARIABLE_LENGTH_CMD: - len = scsi_varlen_cdb_length(cdbp); + len = cdbp[7] + 8; if (len < 10) { printk("short opcode=0x%x command, len=%d " "ext_len=%d", cdb0, len, cdb_len); @@ -334,7 +335,10 @@ void __scsi_print_command(unsigned char *cdb) int k, len; print_opcode_name(cdb, 0); - len = scsi_command_size(cdb); + if (VARIABLE_LENGTH_CMD == cdb[0]) + len = cdb[7] + 8; + else + len = COMMAND_SIZE(cdb[0]); /* print out all bytes in cdb */ for (k = 0; k < len; ++k) printk(" %02x", cdb[k]); diff --git a/trunk/drivers/scsi/dpt/dpti_ioctl.h b/trunk/drivers/scsi/dpt/dpti_ioctl.h index f60236721e0d..cc784e8f6e9d 100644 --- a/trunk/drivers/scsi/dpt/dpti_ioctl.h +++ b/trunk/drivers/scsi/dpt/dpti_ioctl.h @@ -89,7 +89,7 @@ typedef struct { int njobs; /* # of jobs sent to HA */ int qdepth; /* Controller queue depth. */ int wakebase; /* mpx wakeup base index. */ - uINT SGsize; /* Scatter/Gather list size. */ + uLONG SGsize; /* Scatter/Gather list size. */ unsigned heads; /* heads for drives on cntlr. */ unsigned sectors; /* sectors for drives on cntlr. */ uCHAR do_drive32; /* Flag for Above 16 MB Ability */ @@ -97,8 +97,8 @@ typedef struct { char idPAL[4]; /* 4 Bytes Of The ID Pal */ uCHAR primary; /* 1 For Primary, 0 For Secondary */ uCHAR eataVersion; /* EATA Version */ - uINT cpLength; /* EATA Command Packet Length */ - uINT spLength; /* EATA Status Packet Length */ + uLONG cpLength; /* EATA Command Packet Length */ + uLONG spLength; /* EATA Status Packet Length */ uCHAR drqNum; /* DRQ Index (0,5,6,7) */ uCHAR flag1; /* EATA Flags 1 (Byte 9) */ uCHAR flag2; /* EATA Flags 2 (Byte 30) */ @@ -107,23 +107,23 @@ typedef struct { typedef struct { uSHORT length; // Remaining length of this uSHORT drvrHBAnum; // Relative HBA # used by the driver - uINT baseAddr; // Base I/O address + uLONG baseAddr; // Base I/O address uSHORT blinkState; // Blink LED state (0=Not in blink LED) uCHAR pciBusNum; // PCI Bus # (Optional) uCHAR pciDeviceNum; // PCI Device # (Optional) uSHORT hbaFlags; // Miscellaneous HBA flags uSHORT Interrupt; // Interrupt set for this device. # if (defined(_DPT_ARC)) - uINT baseLength; + uLONG baseLength; ADAPTER_OBJECT *AdapterObject; LARGE_INTEGER DmaLogicalAddress; PVOID DmaVirtualAddress; LARGE_INTEGER ReplyLogicalAddress; PVOID ReplyVirtualAddress; # else - uINT reserved1; // Reserved for future expansion - uINT reserved2; // Reserved for future expansion - uINT reserved3; // Reserved for future expansion + uLONG reserved1; // Reserved for future expansion + uLONG reserved2; // Reserved for future expansion + uLONG reserved3; // Reserved for future expansion # endif } drvrHBAinfo_S; diff --git a/trunk/drivers/scsi/dpt/dptsig.h b/trunk/drivers/scsi/dpt/dptsig.h index 72c8992fdf21..94bc894d1200 100644 --- a/trunk/drivers/scsi/dpt/dptsig.h +++ b/trunk/drivers/scsi/dpt/dptsig.h @@ -33,7 +33,11 @@ /* to make sure we are talking the same size under all OS's */ typedef unsigned char sigBYTE; typedef unsigned short sigWORD; -typedef unsigned int sigINT; +#if (defined(_MULTI_DATAMODEL) && defined(sun) && !defined(_ILP32)) +typedef uint32_t sigLONG; +#else +typedef unsigned long sigLONG; +#endif /* * use sigWORDLittleEndian for: @@ -296,7 +300,7 @@ typedef struct dpt_sig { sigBYTE dsFiletype; /* type of file */ sigBYTE dsFiletypeFlags; /* flags to specify load type, etc. */ sigBYTE dsOEM; /* OEM file was created for */ - sigINT dsOS; /* which Operating systems */ + sigLONG dsOS; /* which Operating systems */ sigWORD dsCapabilities; /* RAID levels, etc. */ sigWORD dsDeviceSupp; /* Types of SCSI devices supported */ sigWORD dsAdapterSupp; /* DPT adapter families supported */ diff --git a/trunk/drivers/scsi/dpt/sys_info.h b/trunk/drivers/scsi/dpt/sys_info.h index a90c4cb8ea8b..d23b70c8c768 100644 --- a/trunk/drivers/scsi/dpt/sys_info.h +++ b/trunk/drivers/scsi/dpt/sys_info.h @@ -145,8 +145,8 @@ uCHAR smartROMRevision; uSHORT flags; /* See bit definitions above */ uSHORT conventionalMemSize; /* in KB */ - uINT extendedMemSize; /* in KB */ - uINT osType; /* Same as DPTSIG's definition */ + uLONG extendedMemSize; /* in KB */ + uLONG osType; /* Same as DPTSIG's definition */ uCHAR osMajorVersion; uCHAR osMinorVersion; /* The OS version */ uCHAR osRevision; diff --git a/trunk/drivers/scsi/dpt_i2o.c b/trunk/drivers/scsi/dpt_i2o.c index 0fb5bf4c43ac..ac92ac143b46 100644 --- a/trunk/drivers/scsi/dpt_i2o.c +++ b/trunk/drivers/scsi/dpt_i2o.c @@ -29,6 +29,11 @@ /*#define DEBUG 1 */ /*#define UARTDELAY 1 */ +/* On the real kernel ADDR32 should always be zero for 2.4. GFP_HIGH allocates + high pages. Keep the macro around because of the broken unmerged ia64 tree */ + +#define ADDR32 (0) + #include MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn"); @@ -103,29 +108,28 @@ static dpt_sig_S DPTI_sig = { static DEFINE_MUTEX(adpt_configuration_lock); -static struct i2o_sys_tbl *sys_tbl; -static dma_addr_t sys_tbl_pa; -static int sys_tbl_ind; -static int sys_tbl_len; +static struct i2o_sys_tbl *sys_tbl = NULL; +static int sys_tbl_ind = 0; +static int sys_tbl_len = 0; static adpt_hba* hba_chain = NULL; static int hba_count = 0; -static struct class *adpt_sysfs_class; - -#ifdef CONFIG_COMPAT -static long compat_adpt_ioctl(struct file *, unsigned int, unsigned long); -#endif - static const struct file_operations adpt_fops = { .ioctl = adpt_ioctl, .open = adpt_open, - .release = adpt_close, -#ifdef CONFIG_COMPAT - .compat_ioctl = compat_adpt_ioctl, -#endif + .release = adpt_close }; +#ifdef REBOOT_NOTIFIER +static struct notifier_block adpt_reboot_notifier = +{ + adpt_reboot_event, + NULL, + 0 +}; +#endif + /* Structures and definitions for synchronous message posting. * See adpt_i2o_post_wait() for description * */ @@ -147,21 +151,6 @@ static DEFINE_SPINLOCK(adpt_post_wait_lock); *============================================================================ */ -static inline int dpt_dma64(adpt_hba *pHba) -{ - return (sizeof(dma_addr_t) > 4 && (pHba)->dma64); -} - -static inline u32 dma_high(dma_addr_t addr) -{ - return upper_32_bits(addr); -} - -static inline u32 dma_low(dma_addr_t addr) -{ - return (u32)addr; -} - static u8 adpt_read_blink_led(adpt_hba* host) { if (host->FwDebugBLEDflag_P) { @@ -189,6 +178,8 @@ static int adpt_detect(struct scsi_host_template* sht) struct pci_dev *pDev = NULL; adpt_hba* pHba; + adpt_init(); + PINFO("Detecting Adaptec I2O RAID controllers...\n"); /* search for all Adatpec I2O RAID cards */ @@ -256,29 +247,13 @@ static int adpt_detect(struct scsi_host_template* sht) adpt_inquiry(pHba); } - adpt_sysfs_class = class_create(THIS_MODULE, "dpt_i2o"); - if (IS_ERR(adpt_sysfs_class)) { - printk(KERN_WARNING"dpti: unable to create dpt_i2o class\n"); - adpt_sysfs_class = NULL; - } - for (pHba = hba_chain; pHba; pHba = pHba->next) { - if (adpt_scsi_host_alloc(pHba, sht) < 0){ + if( adpt_scsi_register(pHba,sht) < 0){ adpt_i2o_delete_hba(pHba); continue; } pHba->initialized = TRUE; pHba->state &= ~DPTI_STATE_RESET; - if (adpt_sysfs_class) { - struct device *dev = device_create(adpt_sysfs_class, - NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), - "dpti%d", pHba->unit); - if (IS_ERR(dev)) { - printk(KERN_WARNING"dpti%d: unable to " - "create device in dpt_i2o class\n", - pHba->unit); - } - } } // Register our control device node @@ -307,7 +282,7 @@ static int adpt_release(struct Scsi_Host *host) static void adpt_inquiry(adpt_hba* pHba) { - u32 msg[17]; + u32 msg[14]; u32 *mptr; u32 *lenptr; int direction; @@ -315,12 +290,11 @@ static void adpt_inquiry(adpt_hba* pHba) u32 len; u32 reqlen; u8* buf; - dma_addr_t addr; u8 scb[16]; s32 rcode; memset(msg, 0, sizeof(msg)); - buf = dma_alloc_coherent(&pHba->pDev->dev, 80, &addr, GFP_KERNEL); + buf = kmalloc(80,GFP_KERNEL|ADDR32); if(!buf){ printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name); return; @@ -331,10 +305,7 @@ static void adpt_inquiry(adpt_hba* pHba) direction = 0x00000000; scsidir =0x40000000; // DATA IN (iop<--dev) - if (dpt_dma64(pHba)) - reqlen = 17; // SINGLE SGE, 64 bit - else - reqlen = 14; // SINGLE SGE, 32 bit + reqlen = 14; // SINGLE SGE /* Stick the headers on */ msg[0] = reqlen<<16 | SGL_OFFSET_12; msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID); @@ -367,16 +338,8 @@ static void adpt_inquiry(adpt_hba* pHba) /* Now fill in the SGList and command */ *lenptr = len; - if (dpt_dma64(pHba)) { - *mptr++ = (0x7C<<24)+(2<<16)+0x02; /* Enable 64 bit */ - *mptr++ = 1 << PAGE_SHIFT; - *mptr++ = 0xD0000000|direction|len; - *mptr++ = dma_low(addr); - *mptr++ = dma_high(addr); - } else { - *mptr++ = 0xD0000000|direction|len; - *mptr++ = addr; - } + *mptr++ = 0xD0000000|direction|len; + *mptr++ = virt_to_bus(buf); // Send it on it's way rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120); @@ -384,7 +347,7 @@ static void adpt_inquiry(adpt_hba* pHba) sprintf(pHba->detail, "Adaptec I2O RAID"); printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode); if (rcode != -ETIME && rcode != -EINTR) - dma_free_coherent(&pHba->pDev->dev, 80, buf, addr); + kfree(buf); } else { memset(pHba->detail, 0, sizeof(pHba->detail)); memcpy(&(pHba->detail), "Vendor: Adaptec ", 16); @@ -393,7 +356,7 @@ static void adpt_inquiry(adpt_hba* pHba) memcpy(&(pHba->detail[40]), " FW: ", 4); memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4); pHba->detail[48] = '\0'; /* precautionary */ - dma_free_coherent(&pHba->pDev->dev, 80, buf, addr); + kfree(buf); } adpt_i2o_status_get(pHba); return ; @@ -669,91 +632,6 @@ static int adpt_proc_info(struct Scsi_Host *host, char *buffer, char **start, of return len; } -/* - * Turn a struct scsi_cmnd * into a unique 32 bit 'context'. - */ -static u32 adpt_cmd_to_context(struct scsi_cmnd *cmd) -{ - return (u32)cmd->serial_number; -} - -/* - * Go from a u32 'context' to a struct scsi_cmnd * . - * This could probably be made more efficient. - */ -static struct scsi_cmnd * - adpt_cmd_from_context(adpt_hba * pHba, u32 context) -{ - struct scsi_cmnd * cmd; - struct scsi_device * d; - - if (context == 0) - return NULL; - - spin_unlock(pHba->host->host_lock); - shost_for_each_device(d, pHba->host) { - unsigned long flags; - spin_lock_irqsave(&d->list_lock, flags); - list_for_each_entry(cmd, &d->cmd_list, list) { - if (((u32)cmd->serial_number == context)) { - spin_unlock_irqrestore(&d->list_lock, flags); - scsi_device_put(d); - spin_lock(pHba->host->host_lock); - return cmd; - } - } - spin_unlock_irqrestore(&d->list_lock, flags); - } - spin_lock(pHba->host->host_lock); - - return NULL; -} - -/* - * Turn a pointer to ioctl reply data into an u32 'context' - */ -static u32 adpt_ioctl_to_context(adpt_hba * pHba, void *reply) -{ -#if BITS_PER_LONG == 32 - return (u32)(unsigned long)reply; -#else - ulong flags = 0; - u32 nr, i; - - spin_lock_irqsave(pHba->host->host_lock, flags); - nr = ARRAY_SIZE(pHba->ioctl_reply_context); - for (i = 0; i < nr; i++) { - if (pHba->ioctl_reply_context[i] == NULL) { - pHba->ioctl_reply_context[i] = reply; - break; - } - } - spin_unlock_irqrestore(pHba->host->host_lock, flags); - if (i >= nr) { - kfree (reply); - printk(KERN_WARNING"%s: Too many outstanding " - "ioctl commands\n", pHba->name); - return (u32)-1; - } - - return i; -#endif -} - -/* - * Go from an u32 'context' to a pointer to ioctl reply data. - */ -static void *adpt_ioctl_from_context(adpt_hba *pHba, u32 context) -{ -#if BITS_PER_LONG == 32 - return (void *)(unsigned long)context; -#else - void *p = pHba->ioctl_reply_context[context]; - pHba->ioctl_reply_context[context] = NULL; - - return p; -#endif -} /*=========================================================================== * Error Handling routines @@ -782,7 +660,7 @@ static int adpt_abort(struct scsi_cmnd * cmd) msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid; msg[2] = 0; msg[3]= 0; - msg[4] = adpt_cmd_to_context(cmd); + msg[4] = (u32)cmd; if (pHba->host) spin_lock_irq(pHba->host->host_lock); rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER); @@ -983,6 +861,27 @@ static void adpt_i2o_sys_shutdown(void) printk(KERN_INFO "Adaptec I2O controllers down.\n"); } +/* + * reboot/shutdown notification. + * + * - Quiesce each IOP in the system + * + */ + +#ifdef REBOOT_NOTIFIER +static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p) +{ + + if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF) + return NOTIFY_DONE; + + adpt_i2o_sys_shutdown(); + + return NOTIFY_DONE; +} +#endif + + static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) { @@ -994,7 +893,6 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev u32 hba_map1_area_size = 0; void __iomem *base_addr_virt = NULL; void __iomem *msg_addr_virt = NULL; - int dma64 = 0; int raptorFlag = FALSE; @@ -1008,21 +906,9 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev } pci_set_master(pDev); - - /* - * See if we should enable dma64 mode. - */ - if (sizeof(dma_addr_t) > 4 && - pci_set_dma_mask(pDev, DMA_64BIT_MASK) == 0) { - if (dma_get_required_mask(&pDev->dev) > DMA_32BIT_MASK) - dma64 = 1; - } - if (!dma64 && pci_set_dma_mask(pDev, DMA_32BIT_MASK) != 0) + if (pci_set_dma_mask(pDev, DMA_32BIT_MASK)) return -EINVAL; - /* adapter only supports message blocks below 4GB */ - pci_set_consistent_dma_mask(pDev, DMA_32BIT_MASK); - base_addr0_phys = pci_resource_start(pDev,0); hba_map0_area_size = pci_resource_len(pDev,0); @@ -1043,25 +929,6 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev raptorFlag = TRUE; } -#if BITS_PER_LONG == 64 - /* - * The original Adaptec 64 bit driver has this comment here: - * "x86_64 machines need more optimal mappings" - * - * I assume some HBAs report ridiculously large mappings - * and we need to limit them on platforms with IOMMUs. - */ - if (raptorFlag == TRUE) { - if (hba_map0_area_size > 128) - hba_map0_area_size = 128; - if (hba_map1_area_size > 524288) - hba_map1_area_size = 524288; - } else { - if (hba_map0_area_size > 524288) - hba_map0_area_size = 524288; - } -#endif - base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size); if (!base_addr_virt) { pci_release_regions(pDev); @@ -1124,22 +991,16 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev pHba->state = DPTI_STATE_RESET; pHba->pDev = pDev; pHba->devices = NULL; - pHba->dma64 = dma64; // Initializing the spinlocks spin_lock_init(&pHba->state_lock); spin_lock_init(&adpt_post_wait_lock); if(raptorFlag == 0){ - printk(KERN_INFO "Adaptec I2O RAID controller" - " %d at %p size=%x irq=%d%s\n", - hba_count-1, base_addr_virt, - hba_map0_area_size, pDev->irq, - dma64 ? " (64-bit DMA)" : ""); + printk(KERN_INFO"Adaptec I2O RAID controller %d at %p size=%x irq=%d\n", + hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq); } else { - printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d%s\n", - hba_count-1, pDev->irq, - dma64 ? " (64-bit DMA)" : ""); + printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq); printk(KERN_INFO" BAR0 %p - size= %x\n",base_addr_virt,hba_map0_area_size); printk(KERN_INFO" BAR1 %p - size= %x\n",msg_addr_virt,hba_map1_area_size); } @@ -1192,26 +1053,10 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba) if(pHba->msg_addr_virt != pHba->base_addr_virt){ iounmap(pHba->msg_addr_virt); } - if(pHba->FwDebugBuffer_P) - iounmap(pHba->FwDebugBuffer_P); - if(pHba->hrt) { - dma_free_coherent(&pHba->pDev->dev, - pHba->hrt->num_entries * pHba->hrt->entry_len << 2, - pHba->hrt, pHba->hrt_pa); - } - if(pHba->lct) { - dma_free_coherent(&pHba->pDev->dev, pHba->lct_size, - pHba->lct, pHba->lct_pa); - } - if(pHba->status_block) { - dma_free_coherent(&pHba->pDev->dev, sizeof(i2o_status_block), - pHba->status_block, pHba->status_block_pa); - } - if(pHba->reply_pool) { - dma_free_coherent(&pHba->pDev->dev, - pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, - pHba->reply_pool, pHba->reply_pool_pa); - } + kfree(pHba->hrt); + kfree(pHba->lct); + kfree(pHba->status_block); + kfree(pHba->reply_pool); for(d = pHba->devices; d ; d = next){ next = d->next; @@ -1230,19 +1075,23 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba) pci_dev_put(pHba->pDev); kfree(pHba); - if (adpt_sysfs_class) - device_destroy(adpt_sysfs_class, - MKDEV(DPTI_I2O_MAJOR, pHba->unit)); - if(hba_count <= 0){ unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER); - if (adpt_sysfs_class) { - class_destroy(adpt_sysfs_class); - adpt_sysfs_class = NULL; - } } } + +static int adpt_init(void) +{ + printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n"); +#ifdef REBOOT_NOTIFIER + register_reboot_notifier(&adpt_reboot_notifier); +#endif + + return 0; +} + + static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun) { struct adpt_device* d; @@ -1434,7 +1283,6 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) { u32 msg[8]; u8* status; - dma_addr_t addr; u32 m = EMPTY_QUEUE ; ulong timeout = jiffies + (TMOUT_IOPRESET*HZ); @@ -1457,13 +1305,12 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) schedule_timeout_uninterruptible(1); } while (m == EMPTY_QUEUE); - status = dma_alloc_coherent(&pHba->pDev->dev, 4, &addr, GFP_KERNEL); + status = kzalloc(4, GFP_KERNEL|ADDR32); if(status == NULL) { adpt_send_nop(pHba, m); printk(KERN_ERR"IOP reset failed - no free memory.\n"); return -ENOMEM; } - memset(status,0,4); msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0; msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID; @@ -1471,8 +1318,8 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) msg[3]=0; msg[4]=0; msg[5]=0; - msg[6]=dma_low(addr); - msg[7]=dma_high(addr); + msg[6]=virt_to_bus(status); + msg[7]=0; memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg)); wmb(); @@ -1482,10 +1329,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) while(*status == 0){ if(time_after(jiffies,timeout)){ printk(KERN_WARNING"%s: IOP Reset Timeout\n",pHba->name); - /* We lose 4 bytes of "status" here, but we cannot - free these because controller may awake and corrupt - those bytes at any time */ - /* dma_free_coherent(&pHba->pDev->dev, 4, buf, addr); */ + kfree(status); return -ETIMEDOUT; } rmb(); @@ -1504,10 +1348,6 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) } if(time_after(jiffies,timeout)){ printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name); - /* We lose 4 bytes of "status" here, but we - cannot free these because controller may - awake and corrupt those bytes at any time */ - /* dma_free_coherent(&pHba->pDev->dev, 4, buf, addr); */ return -ETIMEDOUT; } schedule_timeout_uninterruptible(1); @@ -1524,7 +1364,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) PDEBUG("%s: Reset completed.\n", pHba->name); } - dma_free_coherent(&pHba->pDev->dev, 4, status, addr); + kfree(status); #ifdef UARTDELAY // This delay is to allow someone attached to the card through the debug UART to // set up the dump levels that they want before the rest of the initialization sequence @@ -1796,7 +1636,6 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) u32 i = 0; u32 rcode = 0; void *p = NULL; - dma_addr_t addr; ulong flags = 0; memset(&msg, 0, MAX_MESSAGE_SIZE*4); @@ -1829,13 +1668,10 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) } sg_offset = (msg[0]>>4)&0xf; msg[2] = 0x40000000; // IOCTL context - msg[3] = adpt_ioctl_to_context(pHba, reply); - if (msg[3] == (u32)-1) - return -EBUSY; - + msg[3] = (u32)reply; memset(sg_list,0, sizeof(sg_list[0])*pHba->sg_tablesize); if(sg_offset) { - // TODO add 64 bit API + // TODO 64bit fix struct sg_simple_element *sg = (struct sg_simple_element*) (msg+sg_offset); sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); if (sg_count > pHba->sg_tablesize){ @@ -1854,7 +1690,7 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) } sg_size = sg[i].flag_count & 0xffffff; /* Allocate memory for the transfer */ - p = dma_alloc_coherent(&pHba->pDev->dev, sg_size, &addr, GFP_KERNEL); + p = kmalloc(sg_size, GFP_KERNEL|ADDR32); if(!p) { printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", pHba->name,sg_size,i,sg_count); @@ -1864,15 +1700,15 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame. /* Copy in the user's SG buffer if necessary */ if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) { - // sg_simple_element API is 32 bit - if (copy_from_user(p,(void __user *)(ulong)sg[i].addr_bus, sg_size)) { + // TODO 64bit fix + if (copy_from_user(p,(void __user *)sg[i].addr_bus, sg_size)) { printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i); rcode = -EFAULT; goto cleanup; } } - /* sg_simple_element API is 32 bit, but addr < 4GB */ - sg[i].addr_bus = addr; + //TODO 64bit fix + sg[i].addr_bus = (u32)virt_to_bus(p); } } @@ -1900,7 +1736,7 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) if(sg_offset) { /* Copy back the Scatter Gather buffers back to user space */ u32 j; - // TODO add 64 bit API + // TODO 64bit fix struct sg_simple_element* sg; int sg_size; @@ -1920,14 +1756,14 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) } sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); - // TODO add 64 bit API + // TODO 64bit fix sg = (struct sg_simple_element*)(msg + sg_offset); for (j = 0; j < sg_count; j++) { /* Copy out the SG list to user's buffer if necessary */ if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) { sg_size = sg[j].flag_count & 0xffffff; - // sg_simple_element API is 32 bit - if (copy_to_user((void __user *)(ulong)sg[j].addr_bus,sg_list[j], sg_size)) { + // TODO 64bit fix + if (copy_to_user((void __user *)sg[j].addr_bus,sg_list[j], sg_size)) { printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus); rcode = -EFAULT; goto cleanup; @@ -1951,17 +1787,12 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) cleanup: - if (rcode != -ETIME && rcode != -EINTR) { - struct sg_simple_element *sg = - (struct sg_simple_element*) (msg +sg_offset); + if (rcode != -ETIME && rcode != -EINTR) kfree (reply); - while(sg_index) { - if(sg_list[--sg_index]) { - dma_free_coherent(&pHba->pDev->dev, - sg[sg_index].flag_count & 0xffffff, - sg_list[sg_index], - sg[sg_index].addr_bus); - } + while(sg_index) { + if(sg_list[--sg_index]) { + if (rcode != -ETIME && rcode != -EINTR) + kfree(sg_list[sg_index]); } } return rcode; @@ -2147,38 +1978,6 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, return error; } -#ifdef CONFIG_COMPAT -static long compat_adpt_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct inode *inode; - long ret; - - inode = file->f_dentry->d_inode; - - lock_kernel(); - - switch(cmd) { - case DPT_SIGNATURE: - case I2OUSRCMD: - case DPT_CTRLINFO: - case DPT_SYSINFO: - case DPT_BLINKLED: - case I2ORESETCMD: - case I2ORESCANCMD: - case (DPT_TARGET_BUSY & 0xFFFF): - case DPT_TARGET_BUSY: - ret = adpt_ioctl(inode, file, cmd, arg); - break; - default: - ret = -ENOIOCTLCMD; - } - - unlock_kernel(); - - return ret; -} -#endif static irqreturn_t adpt_isr(int irq, void *dev_id) { @@ -2210,16 +2009,7 @@ static irqreturn_t adpt_isr(int irq, void *dev_id) goto out; } } - if (pHba->reply_pool_pa <= m && - m < pHba->reply_pool_pa + - (pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4)) { - reply = (u8 *)pHba->reply_pool + - (m - pHba->reply_pool_pa); - } else { - /* Ick, we should *never* be here */ - printk(KERN_ERR "dpti: reply frame not from pool\n"); - reply = (u8 *)bus_to_virt(m); - } + reply = bus_to_virt(m); if (readl(reply) & MSG_FAIL) { u32 old_m = readl(reply+28); @@ -2239,7 +2029,7 @@ static irqreturn_t adpt_isr(int irq, void *dev_id) } context = readl(reply+8); if(context & 0x40000000){ // IOCTL - void *p = adpt_ioctl_from_context(pHba, readl(reply+12)); + void *p = (void *)readl(reply+12); if( p != NULL) { memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4); } @@ -2253,17 +2043,15 @@ static irqreturn_t adpt_isr(int irq, void *dev_id) status = I2O_POST_WAIT_OK; } if(!(context & 0x40000000)) { - cmd = adpt_cmd_from_context(pHba, - readl(reply+12)); + cmd = (struct scsi_cmnd*) readl(reply+12); if(cmd != NULL) { printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context); } } adpt_i2o_post_wait_complete(context, status); } else { // SCSI message - cmd = adpt_cmd_from_context (pHba, readl(reply+12)); + cmd = (struct scsi_cmnd*) readl(reply+12); if(cmd != NULL){ - scsi_dma_unmap(cmd); if(cmd->serial_number != 0) { // If not timedout adpt_i2o_to_scsi(reply, cmd); } @@ -2284,7 +2072,6 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d int i; u32 msg[MAX_MESSAGE_SIZE]; u32* mptr; - u32* lptr; u32 *lenptr; int direction; int scsidir; @@ -2292,7 +2079,6 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d u32 len; u32 reqlen; s32 rcode; - dma_addr_t addr; memset(msg, 0 , sizeof(msg)); len = scsi_bufflen(cmd); @@ -2332,7 +2118,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d // I2O_CMD_SCSI_EXEC msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid); msg[2] = 0; - msg[3] = adpt_cmd_to_context(cmd); /* Want SCSI control block back */ + msg[3] = (u32)cmd; /* We want the SCSI control block back */ // Our cards use the transaction context as the tag for queueing // Adaptec/DPT Private stuff msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16); @@ -2350,13 +2136,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d memcpy(mptr, cmd->cmnd, cmd->cmd_len); mptr+=4; lenptr=mptr++; /* Remember me - fill in when we know */ - if (dpt_dma64(pHba)) { - reqlen = 16; // SINGLE SGE - *mptr++ = (0x7C<<24)+(2<<16)+0x02; /* Enable 64 bit */ - *mptr++ = 1 << PAGE_SHIFT; - } else { - reqlen = 14; // SINGLE SGE - } + reqlen = 14; // SINGLE SGE /* Now fill in the SGList and command */ nseg = scsi_dma_map(cmd); @@ -2366,16 +2146,12 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d len = 0; scsi_for_each_sg(cmd, sg, nseg, i) { - lptr = mptr; *mptr++ = direction|0x10000000|sg_dma_len(sg); len+=sg_dma_len(sg); - addr = sg_dma_address(sg); - *mptr++ = dma_low(addr); - if (dpt_dma64(pHba)) - *mptr++ = dma_high(addr); + *mptr++ = sg_dma_address(sg); /* Make this an end of list */ if (i == nseg - 1) - *lptr = direction|0xD0000000|sg_dma_len(sg); + mptr[-2] = direction|0xD0000000|sg_dma_len(sg); } reqlen = mptr - msg; *lenptr = len; @@ -2401,13 +2177,13 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d } -static s32 adpt_scsi_host_alloc(adpt_hba* pHba, struct scsi_host_template *sht) +static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht) { - struct Scsi_Host *host; + struct Scsi_Host *host = NULL; - host = scsi_host_alloc(sht, sizeof(adpt_hba*)); + host = scsi_register(sht, sizeof(adpt_hba*)); if (host == NULL) { - printk("%s: scsi_host_alloc returned NULL\n", pHba->name); + printk ("%s: scsi_register returned NULL\n",pHba->name); return -1; } host->hostdata[0] = (unsigned long)pHba; @@ -2424,7 +2200,7 @@ static s32 adpt_scsi_host_alloc(adpt_hba* pHba, struct scsi_host_template *sht) host->max_lun = 256; host->max_channel = pHba->top_scsi_channel + 1; host->cmd_per_lun = 1; - host->unique_id = (u32)sys_tbl_pa + pHba->unit; + host->unique_id = (uint) pHba; host->sg_tablesize = pHba->sg_tablesize; host->can_queue = pHba->post_fifo_size; @@ -2864,10 +2640,11 @@ static s32 adpt_send_nop(adpt_hba*pHba,u32 m) static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) { u8 *status; - dma_addr_t addr; u32 __iomem *msg = NULL; int i; ulong timeout = jiffies + TMOUT_INITOUTBOUND*HZ; + u32* ptr; + u32 outbound_frame; // This had to be a 32 bit address u32 m; do { @@ -2886,14 +2663,13 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) msg=(u32 __iomem *)(pHba->msg_addr_virt+m); - status = dma_alloc_coherent(&pHba->pDev->dev, 4, &addr, GFP_KERNEL); + status = kzalloc(4, GFP_KERNEL|ADDR32); if (!status) { adpt_send_nop(pHba, m); printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n", pHba->name); return -ENOMEM; } - memset(status, 0, 4); writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]); writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]); @@ -2902,7 +2678,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) writel(4096, &msg[4]); /* Host page frame size */ writel((REPLY_FRAME_SIZE)<<16|0x80, &msg[5]); /* Outbound msg frame size and Initcode */ writel(0xD0000004, &msg[6]); /* Simple SG LE, EOB */ - writel((u32)addr, &msg[7]); + writel(virt_to_bus(status), &msg[7]); writel(m, pHba->post_port); wmb(); @@ -2917,10 +2693,6 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) rmb(); if(time_after(jiffies,timeout)){ printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name); - /* We lose 4 bytes of "status" here, but we - cannot free these because controller may - awake and corrupt those bytes at any time */ - /* dma_free_coherent(&pHba->pDev->dev, 4, status, addr); */ return -ETIMEDOUT; } schedule_timeout_uninterruptible(1); @@ -2929,30 +2701,25 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) // If the command was successful, fill the fifo with our reply // message packets if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) { - dma_free_coherent(&pHba->pDev->dev, 4, status, addr); + kfree(status); return -2; } - dma_free_coherent(&pHba->pDev->dev, 4, status, addr); + kfree(status); - if(pHba->reply_pool != NULL) { - dma_free_coherent(&pHba->pDev->dev, - pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, - pHba->reply_pool, pHba->reply_pool_pa); - } + kfree(pHba->reply_pool); - pHba->reply_pool = dma_alloc_coherent(&pHba->pDev->dev, - pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, - &pHba->reply_pool_pa, GFP_KERNEL); + pHba->reply_pool = kzalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32); if (!pHba->reply_pool) { printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name); return -ENOMEM; } - memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4); + ptr = pHba->reply_pool; for(i = 0; i < pHba->reply_fifo_size; i++) { - writel(pHba->reply_pool_pa + (i * REPLY_FRAME_SIZE * 4), - pHba->reply_port); + outbound_frame = (u32)virt_to_bus(ptr); + writel(outbound_frame, pHba->reply_port); wmb(); + ptr += REPLY_FRAME_SIZE; } adpt_i2o_status_get(pHba); return 0; @@ -2976,11 +2743,11 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba) u32 m; u32 __iomem *msg; u8 *status_block=NULL; + ulong status_block_bus; if(pHba->status_block == NULL) { - pHba->status_block = dma_alloc_coherent(&pHba->pDev->dev, - sizeof(i2o_status_block), - &pHba->status_block_pa, GFP_KERNEL); + pHba->status_block = (i2o_status_block*) + kmalloc(sizeof(i2o_status_block),GFP_KERNEL|ADDR32); if(pHba->status_block == NULL) { printk(KERN_ERR "dpti%d: Get Status Block failed; Out of memory. \n", @@ -2990,6 +2757,7 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba) } memset(pHba->status_block, 0, sizeof(i2o_status_block)); status_block = (u8*)(pHba->status_block); + status_block_bus = virt_to_bus(pHba->status_block); timeout = jiffies+TMOUT_GETSTATUS*HZ; do { rmb(); @@ -3014,8 +2782,8 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba) writel(0, &msg[3]); writel(0, &msg[4]); writel(0, &msg[5]); - writel( dma_low(pHba->status_block_pa), &msg[6]); - writel( dma_high(pHba->status_block_pa), &msg[7]); + writel(((u32)status_block_bus)&0xffffffff, &msg[6]); + writel(0, &msg[7]); writel(sizeof(i2o_status_block), &msg[8]); // 88 bytes //post message @@ -3044,17 +2812,7 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba) } // Calculate the Scatter Gather list size - if (dpt_dma64(pHba)) { - pHba->sg_tablesize - = ((pHba->status_block->inbound_frame_size * 4 - - 14 * sizeof(u32)) - / (sizeof(struct sg_simple_element) + sizeof(u32))); - } else { - pHba->sg_tablesize - = ((pHba->status_block->inbound_frame_size * 4 - - 12 * sizeof(u32)) - / sizeof(struct sg_simple_element)); - } + pHba->sg_tablesize = (pHba->status_block->inbound_frame_size * 4 -40)/ sizeof(struct sg_simple_element); if (pHba->sg_tablesize > SG_LIST_ELEMENTS) { pHba->sg_tablesize = SG_LIST_ELEMENTS; } @@ -3105,9 +2863,7 @@ static int adpt_i2o_lct_get(adpt_hba* pHba) } do { if (pHba->lct == NULL) { - pHba->lct = dma_alloc_coherent(&pHba->pDev->dev, - pHba->lct_size, &pHba->lct_pa, - GFP_KERNEL); + pHba->lct = kmalloc(pHba->lct_size, GFP_KERNEL|ADDR32); if(pHba->lct == NULL) { printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n", pHba->name); @@ -3123,7 +2879,7 @@ static int adpt_i2o_lct_get(adpt_hba* pHba) msg[4] = 0xFFFFFFFF; /* All devices */ msg[5] = 0x00000000; /* Report now */ msg[6] = 0xD0000000|pHba->lct_size; - msg[7] = (u32)pHba->lct_pa; + msg[7] = virt_to_bus(pHba->lct); if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 360))) { printk(KERN_ERR "%s: LCT Get failed (status=%#10x.\n", @@ -3134,8 +2890,7 @@ static int adpt_i2o_lct_get(adpt_hba* pHba) if ((pHba->lct->table_size << 2) > pHba->lct_size) { pHba->lct_size = pHba->lct->table_size << 2; - dma_free_coherent(&pHba->pDev->dev, pHba->lct_size, - pHba->lct, pHba->lct_pa); + kfree(pHba->lct); pHba->lct = NULL; } } while (pHba->lct == NULL); @@ -3146,19 +2901,13 @@ static int adpt_i2o_lct_get(adpt_hba* pHba) // I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO; if(adpt_i2o_query_scalar(pHba, 0 , 0x8000, -1, buf, sizeof(buf))>=0) { pHba->FwDebugBufferSize = buf[1]; - pHba->FwDebugBuffer_P = ioremap(pHba->base_addr_phys + buf[0], - pHba->FwDebugBufferSize); - if (pHba->FwDebugBuffer_P) { - pHba->FwDebugFlags_P = pHba->FwDebugBuffer_P + - FW_DEBUG_FLAGS_OFFSET; - pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + - FW_DEBUG_BLED_OFFSET; - pHba->FwDebugBLEDflag_P = pHba->FwDebugBLEDvalue_P + 1; - pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P + - FW_DEBUG_STR_LENGTH_OFFSET; - pHba->FwDebugBuffer_P += buf[2]; - pHba->FwDebugFlags = 0; - } + pHba->FwDebugBuffer_P = pHba->base_addr_virt + buf[0]; + pHba->FwDebugFlags_P = pHba->FwDebugBuffer_P + FW_DEBUG_FLAGS_OFFSET; + pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + FW_DEBUG_BLED_OFFSET; + pHba->FwDebugBLEDflag_P = pHba->FwDebugBLEDvalue_P + 1; + pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P + FW_DEBUG_STR_LENGTH_OFFSET; + pHba->FwDebugBuffer_P += buf[2]; + pHba->FwDebugFlags = 0; } return 0; @@ -3166,30 +2915,25 @@ static int adpt_i2o_lct_get(adpt_hba* pHba) static int adpt_i2o_build_sys_table(void) { - adpt_hba* pHba = hba_chain; + adpt_hba* pHba = NULL; int count = 0; - if (sys_tbl) - dma_free_coherent(&pHba->pDev->dev, sys_tbl_len, - sys_tbl, sys_tbl_pa); - sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs (hba_count) * sizeof(struct i2o_sys_tbl_entry); - sys_tbl = dma_alloc_coherent(&pHba->pDev->dev, - sys_tbl_len, &sys_tbl_pa, GFP_KERNEL); + kfree(sys_tbl); + + sys_tbl = kzalloc(sys_tbl_len, GFP_KERNEL|ADDR32); if (!sys_tbl) { printk(KERN_WARNING "SysTab Set failed. Out of memory.\n"); return -ENOMEM; } - memset(sys_tbl, 0, sys_tbl_len); sys_tbl->num_entries = hba_count; sys_tbl->version = I2OVERSION; sys_tbl->change_ind = sys_tbl_ind++; for(pHba = hba_chain; pHba; pHba = pHba->next) { - u64 addr; // Get updated Status Block so we have the latest information if (adpt_i2o_status_get(pHba)) { sys_tbl->num_entries--; @@ -3205,9 +2949,8 @@ static int adpt_i2o_build_sys_table(void) sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size; sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ?? sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities; - addr = pHba->base_addr_phys + 0x40; - sys_tbl->iops[count].inbound_low = dma_low(addr); - sys_tbl->iops[count].inbound_high = dma_high(addr); + sys_tbl->iops[count].inbound_low = (u32)virt_to_bus(pHba->post_port); + sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus(pHba->post_port)>>32); count++; } @@ -3343,8 +3086,7 @@ static s32 adpt_i2o_hrt_get(adpt_hba* pHba) do { if (pHba->hrt == NULL) { - pHba->hrt = dma_alloc_coherent(&pHba->pDev->dev, - size, &pHba->hrt_pa, GFP_KERNEL); + pHba->hrt=kmalloc(size, GFP_KERNEL|ADDR32); if (pHba->hrt == NULL) { printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", pHba->name); return -ENOMEM; @@ -3356,7 +3098,7 @@ static s32 adpt_i2o_hrt_get(adpt_hba* pHba) msg[2]= 0; msg[3]= 0; msg[4]= (0xD0000000 | size); /* Simple transaction */ - msg[5]= (u32)pHba->hrt_pa; /* Dump it here */ + msg[5]= virt_to_bus(pHba->hrt); /* Dump it here */ if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg),20))) { printk(KERN_ERR "%s: Unable to get HRT (status=%#10x)\n", pHba->name, ret); @@ -3364,10 +3106,8 @@ static s32 adpt_i2o_hrt_get(adpt_hba* pHba) } if (pHba->hrt->num_entries * pHba->hrt->entry_len << 2 > size) { - int newsize = pHba->hrt->num_entries * pHba->hrt->entry_len << 2; - dma_free_coherent(&pHba->pDev->dev, size, - pHba->hrt, pHba->hrt_pa); - size = newsize; + size = pHba->hrt->num_entries * pHba->hrt->entry_len << 2; + kfree(pHba->hrt); pHba->hrt = NULL; } } while(pHba->hrt == NULL); @@ -3381,54 +3121,33 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, int group, int field, void *buf, int buflen) { u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field }; - u8 *opblk_va; - dma_addr_t opblk_pa; - u8 *resblk_va; - dma_addr_t resblk_pa; + u8 *resblk; int size; /* 8 bytes for header */ - resblk_va = dma_alloc_coherent(&pHba->pDev->dev, - sizeof(u8) * (8 + buflen), &resblk_pa, GFP_KERNEL); - if (resblk_va == NULL) { + resblk = kmalloc(sizeof(u8) * (8+buflen), GFP_KERNEL|ADDR32); + if (resblk == NULL) { printk(KERN_CRIT "%s: query scalar failed; Out of memory.\n", pHba->name); return -ENOMEM; } - opblk_va = dma_alloc_coherent(&pHba->pDev->dev, - sizeof(opblk), &opblk_pa, GFP_KERNEL); - if (opblk_va == NULL) { - dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen), - resblk_va, resblk_pa); - printk(KERN_CRIT "%s: query operatio failed; Out of memory.\n", - pHba->name); - return -ENOMEM; - } if (field == -1) /* whole group */ opblk[4] = -1; - memcpy(opblk_va, opblk, sizeof(opblk)); size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid, - opblk_va, opblk_pa, sizeof(opblk), - resblk_va, resblk_pa, sizeof(u8)*(8+buflen)); - dma_free_coherent(&pHba->pDev->dev, sizeof(opblk), opblk_va, opblk_pa); + opblk, sizeof(opblk), resblk, sizeof(u8)*(8+buflen)); if (size == -ETIME) { - dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen), - resblk_va, resblk_pa); printk(KERN_WARNING "%s: issue params failed; Timed out.\n", pHba->name); return -ETIME; } else if (size == -EINTR) { - dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen), - resblk_va, resblk_pa); printk(KERN_WARNING "%s: issue params failed; Interrupted.\n", pHba->name); return -EINTR; } - memcpy(buf, resblk_va+8, buflen); /* cut off header */ + memcpy(buf, resblk+8, buflen); /* cut off header */ - dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen), - resblk_va, resblk_pa); + kfree(resblk); if (size < 0) return size; @@ -3445,11 +3164,10 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, * ResultCount, ErrorInfoSize, BlockStatus and BlockSize. */ static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, - void *opblk_va, dma_addr_t opblk_pa, int oplen, - void *resblk_va, dma_addr_t resblk_pa, int reslen) + void *opblk, int oplen, void *resblk, int reslen) { u32 msg[9]; - u32 *res = (u32 *)resblk_va; + u32 *res = (u32 *)resblk; int wait_status; msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5; @@ -3458,12 +3176,12 @@ static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, msg[3] = 0; msg[4] = 0; msg[5] = 0x54000000 | oplen; /* OperationBlock */ - msg[6] = (u32)opblk_pa; + msg[6] = virt_to_bus(opblk); msg[7] = 0xD0000000 | reslen; /* ResultBlock */ - msg[8] = (u32)resblk_pa; + msg[8] = virt_to_bus(resblk); if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) { - printk("adpt_i2o_issue_params: post_wait failed (%p)\n", resblk_va); + printk("adpt_i2o_issue_params: post_wait failed (%p)\n", resblk); return wait_status; /* -DetailedStatus */ } @@ -3566,7 +3284,7 @@ static int adpt_i2o_systab_send(adpt_hba* pHba) * Private i/o space declaration */ msg[6] = 0x54000000 | sys_tbl_len; - msg[7] = (u32)sys_tbl_pa; + msg[7] = virt_to_phys(sys_tbl); msg[8] = 0x54000000 | 0; msg[9] = 0; msg[10] = 0xD4000000 | 0; @@ -3605,10 +3323,11 @@ static static void adpt_delay(int millisec) #endif static struct scsi_host_template driver_template = { - .module = THIS_MODULE, .name = "dpt_i2o", .proc_name = "dpt_i2o", .proc_info = adpt_proc_info, + .detect = adpt_detect, + .release = adpt_release, .info = adpt_info, .queuecommand = adpt_queue, .eh_abort_handler = adpt_abort, @@ -3622,48 +3341,5 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = 1, .use_clustering = ENABLE_CLUSTERING, }; - -static int __init adpt_init(void) -{ - int error; - adpt_hba *pHba, *next; - - printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n"); - - error = adpt_detect(&driver_template); - if (error < 0) - return error; - if (hba_chain == NULL) - return -ENODEV; - - for (pHba = hba_chain; pHba; pHba = pHba->next) { - error = scsi_add_host(pHba->host, &pHba->pDev->dev); - if (error) - goto fail; - scsi_scan_host(pHba->host); - } - return 0; -fail: - for (pHba = hba_chain; pHba; pHba = next) { - next = pHba->next; - scsi_remove_host(pHba->host); - } - return error; -} - -static void __exit adpt_exit(void) -{ - adpt_hba *pHba, *next; - - for (pHba = hba_chain; pHba; pHba = pHba->next) - scsi_remove_host(pHba->host); - for (pHba = hba_chain; pHba; pHba = next) { - next = pHba->next; - adpt_release(pHba->host); - } -} - -module_init(adpt_init); -module_exit(adpt_exit); - +#include "scsi_module.c" MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/scsi/dpti.h b/trunk/drivers/scsi/dpti.h index 924cd5a51676..fd79068c5869 100644 --- a/trunk/drivers/scsi/dpti.h +++ b/trunk/drivers/scsi/dpti.h @@ -84,6 +84,7 @@ static int adpt_device_reset(struct scsi_cmnd* cmd); #define PCI_DPT_DEVICE_ID (0xA501) // DPT PCI I2O Device ID #define PCI_DPT_RAPTOR_DEVICE_ID (0xA511) +//#define REBOOT_NOTIFIER 1 /* Debugging macro from Linux Device Drivers - Rubini */ #undef PDEBUG #ifdef DEBUG @@ -228,19 +229,14 @@ typedef struct _adpt_hba { u32 post_fifo_size; u32 reply_fifo_size; u32* reply_pool; - dma_addr_t reply_pool_pa; u32 sg_tablesize; // Scatter/Gather List Size. u8 top_scsi_channel; u8 top_scsi_id; u8 top_scsi_lun; - u8 dma64; i2o_status_block* status_block; - dma_addr_t status_block_pa; i2o_hrt* hrt; - dma_addr_t hrt_pa; i2o_lct* lct; - dma_addr_t lct_pa; uint lct_size; struct i2o_device* devices; struct adpt_channel channel[MAX_CHANNEL]; @@ -253,7 +249,6 @@ typedef struct _adpt_hba { void __iomem *FwDebugBLEDflag_P;// Virtual Addr Of FW Debug BLED void __iomem *FwDebugBLEDvalue_P;// Virtual Addr Of FW Debug BLED u32 FwDebugFlags; - u32 *ioctl_reply_context[4]; } adpt_hba; struct sg_simple_element { @@ -269,6 +264,9 @@ static void adpt_i2o_sys_shutdown(void); static int adpt_init(void); static int adpt_i2o_build_sys_table(void); static irqreturn_t adpt_isr(int irq, void *dev_id); +#ifdef REBOOT_NOTIFIER +static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p); +#endif static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d); static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, @@ -277,8 +275,7 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, static const char *adpt_i2o_get_class_name(int class); #endif static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, - void *opblk, dma_addr_t opblk_pa, int oplen, - void *resblk, dma_addr_t resblk_pa, int reslen); + void *opblk, int oplen, void *resblk, int reslen); static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout); static int adpt_i2o_lct_get(adpt_hba* pHba); static int adpt_i2o_parse_lct(adpt_hba* pHba); @@ -292,7 +289,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba); static s32 adpt_i2o_hrt_get(adpt_hba* pHba); static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice); static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd); -static s32 adpt_scsi_host_alloc(adpt_hba* pHba,struct scsi_host_template * sht); +static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht); static s32 adpt_hba_reset(adpt_hba* pHba); static s32 adpt_i2o_reset_hba(adpt_hba* pHba); static s32 adpt_rescan(adpt_hba* pHba); diff --git a/trunk/drivers/scsi/gdth.c b/trunk/drivers/scsi/gdth.c index 8e2e964af668..c6d6e7c6559a 100644 --- a/trunk/drivers/scsi/gdth.c +++ b/trunk/drivers/scsi/gdth.c @@ -465,7 +465,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, scp->request = (struct request *)&wait; scp->timeout_per_command = timeout*HZ; scp->cmd_len = 12; - scp->cmnd = cmnd; + memcpy(scp->cmnd, cmnd, 12); cmndinfo.priority = IOCTL_PRI; cmndinfo.internal_cmd_str = gdtcmd; cmndinfo.internal_command = 1; diff --git a/trunk/drivers/scsi/hptiop.c b/trunk/drivers/scsi/hptiop.c index aaa48e0c8ed0..5b7be1e9841c 100644 --- a/trunk/drivers/scsi/hptiop.c +++ b/trunk/drivers/scsi/hptiop.c @@ -763,9 +763,9 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp, scp, host->host_no, scp->device->channel, scp->device->id, scp->device->lun, - ((u32 *)scp->cmnd)[0], - ((u32 *)scp->cmnd)[1], - ((u32 *)scp->cmnd)[2], + *((u32 *)&scp->cmnd), + *((u32 *)&scp->cmnd + 1), + *((u32 *)&scp->cmnd + 2), _req->index, _req->req_virt); scp->result = 0; diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index ccfd8aca3765..4a922c57125e 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -686,7 +686,7 @@ static void handle_cmd_rsp(struct srp_event_struct *evt_struct) } if (cmnd) { - cmnd->result |= rsp->status; + cmnd->result = rsp->status; if (((cmnd->result >> 1) & 0x1f) == CHECK_CONDITION) memcpy(cmnd->sense_buffer, rsp->data, @@ -730,7 +730,6 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, u16 lun = lun_from_dev(cmnd->device); u8 out_fmt, in_fmt; - cmnd->result = (DID_OK << 16); evt_struct = get_event_struct(&hostdata->pool); if (!evt_struct) return SCSI_MLQUEUE_HOST_BUSY; @@ -739,7 +738,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, srp_cmd = &evt_struct->iu.srp.cmd; memset(srp_cmd, 0x00, SRP_MAX_IU_LEN); srp_cmd->opcode = SRP_CMD; - memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(srp_cmd->cdb)); + memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(cmnd->cmnd)); srp_cmd->lun = ((u64) lun) << 48; if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) { @@ -1348,8 +1347,6 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, del_timer(&evt_struct->timer); - if (crq->status != VIOSRP_OK && evt_struct->cmnd) - evt_struct->cmnd->result = DID_ERROR << 16; if (evt_struct->done) evt_struct->done(evt_struct); else diff --git a/trunk/drivers/scsi/ibmvscsi/viosrp.h b/trunk/drivers/scsi/ibmvscsi/viosrp.h index 4c4aadb3e405..90f1a61283ad 100644 --- a/trunk/drivers/scsi/ibmvscsi/viosrp.h +++ b/trunk/drivers/scsi/ibmvscsi/viosrp.h @@ -59,15 +59,6 @@ enum viosrp_crq_formats { VIOSRP_INLINE_FORMAT = 0x07 }; -enum viosrp_crq_status { - VIOSRP_OK = 0x0, - VIOSRP_NONRECOVERABLE_ERR = 0x1, - VIOSRP_VIOLATES_MAX_XFER = 0x2, - VIOSRP_PARTNER_PANIC = 0x3, - VIOSRP_DEVICE_BUSY = 0x8, - VIOSRP_ADAPTER_FAIL = 0x10 -}; - struct viosrp_crq { u8 valid; /* used by RPA */ u8 format; /* SCSI vs out-of-band */ diff --git a/trunk/drivers/scsi/initio.c b/trunk/drivers/scsi/initio.c index e3f739776bad..dbae3fdb8506 100644 --- a/trunk/drivers/scsi/initio.c +++ b/trunk/drivers/scsi/initio.c @@ -2590,7 +2590,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c cblk->hastat = 0; cblk->tastat = 0; /* Command the command */ - memcpy(cblk->cdb, cmnd->cmnd, cmnd->cmd_len); + memcpy(&cblk->cdb[0], &cmnd->cmnd, cmnd->cmd_len); /* Set up tags */ if (cmnd->device->tagged_supported) { /* Tag Support */ diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 999e91ea7451..de5ae6a65029 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -2791,7 +2791,7 @@ static ssize_t ipr_store_adapter_state(struct device *dev, static struct device_attribute ipr_ioa_state_attr = { .attr = { - .name = "online_state", + .name = "state", .mode = S_IRUGO | S_IWUSR, }, .show = ipr_show_adapter_state, diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.c b/trunk/drivers/scsi/megaraid/megaraid_mbox.c index 70a0f11f48b2..820f91fb63ba 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mbox.c +++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.c @@ -3168,23 +3168,6 @@ megaraid_mbox_support_random_del(adapter_t *adapter) uint8_t raw_mbox[sizeof(mbox_t)]; int rval; - /* - * Newer firmware on Dell CERC expect a different - * random deletion handling, so disable it. - */ - if (adapter->pdev->vendor == PCI_VENDOR_ID_AMI && - adapter->pdev->device == PCI_DEVICE_ID_AMI_MEGARAID3 && - adapter->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && - adapter->pdev->subsystem_device == PCI_SUBSYS_ID_CERC_ATA100_4CH && - (adapter->fw_version[0] > '6' || - (adapter->fw_version[0] == '6' && - adapter->fw_version[2] > '6') || - (adapter->fw_version[0] == '6' - && adapter->fw_version[2] == '6' - && adapter->fw_version[3] > '1'))) { - con_log(CL_DLEVEL1, ("megaraid: disable random deletion\n")); - return 0; - } mbox = (mbox_t *)raw_mbox; diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.h b/trunk/drivers/scsi/megaraid/megaraid_mbox.h index c1d86d961a92..626459d1e902 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mbox.h +++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.h @@ -88,7 +88,6 @@ #define PCI_SUBSYS_ID_PERC3_QC 0x0471 #define PCI_SUBSYS_ID_PERC3_DC 0x0493 #define PCI_SUBSYS_ID_PERC3_SC 0x0475 -#define PCI_SUBSYS_ID_CERC_ATA100_4CH 0x0511 #define MBOX_MAX_SCSI_CMDS 128 // number of cmds reserved for kernel diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.c b/trunk/drivers/scsi/megaraid/megaraid_sas.c index 7d84c8bbcf3f..b937e9cddb23 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_sas.c - * Version : v00.00.03.20-rc1 + * Version : v00.00.03.16-rc1 * * Authors: * (email-id : megaraidlinux@lsi.com) @@ -2650,13 +2650,12 @@ static void megasas_shutdown_controller(struct megasas_instance *instance, return; } -#ifdef CONFIG_PM /** * megasas_suspend - driver suspend entry point * @pdev: PCI device structure * @state: PCI power state to suspend routine */ -static int +static int __devinit megasas_suspend(struct pci_dev *pdev, pm_message_t state) { struct Scsi_Host *host; @@ -2688,7 +2687,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) * megasas_resume- driver resume entry point * @pdev: PCI device structure */ -static int +static int __devinit megasas_resume(struct pci_dev *pdev) { int rval; @@ -2783,16 +2782,12 @@ megasas_resume(struct pci_dev *pdev) return -ENODEV; } -#else -#define megasas_suspend NULL -#define megasas_resume NULL -#endif /** * megasas_detach_one - PCI hot"un"plug entry point * @pdev: PCI device structure */ -static void __devexit megasas_detach_one(struct pci_dev *pdev) +static void megasas_detach_one(struct pci_dev *pdev) { int i; struct Scsi_Host *host; diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.h b/trunk/drivers/scsi/megaraid/megaraid_sas.h index b0c41e671702..3a997eb457bf 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.h +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.h @@ -18,9 +18,9 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "00.00.03.20-rc1" -#define MEGASAS_RELDATE "March 10, 2008" -#define MEGASAS_EXT_VERSION "Mon. March 10 11:02:31 PDT 2008" +#define MEGASAS_VERSION "00.00.03.16-rc1" +#define MEGASAS_RELDATE "Nov. 07, 2007" +#define MEGASAS_EXT_VERSION "Thu. Nov. 07 10:09:32 PDT 2007" /* * Device IDs diff --git a/trunk/drivers/scsi/qla1280.c b/trunk/drivers/scsi/qla1280.c index fa060932d2b4..09ab3eac1c1a 100644 --- a/trunk/drivers/scsi/qla1280.c +++ b/trunk/drivers/scsi/qla1280.c @@ -2858,7 +2858,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) /* Load SCSI command packet. */ pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd)); - memcpy(pkt->scsi_cdb, CMD_CDBP(cmd), CMD_CDBLEN(cmd)); + memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd)); /* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ /* Set transfer direction. */ @@ -3127,7 +3127,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) /* Load SCSI command packet. */ pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd)); - memcpy(pkt->scsi_cdb, CMD_CDBP(cmd), CMD_CDBLEN(cmd)); + memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd)); /*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ /* Set transfer direction. */ diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index 110e776d1a07..12d69d7c8577 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -78,6 +78,15 @@ static void scsi_done(struct scsi_cmnd *cmd); /* Do not call reset on error if we just did a reset within 15 sec. */ #define MIN_RESET_PERIOD (15*HZ) +/* + * Macro to determine the size of SCSI command. This macro takes vendor + * unique commands into account. SCSI commands in groups 6 and 7 are + * vendor unique and we will depend upon the command length being + * supplied correctly in cmd_len. + */ +#define CDB_SIZE(cmd) (((((cmd)->cmnd[0] >> 5) & 7) < 6) ? \ + COMMAND_SIZE((cmd)->cmnd[0]) : (cmd)->cmd_len) + /* * Note - the initial logging level can be set here to log events at boot time. * After the system is up, you may enable logging via the /proc interface. @@ -460,7 +469,6 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); if (!cmd) { scsi_put_host_cmd_pool(gfp_mask); - shost->cmd_pool = NULL; return -ENOMEM; } list_add(&cmd->list, &shost->free_list); @@ -473,13 +481,6 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) */ void scsi_destroy_command_freelist(struct Scsi_Host *shost) { - /* - * If cmd_pool is NULL the free list was not initialized, so - * do not attempt to release resources. - */ - if (!shost->cmd_pool) - return; - while (!list_empty(&shost->free_list)) { struct scsi_cmnd *cmd; @@ -700,11 +701,9 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) * Before we queue this command, check if the command * length exceeds what the host adapter can handle. */ - if (cmd->cmd_len > cmd->device->host->max_cmd_len) { + if (CDB_SIZE(cmd) > cmd->device->host->max_cmd_len) { SCSI_LOG_MLQUEUE(3, - printk("queuecommand : command too long. " - "cdb_size=%d host->max_cmd_len=%d\n", - cmd->cmd_len, cmd->device->host->max_cmd_len)); + printk("queuecommand : command too long.\n")); cmd->result = (DID_ABORT << 16); scsi_done(cmd); diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index eaf5a8add1ba..1eaba6cd80f4 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -626,7 +626,7 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) * @scmd: SCSI command structure to hijack * @ses: structure to save restore information * @cmnd: CDB to send. Can be NULL if no new cmnd is needed - * @cmnd_size: size in bytes of @cmnd (must be <= BLK_MAX_CDB) + * @cmnd_size: size in bytes of @cmnd * @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored) * * This function is used to save a scsi command information before re-execution @@ -648,14 +648,12 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, * command. */ ses->cmd_len = scmd->cmd_len; - ses->cmnd = scmd->cmnd; + memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd)); ses->data_direction = scmd->sc_data_direction; ses->sdb = scmd->sdb; ses->next_rq = scmd->request->next_rq; ses->result = scmd->result; - scmd->cmnd = ses->eh_cmnd; - memset(scmd->cmnd, 0, BLK_MAX_CDB); memset(&scmd->sdb, 0, sizeof(scmd->sdb)); scmd->request->next_rq = NULL; @@ -667,13 +665,14 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, scmd->sdb.table.sgl = &ses->sense_sgl; scmd->sc_data_direction = DMA_FROM_DEVICE; scmd->sdb.table.nents = 1; + memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); scmd->cmnd[0] = REQUEST_SENSE; scmd->cmnd[4] = scmd->sdb.length; scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); } else { scmd->sc_data_direction = DMA_NONE; if (cmnd) { - BUG_ON(cmnd_size > BLK_MAX_CDB); + memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); memcpy(scmd->cmnd, cmnd, cmnd_size); scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); } @@ -706,7 +705,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) * Restore original data */ scmd->cmd_len = ses->cmd_len; - scmd->cmnd = ses->cmnd; + memcpy(scmd->cmnd, ses->cmnd, sizeof(scmd->cmnd)); scmd->sc_data_direction = ses->data_direction; scmd->sdb = ses->sdb; scmd->request->next_rq = ses->next_rq; @@ -1776,8 +1775,8 @@ scsi_reset_provider(struct scsi_device *dev, int flag) scmd->request = &req; memset(&scmd->eh_timeout, 0, sizeof(scmd->eh_timeout)); - scmd->cmnd = req.cmd; - + memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); + scmd->scsi_done = scsi_reset_provider_done_command; memset(&scmd->sdb, 0, sizeof(scmd->sdb)); diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index a82d2fe80fb5..d545ad1cf47a 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -445,7 +445,7 @@ static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) scsi_set_resid(cmd, 0); memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); if (cmd->cmd_len == 0) - cmd->cmd_len = scsi_command_size(cmd->cmnd); + cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); } void scsi_device_unbusy(struct scsi_device *sdev) @@ -1094,8 +1094,6 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, cmd->tag = req->tag; cmd->request = req; - cmd->cmnd = req->cmd; - return cmd; } @@ -1133,6 +1131,8 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) req->buffer = NULL; } + BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); + memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); cmd->cmd_len = req->cmd_len; if (!req->data_len) cmd->sc_data_direction = DMA_NONE; @@ -1169,7 +1169,6 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) if (unlikely(!cmd)) return BLKPREP_DEFER; - memset(cmd->cmnd, 0, BLK_MAX_CDB); return scsi_init_io(cmd, GFP_ATOMIC); } EXPORT_SYMBOL(scsi_setup_fs_cmnd); diff --git a/trunk/drivers/scsi/scsi_tgt_lib.c b/trunk/drivers/scsi/scsi_tgt_lib.c index 257e097c39af..ee8496aa0336 100644 --- a/trunk/drivers/scsi/scsi_tgt_lib.c +++ b/trunk/drivers/scsi/scsi_tgt_lib.c @@ -107,8 +107,6 @@ struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost, cmd->jiffies_at_alloc = jiffies; cmd->request = rq; - cmd->cmnd = rq->cmd; - rq->special = cmd; rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_flags |= REQ_TYPE_BLOCK_PC; diff --git a/trunk/drivers/scsi/u14-34f.c b/trunk/drivers/scsi/u14-34f.c index 329eb8780e74..640333b1e75c 100644 --- a/trunk/drivers/scsi/u14-34f.c +++ b/trunk/drivers/scsi/u14-34f.c @@ -744,8 +744,7 @@ static int wait_on_busy(unsigned long iobase, unsigned int loop) { static int board_inquiry(unsigned int j) { struct mscp *cpp; dma_addr_t id_dma_addr; - unsigned int limit = 0; - unsigned long time; + unsigned int time, limit = 0; id_dma_addr = pci_map_single(HD(j)->pdev, HD(j)->board_id, sizeof(HD(j)->board_id), PCI_DMA_BIDIRECTIONAL); @@ -1393,8 +1392,7 @@ static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) { } static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { - unsigned int i, j, k, c, limit = 0; - unsigned long time; + unsigned int i, j, time, k, c, limit = 0; int arg_done = FALSE; struct scsi_cmnd *SCpnt; diff --git a/trunk/drivers/serial/mpc52xx_uart.c b/trunk/drivers/serial/mpc52xx_uart.c index efc971d9647b..7a3625f52a03 100644 --- a/trunk/drivers/serial/mpc52xx_uart.c +++ b/trunk/drivers/serial/mpc52xx_uart.c @@ -783,9 +783,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) } } - spin_unlock(&port->lock); tty_flip_buffer_push(tty); - spin_lock(&port->lock); return psc_ops->raw_rx_rdy(port); } diff --git a/trunk/drivers/usb/Makefile b/trunk/drivers/usb/Makefile index a419c42e880e..516a6400db43 100644 --- a/trunk/drivers/usb/Makefile +++ b/trunk/drivers/usb/Makefile @@ -17,8 +17,6 @@ obj-$(CONFIG_USB_SL811_HCD) += host/ obj-$(CONFIG_USB_U132_HCD) += host/ obj-$(CONFIG_USB_R8A66597_HCD) += host/ -obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ - obj-$(CONFIG_USB_ACM) += class/ obj-$(CONFIG_USB_PRINTER) += class/ diff --git a/trunk/drivers/usb/atm/Kconfig b/trunk/drivers/usb/atm/Kconfig index be0b8daac9c7..86e64035edb0 100644 --- a/trunk/drivers/usb/atm/Kconfig +++ b/trunk/drivers/usb/atm/Kconfig @@ -19,6 +19,7 @@ if USB_ATM config USB_SPEEDTOUCH tristate "Speedtouch USB support" + depends on USB_ATM select FW_LOADER help Say Y here if you have an SpeedTouch USB or SpeedTouch 330 @@ -31,6 +32,7 @@ config USB_SPEEDTOUCH config USB_CXACRU tristate "Conexant AccessRunner USB support" + depends on USB_ATM select FW_LOADER help Say Y here if you have an ADSL USB modem based on the Conexant @@ -43,6 +45,7 @@ config USB_CXACRU config USB_UEAGLEATM tristate "ADI 930 and eagle USB DSL modem" + depends on USB_ATM select FW_LOADER help Say Y here if you have an ADSL USB modem based on the ADI 930 @@ -55,6 +58,7 @@ config USB_UEAGLEATM config USB_XUSBATM tristate "Other USB DSL modem support" + depends on USB_ATM help Say Y here if you have a DSL USB modem not explicitly supported by another USB DSL drivers. In order to use your modem you will need to diff --git a/trunk/drivers/usb/c67x00/Makefile b/trunk/drivers/usb/c67x00/Makefile deleted file mode 100644 index 868bc41b5980..000000000000 --- a/trunk/drivers/usb/c67x00/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for Cypress C67X00 USB Controller -# - -ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG - -obj-$(CONFIG_USB_C67X00_HCD) += c67x00.o - -c67x00-objs := c67x00-drv.o c67x00-ll-hpi.o c67x00-hcd.o c67x00-sched.o diff --git a/trunk/drivers/usb/c67x00/c67x00-drv.c b/trunk/drivers/usb/c67x00/c67x00-drv.c deleted file mode 100644 index 5633bc5c8bf2..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00-drv.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * c67x00-drv.c: Cypress C67X00 USB Common infrastructure - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -/* - * This file implements the common infrastructure for using the c67x00. - * It is both the link between the platform configuration and subdrivers and - * the link between the common hardware parts and the subdrivers (e.g. - * interrupt handling). - * - * The c67x00 has 2 SIE's (serial interface engine) wich can be configured - * to be host, device or OTG (with some limitations, E.G. only SIE1 can be OTG). - * - * Depending on the platform configuration, the SIE's are created and - * the corresponding subdriver is initialized (c67x00_probe_sie). - */ - -#include -#include -#include -#include -#include - -#include "c67x00.h" -#include "c67x00-hcd.h" - -static void c67x00_probe_sie(struct c67x00_sie *sie, - struct c67x00_device *dev, int sie_num) -{ - spin_lock_init(&sie->lock); - sie->dev = dev; - sie->sie_num = sie_num; - sie->mode = c67x00_sie_config(dev->pdata->sie_config, sie_num); - - switch (sie->mode) { - case C67X00_SIE_HOST: - c67x00_hcd_probe(sie); - break; - - case C67X00_SIE_UNUSED: - dev_info(sie_dev(sie), - "Not using SIE %d as requested\n", sie->sie_num); - break; - - default: - dev_err(sie_dev(sie), - "Unsupported configuration: 0x%x for SIE %d\n", - sie->mode, sie->sie_num); - break; - } -} - -static void c67x00_remove_sie(struct c67x00_sie *sie) -{ - switch (sie->mode) { - case C67X00_SIE_HOST: - c67x00_hcd_remove(sie); - break; - - default: - break; - } -} - -static irqreturn_t c67x00_irq(int irq, void *__dev) -{ - struct c67x00_device *c67x00 = __dev; - struct c67x00_sie *sie; - u16 msg, int_status; - int i, count = 8; - - int_status = c67x00_ll_hpi_status(c67x00); - if (!int_status) - return IRQ_NONE; - - while (int_status != 0 && (count-- >= 0)) { - c67x00_ll_irq(c67x00, int_status); - for (i = 0; i < C67X00_SIES; i++) { - sie = &c67x00->sie[i]; - msg = 0; - if (int_status & SIEMSG_FLG(i)) - msg = c67x00_ll_fetch_siemsg(c67x00, i); - if (sie->irq) - sie->irq(sie, int_status, msg); - } - int_status = c67x00_ll_hpi_status(c67x00); - } - - if (int_status) - dev_warn(&c67x00->pdev->dev, "Not all interrupts handled! " - "status = 0x%04x\n", int_status); - - return IRQ_HANDLED; -} - -/* ------------------------------------------------------------------------- */ - -static int __devinit c67x00_drv_probe(struct platform_device *pdev) -{ - struct c67x00_device *c67x00; - struct c67x00_platform_data *pdata; - struct resource *res, *res2; - int ret, i; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res2) - return -ENODEV; - - pdata = pdev->dev.platform_data; - if (!pdata) - return -ENODEV; - - c67x00 = kzalloc(sizeof(*c67x00), GFP_KERNEL); - if (!c67x00) - return -ENOMEM; - - if (!request_mem_region(res->start, res->end - res->start + 1, - pdev->name)) { - dev_err(&pdev->dev, "Memory region busy\n"); - ret = -EBUSY; - goto request_mem_failed; - } - c67x00->hpi.base = ioremap(res->start, res->end - res->start + 1); - if (!c67x00->hpi.base) { - dev_err(&pdev->dev, "Unable to map HPI registers\n"); - ret = -EIO; - goto map_failed; - } - - spin_lock_init(&c67x00->hpi.lock); - c67x00->hpi.regstep = pdata->hpi_regstep; - c67x00->pdata = pdev->dev.platform_data; - c67x00->pdev = pdev; - - c67x00_ll_init(c67x00); - c67x00_ll_hpi_reg_init(c67x00); - - ret = request_irq(res2->start, c67x00_irq, 0, pdev->name, c67x00); - if (ret) { - dev_err(&pdev->dev, "Cannot claim IRQ\n"); - goto request_irq_failed; - } - - ret = c67x00_ll_reset(c67x00); - if (ret) { - dev_err(&pdev->dev, "Device reset failed\n"); - goto reset_failed; - } - - for (i = 0; i < C67X00_SIES; i++) - c67x00_probe_sie(&c67x00->sie[i], c67x00, i); - - platform_set_drvdata(pdev, c67x00); - - return 0; - - reset_failed: - free_irq(res2->start, c67x00); - request_irq_failed: - iounmap(c67x00->hpi.base); - map_failed: - release_mem_region(res->start, res->end - res->start + 1); - request_mem_failed: - kfree(c67x00); - - return ret; -} - -static int __devexit c67x00_drv_remove(struct platform_device *pdev) -{ - struct c67x00_device *c67x00 = platform_get_drvdata(pdev); - struct resource *res; - int i; - - for (i = 0; i < C67X00_SIES; i++) - c67x00_remove_sie(&c67x00->sie[i]); - - c67x00_ll_release(c67x00); - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res) - free_irq(res->start, c67x00); - - iounmap(c67x00->hpi.base); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res) - release_mem_region(res->start, res->end - res->start + 1); - - kfree(c67x00); - - return 0; -} - -static struct platform_driver c67x00_driver = { - .probe = c67x00_drv_probe, - .remove = __devexit_p(c67x00_drv_remove), - .driver = { - .owner = THIS_MODULE, - .name = "c67x00", - }, -}; -MODULE_ALIAS("platform:c67x00"); - -static int __init c67x00_init(void) -{ - return platform_driver_register(&c67x00_driver); -} - -static void __exit c67x00_exit(void) -{ - platform_driver_unregister(&c67x00_driver); -} - -module_init(c67x00_init); -module_exit(c67x00_exit); - -MODULE_AUTHOR("Peter Korsgaard, Jan Veldeman, Grant Likely"); -MODULE_DESCRIPTION("Cypress C67X00 USB Controller Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/c67x00/c67x00-hcd.c b/trunk/drivers/usb/c67x00/c67x00-hcd.c deleted file mode 100644 index a22b887f4e9e..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00-hcd.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * c67x00-hcd.c: Cypress C67X00 USB Host Controller Driver - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#include -#include -#include - -#include "c67x00.h" -#include "c67x00-hcd.h" - -/* -------------------------------------------------------------------------- - * Root Hub Support - */ - -static __u8 c67x00_hub_des[] = { - 0x09, /* __u8 bLength; */ - 0x29, /* __u8 bDescriptorType; Hub-descriptor */ - 0x02, /* __u8 bNbrPorts; */ - 0x00, /* __u16 wHubCharacteristics; */ - 0x00, /* (per-port OC, no power switching) */ - 0x32, /* __u8 bPwrOn2pwrGood; 2ms */ - 0x00, /* __u8 bHubContrCurrent; 0 mA */ - 0x00, /* __u8 DeviceRemovable; ** 7 Ports max ** */ - 0xff, /* __u8 PortPwrCtrlMask; ** 7 ports max ** */ -}; - -static void c67x00_hub_reset_host_port(struct c67x00_sie *sie, int port) -{ - struct c67x00_hcd *c67x00 = sie->private_data; - unsigned long flags; - - c67x00_ll_husb_reset(sie, port); - - spin_lock_irqsave(&c67x00->lock, flags); - c67x00_ll_husb_reset_port(sie, port); - spin_unlock_irqrestore(&c67x00->lock, flags); - - c67x00_ll_set_husb_eot(sie->dev, DEFAULT_EOT); -} - -static int c67x00_hub_status_data(struct usb_hcd *hcd, char *buf) -{ - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - struct c67x00_sie *sie = c67x00->sie; - u16 status; - int i; - - *buf = 0; - status = c67x00_ll_usb_get_status(sie); - for (i = 0; i < C67X00_PORTS; i++) - if (status & PORT_CONNECT_CHANGE(i)) - *buf |= (1 << i); - - /* bit 0 denotes hub change, b1..n port change */ - *buf <<= 1; - - return !!*buf; -} - -static int c67x00_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, - u16 wIndex, char *buf, u16 wLength) -{ - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - struct c67x00_sie *sie = c67x00->sie; - u16 status, usb_status; - int len = 0; - unsigned int port = wIndex-1; - u16 wPortChange, wPortStatus; - - switch (typeReq) { - - case GetHubStatus: - *(__le32 *) buf = cpu_to_le32(0); - len = 4; /* hub power */ - break; - - case GetPortStatus: - if (wIndex > C67X00_PORTS) - return -EPIPE; - - status = c67x00_ll_usb_get_status(sie); - usb_status = c67x00_ll_get_usb_ctl(sie); - - wPortChange = 0; - if (status & PORT_CONNECT_CHANGE(port)) - wPortChange |= USB_PORT_STAT_C_CONNECTION; - - wPortStatus = USB_PORT_STAT_POWER; - if (!(status & PORT_SE0_STATUS(port))) - wPortStatus |= USB_PORT_STAT_CONNECTION; - if (usb_status & LOW_SPEED_PORT(port)) { - wPortStatus |= USB_PORT_STAT_LOW_SPEED; - c67x00->low_speed_ports |= (1 << port); - } else - c67x00->low_speed_ports &= ~(1 << port); - - if (usb_status & SOF_EOP_EN(port)) - wPortStatus |= USB_PORT_STAT_ENABLE; - - *(__le16 *) buf = cpu_to_le16(wPortStatus); - *(__le16 *) (buf + 2) = cpu_to_le16(wPortChange); - len = 4; - break; - - case SetHubFeature: /* We don't implement these */ - case ClearHubFeature: - switch (wValue) { - case C_HUB_OVER_CURRENT: - case C_HUB_LOCAL_POWER: - len = 0; - break; - - default: - return -EPIPE; - } - break; - - case SetPortFeature: - if (wIndex > C67X00_PORTS) - return -EPIPE; - - switch (wValue) { - case USB_PORT_FEAT_SUSPEND: - dev_dbg(c67x00_hcd_dev(c67x00), - "SetPortFeature %d (SUSPEND)\n", port); - len = 0; - break; - - case USB_PORT_FEAT_RESET: - c67x00_hub_reset_host_port(sie, port); - len = 0; - break; - - case USB_PORT_FEAT_POWER: - /* Power always enabled */ - len = 0; - break; - - default: - dev_dbg(c67x00_hcd_dev(c67x00), - "%s: SetPortFeature %d (0x%04x) Error!\n", - __func__, port, wValue); - return -EPIPE; - } - break; - - case ClearPortFeature: - if (wIndex > C67X00_PORTS) - return -EPIPE; - - switch (wValue) { - case USB_PORT_FEAT_ENABLE: - /* Reset the port so that the c67x00 also notices the - * disconnect */ - c67x00_hub_reset_host_port(sie, port); - len = 0; - break; - - case USB_PORT_FEAT_C_ENABLE: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): C_ENABLE\n", port); - len = 0; - break; - - case USB_PORT_FEAT_SUSPEND: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): SUSPEND\n", port); - len = 0; - break; - - case USB_PORT_FEAT_C_SUSPEND: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): C_SUSPEND\n", port); - len = 0; - break; - - case USB_PORT_FEAT_POWER: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): POWER\n", port); - return -EPIPE; - - case USB_PORT_FEAT_C_CONNECTION: - c67x00_ll_usb_clear_status(sie, - PORT_CONNECT_CHANGE(port)); - len = 0; - break; - - case USB_PORT_FEAT_C_OVER_CURRENT: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): OVER_CURRENT\n", port); - len = 0; - break; - - case USB_PORT_FEAT_C_RESET: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): C_RESET\n", port); - len = 0; - break; - - default: - dev_dbg(c67x00_hcd_dev(c67x00), - "%s: ClearPortFeature %d (0x%04x) Error!\n", - __func__, port, wValue); - return -EPIPE; - } - break; - - case GetHubDescriptor: - len = min_t(unsigned int, sizeof(c67x00_hub_des), wLength); - memcpy(buf, c67x00_hub_des, len); - break; - - default: - dev_dbg(c67x00_hcd_dev(c67x00), "%s: unknown\n", __func__); - return -EPIPE; - } - - return 0; -} - -/* --------------------------------------------------------------------- - * Main part of host controller driver - */ - -/** - * c67x00_hcd_irq - * - * This function is called from the interrupt handler in c67x00-drv.c - */ -static void c67x00_hcd_irq(struct c67x00_sie *sie, u16 int_status, u16 msg) -{ - struct c67x00_hcd *c67x00 = sie->private_data; - struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00); - - /* Handle sie message flags */ - if (msg) { - if (msg & HUSB_TDListDone) - c67x00_sched_kick(c67x00); - else - dev_warn(c67x00_hcd_dev(c67x00), - "Unknown SIE msg flag(s): 0x%04x\n", msg); - } - - if (unlikely(hcd->state == HC_STATE_HALT)) - return; - - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) - return; - - /* Handle Start of frame events */ - if (int_status & SOFEOP_FLG(sie->sie_num)) { - c67x00_ll_usb_clear_status(sie, SOF_EOP_IRQ_FLG); - c67x00_sched_kick(c67x00); - set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); - } -} - -/** - * c67x00_hcd_start: Host controller start hook - */ -static int c67x00_hcd_start(struct usb_hcd *hcd) -{ - hcd->uses_new_polling = 1; - hcd->state = HC_STATE_RUNNING; - hcd->poll_rh = 1; - - return 0; -} - -/** - * c67x00_hcd_stop: Host controller stop hook - */ -static void c67x00_hcd_stop(struct usb_hcd *hcd) -{ - /* Nothing to do */ -} - -static int c67x00_hcd_get_frame(struct usb_hcd *hcd) -{ - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - u16 temp_val; - - dev_dbg(c67x00_hcd_dev(c67x00), "%s\n", __func__); - temp_val = c67x00_ll_husb_get_frame(c67x00->sie); - temp_val &= HOST_FRAME_MASK; - return temp_val ? (temp_val - 1) : HOST_FRAME_MASK; -} - -static struct hc_driver c67x00_hc_driver = { - .description = "c67x00-hcd", - .product_desc = "Cypress C67X00 Host Controller", - .hcd_priv_size = sizeof(struct c67x00_hcd), - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = c67x00_hcd_start, - .stop = c67x00_hcd_stop, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = c67x00_urb_enqueue, - .urb_dequeue = c67x00_urb_dequeue, - .endpoint_disable = c67x00_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = c67x00_hcd_get_frame, - - /* - * root hub support - */ - .hub_status_data = c67x00_hub_status_data, - .hub_control = c67x00_hub_control, -}; - -/* --------------------------------------------------------------------- - * Setup/Teardown routines - */ - -int c67x00_hcd_probe(struct c67x00_sie *sie) -{ - struct c67x00_hcd *c67x00; - struct usb_hcd *hcd; - unsigned long flags; - int retval; - - if (usb_disabled()) - return -ENODEV; - - hcd = usb_create_hcd(&c67x00_hc_driver, sie_dev(sie), "c67x00_sie"); - if (!hcd) { - retval = -ENOMEM; - goto err0; - } - c67x00 = hcd_to_c67x00_hcd(hcd); - - spin_lock_init(&c67x00->lock); - c67x00->sie = sie; - - INIT_LIST_HEAD(&c67x00->list[PIPE_ISOCHRONOUS]); - INIT_LIST_HEAD(&c67x00->list[PIPE_INTERRUPT]); - INIT_LIST_HEAD(&c67x00->list[PIPE_CONTROL]); - INIT_LIST_HEAD(&c67x00->list[PIPE_BULK]); - c67x00->urb_count = 0; - INIT_LIST_HEAD(&c67x00->td_list); - c67x00->td_base_addr = CY_HCD_BUF_ADDR + SIE_TD_OFFSET(sie->sie_num); - c67x00->buf_base_addr = CY_HCD_BUF_ADDR + SIE_BUF_OFFSET(sie->sie_num); - c67x00->max_frame_bw = MAX_FRAME_BW_STD; - - c67x00_ll_husb_init_host_port(sie); - - init_completion(&c67x00->endpoint_disable); - retval = c67x00_sched_start_scheduler(c67x00); - if (retval) - goto err1; - - retval = usb_add_hcd(hcd, 0, 0); - if (retval) { - dev_dbg(sie_dev(sie), "%s: usb_add_hcd returned %d\n", - __func__, retval); - goto err2; - } - - spin_lock_irqsave(&sie->lock, flags); - sie->private_data = c67x00; - sie->irq = c67x00_hcd_irq; - spin_unlock_irqrestore(&sie->lock, flags); - - return retval; - - err2: - c67x00_sched_stop_scheduler(c67x00); - err1: - usb_put_hcd(hcd); - err0: - return retval; -} - -/* may be called with controller, bus, and devices active */ -void c67x00_hcd_remove(struct c67x00_sie *sie) -{ - struct c67x00_hcd *c67x00 = sie->private_data; - struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00); - - c67x00_sched_stop_scheduler(c67x00); - usb_remove_hcd(hcd); - usb_put_hcd(hcd); -} diff --git a/trunk/drivers/usb/c67x00/c67x00-hcd.h b/trunk/drivers/usb/c67x00/c67x00-hcd.h deleted file mode 100644 index e8c6d94b2514..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00-hcd.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * c67x00-hcd.h: Cypress C67X00 USB HCD - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#ifndef _USB_C67X00_HCD_H -#define _USB_C67X00_HCD_H - -#include -#include -#include -#include -#include "../core/hcd.h" -#include "c67x00.h" - -/* - * The following parameters depend on the CPU speed, bus speed, ... - * These can be tuned for specific use cases, e.g. if isochronous transfers - * are very important, bandwith can be sacrificed to guarantee that the - * 1ms deadline will be met. - * If bulk transfers are important, the MAX_FRAME_BW can be increased, - * but some (or many) isochronous deadlines might not be met. - * - * The values are specified in bittime. - */ - -/* - * The current implementation switches between _STD (default) and _ISO (when - * isochronous transfers are scheduled), in order to optimize the throughput - * in normal cicrumstances, but also provide good isochronous behaviour. - * - * Bandwidth is described in bit time so with a 12MHz USB clock and 1ms - * frames; there are 12000 bit times per frame. - */ - -#define TOTAL_FRAME_BW 12000 -#define DEFAULT_EOT 2250 - -#define MAX_FRAME_BW_STD (TOTAL_FRAME_BW - DEFAULT_EOT) -#define MAX_FRAME_BW_ISO 2400 - -/* - * Periodic transfers may only use 90% of the full frame, but as - * we currently don't even use 90% of the full frame, we may - * use the full usable time for periodic transfers. - */ -#define MAX_PERIODIC_BW(full_bw) full_bw - -/* -------------------------------------------------------------------------- */ - -struct c67x00_hcd { - spinlock_t lock; - struct c67x00_sie *sie; - unsigned int low_speed_ports; /* bitmask of low speed ports */ - unsigned int urb_count; - unsigned int urb_iso_count; - - struct list_head list[4]; /* iso, int, ctrl, bulk */ -#if PIPE_BULK != 3 -#error "Sanity check failed, this code presumes PIPE_... to range from 0 to 3" -#endif - - /* USB bandwidth allocated to td_list */ - int bandwidth_allocated; - /* USB bandwidth allocated for isoc/int transfer */ - int periodic_bw_allocated; - struct list_head td_list; - int max_frame_bw; - - u16 td_base_addr; - u16 buf_base_addr; - u16 next_td_addr; - u16 next_buf_addr; - - struct tasklet_struct tasklet; - - struct completion endpoint_disable; - - u16 current_frame; - u16 last_frame; -}; - -static inline struct c67x00_hcd *hcd_to_c67x00_hcd(struct usb_hcd *hcd) -{ - return (struct c67x00_hcd *)(hcd->hcd_priv); -} - -static inline struct usb_hcd *c67x00_hcd_to_hcd(struct c67x00_hcd *c67x00) -{ - return container_of((void *)c67x00, struct usb_hcd, hcd_priv); -} - -/* --------------------------------------------------------------------- - * Functions used by c67x00-drv - */ - -int c67x00_hcd_probe(struct c67x00_sie *sie); -void c67x00_hcd_remove(struct c67x00_sie *sie); - -/* --------------------------------------------------------------------- - * Transfer Descriptor scheduling functions - */ -int c67x00_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags); -int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); -void c67x00_endpoint_disable(struct usb_hcd *hcd, - struct usb_host_endpoint *ep); - -void c67x00_hcd_msg_received(struct c67x00_sie *sie, u16 msg); -void c67x00_sched_kick(struct c67x00_hcd *c67x00); -int c67x00_sched_start_scheduler(struct c67x00_hcd *c67x00); -void c67x00_sched_stop_scheduler(struct c67x00_hcd *c67x00); - -#define c67x00_hcd_dev(x) (c67x00_hcd_to_hcd(x)->self.controller) - -#endif /* _USB_C67X00_HCD_H */ diff --git a/trunk/drivers/usb/c67x00/c67x00-ll-hpi.c b/trunk/drivers/usb/c67x00/c67x00-ll-hpi.c deleted file mode 100644 index f3430b372f09..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00-ll-hpi.c +++ /dev/null @@ -1,480 +0,0 @@ -/* - * c67x00-ll-hpi.c: Cypress C67X00 USB Low level interface using HPI - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#include -#include -#include -#include "c67x00.h" - -#define COMM_REGS 14 - -struct c67x00_lcp_int_data { - u16 regs[COMM_REGS]; -}; - -/* -------------------------------------------------------------------------- */ -/* Interface definitions */ - -#define COMM_ACK 0x0FED -#define COMM_NAK 0xDEAD - -#define COMM_RESET 0xFA50 -#define COMM_EXEC_INT 0xCE01 -#define COMM_INT_NUM 0x01C2 - -/* Registers 0 to COMM_REGS-1 */ -#define COMM_R(x) (0x01C4 + 2 * (x)) - -#define HUSB_SIE_pCurrentTDPtr(x) ((x) ? 0x01B2 : 0x01B0) -#define HUSB_SIE_pTDListDone_Sem(x) ((x) ? 0x01B8 : 0x01B6) -#define HUSB_pEOT 0x01B4 - -/* Software interrupts */ -/* 114, 115: */ -#define HUSB_SIE_INIT_INT(x) ((x) ? 0x0073 : 0x0072) -#define HUSB_RESET_INT 0x0074 - -#define SUSB_INIT_INT 0x0071 -#define SUSB_INIT_INT_LOC (SUSB_INIT_INT * 2) - -/* ----------------------------------------------------------------------- - * HPI implementation - * - * The c67x00 chip also support control via SPI or HSS serial - * interfaces. However, this driver assumes that register access can - * be performed from IRQ context. While this is a safe assuption with - * the HPI interface, it is not true for the serial interfaces. - */ - -/* HPI registers */ -#define HPI_DATA 0 -#define HPI_MAILBOX 1 -#define HPI_ADDR 2 -#define HPI_STATUS 3 - -static inline u16 hpi_read_reg(struct c67x00_device *dev, int reg) -{ - return __raw_readw(dev->hpi.base + reg * dev->hpi.regstep); -} - -static inline void hpi_write_reg(struct c67x00_device *dev, int reg, u16 value) -{ - __raw_writew(value, dev->hpi.base + reg * dev->hpi.regstep); -} - -static inline u16 hpi_read_word_nolock(struct c67x00_device *dev, u16 reg) -{ - hpi_write_reg(dev, HPI_ADDR, reg); - return hpi_read_reg(dev, HPI_DATA); -} - -static u16 hpi_read_word(struct c67x00_device *dev, u16 reg) -{ - u16 value; - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - value = hpi_read_word_nolock(dev, reg); - spin_unlock_irqrestore(&dev->hpi.lock, flags); - - return value; -} - -static void hpi_write_word_nolock(struct c67x00_device *dev, u16 reg, u16 value) -{ - hpi_write_reg(dev, HPI_ADDR, reg); - hpi_write_reg(dev, HPI_DATA, value); -} - -static void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - hpi_write_word_nolock(dev, reg, value); - spin_unlock_irqrestore(&dev->hpi.lock, flags); -} - -/* - * Only data is little endian, addr has cpu endianess - */ -static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, - u16 *data, u16 count) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&dev->hpi.lock, flags); - - hpi_write_reg(dev, HPI_ADDR, addr); - for (i = 0; i < count; i++) - hpi_write_reg(dev, HPI_DATA, cpu_to_le16(*data++)); - - spin_unlock_irqrestore(&dev->hpi.lock, flags); -} - -/* - * Only data is little endian, addr has cpu endianess - */ -static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr, - u16 *data, u16 count) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&dev->hpi.lock, flags); - hpi_write_reg(dev, HPI_ADDR, addr); - for (i = 0; i < count; i++) - *data++ = le16_to_cpu(hpi_read_reg(dev, HPI_DATA)); - - spin_unlock_irqrestore(&dev->hpi.lock, flags); -} - -static void hpi_set_bits(struct c67x00_device *dev, u16 reg, u16 mask) -{ - u16 value; - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - value = hpi_read_word_nolock(dev, reg); - hpi_write_word_nolock(dev, reg, value | mask); - spin_unlock_irqrestore(&dev->hpi.lock, flags); -} - -static void hpi_clear_bits(struct c67x00_device *dev, u16 reg, u16 mask) -{ - u16 value; - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - value = hpi_read_word_nolock(dev, reg); - hpi_write_word_nolock(dev, reg, value & ~mask); - spin_unlock_irqrestore(&dev->hpi.lock, flags); -} - -static u16 hpi_recv_mbox(struct c67x00_device *dev) -{ - u16 value; - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - value = hpi_read_reg(dev, HPI_MAILBOX); - spin_unlock_irqrestore(&dev->hpi.lock, flags); - - return value; -} - -static u16 hpi_send_mbox(struct c67x00_device *dev, u16 value) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - hpi_write_reg(dev, HPI_MAILBOX, value); - spin_unlock_irqrestore(&dev->hpi.lock, flags); - - return value; -} - -u16 c67x00_ll_hpi_status(struct c67x00_device *dev) -{ - u16 value; - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - value = hpi_read_reg(dev, HPI_STATUS); - spin_unlock_irqrestore(&dev->hpi.lock, flags); - - return value; -} - -void c67x00_ll_hpi_reg_init(struct c67x00_device *dev) -{ - int i; - - hpi_recv_mbox(dev); - c67x00_ll_hpi_status(dev); - hpi_write_word(dev, HPI_IRQ_ROUTING_REG, 0); - - for (i = 0; i < C67X00_SIES; i++) { - hpi_write_word(dev, SIEMSG_REG(i), 0); - hpi_read_word(dev, SIEMSG_REG(i)); - } -} - -void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie) -{ - hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG, - SOFEOP_TO_HPI_EN(sie->sie_num)); -} - -void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie) -{ - hpi_clear_bits(sie->dev, HPI_IRQ_ROUTING_REG, - SOFEOP_TO_HPI_EN(sie->sie_num)); -} - -/* -------------------------------------------------------------------------- */ -/* Transactions */ - -static inline u16 ll_recv_msg(struct c67x00_device *dev) -{ - u16 res; - - res = wait_for_completion_timeout(&dev->hpi.lcp.msg_received, 5 * HZ); - WARN_ON(!res); - - return (res == 0) ? -EIO : 0; -} - -/* -------------------------------------------------------------------------- */ -/* General functions */ - -u16 c67x00_ll_fetch_siemsg(struct c67x00_device *dev, int sie_num) -{ - u16 val; - - val = hpi_read_word(dev, SIEMSG_REG(sie_num)); - /* clear register to allow next message */ - hpi_write_word(dev, SIEMSG_REG(sie_num), 0); - - return val; -} - -u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie) -{ - return hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)); -} - -/** - * c67x00_ll_usb_clear_status - clear the USB status bits - */ -void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits) -{ - hpi_write_word(sie->dev, USB_STAT_REG(sie->sie_num), bits); -} - -u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie) -{ - return hpi_read_word(sie->dev, USB_STAT_REG(sie->sie_num)); -} - -/* -------------------------------------------------------------------------- */ - -static int c67x00_comm_exec_int(struct c67x00_device *dev, u16 nr, - struct c67x00_lcp_int_data *data) -{ - int i, rc; - - mutex_lock(&dev->hpi.lcp.mutex); - hpi_write_word(dev, COMM_INT_NUM, nr); - for (i = 0; i < COMM_REGS; i++) - hpi_write_word(dev, COMM_R(i), data->regs[i]); - hpi_send_mbox(dev, COMM_EXEC_INT); - rc = ll_recv_msg(dev); - mutex_unlock(&dev->hpi.lcp.mutex); - - return rc; -} - -/* -------------------------------------------------------------------------- */ -/* Host specific functions */ - -void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value) -{ - mutex_lock(&dev->hpi.lcp.mutex); - hpi_write_word(dev, HUSB_pEOT, value); - mutex_unlock(&dev->hpi.lcp.mutex); -} - -static inline void c67x00_ll_husb_sie_init(struct c67x00_sie *sie) -{ - struct c67x00_device *dev = sie->dev; - struct c67x00_lcp_int_data data; - int rc; - - rc = c67x00_comm_exec_int(dev, HUSB_SIE_INIT_INT(sie->sie_num), &data); - BUG_ON(rc); /* No return path for error code; crash spectacularly */ -} - -void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port) -{ - struct c67x00_device *dev = sie->dev; - struct c67x00_lcp_int_data data; - int rc; - - data.regs[0] = 50; /* Reset USB port for 50ms */ - data.regs[1] = port | (sie->sie_num << 1); - rc = c67x00_comm_exec_int(dev, HUSB_RESET_INT, &data); - BUG_ON(rc); /* No return path for error code; crash spectacularly */ -} - -void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr) -{ - hpi_write_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num), addr); -} - -u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie) -{ - return hpi_read_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num)); -} - -u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie) -{ - return hpi_read_word(sie->dev, HOST_FRAME_REG(sie->sie_num)); -} - -void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie) -{ - /* Set port into host mode */ - hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), HOST_MODE); - c67x00_ll_husb_sie_init(sie); - /* Clear interrupts */ - c67x00_ll_usb_clear_status(sie, HOST_STAT_MASK); - /* Check */ - if (!(hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)) & HOST_MODE)) - dev_warn(sie_dev(sie), - "SIE %d not set to host mode\n", sie->sie_num); -} - -void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port) -{ - /* Clear connect change */ - c67x00_ll_usb_clear_status(sie, PORT_CONNECT_CHANGE(port)); - - /* Enable interrupts */ - hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG, - SOFEOP_TO_CPU_EN(sie->sie_num)); - hpi_set_bits(sie->dev, HOST_IRQ_EN_REG(sie->sie_num), - SOF_EOP_IRQ_EN | DONE_IRQ_EN); - - /* Enable pull down transistors */ - hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), PORT_RES_EN(port)); -} - -/* -------------------------------------------------------------------------- */ - -void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status) -{ - if ((int_status & MBX_OUT_FLG) == 0) - return; - - dev->hpi.lcp.last_msg = hpi_recv_mbox(dev); - complete(&dev->hpi.lcp.msg_received); -} - -/* -------------------------------------------------------------------------- */ - -int c67x00_ll_reset(struct c67x00_device *dev) -{ - int rc; - - mutex_lock(&dev->hpi.lcp.mutex); - hpi_send_mbox(dev, COMM_RESET); - rc = ll_recv_msg(dev); - mutex_unlock(&dev->hpi.lcp.mutex); - - return rc; -} - -/* -------------------------------------------------------------------------- */ - -/** - * c67x00_ll_write_mem_le16 - write into c67x00 memory - * Only data is little endian, addr has cpu endianess. - */ -void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr, - void *data, int len) -{ - u8 *buf = data; - - /* Sanity check */ - if (addr + len > 0xffff) { - dev_err(&dev->pdev->dev, - "Trying to write beyond writable region!\n"); - return; - } - - if (addr & 0x01) { - /* unaligned access */ - u16 tmp; - tmp = hpi_read_word(dev, addr - 1); - tmp = (tmp & 0x00ff) | (*buf++ << 8); - hpi_write_word(dev, addr - 1, tmp); - addr++; - len--; - } - - hpi_write_words_le16(dev, addr, (u16 *)buf, len / 2); - buf += len & ~0x01; - addr += len & ~0x01; - len &= 0x01; - - if (len) { - u16 tmp; - tmp = hpi_read_word(dev, addr); - tmp = (tmp & 0xff00) | *buf; - hpi_write_word(dev, addr, tmp); - } -} - -/** - * c67x00_ll_read_mem_le16 - read from c67x00 memory - * Only data is little endian, addr has cpu endianess. - */ -void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr, - void *data, int len) -{ - u8 *buf = data; - - if (addr & 0x01) { - /* unaligned access */ - u16 tmp; - tmp = hpi_read_word(dev, addr - 1); - *buf++ = (tmp >> 8) & 0x00ff; - addr++; - len--; - } - - hpi_read_words_le16(dev, addr, (u16 *)buf, len / 2); - buf += len & ~0x01; - addr += len & ~0x01; - len &= 0x01; - - if (len) { - u16 tmp; - tmp = hpi_read_word(dev, addr); - *buf = tmp & 0x00ff; - } -} - -/* -------------------------------------------------------------------------- */ - -void c67x00_ll_init(struct c67x00_device *dev) -{ - mutex_init(&dev->hpi.lcp.mutex); - init_completion(&dev->hpi.lcp.msg_received); -} - -void c67x00_ll_release(struct c67x00_device *dev) -{ -} diff --git a/trunk/drivers/usb/c67x00/c67x00-sched.c b/trunk/drivers/usb/c67x00/c67x00-sched.c deleted file mode 100644 index 85dfe2965661..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00-sched.c +++ /dev/null @@ -1,1170 +0,0 @@ -/* - * c67x00-sched.c: Cypress C67X00 USB Host Controller Driver - TD scheduling - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#include - -#include "c67x00.h" -#include "c67x00-hcd.h" - -/* - * These are the stages for a control urb, they are kept - * in both urb->interval and td->privdata. - */ -#define SETUP_STAGE 0 -#define DATA_STAGE 1 -#define STATUS_STAGE 2 - -/* -------------------------------------------------------------------------- */ - -/** - * struct c67x00_ep_data: Host endpoint data structure - */ -struct c67x00_ep_data { - struct list_head queue; - struct list_head node; - struct usb_host_endpoint *hep; - struct usb_device *dev; - u16 next_frame; /* For int/isoc transactions */ -}; - -/** - * struct c67x00_td - * - * Hardware parts are little endiannes, SW in CPU endianess. - */ -struct c67x00_td { - /* HW specific part */ - __le16 ly_base_addr; /* Bytes 0-1 */ - __le16 port_length; /* Bytes 2-3 */ - u8 pid_ep; /* Byte 4 */ - u8 dev_addr; /* Byte 5 */ - u8 ctrl_reg; /* Byte 6 */ - u8 status; /* Byte 7 */ - u8 retry_cnt; /* Byte 8 */ -#define TT_OFFSET 2 -#define TT_CONTROL 0 -#define TT_ISOCHRONOUS 1 -#define TT_BULK 2 -#define TT_INTERRUPT 3 - u8 residue; /* Byte 9 */ - __le16 next_td_addr; /* Bytes 10-11 */ - /* SW part */ - struct list_head td_list; - u16 td_addr; - void *data; - struct urb *urb; - unsigned long privdata; - - /* These are needed for handling the toggle bits: - * an urb can be dequeued while a td is in progress - * after checking the td, the toggle bit might need to - * be fixed */ - struct c67x00_ep_data *ep_data; - unsigned int pipe; -}; - -struct c67x00_urb_priv { - struct list_head hep_node; - struct urb *urb; - int port; - int cnt; /* packet number for isoc */ - int status; - struct c67x00_ep_data *ep_data; -}; - -#define td_udev(td) ((td)->ep_data->dev) - -#define CY_TD_SIZE 12 - -#define TD_PIDEP_OFFSET 0x04 -#define TD_PIDEPMASK_PID 0xF0 -#define TD_PIDEPMASK_EP 0x0F -#define TD_PORTLENMASK_DL 0x02FF -#define TD_PORTLENMASK_PN 0xC000 - -#define TD_STATUS_OFFSET 0x07 -#define TD_STATUSMASK_ACK 0x01 -#define TD_STATUSMASK_ERR 0x02 -#define TD_STATUSMASK_TMOUT 0x04 -#define TD_STATUSMASK_SEQ 0x08 -#define TD_STATUSMASK_SETUP 0x10 -#define TD_STATUSMASK_OVF 0x20 -#define TD_STATUSMASK_NAK 0x40 -#define TD_STATUSMASK_STALL 0x80 - -#define TD_ERROR_MASK (TD_STATUSMASK_ERR | TD_STATUSMASK_TMOUT | \ - TD_STATUSMASK_STALL) - -#define TD_RETRYCNT_OFFSET 0x08 -#define TD_RETRYCNTMASK_ACT_FLG 0x10 -#define TD_RETRYCNTMASK_TX_TYPE 0x0C -#define TD_RETRYCNTMASK_RTY_CNT 0x03 - -#define TD_RESIDUE_OVERFLOW 0x80 - -#define TD_PID_IN 0x90 - -/* Residue: signed 8bits, neg -> OVERFLOW, pos -> UNDERFLOW */ -#define td_residue(td) ((__s8)(td->residue)) -#define td_ly_base_addr(td) (__le16_to_cpu((td)->ly_base_addr)) -#define td_port_length(td) (__le16_to_cpu((td)->port_length)) -#define td_next_td_addr(td) (__le16_to_cpu((td)->next_td_addr)) - -#define td_active(td) ((td)->retry_cnt & TD_RETRYCNTMASK_ACT_FLG) -#define td_length(td) (td_port_length(td) & TD_PORTLENMASK_DL) - -#define td_sequence_ok(td) (!td->status || \ - (!(td->status & TD_STATUSMASK_SEQ) == \ - !(td->ctrl_reg & SEQ_SEL))) - -#define td_acked(td) (!td->status || \ - (td->status & TD_STATUSMASK_ACK)) -#define td_actual_bytes(td) (td_length(td) - td_residue(td)) - -/* -------------------------------------------------------------------------- */ - -#ifdef DEBUG - -/** - * dbg_td - Dump the contents of the TD - */ -static void dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg) -{ - struct device *dev = c67x00_hcd_dev(c67x00); - - dev_dbg(dev, "### %s at 0x%04x\n", msg, td->td_addr); - dev_dbg(dev, "urb: 0x%p\n", td->urb); - dev_dbg(dev, "endpoint: %4d\n", usb_pipeendpoint(td->pipe)); - dev_dbg(dev, "pipeout: %4d\n", usb_pipeout(td->pipe)); - dev_dbg(dev, "ly_base_addr: 0x%04x\n", td_ly_base_addr(td)); - dev_dbg(dev, "port_length: 0x%04x\n", td_port_length(td)); - dev_dbg(dev, "pid_ep: 0x%02x\n", td->pid_ep); - dev_dbg(dev, "dev_addr: 0x%02x\n", td->dev_addr); - dev_dbg(dev, "ctrl_reg: 0x%02x\n", td->ctrl_reg); - dev_dbg(dev, "status: 0x%02x\n", td->status); - dev_dbg(dev, "retry_cnt: 0x%02x\n", td->retry_cnt); - dev_dbg(dev, "residue: 0x%02x\n", td->residue); - dev_dbg(dev, "next_td_addr: 0x%04x\n", td_next_td_addr(td)); - dev_dbg(dev, "data:"); - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, - td->data, td_length(td), 1); -} -#else /* DEBUG */ - -static inline void -dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg) { } - -#endif /* DEBUG */ - -/* -------------------------------------------------------------------------- */ -/* Helper functions */ - -static inline u16 c67x00_get_current_frame_number(struct c67x00_hcd *c67x00) -{ - return c67x00_ll_husb_get_frame(c67x00->sie) & HOST_FRAME_MASK; -} - -/** - * frame_add - * Software wraparound for framenumbers. - */ -static inline u16 frame_add(u16 a, u16 b) -{ - return (a + b) & HOST_FRAME_MASK; -} - -/** - * frame_after - is frame a after frame b - */ -static inline int frame_after(u16 a, u16 b) -{ - return ((HOST_FRAME_MASK + a - b) & HOST_FRAME_MASK) < - (HOST_FRAME_MASK / 2); -} - -/** - * frame_after_eq - is frame a after or equal to frame b - */ -static inline int frame_after_eq(u16 a, u16 b) -{ - return ((HOST_FRAME_MASK + 1 + a - b) & HOST_FRAME_MASK) < - (HOST_FRAME_MASK / 2); -} - -/* -------------------------------------------------------------------------- */ - -/** - * c67x00_release_urb - remove link from all tds to this urb - * Disconnects the urb from it's tds, so that it can be given back. - * pre: urb->hcpriv != NULL - */ -static void c67x00_release_urb(struct c67x00_hcd *c67x00, struct urb *urb) -{ - struct c67x00_td *td; - struct c67x00_urb_priv *urbp; - - BUG_ON(!urb); - - c67x00->urb_count--; - - if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { - c67x00->urb_iso_count--; - if (c67x00->urb_iso_count == 0) - c67x00->max_frame_bw = MAX_FRAME_BW_STD; - } - - /* TODO this might be not so efficient when we've got many urbs! - * Alternatives: - * * only clear when needed - * * keep a list of tds with each urbp - */ - list_for_each_entry(td, &c67x00->td_list, td_list) - if (urb == td->urb) - td->urb = NULL; - - urbp = urb->hcpriv; - urb->hcpriv = NULL; - list_del(&urbp->hep_node); - kfree(urbp); -} - -/* -------------------------------------------------------------------------- */ - -static struct c67x00_ep_data * -c67x00_ep_data_alloc(struct c67x00_hcd *c67x00, struct urb *urb) -{ - struct usb_host_endpoint *hep = urb->ep; - struct c67x00_ep_data *ep_data; - int type; - - c67x00->current_frame = c67x00_get_current_frame_number(c67x00); - - /* Check if endpoint already has a c67x00_ep_data struct allocated */ - if (hep->hcpriv) { - ep_data = hep->hcpriv; - if (frame_after(c67x00->current_frame, ep_data->next_frame)) - ep_data->next_frame = - frame_add(c67x00->current_frame, 1); - return hep->hcpriv; - } - - /* Allocate and initialize a new c67x00 endpoint data structure */ - ep_data = kzalloc(sizeof(*ep_data), GFP_ATOMIC); - if (!ep_data) - return NULL; - - INIT_LIST_HEAD(&ep_data->queue); - INIT_LIST_HEAD(&ep_data->node); - ep_data->hep = hep; - - /* hold a reference to udev as long as this endpoint lives, - * this is needed to possibly fix the data toggle */ - ep_data->dev = usb_get_dev(urb->dev); - hep->hcpriv = ep_data; - - /* For ISOC and INT endpoints, start ASAP: */ - ep_data->next_frame = frame_add(c67x00->current_frame, 1); - - /* Add the endpoint data to one of the pipe lists; must be added - in order of endpoint address */ - type = usb_pipetype(urb->pipe); - if (list_empty(&ep_data->node)) { - list_add(&ep_data->node, &c67x00->list[type]); - } else { - struct c67x00_ep_data *prev; - - list_for_each_entry(prev, &c67x00->list[type], node) { - if (prev->hep->desc.bEndpointAddress > - hep->desc.bEndpointAddress) { - list_add(&ep_data->node, prev->node.prev); - break; - } - } - } - - return ep_data; -} - -static int c67x00_ep_data_free(struct usb_host_endpoint *hep) -{ - struct c67x00_ep_data *ep_data = hep->hcpriv; - - if (!ep_data) - return 0; - - if (!list_empty(&ep_data->queue)) - return -EBUSY; - - usb_put_dev(ep_data->dev); - list_del(&ep_data->queue); - list_del(&ep_data->node); - - kfree(ep_data); - hep->hcpriv = NULL; - - return 0; -} - -void c67x00_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep) -{ - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - unsigned long flags; - - if (!list_empty(&ep->urb_list)) - dev_warn(c67x00_hcd_dev(c67x00), "error: urb list not empty\n"); - - spin_lock_irqsave(&c67x00->lock, flags); - - /* loop waiting for all transfers in the endpoint queue to complete */ - while (c67x00_ep_data_free(ep)) { - /* Drop the lock so we can sleep waiting for the hardware */ - spin_unlock_irqrestore(&c67x00->lock, flags); - - /* it could happen that we reinitialize this completion, while - * somebody was waiting for that completion. The timeout and - * while loop handle such cases, but this might be improved */ - INIT_COMPLETION(c67x00->endpoint_disable); - c67x00_sched_kick(c67x00); - wait_for_completion_timeout(&c67x00->endpoint_disable, 1 * HZ); - - spin_lock_irqsave(&c67x00->lock, flags); - } - - spin_unlock_irqrestore(&c67x00->lock, flags); -} - -/* -------------------------------------------------------------------------- */ - -static inline int get_root_port(struct usb_device *dev) -{ - while (dev->parent->parent) - dev = dev->parent; - return dev->portnum; -} - -int c67x00_urb_enqueue(struct usb_hcd *hcd, - struct urb *urb, gfp_t mem_flags) -{ - int ret; - unsigned long flags; - struct c67x00_urb_priv *urbp; - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - int port = get_root_port(urb->dev)-1; - - spin_lock_irqsave(&c67x00->lock, flags); - - /* Make sure host controller is running */ - if (!HC_IS_RUNNING(hcd->state)) { - ret = -ENODEV; - goto err_not_linked; - } - - ret = usb_hcd_link_urb_to_ep(hcd, urb); - if (ret) - goto err_not_linked; - - /* Allocate and initialize urb private data */ - urbp = kzalloc(sizeof(*urbp), mem_flags); - if (!urbp) { - ret = -ENOMEM; - goto err_urbp; - } - - INIT_LIST_HEAD(&urbp->hep_node); - urbp->urb = urb; - urbp->port = port; - - urbp->ep_data = c67x00_ep_data_alloc(c67x00, urb); - - if (!urbp->ep_data) { - ret = -ENOMEM; - goto err_epdata; - } - - /* TODO claim bandwidth with usb_claim_bandwidth? - * also release it somewhere! */ - - urb->hcpriv = urbp; - - urb->actual_length = 0; /* Nothing received/transmitted yet */ - - switch (usb_pipetype(urb->pipe)) { - case PIPE_CONTROL: - urb->interval = SETUP_STAGE; - break; - case PIPE_INTERRUPT: - break; - case PIPE_BULK: - break; - case PIPE_ISOCHRONOUS: - if (c67x00->urb_iso_count == 0) - c67x00->max_frame_bw = MAX_FRAME_BW_ISO; - c67x00->urb_iso_count++; - /* Assume always URB_ISO_ASAP, FIXME */ - if (list_empty(&urbp->ep_data->queue)) - urb->start_frame = urbp->ep_data->next_frame; - else { - /* Go right after the last one */ - struct urb *last_urb; - - last_urb = list_entry(urbp->ep_data->queue.prev, - struct c67x00_urb_priv, - hep_node)->urb; - urb->start_frame = - frame_add(last_urb->start_frame, - last_urb->number_of_packets * - last_urb->interval); - } - urbp->cnt = 0; - break; - } - - /* Add the URB to the endpoint queue */ - list_add_tail(&urbp->hep_node, &urbp->ep_data->queue); - - /* If this is the only URB, kick start the controller */ - if (!c67x00->urb_count++) - c67x00_ll_hpi_enable_sofeop(c67x00->sie); - - c67x00_sched_kick(c67x00); - spin_unlock_irqrestore(&c67x00->lock, flags); - - return 0; - -err_epdata: - kfree(urbp); -err_urbp: - usb_hcd_unlink_urb_from_ep(hcd, urb); -err_not_linked: - spin_unlock_irqrestore(&c67x00->lock, flags); - - return ret; -} - -int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) -{ - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - unsigned long flags; - int rc; - - spin_lock_irqsave(&c67x00->lock, flags); - rc = usb_hcd_check_unlink_urb(hcd, urb, status); - if (rc) - goto done; - - c67x00_release_urb(c67x00, urb); - usb_hcd_unlink_urb_from_ep(hcd, urb); - - spin_unlock(&c67x00->lock); - usb_hcd_giveback_urb(hcd, urb, status); - spin_lock(&c67x00->lock); - - spin_unlock_irqrestore(&c67x00->lock, flags); - - return 0; - - done: - spin_unlock_irqrestore(&c67x00->lock, flags); - return rc; -} - -/* -------------------------------------------------------------------------- */ - -/* - * pre: c67x00 locked, urb unlocked - */ -static void -c67x00_giveback_urb(struct c67x00_hcd *c67x00, struct urb *urb, int status) -{ - struct c67x00_urb_priv *urbp; - - if (!urb) - return; - - urbp = urb->hcpriv; - urbp->status = status; - - list_del_init(&urbp->hep_node); - - c67x00_release_urb(c67x00, urb); - usb_hcd_unlink_urb_from_ep(c67x00_hcd_to_hcd(c67x00), urb); - spin_unlock(&c67x00->lock); - usb_hcd_giveback_urb(c67x00_hcd_to_hcd(c67x00), urb, urbp->status); - spin_lock(&c67x00->lock); -} - -/* -------------------------------------------------------------------------- */ - -static int c67x00_claim_frame_bw(struct c67x00_hcd *c67x00, struct urb *urb, - int len, int periodic) -{ - struct c67x00_urb_priv *urbp = urb->hcpriv; - int bit_time; - - /* According to the C67x00 BIOS user manual, page 3-18,19, the - * following calculations provide the full speed bit times for - * a transaction. - * - * FS(in) = 112.5 + 9.36*BC + HOST_DELAY - * FS(in,iso) = 90.5 + 9.36*BC + HOST_DELAY - * FS(out) = 112.5 + 9.36*BC + HOST_DELAY - * FS(out,iso) = 78.4 + 9.36*BC + HOST_DELAY - * LS(in) = 802.4 + 75.78*BC + HOST_DELAY - * LS(out) = 802.6 + 74.67*BC + HOST_DELAY - * - * HOST_DELAY == 106 for the c67200 and c67300. - */ - - /* make calculations in 1/100 bit times to maintain resolution */ - if (urbp->ep_data->dev->speed == USB_SPEED_LOW) { - /* Low speed pipe */ - if (usb_pipein(urb->pipe)) - bit_time = 80240 + 7578*len; - else - bit_time = 80260 + 7467*len; - } else { - /* FS pipes */ - if (usb_pipeisoc(urb->pipe)) - bit_time = usb_pipein(urb->pipe) ? 9050 : 7840; - else - bit_time = 11250; - bit_time += 936*len; - } - - /* Scale back down to integer bit times. Use a host delay of 106. - * (this is the only place it is used) */ - bit_time = ((bit_time+50) / 100) + 106; - - if (unlikely(bit_time + c67x00->bandwidth_allocated >= - c67x00->max_frame_bw)) - return -EMSGSIZE; - - if (unlikely(c67x00->next_td_addr + CY_TD_SIZE >= - c67x00->td_base_addr + SIE_TD_SIZE)) - return -EMSGSIZE; - - if (unlikely(c67x00->next_buf_addr + len >= - c67x00->buf_base_addr + SIE_TD_BUF_SIZE)) - return -EMSGSIZE; - - if (periodic) { - if (unlikely(bit_time + c67x00->periodic_bw_allocated >= - MAX_PERIODIC_BW(c67x00->max_frame_bw))) - return -EMSGSIZE; - c67x00->periodic_bw_allocated += bit_time; - } - - c67x00->bandwidth_allocated += bit_time; - return 0; -} - -/* -------------------------------------------------------------------------- */ - -/** - * td_addr and buf_addr must be word aligned - */ -static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb, - void *data, int len, int pid, int toggle, - unsigned long privdata) -{ - struct c67x00_td *td; - struct c67x00_urb_priv *urbp = urb->hcpriv; - const __u8 active_flag = 1, retry_cnt = 1; - __u8 cmd = 0; - int tt = 0; - - if (c67x00_claim_frame_bw(c67x00, urb, len, usb_pipeisoc(urb->pipe) - || usb_pipeint(urb->pipe))) - return -EMSGSIZE; /* Not really an error, but expected */ - - td = kzalloc(sizeof(*td), GFP_ATOMIC); - if (!td) - return -ENOMEM; - - td->pipe = urb->pipe; - td->ep_data = urbp->ep_data; - - if ((td_udev(td)->speed == USB_SPEED_LOW) && - !(c67x00->low_speed_ports & (1 << urbp->port))) - cmd |= PREAMBLE_EN; - - switch (usb_pipetype(td->pipe)) { - case PIPE_ISOCHRONOUS: - tt = TT_ISOCHRONOUS; - cmd |= ISO_EN; - break; - case PIPE_CONTROL: - tt = TT_CONTROL; - break; - case PIPE_BULK: - tt = TT_BULK; - break; - case PIPE_INTERRUPT: - tt = TT_INTERRUPT; - break; - } - - if (toggle) - cmd |= SEQ_SEL; - - cmd |= ARM_EN; - - /* SW part */ - td->td_addr = c67x00->next_td_addr; - c67x00->next_td_addr = c67x00->next_td_addr + CY_TD_SIZE; - - /* HW part */ - td->ly_base_addr = __cpu_to_le16(c67x00->next_buf_addr); - td->port_length = __cpu_to_le16((c67x00->sie->sie_num << 15) | - (urbp->port << 14) | (len & 0x3FF)); - td->pid_ep = ((pid & 0xF) << TD_PIDEP_OFFSET) | - (usb_pipeendpoint(td->pipe) & 0xF); - td->dev_addr = usb_pipedevice(td->pipe) & 0x7F; - td->ctrl_reg = cmd; - td->status = 0; - td->retry_cnt = (tt << TT_OFFSET) | (active_flag << 4) | retry_cnt; - td->residue = 0; - td->next_td_addr = __cpu_to_le16(c67x00->next_td_addr); - - /* SW part */ - td->data = data; - td->urb = urb; - td->privdata = privdata; - - c67x00->next_buf_addr += (len + 1) & ~0x01; /* properly align */ - - list_add_tail(&td->td_list, &c67x00->td_list); - return 0; -} - -static inline void c67x00_release_td(struct c67x00_td *td) -{ - list_del_init(&td->td_list); - kfree(td); -} - -/* -------------------------------------------------------------------------- */ - -static int c67x00_add_data_urb(struct c67x00_hcd *c67x00, struct urb *urb) -{ - int remaining; - int toggle; - int pid; - int ret = 0; - int maxps; - int need_empty; - - toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), - usb_pipeout(urb->pipe)); - remaining = urb->transfer_buffer_length - urb->actual_length; - - maxps = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); - - need_empty = (urb->transfer_flags & URB_ZERO_PACKET) && - usb_pipeout(urb->pipe) && !(remaining % maxps); - - while (remaining || need_empty) { - int len; - char *td_buf; - - len = (remaining > maxps) ? maxps : remaining; - if (!len) - need_empty = 0; - - pid = usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN; - td_buf = urb->transfer_buffer + urb->transfer_buffer_length - - remaining; - ret = c67x00_create_td(c67x00, urb, td_buf, len, pid, toggle, - DATA_STAGE); - if (ret) - return ret; /* td wasn't created */ - - toggle ^= 1; - remaining -= len; - if (usb_pipecontrol(urb->pipe)) - break; - } - - return 0; -} - -/** - * return 0 in case more bandwidth is available, else errorcode - */ -static int c67x00_add_ctrl_urb(struct c67x00_hcd *c67x00, struct urb *urb) -{ - int ret; - int pid; - - switch (urb->interval) { - default: - case SETUP_STAGE: - ret = c67x00_create_td(c67x00, urb, urb->setup_packet, - 8, USB_PID_SETUP, 0, SETUP_STAGE); - if (ret) - return ret; - urb->interval = SETUP_STAGE; - usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), - usb_pipeout(urb->pipe), 1); - break; - case DATA_STAGE: - if (urb->transfer_buffer_length) { - ret = c67x00_add_data_urb(c67x00, urb); - if (ret) - return ret; - break; - } /* else fallthrough */ - case STATUS_STAGE: - pid = !usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN; - ret = c67x00_create_td(c67x00, urb, NULL, 0, pid, 1, - STATUS_STAGE); - if (ret) - return ret; - break; - } - - return 0; -} - -/* - * return 0 in case more bandwidth is available, else errorcode - */ -static int c67x00_add_int_urb(struct c67x00_hcd *c67x00, struct urb *urb) -{ - struct c67x00_urb_priv *urbp = urb->hcpriv; - - if (frame_after_eq(c67x00->current_frame, urbp->ep_data->next_frame)) { - urbp->ep_data->next_frame = - frame_add(urbp->ep_data->next_frame, urb->interval); - return c67x00_add_data_urb(c67x00, urb); - } - return 0; -} - -static int c67x00_add_iso_urb(struct c67x00_hcd *c67x00, struct urb *urb) -{ - struct c67x00_urb_priv *urbp = urb->hcpriv; - - if (frame_after_eq(c67x00->current_frame, urbp->ep_data->next_frame)) { - char *td_buf; - int len, pid, ret; - - BUG_ON(urbp->cnt >= urb->number_of_packets); - - td_buf = urb->transfer_buffer + - urb->iso_frame_desc[urbp->cnt].offset; - len = urb->iso_frame_desc[urbp->cnt].length; - pid = usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN; - - ret = c67x00_create_td(c67x00, urb, td_buf, len, pid, 0, - urbp->cnt); - if (ret) { - printk(KERN_DEBUG "create failed: %d\n", ret); - urb->iso_frame_desc[urbp->cnt].actual_length = 0; - urb->iso_frame_desc[urbp->cnt].status = ret; - if (urbp->cnt + 1 == urb->number_of_packets) - c67x00_giveback_urb(c67x00, urb, 0); - } - - urbp->ep_data->next_frame = - frame_add(urbp->ep_data->next_frame, urb->interval); - urbp->cnt++; - } - return 0; -} - -/* -------------------------------------------------------------------------- */ - -static void c67x00_fill_from_list(struct c67x00_hcd *c67x00, int type, - int (*add)(struct c67x00_hcd *, struct urb *)) -{ - struct c67x00_ep_data *ep_data; - struct urb *urb; - - /* traverse every endpoint on the list */ - list_for_each_entry(ep_data, &c67x00->list[type], node) { - if (!list_empty(&ep_data->queue)) { - /* and add the first urb */ - /* isochronous transfer rely on this */ - urb = list_entry(ep_data->queue.next, - struct c67x00_urb_priv, - hep_node)->urb; - add(c67x00, urb); - } - } -} - -static void c67x00_fill_frame(struct c67x00_hcd *c67x00) -{ - struct c67x00_td *td, *ttd; - - /* Check if we can proceed */ - if (!list_empty(&c67x00->td_list)) { - dev_warn(c67x00_hcd_dev(c67x00), - "TD list not empty! This should not happen!\n"); - list_for_each_entry_safe(td, ttd, &c67x00->td_list, td_list) { - dbg_td(c67x00, td, "Unprocessed td"); - c67x00_release_td(td); - } - } - - /* Reinitialize variables */ - c67x00->bandwidth_allocated = 0; - c67x00->periodic_bw_allocated = 0; - - c67x00->next_td_addr = c67x00->td_base_addr; - c67x00->next_buf_addr = c67x00->buf_base_addr; - - /* Fill the list */ - c67x00_fill_from_list(c67x00, PIPE_ISOCHRONOUS, c67x00_add_iso_urb); - c67x00_fill_from_list(c67x00, PIPE_INTERRUPT, c67x00_add_int_urb); - c67x00_fill_from_list(c67x00, PIPE_CONTROL, c67x00_add_ctrl_urb); - c67x00_fill_from_list(c67x00, PIPE_BULK, c67x00_add_data_urb); -} - -/* -------------------------------------------------------------------------- */ - -/** - * Get TD from C67X00 - */ -static inline void -c67x00_parse_td(struct c67x00_hcd *c67x00, struct c67x00_td *td) -{ - c67x00_ll_read_mem_le16(c67x00->sie->dev, - td->td_addr, td, CY_TD_SIZE); - - if (usb_pipein(td->pipe) && td_actual_bytes(td)) - c67x00_ll_read_mem_le16(c67x00->sie->dev, td_ly_base_addr(td), - td->data, td_actual_bytes(td)); -} - -static int c67x00_td_to_error(struct c67x00_hcd *c67x00, struct c67x00_td *td) -{ - if (td->status & TD_STATUSMASK_ERR) { - dbg_td(c67x00, td, "ERROR_FLAG"); - return -EILSEQ; - } - if (td->status & TD_STATUSMASK_STALL) { - /* dbg_td(c67x00, td, "STALL"); */ - return -EPIPE; - } - if (td->status & TD_STATUSMASK_TMOUT) { - dbg_td(c67x00, td, "TIMEOUT"); - return -ETIMEDOUT; - } - - return 0; -} - -static inline int c67x00_end_of_data(struct c67x00_td *td) -{ - int maxps, need_empty, remaining; - struct urb *urb = td->urb; - int act_bytes; - - act_bytes = td_actual_bytes(td); - - if (unlikely(!act_bytes)) - return 1; /* This was an empty packet */ - - maxps = usb_maxpacket(td_udev(td), td->pipe, usb_pipeout(td->pipe)); - - if (unlikely(act_bytes < maxps)) - return 1; /* Smaller then full packet */ - - remaining = urb->transfer_buffer_length - urb->actual_length; - need_empty = (urb->transfer_flags & URB_ZERO_PACKET) && - usb_pipeout(urb->pipe) && !(remaining % maxps); - - if (unlikely(!remaining && !need_empty)) - return 1; - - return 0; -} - -/* -------------------------------------------------------------------------- */ - -/* Remove all td's from the list which come - * after last_td and are meant for the same pipe. - * This is used when a short packet has occured */ -static inline void c67x00_clear_pipe(struct c67x00_hcd *c67x00, - struct c67x00_td *last_td) -{ - struct c67x00_td *td, *tmp; - td = last_td; - tmp = last_td; - while (td->td_list.next != &c67x00->td_list) { - td = list_entry(td->td_list.next, struct c67x00_td, td_list); - if (td->pipe == last_td->pipe) { - c67x00_release_td(td); - td = tmp; - } - tmp = td; - } -} - -/* -------------------------------------------------------------------------- */ - -static void c67x00_handle_successful_td(struct c67x00_hcd *c67x00, - struct c67x00_td *td) -{ - struct urb *urb = td->urb; - - if (!urb) - return; - - urb->actual_length += td_actual_bytes(td); - - switch (usb_pipetype(td->pipe)) { - /* isochronous tds are handled separately */ - case PIPE_CONTROL: - switch (td->privdata) { - case SETUP_STAGE: - urb->interval = - urb->transfer_buffer_length ? - DATA_STAGE : STATUS_STAGE; - /* Don't count setup_packet with normal data: */ - urb->actual_length = 0; - break; - - case DATA_STAGE: - if (c67x00_end_of_data(td)) { - urb->interval = STATUS_STAGE; - c67x00_clear_pipe(c67x00, td); - } - break; - - case STATUS_STAGE: - urb->interval = 0; - c67x00_giveback_urb(c67x00, urb, 0); - break; - } - break; - - case PIPE_INTERRUPT: - case PIPE_BULK: - if (unlikely(c67x00_end_of_data(td))) { - c67x00_clear_pipe(c67x00, td); - c67x00_giveback_urb(c67x00, urb, 0); - } - break; - } -} - -static void c67x00_handle_isoc(struct c67x00_hcd *c67x00, struct c67x00_td *td) -{ - struct urb *urb = td->urb; - struct c67x00_urb_priv *urbp; - int cnt; - - if (!urb) - return; - - urbp = urb->hcpriv; - cnt = td->privdata; - - if (td->status & TD_ERROR_MASK) - urb->error_count++; - - urb->iso_frame_desc[cnt].actual_length = td_actual_bytes(td); - urb->iso_frame_desc[cnt].status = c67x00_td_to_error(c67x00, td); - if (cnt + 1 == urb->number_of_packets) /* Last packet */ - c67x00_giveback_urb(c67x00, urb, 0); -} - -/* -------------------------------------------------------------------------- */ - -/** - * c67x00_check_td_list - handle tds which have been processed by the c67x00 - * pre: current_td == 0 - */ -static inline void c67x00_check_td_list(struct c67x00_hcd *c67x00) -{ - struct c67x00_td *td, *tmp; - struct urb *urb; - int ack_ok; - int clear_endpoint; - - list_for_each_entry_safe(td, tmp, &c67x00->td_list, td_list) { - /* get the TD */ - c67x00_parse_td(c67x00, td); - urb = td->urb; /* urb can be NULL! */ - ack_ok = 0; - clear_endpoint = 1; - - /* Handle isochronous transfers separately */ - if (usb_pipeisoc(td->pipe)) { - clear_endpoint = 0; - c67x00_handle_isoc(c67x00, td); - goto cont; - } - - /* When an error occurs, all td's for that pipe go into an - * inactive state. This state matches successful transfers so - * we must make sure not to service them. */ - if (td->status & TD_ERROR_MASK) { - c67x00_giveback_urb(c67x00, urb, - c67x00_td_to_error(c67x00, td)); - goto cont; - } - - if ((td->status & TD_STATUSMASK_NAK) || !td_sequence_ok(td) || - !td_acked(td)) - goto cont; - - /* Sequence ok and acked, don't need to fix toggle */ - ack_ok = 1; - - if (unlikely(td->status & TD_STATUSMASK_OVF)) { - if (td_residue(td) & TD_RESIDUE_OVERFLOW) { - /* Overflow */ - c67x00_giveback_urb(c67x00, urb, -EOVERFLOW); - goto cont; - } - } - - clear_endpoint = 0; - c67x00_handle_successful_td(c67x00, td); - -cont: - if (clear_endpoint) - c67x00_clear_pipe(c67x00, td); - if (ack_ok) - usb_settoggle(td_udev(td), usb_pipeendpoint(td->pipe), - usb_pipeout(td->pipe), - !(td->ctrl_reg & SEQ_SEL)); - /* next in list could have been removed, due to clear_pipe! */ - tmp = list_entry(td->td_list.next, typeof(*td), td_list); - c67x00_release_td(td); - } -} - -/* -------------------------------------------------------------------------- */ - -static inline int c67x00_all_tds_processed(struct c67x00_hcd *c67x00) -{ - /* If all tds are processed, we can check the previous frame (if - * there was any) and start our next frame. - */ - return !c67x00_ll_husb_get_current_td(c67x00->sie); -} - -/** - * Send td to C67X00 - */ -static void c67x00_send_td(struct c67x00_hcd *c67x00, struct c67x00_td *td) -{ - int len = td_length(td); - - if (len && ((td->pid_ep & TD_PIDEPMASK_PID) != TD_PID_IN)) - c67x00_ll_write_mem_le16(c67x00->sie->dev, td_ly_base_addr(td), - td->data, len); - - c67x00_ll_write_mem_le16(c67x00->sie->dev, - td->td_addr, td, CY_TD_SIZE); -} - -static void c67x00_send_frame(struct c67x00_hcd *c67x00) -{ - struct c67x00_td *td; - - if (list_empty(&c67x00->td_list)) - dev_warn(c67x00_hcd_dev(c67x00), - "%s: td list should not be empty here!\n", - __func__); - - list_for_each_entry(td, &c67x00->td_list, td_list) { - if (td->td_list.next == &c67x00->td_list) - td->next_td_addr = 0; /* Last td in list */ - - c67x00_send_td(c67x00, td); - } - - c67x00_ll_husb_set_current_td(c67x00->sie, c67x00->td_base_addr); -} - -/* -------------------------------------------------------------------------- */ - -/** - * c67x00_do_work - Schedulers state machine - */ -static void c67x00_do_work(struct c67x00_hcd *c67x00) -{ - spin_lock(&c67x00->lock); - /* Make sure all tds are processed */ - if (!c67x00_all_tds_processed(c67x00)) - goto out; - - c67x00_check_td_list(c67x00); - - /* no td's are being processed (current == 0) - * and all have been "checked" */ - complete(&c67x00->endpoint_disable); - - if (!list_empty(&c67x00->td_list)) - goto out; - - c67x00->current_frame = c67x00_get_current_frame_number(c67x00); - if (c67x00->current_frame == c67x00->last_frame) - goto out; /* Don't send tds in same frame */ - c67x00->last_frame = c67x00->current_frame; - - /* If no urbs are scheduled, our work is done */ - if (!c67x00->urb_count) { - c67x00_ll_hpi_disable_sofeop(c67x00->sie); - goto out; - } - - c67x00_fill_frame(c67x00); - if (!list_empty(&c67x00->td_list)) - /* TD's have been added to the frame */ - c67x00_send_frame(c67x00); - - out: - spin_unlock(&c67x00->lock); -} - -/* -------------------------------------------------------------------------- */ - -static void c67x00_sched_tasklet(unsigned long __c67x00) -{ - struct c67x00_hcd *c67x00 = (struct c67x00_hcd *)__c67x00; - c67x00_do_work(c67x00); -} - -void c67x00_sched_kick(struct c67x00_hcd *c67x00) -{ - tasklet_hi_schedule(&c67x00->tasklet); -} - -int c67x00_sched_start_scheduler(struct c67x00_hcd *c67x00) -{ - tasklet_init(&c67x00->tasklet, c67x00_sched_tasklet, - (unsigned long)c67x00); - return 0; -} - -void c67x00_sched_stop_scheduler(struct c67x00_hcd *c67x00) -{ - tasklet_kill(&c67x00->tasklet); -} diff --git a/trunk/drivers/usb/c67x00/c67x00.h b/trunk/drivers/usb/c67x00/c67x00.h deleted file mode 100644 index a26e9ded0f32..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * c67x00.h: Cypress C67X00 USB register and field definitions - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#ifndef _USB_C67X00_H -#define _USB_C67X00_H - -#include -#include -#include -#include - -/* --------------------------------------------------------------------- - * Cypress C67x00 register definitions - */ - -/* Hardware Revision Register */ -#define HW_REV_REG 0xC004 - -/* General USB registers */ -/* ===================== */ - -/* USB Control Register */ -#define USB_CTL_REG(x) ((x) ? 0xC0AA : 0xC08A) - -#define LOW_SPEED_PORT(x) ((x) ? 0x0800 : 0x0400) -#define HOST_MODE 0x0200 -#define PORT_RES_EN(x) ((x) ? 0x0100 : 0x0080) -#define SOF_EOP_EN(x) ((x) ? 0x0002 : 0x0001) - -/* USB status register - Notice it has different content in hcd/udc mode */ -#define USB_STAT_REG(x) ((x) ? 0xC0B0 : 0xC090) - -#define EP0_IRQ_FLG 0x0001 -#define EP1_IRQ_FLG 0x0002 -#define EP2_IRQ_FLG 0x0004 -#define EP3_IRQ_FLG 0x0008 -#define EP4_IRQ_FLG 0x0010 -#define EP5_IRQ_FLG 0x0020 -#define EP6_IRQ_FLG 0x0040 -#define EP7_IRQ_FLG 0x0080 -#define RESET_IRQ_FLG 0x0100 -#define SOF_EOP_IRQ_FLG 0x0200 -#define ID_IRQ_FLG 0x4000 -#define VBUS_IRQ_FLG 0x8000 - -/* USB Host only registers */ -/* ======================= */ - -/* Host n Control Register */ -#define HOST_CTL_REG(x) ((x) ? 0xC0A0 : 0xC080) - -#define PREAMBLE_EN 0x0080 /* Preamble enable */ -#define SEQ_SEL 0x0040 /* Data Toggle Sequence Bit Select */ -#define ISO_EN 0x0010 /* Isochronous enable */ -#define ARM_EN 0x0001 /* Arm operation */ - -/* Host n Interrupt Enable Register */ -#define HOST_IRQ_EN_REG(x) ((x) ? 0xC0AC : 0xC08C) - -#define SOF_EOP_IRQ_EN 0x0200 /* SOF/EOP Interrupt Enable */ -#define SOF_EOP_TMOUT_IRQ_EN 0x0800 /* SOF/EOP Timeout Interrupt Enable */ -#define ID_IRQ_EN 0x4000 /* ID interrupt enable */ -#define VBUS_IRQ_EN 0x8000 /* VBUS interrupt enable */ -#define DONE_IRQ_EN 0x0001 /* Done Interrupt Enable */ - -/* USB status register */ -#define HOST_STAT_MASK 0x02FD -#define PORT_CONNECT_CHANGE(x) ((x) ? 0x0020 : 0x0010) -#define PORT_SE0_STATUS(x) ((x) ? 0x0008 : 0x0004) - -/* Host Frame Register */ -#define HOST_FRAME_REG(x) ((x) ? 0xC0B6 : 0xC096) - -#define HOST_FRAME_MASK 0x07FF - -/* USB Peripheral only registers */ -/* ============================= */ - -/* Device n Port Sel reg */ -#define DEVICE_N_PORT_SEL(x) ((x) ? 0xC0A4 : 0xC084) - -/* Device n Interrupt Enable Register */ -#define DEVICE_N_IRQ_EN_REG(x) ((x) ? 0xC0AC : 0xC08C) - -#define DEVICE_N_ENDPOINT_N_CTL_REG(dev, ep) ((dev) \ - ? (0x0280 + (ep << 4)) \ - : (0x0200 + (ep << 4))) -#define DEVICE_N_ENDPOINT_N_STAT_REG(dev, ep) ((dev) \ - ? (0x0286 + (ep << 4)) \ - : (0x0206 + (ep << 4))) - -#define DEVICE_N_ADDRESS(dev) ((dev) ? (0xC0AE) : (0xC08E)) - -/* HPI registers */ -/* ============= */ - -/* HPI Status register */ -#define SOFEOP_FLG(x) (1 << ((x) ? 12 : 10)) -#define SIEMSG_FLG(x) (1 << (4 + (x))) -#define RESET_FLG(x) ((x) ? 0x0200 : 0x0002) -#define DONE_FLG(x) (1 << (2 + (x))) -#define RESUME_FLG(x) (1 << (6 + (x))) -#define MBX_OUT_FLG 0x0001 /* Message out available */ -#define MBX_IN_FLG 0x0100 -#define ID_FLG 0x4000 -#define VBUS_FLG 0x8000 - -/* Interrupt routing register */ -#define HPI_IRQ_ROUTING_REG 0x0142 - -#define HPI_SWAP_ENABLE(x) ((x) ? 0x0100 : 0x0001) -#define RESET_TO_HPI_ENABLE(x) ((x) ? 0x0200 : 0x0002) -#define DONE_TO_HPI_ENABLE(x) ((x) ? 0x0008 : 0x0004) -#define RESUME_TO_HPI_ENABLE(x) ((x) ? 0x0080 : 0x0040) -#define SOFEOP_TO_HPI_EN(x) ((x) ? 0x2000 : 0x0800) -#define SOFEOP_TO_CPU_EN(x) ((x) ? 0x1000 : 0x0400) -#define ID_TO_HPI_ENABLE 0x4000 -#define VBUS_TO_HPI_ENABLE 0x8000 - -/* SIE msg registers */ -#define SIEMSG_REG(x) ((x) ? 0x0148 : 0x0144) - -#define HUSB_TDListDone 0x1000 - -#define SUSB_EP0_MSG 0x0001 -#define SUSB_EP1_MSG 0x0002 -#define SUSB_EP2_MSG 0x0004 -#define SUSB_EP3_MSG 0x0008 -#define SUSB_EP4_MSG 0x0010 -#define SUSB_EP5_MSG 0x0020 -#define SUSB_EP6_MSG 0x0040 -#define SUSB_EP7_MSG 0x0080 -#define SUSB_RST_MSG 0x0100 -#define SUSB_SOF_MSG 0x0200 -#define SUSB_CFG_MSG 0x0400 -#define SUSB_SUS_MSG 0x0800 -#define SUSB_ID_MSG 0x4000 -#define SUSB_VBUS_MSG 0x8000 - -/* BIOS interrupt routines */ - -#define SUSBx_RECEIVE_INT(x) ((x) ? 97 : 81) -#define SUSBx_SEND_INT(x) ((x) ? 96 : 80) - -#define SUSBx_DEV_DESC_VEC(x) ((x) ? 0x00D4 : 0x00B4) -#define SUSBx_CONF_DESC_VEC(x) ((x) ? 0x00D6 : 0x00B6) -#define SUSBx_STRING_DESC_VEC(x) ((x) ? 0x00D8 : 0x00B8) - -#define CY_HCD_BUF_ADDR 0x500 /* Base address for host */ -#define SIE_TD_SIZE 0x200 /* size of the td list */ -#define SIE_TD_BUF_SIZE 0x400 /* size of the data buffer */ - -#define SIE_TD_OFFSET(host) ((host) ? (SIE_TD_SIZE+SIE_TD_BUF_SIZE) : 0) -#define SIE_BUF_OFFSET(host) (SIE_TD_OFFSET(host) + SIE_TD_SIZE) - -/* Base address of HCD + 2 x TD_SIZE + 2 x TD_BUF_SIZE */ -#define CY_UDC_REQ_HEADER_BASE 0x1100 -/* 8- byte request headers for IN/OUT transfers */ -#define CY_UDC_REQ_HEADER_SIZE 8 - -#define CY_UDC_REQ_HEADER_ADDR(ep_num) (CY_UDC_REQ_HEADER_BASE + \ - ((ep_num) * CY_UDC_REQ_HEADER_SIZE)) -#define CY_UDC_DESC_BASE_ADDRESS (CY_UDC_REQ_HEADER_ADDR(8)) - -#define CY_UDC_BIOS_REPLACE_BASE 0x1800 -#define CY_UDC_REQ_BUFFER_BASE 0x2000 -#define CY_UDC_REQ_BUFFER_SIZE 0x0400 -#define CY_UDC_REQ_BUFFER_ADDR(ep_num) (CY_UDC_REQ_BUFFER_BASE + \ - ((ep_num) * CY_UDC_REQ_BUFFER_SIZE)) - -/* --------------------------------------------------------------------- - * Driver data structures - */ - -struct c67x00_device; - -/** - * struct c67x00_sie - Common data associated with a SIE - * @lock: lock to protect this struct and the associated chip registers - * @private_data: subdriver dependent data - * @irq: subdriver dependent irq handler, set NULL when not used - * @dev: link to common driver structure - * @sie_num: SIE number on chip, starting from 0 - * @mode: SIE mode (host/peripheral/otg/not used) - */ -struct c67x00_sie { - /* Entries to be used by the subdrivers */ - spinlock_t lock; /* protect this structure */ - void *private_data; - void (*irq) (struct c67x00_sie *sie, u16 int_status, u16 msg); - - /* Read only: */ - struct c67x00_device *dev; - int sie_num; - int mode; -}; - -#define sie_dev(s) (&(s)->dev->pdev->dev) - -/** - * struct c67x00_lcp - */ -struct c67x00_lcp { - /* Internal use only */ - struct mutex mutex; - struct completion msg_received; - u16 last_msg; -}; - -/* - * struct c67x00_hpi - */ -struct c67x00_hpi { - void __iomem *base; - int regstep; - spinlock_t lock; - struct c67x00_lcp lcp; -}; - -#define C67X00_SIES 2 -#define C67X00_PORTS 2 - -/** - * struct c67x00_device - Common data associated with a c67x00 instance - * @hpi: hpi addresses - * @sie: array of sie's on this chip - * @pdev: platform device of instance - * @pdata: configuration provided by the platform - */ -struct c67x00_device { - struct c67x00_hpi hpi; - struct c67x00_sie sie[C67X00_SIES]; - struct platform_device *pdev; - struct c67x00_platform_data *pdata; -}; - -/* --------------------------------------------------------------------- - * Low level interface functions - */ - -/* Host Port Interface (HPI) functions */ -u16 c67x00_ll_hpi_status(struct c67x00_device *dev); -void c67x00_ll_hpi_reg_init(struct c67x00_device *dev); -void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie); -void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie); - -/* General functions */ -u16 c67x00_ll_fetch_siemsg(struct c67x00_device *dev, int sie_num); -u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie); -void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits); -u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie); -void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr, - void *data, int len); -void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr, - void *data, int len); - -/* Host specific functions */ -void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value); -void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port); -void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr); -u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie); -u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie); -void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie); -void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port); - -/* Called by c67x00_irq to handle lcp interrupts */ -void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status); - -/* Setup and teardown */ -void c67x00_ll_init(struct c67x00_device *dev); -void c67x00_ll_release(struct c67x00_device *dev); -int c67x00_ll_reset(struct c67x00_device *dev); - -#endif /* _USB_C67X00_H */ diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 3e69266e1f4d..e819e5359d57 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -394,9 +394,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, if (!io->urbs) goto nomem; - urb_flags = URB_NO_INTERRUPT; - if (dma) - urb_flags |= URB_NO_TRANSFER_DMA_MAP; + urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT; if (usb_pipein(pipe)) urb_flags |= URB_SHORT_NOT_OK; diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index 6e784d2db423..f7b54651dd42 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -231,26 +231,6 @@ config SUPERH_BUILT_IN_M66592 However, this problem is improved if change a value of NET_IP_ALIGN to 4. -config USB_GADGET_PXA27X - boolean "PXA 27x" - depends on ARCH_PXA && PXA27x - help - Intel's PXA 27x series XScale ARM v5TE processors include - an integrated full speed USB 1.1 device controller. - - It has up to 23 endpoints, as well as endpoint zero (for - control transfers). - - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "pxa27x_udc" and force all - gadget drivers to also be dynamically linked. - -config USB_PXA27X - tristate - depends on USB_GADGET_PXA27X - default USB_GADGET - select USB_GADGET_SELECTED - config USB_GADGET_GOKU boolean "Toshiba TC86C001 'Goku-S'" depends on PCI diff --git a/trunk/drivers/usb/gadget/Makefile b/trunk/drivers/usb/gadget/Makefile index 12357255d740..c3aab80b6c76 100644 --- a/trunk/drivers/usb/gadget/Makefile +++ b/trunk/drivers/usb/gadget/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2280) += net2280.o obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o -obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o obj-$(CONFIG_USB_GOKU) += goku_udc.o obj-$(CONFIG_USB_OMAP) += omap_udc.o obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index 8d61ea67a817..bb93bdd76593 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -235,6 +235,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); #define DEV_CONFIG_CDC #endif +#ifdef CONFIG_USB_GADGET_PXA27X +#define DEV_CONFIG_CDC +#endif + #ifdef CONFIG_USB_GADGET_S3C2410 #define DEV_CONFIG_CDC #endif @@ -266,10 +270,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); #define DEV_CONFIG_SUBSET #endif -#ifdef CONFIG_USB_GADGET_PXA27X -#define DEV_CONFIG_SUBSET -#endif - #ifdef CONFIG_USB_GADGET_SUPERH #define DEV_CONFIG_SUBSET #endif diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index 47bb9f09a1aa..bf3f946fd455 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -2307,29 +2307,6 @@ static int halt_bulk_in_endpoint(struct fsg_dev *fsg) return rc; } -static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) -{ - int rc; - - DBG(fsg, "bulk-in set wedge\n"); - rc = usb_ep_set_wedge(fsg->bulk_in); - if (rc == -EAGAIN) - VDBG(fsg, "delayed bulk-in endpoint wedge\n"); - while (rc != 0) { - if (rc != -EAGAIN) { - WARN(fsg, "usb_ep_set_wedge -> %d\n", rc); - rc = 0; - break; - } - - /* Wait for a short time and then try again */ - if (msleep_interruptible(100) != 0) - return -EINTR; - rc = usb_ep_set_wedge(fsg->bulk_in); - } - return rc; -} - static int pad_with_zeros(struct fsg_dev *fsg) { struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; @@ -2980,7 +2957,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) * We aren't required to halt the OUT endpoint; instead * we can simply accept and discard any data received * until the next reset. */ - wedge_bulk_in_endpoint(fsg); + halt_bulk_in_endpoint(fsg); set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); return -EINVAL; } diff --git a/trunk/drivers/usb/gadget/pxa27x_udc.c b/trunk/drivers/usb/gadget/pxa27x_udc.c deleted file mode 100644 index 75eba202f737..000000000000 --- a/trunk/drivers/usb/gadget/pxa27x_udc.c +++ /dev/null @@ -1,2404 +0,0 @@ -/* - * Handles the Intel 27x USB Device Controller (UDC) - * - * Inspired by original driver by Frank Becker, David Brownell, and others. - * Copyright (C) 2008 Robert Jarzmik - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include - -#include "pxa27x_udc.h" - -/* - * This driver handles the USB Device Controller (UDC) in Intel's PXA 27x - * series processors. - * - * Such controller drivers work with a gadget driver. The gadget driver - * returns descriptors, implements configuration and data protocols used - * by the host to interact with this device, and allocates endpoints to - * the different protocol interfaces. The controller driver virtualizes - * usb hardware so that the gadget drivers will be more portable. - * - * This UDC hardware wants to implement a bit too much USB protocol. The - * biggest issues are: that the endpoints have to be set up before the - * controller can be enabled (minor, and not uncommon); and each endpoint - * can only have one configuration, interface and alternative interface - * number (major, and very unusual). Once set up, these cannot be changed - * without a controller reset. - * - * The workaround is to setup all combinations necessary for the gadgets which - * will work with this driver. This is done in pxa_udc structure, statically. - * See pxa_udc, udc_usb_ep versus pxa_ep, and matching function find_pxa_ep. - * (You could modify this if needed. Some drivers have a "fifo_mode" module - * parameter to facilitate such changes.) - * - * The combinations have been tested with these gadgets : - * - zero gadget - * - file storage gadget - * - ether gadget - * - * The driver doesn't use DMA, only IO access and IRQ callbacks. No use is - * made of UDC's double buffering either. USB "On-The-Go" is not implemented. - * - * All the requests are handled the same way : - * - the drivers tries to handle the request directly to the IO - * - if the IO fifo is not big enough, the remaining is send/received in - * interrupt handling. - */ - -#define DRIVER_VERSION "2008-04-18" -#define DRIVER_DESC "PXA 27x USB Device Controller driver" - -static const char driver_name[] = "pxa27x_udc"; -static struct pxa_udc *the_controller; - -static void handle_ep(struct pxa_ep *ep); - -/* - * Debug filesystem - */ -#ifdef CONFIG_USB_GADGET_DEBUG_FS - -#include -#include -#include - -static int state_dbg_show(struct seq_file *s, void *p) -{ - struct pxa_udc *udc = s->private; - int pos = 0, ret; - u32 tmp; - - ret = -ENODEV; - if (!udc->driver) - goto out; - - /* basic device status */ - pos += seq_printf(s, DRIVER_DESC "\n" - "%s version: %s\nGadget driver: %s\n", - driver_name, DRIVER_VERSION, - udc->driver ? udc->driver->driver.name : "(none)"); - - tmp = udc_readl(udc, UDCCR); - pos += seq_printf(s, - "udccr=0x%0x(%s%s%s%s%s%s%s%s%s%s), " - "con=%d,inter=%d,altinter=%d\n", tmp, - (tmp & UDCCR_OEN) ? " oen":"", - (tmp & UDCCR_AALTHNP) ? " aalthnp":"", - (tmp & UDCCR_AHNP) ? " rem" : "", - (tmp & UDCCR_BHNP) ? " rstir" : "", - (tmp & UDCCR_DWRE) ? " dwre" : "", - (tmp & UDCCR_SMAC) ? " smac" : "", - (tmp & UDCCR_EMCE) ? " emce" : "", - (tmp & UDCCR_UDR) ? " udr" : "", - (tmp & UDCCR_UDA) ? " uda" : "", - (tmp & UDCCR_UDE) ? " ude" : "", - (tmp & UDCCR_ACN) >> UDCCR_ACN_S, - (tmp & UDCCR_AIN) >> UDCCR_AIN_S, - (tmp & UDCCR_AAISN) >> UDCCR_AAISN_S); - /* registers for device and ep0 */ - pos += seq_printf(s, "udcicr0=0x%08x udcicr1=0x%08x\n", - udc_readl(udc, UDCICR0), udc_readl(udc, UDCICR1)); - pos += seq_printf(s, "udcisr0=0x%08x udcisr1=0x%08x\n", - udc_readl(udc, UDCISR0), udc_readl(udc, UDCISR1)); - pos += seq_printf(s, "udcfnr=%d\n", udc_readl(udc, UDCFNR)); - pos += seq_printf(s, "irqs: reset=%lu, suspend=%lu, resume=%lu, " - "reconfig=%lu\n", - udc->stats.irqs_reset, udc->stats.irqs_suspend, - udc->stats.irqs_resume, udc->stats.irqs_reconfig); - - ret = 0; -out: - return ret; -} - -static int queues_dbg_show(struct seq_file *s, void *p) -{ - struct pxa_udc *udc = s->private; - struct pxa_ep *ep; - struct pxa27x_request *req; - int pos = 0, i, maxpkt, ret; - - ret = -ENODEV; - if (!udc->driver) - goto out; - - /* dump endpoint queues */ - for (i = 0; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - maxpkt = ep->fifo_size; - pos += seq_printf(s, "%-12s max_pkt=%d %s\n", - EPNAME(ep), maxpkt, "pio"); - - if (list_empty(&ep->queue)) { - pos += seq_printf(s, "\t(nothing queued)\n"); - continue; - } - - list_for_each_entry(req, &ep->queue, queue) { - pos += seq_printf(s, "\treq %p len %d/%d buf %p\n", - &req->req, req->req.actual, - req->req.length, req->req.buf); - } - } - - ret = 0; -out: - return ret; -} - -static int eps_dbg_show(struct seq_file *s, void *p) -{ - struct pxa_udc *udc = s->private; - struct pxa_ep *ep; - int pos = 0, i, ret; - u32 tmp; - - ret = -ENODEV; - if (!udc->driver) - goto out; - - ep = &udc->pxa_ep[0]; - tmp = udc_ep_readl(ep, UDCCSR); - pos += seq_printf(s, "udccsr0=0x%03x(%s%s%s%s%s%s%s)\n", tmp, - (tmp & UDCCSR0_SA) ? " sa" : "", - (tmp & UDCCSR0_RNE) ? " rne" : "", - (tmp & UDCCSR0_FST) ? " fst" : "", - (tmp & UDCCSR0_SST) ? " sst" : "", - (tmp & UDCCSR0_DME) ? " dme" : "", - (tmp & UDCCSR0_IPR) ? " ipr" : "", - (tmp & UDCCSR0_OPC) ? " opc" : ""); - for (i = 0; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - tmp = i? udc_ep_readl(ep, UDCCR) : udc_readl(udc, UDCCR); - pos += seq_printf(s, "%-12s: " - "IN %lu(%lu reqs), OUT %lu(%lu reqs), " - "irqs=%lu, udccr=0x%08x, udccsr=0x%03x, " - "udcbcr=%d\n", - EPNAME(ep), - ep->stats.in_bytes, ep->stats.in_ops, - ep->stats.out_bytes, ep->stats.out_ops, - ep->stats.irqs, - tmp, udc_ep_readl(ep, UDCCSR), - udc_ep_readl(ep, UDCBCR)); - } - - ret = 0; -out: - return ret; -} - -static int eps_dbg_open(struct inode *inode, struct file *file) -{ - return single_open(file, eps_dbg_show, inode->i_private); -} - -static int queues_dbg_open(struct inode *inode, struct file *file) -{ - return single_open(file, queues_dbg_show, inode->i_private); -} - -static int state_dbg_open(struct inode *inode, struct file *file) -{ - return single_open(file, state_dbg_show, inode->i_private); -} - -static const struct file_operations state_dbg_fops = { - .owner = THIS_MODULE, - .open = state_dbg_open, - .llseek = seq_lseek, - .read = seq_read, - .release = single_release, -}; - -static const struct file_operations queues_dbg_fops = { - .owner = THIS_MODULE, - .open = queues_dbg_open, - .llseek = seq_lseek, - .read = seq_read, - .release = single_release, -}; - -static const struct file_operations eps_dbg_fops = { - .owner = THIS_MODULE, - .open = eps_dbg_open, - .llseek = seq_lseek, - .read = seq_read, - .release = single_release, -}; - -static void pxa_init_debugfs(struct pxa_udc *udc) -{ - struct dentry *root, *state, *queues, *eps; - - root = debugfs_create_dir(udc->gadget.name, NULL); - if (IS_ERR(root) || !root) - goto err_root; - - state = debugfs_create_file("udcstate", 0400, root, udc, - &state_dbg_fops); - if (!state) - goto err_state; - queues = debugfs_create_file("queues", 0400, root, udc, - &queues_dbg_fops); - if (!queues) - goto err_queues; - eps = debugfs_create_file("epstate", 0400, root, udc, - &eps_dbg_fops); - if (!queues) - goto err_eps; - - udc->debugfs_root = root; - udc->debugfs_state = state; - udc->debugfs_queues = queues; - udc->debugfs_eps = eps; - return; -err_eps: - debugfs_remove(eps); -err_queues: - debugfs_remove(queues); -err_state: - debugfs_remove(root); -err_root: - dev_err(udc->dev, "debugfs is not available\n"); -} - -static void pxa_cleanup_debugfs(struct pxa_udc *udc) -{ - debugfs_remove(udc->debugfs_eps); - debugfs_remove(udc->debugfs_queues); - debugfs_remove(udc->debugfs_state); - debugfs_remove(udc->debugfs_root); - udc->debugfs_eps = NULL; - udc->debugfs_queues = NULL; - udc->debugfs_state = NULL; - udc->debugfs_root = NULL; -} - -#else -static inline void pxa_init_debugfs(struct pxa_udc *udc) -{ -} - -static inline void pxa_cleanup_debugfs(struct pxa_udc *udc) -{ -} -#endif - -/** - * is_match_usb_pxa - check if usb_ep and pxa_ep match - * @udc_usb_ep: usb endpoint - * @ep: pxa endpoint - * @config: configuration required in pxa_ep - * @interface: interface required in pxa_ep - * @altsetting: altsetting required in pxa_ep - * - * Returns 1 if all criteria match between pxa and usb endpoint, 0 otherwise - */ -static int is_match_usb_pxa(struct udc_usb_ep *udc_usb_ep, struct pxa_ep *ep, - int config, int interface, int altsetting) -{ - if (usb_endpoint_num(&udc_usb_ep->desc) != ep->addr) - return 0; - if (usb_endpoint_dir_in(&udc_usb_ep->desc) != ep->dir_in) - return 0; - if (usb_endpoint_type(&udc_usb_ep->desc) != ep->type) - return 0; - if ((ep->config != config) || (ep->interface != interface) - || (ep->alternate != altsetting)) - return 0; - return 1; -} - -/** - * find_pxa_ep - find pxa_ep structure matching udc_usb_ep - * @udc: pxa udc - * @udc_usb_ep: udc_usb_ep structure - * - * Match udc_usb_ep and all pxa_ep available, to see if one matches. - * This is necessary because of the strong pxa hardware restriction requiring - * that once pxa endpoints are initialized, their configuration is freezed, and - * no change can be made to their address, direction, or in which configuration, - * interface or altsetting they are active ... which differs from more usual - * models which have endpoints be roughly just addressable fifos, and leave - * configuration events up to gadget drivers (like all control messages). - * - * Note that there is still a blurred point here : - * - we rely on UDCCR register "active interface" and "active altsetting". - * This is a nonsense in regard of USB spec, where multiple interfaces are - * active at the same time. - * - if we knew for sure that the pxa can handle multiple interface at the - * same time, assuming Intel's Developer Guide is wrong, this function - * should be reviewed, and a cache of couples (iface, altsetting) should - * be kept in the pxa_udc structure. In this case this function would match - * against the cache of couples instead of the "last altsetting" set up. - * - * Returns the matched pxa_ep structure or NULL if none found - */ -static struct pxa_ep *find_pxa_ep(struct pxa_udc *udc, - struct udc_usb_ep *udc_usb_ep) -{ - int i; - struct pxa_ep *ep; - int cfg = udc->config; - int iface = udc->last_interface; - int alt = udc->last_alternate; - - if (udc_usb_ep == &udc->udc_usb_ep[0]) - return &udc->pxa_ep[0]; - - for (i = 1; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - if (is_match_usb_pxa(udc_usb_ep, ep, cfg, iface, alt)) - return ep; - } - return NULL; -} - -/** - * update_pxa_ep_matches - update pxa_ep cached values in all udc_usb_ep - * @udc: pxa udc - * - * Context: in_interrupt() - * - * Updates all pxa_ep fields in udc_usb_ep structures, if this field was - * previously set up (and is not NULL). The update is necessary is a - * configuration change or altsetting change was issued by the USB host. - */ -static void update_pxa_ep_matches(struct pxa_udc *udc) -{ - int i; - struct udc_usb_ep *udc_usb_ep; - - for (i = 1; i < NR_USB_ENDPOINTS; i++) { - udc_usb_ep = &udc->udc_usb_ep[i]; - if (udc_usb_ep->pxa_ep) - udc_usb_ep->pxa_ep = find_pxa_ep(udc, udc_usb_ep); - } -} - -/** - * pio_irq_enable - Enables irq generation for one endpoint - * @ep: udc endpoint - */ -static void pio_irq_enable(struct pxa_ep *ep) -{ - struct pxa_udc *udc = ep->dev; - int index = EPIDX(ep); - u32 udcicr0 = udc_readl(udc, UDCICR0); - u32 udcicr1 = udc_readl(udc, UDCICR1); - - if (index < 16) - udc_writel(udc, UDCICR0, udcicr0 | (3 << (index * 2))); - else - udc_writel(udc, UDCICR1, udcicr1 | (3 << ((index - 16) * 2))); -} - -/** - * pio_irq_disable - Disables irq generation for one endpoint - * @ep: udc endpoint - * @index: endpoint number - */ -static void pio_irq_disable(struct pxa_ep *ep) -{ - struct pxa_udc *udc = ep->dev; - int index = EPIDX(ep); - u32 udcicr0 = udc_readl(udc, UDCICR0); - u32 udcicr1 = udc_readl(udc, UDCICR1); - - if (index < 16) - udc_writel(udc, UDCICR0, udcicr0 & ~(3 << (index * 2))); - else - udc_writel(udc, UDCICR1, udcicr1 & ~(3 << ((index - 16) * 2))); -} - -/** - * udc_set_mask_UDCCR - set bits in UDCCR - * @udc: udc device - * @mask: bits to set in UDCCR - * - * Sets bits in UDCCR, leaving DME and FST bits as they were. - */ -static inline void udc_set_mask_UDCCR(struct pxa_udc *udc, int mask) -{ - u32 udccr = udc_readl(udc, UDCCR); - udc_writel(udc, UDCCR, - (udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS)); -} - -/** - * udc_clear_mask_UDCCR - clears bits in UDCCR - * @udc: udc device - * @mask: bit to clear in UDCCR - * - * Clears bits in UDCCR, leaving DME and FST bits as they were. - */ -static inline void udc_clear_mask_UDCCR(struct pxa_udc *udc, int mask) -{ - u32 udccr = udc_readl(udc, UDCCR); - udc_writel(udc, UDCCR, - (udccr & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS)); -} - -/** - * ep_count_bytes_remain - get how many bytes in udc endpoint - * @ep: udc endpoint - * - * Returns number of bytes in OUT fifos. Broken for IN fifos (-EOPNOTSUPP) - */ -static int ep_count_bytes_remain(struct pxa_ep *ep) -{ - if (ep->dir_in) - return -EOPNOTSUPP; - return udc_ep_readl(ep, UDCBCR) & 0x3ff; -} - -/** - * ep_is_empty - checks if ep has byte ready for reading - * @ep: udc endpoint - * - * If endpoint is the control endpoint, checks if there are bytes in the - * control endpoint fifo. If endpoint is a data endpoint, checks if bytes - * are ready for reading on OUT endpoint. - * - * Returns 0 if ep not empty, 1 if ep empty, -EOPNOTSUPP if IN endpoint - */ -static int ep_is_empty(struct pxa_ep *ep) -{ - int ret; - - if (!is_ep0(ep) && ep->dir_in) - return -EOPNOTSUPP; - if (is_ep0(ep)) - ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR0_RNE); - else - ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNE); - return ret; -} - -/** - * ep_is_full - checks if ep has place to write bytes - * @ep: udc endpoint - * - * If endpoint is not the control endpoint and is an IN endpoint, checks if - * there is place to write bytes into the endpoint. - * - * Returns 0 if ep not full, 1 if ep full, -EOPNOTSUPP if OUT endpoint - */ -static int ep_is_full(struct pxa_ep *ep) -{ - if (is_ep0(ep)) - return (udc_ep_readl(ep, UDCCSR) & UDCCSR0_IPR); - if (!ep->dir_in) - return -EOPNOTSUPP; - return (!(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNF)); -} - -/** - * epout_has_pkt - checks if OUT endpoint fifo has a packet available - * @ep: pxa endpoint - * - * Returns 1 if a complete packet is available, 0 if not, -EOPNOTSUPP for IN ep. - */ -static int epout_has_pkt(struct pxa_ep *ep) -{ - if (!is_ep0(ep) && ep->dir_in) - return -EOPNOTSUPP; - if (is_ep0(ep)) - return (udc_ep_readl(ep, UDCCSR) & UDCCSR0_OPC); - return (udc_ep_readl(ep, UDCCSR) & UDCCSR_PC); -} - -/** - * set_ep0state - Set ep0 automata state - * @dev: udc device - * @state: state - */ -static void set_ep0state(struct pxa_udc *udc, int state) -{ - struct pxa_ep *ep = &udc->pxa_ep[0]; - char *old_stname = EP0_STNAME(udc); - - udc->ep0state = state; - ep_dbg(ep, "state=%s->%s, udccsr0=0x%03x, udcbcr=%d\n", old_stname, - EP0_STNAME(udc), udc_ep_readl(ep, UDCCSR), - udc_ep_readl(ep, UDCBCR)); -} - -/** - * ep0_idle - Put control endpoint into idle state - * @dev: udc device - */ -static void ep0_idle(struct pxa_udc *dev) -{ - set_ep0state(dev, WAIT_FOR_SETUP); -} - -/** - * inc_ep_stats_reqs - Update ep stats counts - * @ep: physical endpoint - * @req: usb request - * @is_in: ep direction (USB_DIR_IN or 0) - * - */ -static void inc_ep_stats_reqs(struct pxa_ep *ep, int is_in) -{ - if (is_in) - ep->stats.in_ops++; - else - ep->stats.out_ops++; -} - -/** - * inc_ep_stats_bytes - Update ep stats counts - * @ep: physical endpoint - * @count: bytes transfered on endpoint - * @req: usb request - * @is_in: ep direction (USB_DIR_IN or 0) - */ -static void inc_ep_stats_bytes(struct pxa_ep *ep, int count, int is_in) -{ - if (is_in) - ep->stats.in_bytes += count; - else - ep->stats.out_bytes += count; -} - -/** - * pxa_ep_setup - Sets up an usb physical endpoint - * @ep: pxa27x physical endpoint - * - * Find the physical pxa27x ep, and setup its UDCCR - */ -static __init void pxa_ep_setup(struct pxa_ep *ep) -{ - u32 new_udccr; - - new_udccr = ((ep->config << UDCCONR_CN_S) & UDCCONR_CN) - | ((ep->interface << UDCCONR_IN_S) & UDCCONR_IN) - | ((ep->alternate << UDCCONR_AISN_S) & UDCCONR_AISN) - | ((EPADDR(ep) << UDCCONR_EN_S) & UDCCONR_EN) - | ((EPXFERTYPE(ep) << UDCCONR_ET_S) & UDCCONR_ET) - | ((ep->dir_in) ? UDCCONR_ED : 0) - | ((ep->fifo_size << UDCCONR_MPS_S) & UDCCONR_MPS) - | UDCCONR_EE; - - udc_ep_writel(ep, UDCCR, new_udccr); -} - -/** - * pxa_eps_setup - Sets up all usb physical endpoints - * @dev: udc device - * - * Setup all pxa physical endpoints, except ep0 - */ -static __init void pxa_eps_setup(struct pxa_udc *dev) -{ - unsigned int i; - - dev_dbg(dev->dev, "%s: dev=%p\n", __func__, dev); - - for (i = 1; i < NR_PXA_ENDPOINTS; i++) - pxa_ep_setup(&dev->pxa_ep[i]); -} - -/** - * pxa_ep_alloc_request - Allocate usb request - * @_ep: usb endpoint - * @gfp_flags: - * - * For the pxa27x, these can just wrap kmalloc/kfree. gadget drivers - * must still pass correctly initialized endpoints, since other controller - * drivers may care about how it's currently set up (dma issues etc). - */ -static struct usb_request * -pxa_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) -{ - struct pxa27x_request *req; - - req = kzalloc(sizeof *req, gfp_flags); - if (!req || !_ep) - return NULL; - - INIT_LIST_HEAD(&req->queue); - req->in_use = 0; - req->udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - - return &req->req; -} - -/** - * pxa_ep_free_request - Free usb request - * @_ep: usb endpoint - * @_req: usb request - * - * Wrapper around kfree to free _req - */ -static void pxa_ep_free_request(struct usb_ep *_ep, struct usb_request *_req) -{ - struct pxa27x_request *req; - - req = container_of(_req, struct pxa27x_request, req); - WARN_ON(!list_empty(&req->queue)); - kfree(req); -} - -/** - * ep_add_request - add a request to the endpoint's queue - * @ep: usb endpoint - * @req: usb request - * - * Context: ep->lock held - * - * Queues the request in the endpoint's queue, and enables the interrupts - * on the endpoint. - */ -static void ep_add_request(struct pxa_ep *ep, struct pxa27x_request *req) -{ - if (unlikely(!req)) - return; - ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req, - req->req.length, udc_ep_readl(ep, UDCCSR)); - - req->in_use = 1; - list_add_tail(&req->queue, &ep->queue); - pio_irq_enable(ep); -} - -/** - * ep_del_request - removes a request from the endpoint's queue - * @ep: usb endpoint - * @req: usb request - * - * Context: ep->lock held - * - * Unqueue the request from the endpoint's queue. If there are no more requests - * on the endpoint, and if it's not the control endpoint, interrupts are - * disabled on the endpoint. - */ -static void ep_del_request(struct pxa_ep *ep, struct pxa27x_request *req) -{ - if (unlikely(!req)) - return; - ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req, - req->req.length, udc_ep_readl(ep, UDCCSR)); - - list_del_init(&req->queue); - req->in_use = 0; - if (!is_ep0(ep) && list_empty(&ep->queue)) - pio_irq_disable(ep); -} - -/** - * req_done - Complete an usb request - * @ep: pxa physical endpoint - * @req: pxa request - * @status: usb request status sent to gadget API - * - * Context: ep->lock held - * - * Retire a pxa27x usb request. Endpoint must be locked. - */ -static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status) -{ - ep_del_request(ep, req); - if (likely(req->req.status == -EINPROGRESS)) - req->req.status = status; - else - status = req->req.status; - - if (status && status != -ESHUTDOWN) - ep_dbg(ep, "complete req %p stat %d len %u/%u\n", - &req->req, status, - req->req.actual, req->req.length); - - req->req.complete(&req->udc_usb_ep->usb_ep, &req->req); -} - -/** - * ep_end_out_req - Ends control endpoint in request - * @ep: physical endpoint - * @req: pxa request - * - * Context: ep->lock held - * - * Ends endpoint in request (completes usb request). - */ -static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) -{ - inc_ep_stats_reqs(ep, !USB_DIR_IN); - req_done(ep, req, 0); -} - -/** - * ep0_end_out_req - Ends control endpoint in request (ends data stage) - * @ep: physical endpoint - * @req: pxa request - * - * Context: ep->lock held - * - * Ends control endpoint in request (completes usb request), and puts - * control endpoint into idle state - */ -static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) -{ - set_ep0state(ep->dev, OUT_STATUS_STAGE); - ep_end_out_req(ep, req); - ep0_idle(ep->dev); -} - -/** - * ep_end_in_req - Ends endpoint out request - * @ep: physical endpoint - * @req: pxa request - * - * Context: ep->lock held - * - * Ends endpoint out request (completes usb request). - */ -static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) -{ - inc_ep_stats_reqs(ep, USB_DIR_IN); - req_done(ep, req, 0); -} - -/** - * ep0_end_in_req - Ends control endpoint out request (ends data stage) - * @ep: physical endpoint - * @req: pxa request - * - * Context: ep->lock held - * - * Ends control endpoint out request (completes usb request), and puts - * control endpoint into status state - */ -static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) -{ - struct pxa_udc *udc = ep->dev; - - set_ep0state(udc, IN_STATUS_STAGE); - ep_end_in_req(ep, req); -} - -/** - * nuke - Dequeue all requests - * @ep: pxa endpoint - * @status: usb request status - * - * Context: ep->lock held - * - * Dequeues all requests on an endpoint. As a side effect, interrupts will be - * disabled on that endpoint (because no more requests). - */ -static void nuke(struct pxa_ep *ep, int status) -{ - struct pxa27x_request *req; - - while (!list_empty(&ep->queue)) { - req = list_entry(ep->queue.next, struct pxa27x_request, queue); - req_done(ep, req, status); - } -} - -/** - * read_packet - transfer 1 packet from an OUT endpoint into request - * @ep: pxa physical endpoint - * @req: usb request - * - * Takes bytes from OUT endpoint and transfers them info the usb request. - * If there is less space in request than bytes received in OUT endpoint, - * bytes are left in the OUT endpoint. - * - * Returns how many bytes were actually transfered - */ -static int read_packet(struct pxa_ep *ep, struct pxa27x_request *req) -{ - u32 *buf; - int bytes_ep, bufferspace, count, i; - - bytes_ep = ep_count_bytes_remain(ep); - bufferspace = req->req.length - req->req.actual; - - buf = (u32 *)(req->req.buf + req->req.actual); - prefetchw(buf); - - if (likely(!ep_is_empty(ep))) - count = min(bytes_ep, bufferspace); - else /* zlp */ - count = 0; - - for (i = count; i > 0; i -= 4) - *buf++ = udc_ep_readl(ep, UDCDR); - req->req.actual += count; - - udc_ep_writel(ep, UDCCSR, UDCCSR_PC); - - return count; -} - -/** - * write_packet - transfer 1 packet from request into an IN endpoint - * @ep: pxa physical endpoint - * @req: usb request - * @max: max bytes that fit into endpoint - * - * Takes bytes from usb request, and transfers them into the physical - * endpoint. If there are no bytes to transfer, doesn't write anything - * to physical endpoint. - * - * Returns how many bytes were actually transfered. - */ -static int write_packet(struct pxa_ep *ep, struct pxa27x_request *req, - unsigned int max) -{ - int length, count, remain, i; - u32 *buf; - u8 *buf_8; - - buf = (u32 *)(req->req.buf + req->req.actual); - prefetch(buf); - - length = min(req->req.length - req->req.actual, max); - req->req.actual += length; - - remain = length & 0x3; - count = length & ~(0x3); - for (i = count; i > 0 ; i -= 4) - udc_ep_writel(ep, UDCDR, *buf++); - - buf_8 = (u8 *)buf; - for (i = remain; i > 0; i--) - udc_ep_writeb(ep, UDCDR, *buf_8++); - - ep_vdbg(ep, "length=%d+%d, udccsr=0x%03x\n", count, remain, - udc_ep_readl(ep, UDCCSR)); - - return length; -} - -/** - * read_fifo - Transfer packets from OUT endpoint into usb request - * @ep: pxa physical endpoint - * @req: usb request - * - * Context: callable when in_interrupt() - * - * Unload as many packets as possible from the fifo we use for usb OUT - * transfers and put them into the request. Caller should have made sure - * there's at least one packet ready. - * Doesn't complete the request, that's the caller's job - * - * Returns 1 if the request completed, 0 otherwise - */ -static int read_fifo(struct pxa_ep *ep, struct pxa27x_request *req) -{ - int count, is_short, completed = 0; - - while (epout_has_pkt(ep)) { - count = read_packet(ep, req); - inc_ep_stats_bytes(ep, count, !USB_DIR_IN); - - is_short = (count < ep->fifo_size); - ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n", - udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "", - &req->req, req->req.actual, req->req.length); - - /* completion */ - if (is_short || req->req.actual == req->req.length) { - completed = 1; - break; - } - /* finished that packet. the next one may be waiting... */ - } - return completed; -} - -/** - * write_fifo - transfer packets from usb request into an IN endpoint - * @ep: pxa physical endpoint - * @req: pxa usb request - * - * Write to an IN endpoint fifo, as many packets as possible. - * irqs will use this to write the rest later. - * caller guarantees at least one packet buffer is ready (or a zlp). - * Doesn't complete the request, that's the caller's job - * - * Returns 1 if request fully transfered, 0 if partial transfer - */ -static int write_fifo(struct pxa_ep *ep, struct pxa27x_request *req) -{ - unsigned max; - int count, is_short, is_last = 0, completed = 0, totcount = 0; - u32 udccsr; - - max = ep->fifo_size; - do { - is_short = 0; - - udccsr = udc_ep_readl(ep, UDCCSR); - if (udccsr & UDCCSR_PC) { - ep_vdbg(ep, "Clearing Transmit Complete, udccsr=%x\n", - udccsr); - udc_ep_writel(ep, UDCCSR, UDCCSR_PC); - } - if (udccsr & UDCCSR_TRN) { - ep_vdbg(ep, "Clearing Underrun on, udccsr=%x\n", - udccsr); - udc_ep_writel(ep, UDCCSR, UDCCSR_TRN); - } - - count = write_packet(ep, req, max); - inc_ep_stats_bytes(ep, count, USB_DIR_IN); - totcount += count; - - /* last packet is usually short (or a zlp) */ - if (unlikely(count < max)) { - is_last = 1; - is_short = 1; - } else { - if (likely(req->req.length > req->req.actual) - || req->req.zero) - is_last = 0; - else - is_last = 1; - /* interrupt/iso maxpacket may not fill the fifo */ - is_short = unlikely(max < ep->fifo_size); - } - - if (is_short) - udc_ep_writel(ep, UDCCSR, UDCCSR_SP); - - /* requests complete when all IN data is in the FIFO */ - if (is_last) { - completed = 1; - break; - } - } while (!ep_is_full(ep)); - - ep_dbg(ep, "wrote count:%d bytes%s%s, left:%d req=%p\n", - totcount, is_last ? "/L" : "", is_short ? "/S" : "", - req->req.length - req->req.actual, &req->req); - - return completed; -} - -/** - * read_ep0_fifo - Transfer packets from control endpoint into usb request - * @ep: control endpoint - * @req: pxa usb request - * - * Special ep0 version of the above read_fifo. Reads as many bytes from control - * endpoint as can be read, and stores them into usb request (limited by request - * maximum length). - * - * Returns 0 if usb request only partially filled, 1 if fully filled - */ -static int read_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req) -{ - int count, is_short, completed = 0; - - while (epout_has_pkt(ep)) { - count = read_packet(ep, req); - udc_ep_writel(ep, UDCCSR, UDCCSR0_OPC); - inc_ep_stats_bytes(ep, count, !USB_DIR_IN); - - is_short = (count < ep->fifo_size); - ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n", - udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "", - &req->req, req->req.actual, req->req.length); - - if (is_short || req->req.actual >= req->req.length) { - completed = 1; - break; - } - } - - return completed; -} - -/** - * write_ep0_fifo - Send a request to control endpoint (ep0 in) - * @ep: control endpoint - * @req: request - * - * Context: callable when in_interrupt() - * - * Sends a request (or a part of the request) to the control endpoint (ep0 in). - * If the request doesn't fit, the remaining part will be sent from irq. - * The request is considered fully written only if either : - * - last write transfered all remaining bytes, but fifo was not fully filled - * - last write was a 0 length write - * - * Returns 1 if request fully written, 0 if request only partially sent - */ -static int write_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req) -{ - unsigned count; - int is_last, is_short; - - count = write_packet(ep, req, EP0_FIFO_SIZE); - inc_ep_stats_bytes(ep, count, USB_DIR_IN); - - is_short = (count < EP0_FIFO_SIZE); - is_last = ((count == 0) || (count < EP0_FIFO_SIZE)); - - /* Sends either a short packet or a 0 length packet */ - if (unlikely(is_short)) - udc_ep_writel(ep, UDCCSR, UDCCSR0_IPR); - - ep_dbg(ep, "in %d bytes%s%s, %d left, req=%p, udccsr0=0x%03x\n", - count, is_short ? "/S" : "", is_last ? "/L" : "", - req->req.length - req->req.actual, - &req->req, udc_ep_readl(ep, UDCCSR)); - - return is_last; -} - -/** - * pxa_ep_queue - Queue a request into an IN endpoint - * @_ep: usb endpoint - * @_req: usb request - * @gfp_flags: flags - * - * Context: normally called when !in_interrupt, but callable when in_interrupt() - * in the special case of ep0 setup : - * (irq->handle_ep0_ctrl_req->gadget_setup->pxa_ep_queue) - * - * Returns 0 if succedeed, error otherwise - */ -static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, - gfp_t gfp_flags) -{ - struct udc_usb_ep *udc_usb_ep; - struct pxa_ep *ep; - struct pxa27x_request *req; - struct pxa_udc *dev; - unsigned long flags; - int rc = 0; - int is_first_req; - unsigned length; - - req = container_of(_req, struct pxa27x_request, req); - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - - if (unlikely(!_req || !_req->complete || !_req->buf)) - return -EINVAL; - - if (unlikely(!_ep)) - return -EINVAL; - - dev = udc_usb_ep->dev; - ep = udc_usb_ep->pxa_ep; - if (unlikely(!ep)) - return -EINVAL; - - dev = ep->dev; - if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) { - ep_dbg(ep, "bogus device state\n"); - return -ESHUTDOWN; - } - - /* iso is always one packet per request, that's the only way - * we can report per-packet status. that also helps with dma. - */ - if (unlikely(EPXFERTYPE_is_ISO(ep) - && req->req.length > ep->fifo_size)) - return -EMSGSIZE; - - spin_lock_irqsave(&ep->lock, flags); - - is_first_req = list_empty(&ep->queue); - ep_dbg(ep, "queue req %p(first=%s), len %d buf %p\n", - _req, is_first_req ? "yes" : "no", - _req->length, _req->buf); - - if (!ep->enabled) { - _req->status = -ESHUTDOWN; - rc = -ESHUTDOWN; - goto out; - } - - if (req->in_use) { - ep_err(ep, "refusing to queue req %p (already queued)\n", req); - goto out; - } - - length = _req->length; - _req->status = -EINPROGRESS; - _req->actual = 0; - - ep_add_request(ep, req); - - if (is_ep0(ep)) { - switch (dev->ep0state) { - case WAIT_ACK_SET_CONF_INTERF: - if (length == 0) { - ep_end_in_req(ep, req); - } else { - ep_err(ep, "got a request of %d bytes while" - "in state WATI_ACK_SET_CONF_INTERF\n", - length); - ep_del_request(ep, req); - rc = -EL2HLT; - } - ep0_idle(ep->dev); - break; - case IN_DATA_STAGE: - if (!ep_is_full(ep)) - if (write_ep0_fifo(ep, req)) - ep0_end_in_req(ep, req); - break; - case OUT_DATA_STAGE: - if ((length == 0) || !epout_has_pkt(ep)) - if (read_ep0_fifo(ep, req)) - ep0_end_out_req(ep, req); - break; - default: - ep_err(ep, "odd state %s to send me a request\n", - EP0_STNAME(ep->dev)); - ep_del_request(ep, req); - rc = -EL2HLT; - break; - } - } else { - handle_ep(ep); - } - -out: - spin_unlock_irqrestore(&ep->lock, flags); - return rc; -} - -/** - * pxa_ep_dequeue - Dequeue one request - * @_ep: usb endpoint - * @_req: usb request - * - * Return 0 if no error, -EINVAL or -ECONNRESET otherwise - */ -static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - struct pxa27x_request *req; - unsigned long flags; - int rc; - - if (!_ep) - return -EINVAL; - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - ep = udc_usb_ep->pxa_ep; - if (!ep || is_ep0(ep)) - return -EINVAL; - - spin_lock_irqsave(&ep->lock, flags); - - /* make sure it's actually queued on this endpoint */ - list_for_each_entry(req, &ep->queue, queue) { - if (&req->req == _req) - break; - } - - rc = -EINVAL; - if (&req->req != _req) - goto out; - - rc = 0; - req_done(ep, req, -ECONNRESET); -out: - spin_unlock_irqrestore(&ep->lock, flags); - return rc; -} - -/** - * pxa_ep_set_halt - Halts operations on one endpoint - * @_ep: usb endpoint - * @value: - * - * Returns 0 if no error, -EINVAL, -EROFS, -EAGAIN otherwise - */ -static int pxa_ep_set_halt(struct usb_ep *_ep, int value) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - unsigned long flags; - int rc; - - - if (!_ep) - return -EINVAL; - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - ep = udc_usb_ep->pxa_ep; - if (!ep || is_ep0(ep)) - return -EINVAL; - - if (value == 0) { - /* - * This path (reset toggle+halt) is needed to implement - * SET_INTERFACE on normal hardware. but it can't be - * done from software on the PXA UDC, and the hardware - * forgets to do it as part of SET_INTERFACE automagic. - */ - ep_dbg(ep, "only host can clear halt\n"); - return -EROFS; - } - - spin_lock_irqsave(&ep->lock, flags); - - rc = -EAGAIN; - if (ep->dir_in && (ep_is_full(ep) || !list_empty(&ep->queue))) - goto out; - - /* FST, FEF bits are the same for control and non control endpoints */ - rc = 0; - udc_ep_writel(ep, UDCCSR, UDCCSR_FST | UDCCSR_FEF); - if (is_ep0(ep)) - set_ep0state(ep->dev, STALL); - -out: - spin_unlock_irqrestore(&ep->lock, flags); - return rc; -} - -/** - * pxa_ep_fifo_status - Get how many bytes in physical endpoint - * @_ep: usb endpoint - * - * Returns number of bytes in OUT fifos. Broken for IN fifos. - */ -static int pxa_ep_fifo_status(struct usb_ep *_ep) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - - if (!_ep) - return -ENODEV; - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - ep = udc_usb_ep->pxa_ep; - if (!ep || is_ep0(ep)) - return -ENODEV; - - if (ep->dir_in) - return -EOPNOTSUPP; - if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN || ep_is_empty(ep)) - return 0; - else - return ep_count_bytes_remain(ep) + 1; -} - -/** - * pxa_ep_fifo_flush - Flushes one endpoint - * @_ep: usb endpoint - * - * Discards all data in one endpoint(IN or OUT), except control endpoint. - */ -static void pxa_ep_fifo_flush(struct usb_ep *_ep) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - unsigned long flags; - - if (!_ep) - return; - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - ep = udc_usb_ep->pxa_ep; - if (!ep || is_ep0(ep)) - return; - - spin_lock_irqsave(&ep->lock, flags); - - if (unlikely(!list_empty(&ep->queue))) - ep_dbg(ep, "called while queue list not empty\n"); - ep_dbg(ep, "called\n"); - - /* for OUT, just read and discard the FIFO contents. */ - if (!ep->dir_in) { - while (!ep_is_empty(ep)) - udc_ep_readl(ep, UDCDR); - } else { - /* most IN status is the same, but ISO can't stall */ - udc_ep_writel(ep, UDCCSR, - UDCCSR_PC | UDCCSR_FEF | UDCCSR_TRN - | (EPXFERTYPE_is_ISO(ep) ? 0 : UDCCSR_SST)); - } - - spin_unlock_irqrestore(&ep->lock, flags); - - return; -} - -/** - * pxa_ep_enable - Enables usb endpoint - * @_ep: usb endpoint - * @desc: usb endpoint descriptor - * - * Nothing much to do here, as ep configuration is done once and for all - * before udc is enabled. After udc enable, no physical endpoint configuration - * can be changed. - * Function makes sanity checks and flushes the endpoint. - */ -static int pxa_ep_enable(struct usb_ep *_ep, - const struct usb_endpoint_descriptor *desc) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - struct pxa_udc *udc; - - if (!_ep || !desc) - return -EINVAL; - - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - if (udc_usb_ep->pxa_ep) { - ep = udc_usb_ep->pxa_ep; - ep_warn(ep, "usb_ep %s already enabled, doing nothing\n", - _ep->name); - } else { - ep = find_pxa_ep(udc_usb_ep->dev, udc_usb_ep); - } - - if (!ep || is_ep0(ep)) { - dev_err(udc_usb_ep->dev->dev, - "unable to match pxa_ep for ep %s\n", - _ep->name); - return -EINVAL; - } - - if ((desc->bDescriptorType != USB_DT_ENDPOINT) - || (ep->type != usb_endpoint_type(desc))) { - ep_err(ep, "type mismatch\n"); - return -EINVAL; - } - - if (ep->fifo_size < le16_to_cpu(desc->wMaxPacketSize)) { - ep_err(ep, "bad maxpacket\n"); - return -ERANGE; - } - - udc_usb_ep->pxa_ep = ep; - udc = ep->dev; - - if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) { - ep_err(ep, "bogus device state\n"); - return -ESHUTDOWN; - } - - ep->enabled = 1; - - /* flush fifo (mostly for OUT buffers) */ - pxa_ep_fifo_flush(_ep); - - ep_dbg(ep, "enabled\n"); - return 0; -} - -/** - * pxa_ep_disable - Disable usb endpoint - * @_ep: usb endpoint - * - * Same as for pxa_ep_enable, no physical endpoint configuration can be - * changed. - * Function flushes the endpoint and related requests. - */ -static int pxa_ep_disable(struct usb_ep *_ep) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - unsigned long flags; - - if (!_ep) - return -EINVAL; - - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - ep = udc_usb_ep->pxa_ep; - if (!ep || is_ep0(ep) || !list_empty(&ep->queue)) - return -EINVAL; - - spin_lock_irqsave(&ep->lock, flags); - ep->enabled = 0; - nuke(ep, -ESHUTDOWN); - spin_unlock_irqrestore(&ep->lock, flags); - - pxa_ep_fifo_flush(_ep); - udc_usb_ep->pxa_ep = NULL; - - ep_dbg(ep, "disabled\n"); - return 0; -} - -static struct usb_ep_ops pxa_ep_ops = { - .enable = pxa_ep_enable, - .disable = pxa_ep_disable, - - .alloc_request = pxa_ep_alloc_request, - .free_request = pxa_ep_free_request, - - .queue = pxa_ep_queue, - .dequeue = pxa_ep_dequeue, - - .set_halt = pxa_ep_set_halt, - .fifo_status = pxa_ep_fifo_status, - .fifo_flush = pxa_ep_fifo_flush, -}; - - -/** - * pxa_udc_get_frame - Returns usb frame number - * @_gadget: usb gadget - */ -static int pxa_udc_get_frame(struct usb_gadget *_gadget) -{ - struct pxa_udc *udc = to_gadget_udc(_gadget); - - return (udc_readl(udc, UDCFNR) & 0x7ff); -} - -/** - * pxa_udc_wakeup - Force udc device out of suspend - * @_gadget: usb gadget - * - * Returns 0 if succesfull, error code otherwise - */ -static int pxa_udc_wakeup(struct usb_gadget *_gadget) -{ - struct pxa_udc *udc = to_gadget_udc(_gadget); - - /* host may not have enabled remote wakeup */ - if ((udc_readl(udc, UDCCR) & UDCCR_DWRE) == 0) - return -EHOSTUNREACH; - udc_set_mask_UDCCR(udc, UDCCR_UDR); - return 0; -} - -static const struct usb_gadget_ops pxa_udc_ops = { - .get_frame = pxa_udc_get_frame, - .wakeup = pxa_udc_wakeup, - /* current versions must always be self-powered */ -}; - -/** - * udc_disable - disable udc device controller - * @udc: udc device - * - * Disables the udc device : disables clocks, udc interrupts, control endpoint - * interrupts. - */ -static void udc_disable(struct pxa_udc *udc) -{ - udc_writel(udc, UDCICR0, 0); - udc_writel(udc, UDCICR1, 0); - - udc_clear_mask_UDCCR(udc, UDCCR_UDE); - clk_disable(udc->clk); - - ep0_idle(udc); - udc->gadget.speed = USB_SPEED_UNKNOWN; - udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); -} - -/** - * udc_init_data - Initialize udc device data structures - * @dev: udc device - * - * Initializes gadget endpoint list, endpoints locks. No action is taken - * on the hardware. - */ -static __init void udc_init_data(struct pxa_udc *dev) -{ - int i; - struct pxa_ep *ep; - - /* device/ep0 records init */ - INIT_LIST_HEAD(&dev->gadget.ep_list); - INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); - dev->udc_usb_ep[0].pxa_ep = &dev->pxa_ep[0]; - ep0_idle(dev); - strcpy(dev->dev->bus_id, ""); - - /* PXA endpoints init */ - for (i = 0; i < NR_PXA_ENDPOINTS; i++) { - ep = &dev->pxa_ep[i]; - - ep->enabled = is_ep0(ep); - INIT_LIST_HEAD(&ep->queue); - spin_lock_init(&ep->lock); - } - - /* USB endpoints init */ - for (i = 0; i < NR_USB_ENDPOINTS; i++) - if (i != 0) - list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list, - &dev->gadget.ep_list); -} - -/** - * udc_enable - Enables the udc device - * @dev: udc device - * - * Enables the udc device : enables clocks, udc interrupts, control endpoint - * interrupts, sets usb as UDC client and setups endpoints. - */ -static void udc_enable(struct pxa_udc *udc) -{ - udc_writel(udc, UDCICR0, 0); - udc_writel(udc, UDCICR1, 0); - udc_writel(udc, UP2OCR, UP2OCR_HXOE); - udc_clear_mask_UDCCR(udc, UDCCR_UDE); - - clk_enable(udc->clk); - - ep0_idle(udc); - udc->gadget.speed = USB_SPEED_FULL; - memset(&udc->stats, 0, sizeof(udc->stats)); - - udc_set_mask_UDCCR(udc, UDCCR_UDE); - udelay(2); - if (udc_readl(udc, UDCCR) & UDCCR_EMCE) - dev_err(udc->dev, "Configuration errors, udc disabled\n"); - - /* - * Caller must be able to sleep in order to cope with startup transients - */ - msleep(100); - - /* enable suspend/resume and reset irqs */ - udc_writel(udc, UDCICR1, - UDCICR1_IECC | UDCICR1_IERU - | UDCICR1_IESU | UDCICR1_IERS); - - /* enable ep0 irqs */ - pio_irq_enable(&udc->pxa_ep[0]); - - dev_info(udc->dev, "UDC connecting\n"); - if (udc->mach->udc_command) - udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); -} - -/** - * usb_gadget_register_driver - Register gadget driver - * @driver: gadget driver - * - * When a driver is successfully registered, it will receive control requests - * including set_configuration(), which enables non-control requests. Then - * usb traffic follows until a disconnect is reported. Then a host may connect - * again, or the driver might get unbound. - * - * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise - */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) -{ - struct pxa_udc *udc = the_controller; - int retval; - - if (!driver || driver->speed != USB_SPEED_FULL || !driver->bind - || !driver->disconnect || !driver->setup) - return -EINVAL; - if (!udc) - return -ENODEV; - if (udc->driver) - return -EBUSY; - - /* first hook up the driver ... */ - udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; - - retval = device_add(&udc->gadget.dev); - if (retval) { - dev_err(udc->dev, "device_add error %d\n", retval); - goto add_fail; - } - retval = driver->bind(&udc->gadget); - if (retval) { - dev_err(udc->dev, "bind to driver %s --> error %d\n", - driver->driver.name, retval); - goto bind_fail; - } - dev_dbg(udc->dev, "registered gadget driver '%s'\n", - driver->driver.name); - - udc_enable(udc); - return 0; - -bind_fail: - device_del(&udc->gadget.dev); -add_fail: - udc->driver = NULL; - udc->gadget.dev.driver = NULL; - return retval; -} -EXPORT_SYMBOL(usb_gadget_register_driver); - - -/** - * stop_activity - Stops udc endpoints - * @udc: udc device - * @driver: gadget driver - * - * Disables all udc endpoints (even control endpoint), report disconnect to - * the gadget user. - */ -static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver) -{ - int i; - - /* don't disconnect drivers more than once */ - if (udc->gadget.speed == USB_SPEED_UNKNOWN) - driver = NULL; - udc->gadget.speed = USB_SPEED_UNKNOWN; - - for (i = 0; i < NR_USB_ENDPOINTS; i++) - pxa_ep_disable(&udc->udc_usb_ep[i].usb_ep); - - if (driver) - driver->disconnect(&udc->gadget); -} - -/** - * usb_gadget_unregister_driver - Unregister the gadget driver - * @driver: gadget driver - * - * Returns 0 if no error, -ENODEV, -EINVAL otherwise - */ -int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) -{ - struct pxa_udc *udc = the_controller; - - if (!udc) - return -ENODEV; - if (!driver || driver != udc->driver || !driver->unbind) - return -EINVAL; - - stop_activity(udc, driver); - udc_disable(udc); - - driver->unbind(&udc->gadget); - udc->driver = NULL; - - device_del(&udc->gadget.dev); - - dev_info(udc->dev, "unregistered gadget driver '%s'\n", - driver->driver.name); - return 0; -} -EXPORT_SYMBOL(usb_gadget_unregister_driver); - -/** - * handle_ep0_ctrl_req - handle control endpoint control request - * @udc: udc device - * @req: control request - */ -static void handle_ep0_ctrl_req(struct pxa_udc *udc, - struct pxa27x_request *req) -{ - struct pxa_ep *ep = &udc->pxa_ep[0]; - union { - struct usb_ctrlrequest r; - u32 word[2]; - } u; - int i; - int have_extrabytes = 0; - - nuke(ep, -EPROTO); - - /* read SETUP packet */ - for (i = 0; i < 2; i++) { - if (unlikely(ep_is_empty(ep))) - goto stall; - u.word[i] = udc_ep_readl(ep, UDCDR); - } - - have_extrabytes = !ep_is_empty(ep); - while (!ep_is_empty(ep)) { - i = udc_ep_readl(ep, UDCDR); - ep_err(ep, "wrong to have extra bytes for setup : 0x%08x\n", i); - } - - le16_to_cpus(&u.r.wValue); - le16_to_cpus(&u.r.wIndex); - le16_to_cpus(&u.r.wLength); - - ep_dbg(ep, "SETUP %02x.%02x v%04x i%04x l%04x\n", - u.r.bRequestType, u.r.bRequest, - u.r.wValue, u.r.wIndex, u.r.wLength); - if (unlikely(have_extrabytes)) - goto stall; - - if (u.r.bRequestType & USB_DIR_IN) - set_ep0state(udc, IN_DATA_STAGE); - else - set_ep0state(udc, OUT_DATA_STAGE); - - /* Tell UDC to enter Data Stage */ - udc_ep_writel(ep, UDCCSR, UDCCSR0_SA | UDCCSR0_OPC); - - i = udc->driver->setup(&udc->gadget, &u.r); - if (i < 0) - goto stall; -out: - return; -stall: - ep_dbg(ep, "protocol STALL, udccsr0=%03x err %d\n", - udc_ep_readl(ep, UDCCSR), i); - udc_ep_writel(ep, UDCCSR, UDCCSR0_FST | UDCCSR0_FTF); - set_ep0state(udc, STALL); - goto out; -} - -/** - * handle_ep0 - Handle control endpoint data transfers - * @udc: udc device - * @fifo_irq: 1 if triggered by fifo service type irq - * @opc_irq: 1 if triggered by output packet complete type irq - * - * Context : when in_interrupt() or with ep->lock held - * - * Tries to transfer all pending request data into the endpoint and/or - * transfer all pending data in the endpoint into usb requests. - * Handles states of ep0 automata. - * - * PXA27x hardware handles several standard usb control requests without - * driver notification. The requests fully handled by hardware are : - * SET_ADDRESS, SET_FEATURE, CLEAR_FEATURE, GET_CONFIGURATION, GET_INTERFACE, - * GET_STATUS - * The requests handled by hardware, but with irq notification are : - * SYNCH_FRAME, SET_CONFIGURATION, SET_INTERFACE - * The remaining standard requests really handled by handle_ep0 are : - * GET_DESCRIPTOR, SET_DESCRIPTOR, specific requests. - * Requests standardized outside of USB 2.0 chapter 9 are handled more - * uniformly, by gadget drivers. - * - * The control endpoint state machine is _not_ USB spec compliant, it's even - * hardly compliant with Intel PXA270 developers guide. - * The key points which inferred this state machine are : - * - on every setup token, bit UDCCSR0_SA is raised and held until cleared by - * software. - * - on every OUT packet received, UDCCSR0_OPC is raised and held until - * cleared by software. - * - clearing UDCCSR0_OPC always flushes ep0. If in setup stage, never do it - * before reading ep0. - * - irq can be called on a "packet complete" event (opc_irq=1), while - * UDCCSR0_OPC is not yet raised (delta can be as big as 100ms - * from experimentation). - * - as UDCCSR0_SA can be activated while in irq handling, and clearing - * UDCCSR0_OPC would flush the setup data, we almost never clear UDCCSR0_OPC - * => we never actually read the "status stage" packet of an IN data stage - * => this is not documented in Intel documentation - * - hardware as no idea of STATUS STAGE, it only handle SETUP STAGE and DATA - * STAGE. The driver add STATUS STAGE to send last zero length packet in - * OUT_STATUS_STAGE. - * - special attention was needed for IN_STATUS_STAGE. If a packet complete - * event is detected, we terminate the status stage without ackowledging the - * packet (not to risk to loose a potential SETUP packet) - */ -static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq) -{ - u32 udccsr0; - struct pxa_ep *ep = &udc->pxa_ep[0]; - struct pxa27x_request *req = NULL; - int completed = 0; - - udccsr0 = udc_ep_readl(ep, UDCCSR); - ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n", - EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR), - (fifo_irq << 1 | opc_irq)); - - if (!list_empty(&ep->queue)) - req = list_entry(ep->queue.next, struct pxa27x_request, queue); - - if (udccsr0 & UDCCSR0_SST) { - ep_dbg(ep, "clearing stall status\n"); - nuke(ep, -EPIPE); - udc_ep_writel(ep, UDCCSR, UDCCSR0_SST); - ep0_idle(udc); - } - - if (udccsr0 & UDCCSR0_SA) { - nuke(ep, 0); - set_ep0state(udc, SETUP_STAGE); - } - - switch (udc->ep0state) { - case WAIT_FOR_SETUP: - /* - * Hardware bug : beware, we cannot clear OPC, since we would - * miss a potential OPC irq for a setup packet. - * So, we only do ... nothing, and hope for a next irq with - * UDCCSR0_SA set. - */ - break; - case SETUP_STAGE: - udccsr0 &= UDCCSR0_CTRL_REQ_MASK; - if (likely(udccsr0 == UDCCSR0_CTRL_REQ_MASK)) - handle_ep0_ctrl_req(udc, req); - break; - case IN_DATA_STAGE: /* GET_DESCRIPTOR */ - if (epout_has_pkt(ep)) - udc_ep_writel(ep, UDCCSR, UDCCSR0_OPC); - if (req && !ep_is_full(ep)) - completed = write_ep0_fifo(ep, req); - if (completed) - ep0_end_in_req(ep, req); - break; - case OUT_DATA_STAGE: /* SET_DESCRIPTOR */ - if (epout_has_pkt(ep) && req) - completed = read_ep0_fifo(ep, req); - if (completed) - ep0_end_out_req(ep, req); - break; - case STALL: - udc_ep_writel(ep, UDCCSR, UDCCSR0_FST); - break; - case IN_STATUS_STAGE: - /* - * Hardware bug : beware, we cannot clear OPC, since we would - * miss a potential PC irq for a setup packet. - * So, we only put the ep0 into WAIT_FOR_SETUP state. - */ - if (opc_irq) - ep0_idle(udc); - break; - case OUT_STATUS_STAGE: - case WAIT_ACK_SET_CONF_INTERF: - ep_warn(ep, "should never get in %s state here!!!\n", - EP0_STNAME(ep->dev)); - ep0_idle(udc); - break; - } -} - -/** - * handle_ep - Handle endpoint data tranfers - * @ep: pxa physical endpoint - * - * Tries to transfer all pending request data into the endpoint and/or - * transfer all pending data in the endpoint into usb requests. - * - * Is always called when in_interrupt() or with ep->lock held. - */ -static void handle_ep(struct pxa_ep *ep) -{ - struct pxa27x_request *req; - int completed; - u32 udccsr; - int is_in = ep->dir_in; - int loop = 0; - - do { - completed = 0; - udccsr = udc_ep_readl(ep, UDCCSR); - if (likely(!list_empty(&ep->queue))) - req = list_entry(ep->queue.next, - struct pxa27x_request, queue); - else - req = NULL; - - ep_dbg(ep, "req:%p, udccsr 0x%03x loop=%d\n", - req, udccsr, loop++); - - if (unlikely(udccsr & (UDCCSR_SST | UDCCSR_TRN))) - udc_ep_writel(ep, UDCCSR, - udccsr & (UDCCSR_SST | UDCCSR_TRN)); - if (!req) - break; - - if (unlikely(is_in)) { - if (likely(!ep_is_full(ep))) - completed = write_fifo(ep, req); - if (completed) - ep_end_in_req(ep, req); - } else { - if (likely(epout_has_pkt(ep))) - completed = read_fifo(ep, req); - if (completed) - ep_end_out_req(ep, req); - } - } while (completed); -} - -/** - * pxa27x_change_configuration - Handle SET_CONF usb request notification - * @udc: udc device - * @config: usb configuration - * - * Post the request to upper level. - * Don't use any pxa specific harware configuration capabilities - */ -static void pxa27x_change_configuration(struct pxa_udc *udc, int config) -{ - struct usb_ctrlrequest req ; - - dev_dbg(udc->dev, "config=%d\n", config); - - udc->config = config; - udc->last_interface = 0; - udc->last_alternate = 0; - - req.bRequestType = 0; - req.bRequest = USB_REQ_SET_CONFIGURATION; - req.wValue = config; - req.wIndex = 0; - req.wLength = 0; - - set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF); - udc->driver->setup(&udc->gadget, &req); -} - -/** - * pxa27x_change_interface - Handle SET_INTERF usb request notification - * @udc: udc device - * @iface: interface number - * @alt: alternate setting number - * - * Post the request to upper level. - * Don't use any pxa specific harware configuration capabilities - */ -static void pxa27x_change_interface(struct pxa_udc *udc, int iface, int alt) -{ - struct usb_ctrlrequest req; - - dev_dbg(udc->dev, "interface=%d, alternate setting=%d\n", iface, alt); - - udc->last_interface = iface; - udc->last_alternate = alt; - - req.bRequestType = USB_RECIP_INTERFACE; - req.bRequest = USB_REQ_SET_INTERFACE; - req.wValue = alt; - req.wIndex = iface; - req.wLength = 0; - - set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF); - udc->driver->setup(&udc->gadget, &req); -} - -/* - * irq_handle_data - Handle data transfer - * @irq: irq IRQ number - * @udc: dev pxa_udc device structure - * - * Called from irq handler, transferts data to or from endpoint to queue - */ -static void irq_handle_data(int irq, struct pxa_udc *udc) -{ - int i; - struct pxa_ep *ep; - u32 udcisr0 = udc_readl(udc, UDCISR0) & UDCCISR0_EP_MASK; - u32 udcisr1 = udc_readl(udc, UDCISR1) & UDCCISR1_EP_MASK; - - if (udcisr0 & UDCISR_INT_MASK) { - udc->pxa_ep[0].stats.irqs++; - udc_writel(udc, UDCISR0, UDCISR_INT(0, UDCISR_INT_MASK)); - handle_ep0(udc, !!(udcisr0 & UDCICR_FIFOERR), - !!(udcisr0 & UDCICR_PKTCOMPL)); - } - - udcisr0 >>= 2; - for (i = 1; udcisr0 != 0 && i < 16; udcisr0 >>= 2, i++) { - if (!(udcisr0 & UDCISR_INT_MASK)) - continue; - - udc_writel(udc, UDCISR0, UDCISR_INT(i, UDCISR_INT_MASK)); - ep = &udc->pxa_ep[i]; - ep->stats.irqs++; - handle_ep(ep); - } - - for (i = 16; udcisr1 != 0 && i < 24; udcisr1 >>= 2, i++) { - udc_writel(udc, UDCISR1, UDCISR_INT(i - 16, UDCISR_INT_MASK)); - if (!(udcisr1 & UDCISR_INT_MASK)) - continue; - - ep = &udc->pxa_ep[i]; - ep->stats.irqs++; - handle_ep(ep); - } - -} - -/** - * irq_udc_suspend - Handle IRQ "UDC Suspend" - * @udc: udc device - */ -static void irq_udc_suspend(struct pxa_udc *udc) -{ - udc_writel(udc, UDCISR1, UDCISR1_IRSU); - udc->stats.irqs_suspend++; - - if (udc->gadget.speed != USB_SPEED_UNKNOWN - && udc->driver && udc->driver->suspend) - udc->driver->suspend(&udc->gadget); - ep0_idle(udc); -} - -/** - * irq_udc_resume - Handle IRQ "UDC Resume" - * @udc: udc device - */ -static void irq_udc_resume(struct pxa_udc *udc) -{ - udc_writel(udc, UDCISR1, UDCISR1_IRRU); - udc->stats.irqs_resume++; - - if (udc->gadget.speed != USB_SPEED_UNKNOWN - && udc->driver && udc->driver->resume) - udc->driver->resume(&udc->gadget); -} - -/** - * irq_udc_reconfig - Handle IRQ "UDC Change Configuration" - * @udc: udc device - */ -static void irq_udc_reconfig(struct pxa_udc *udc) -{ - unsigned config, interface, alternate, config_change; - u32 udccr = udc_readl(udc, UDCCR); - - udc_writel(udc, UDCISR1, UDCISR1_IRCC); - udc->stats.irqs_reconfig++; - - config = (udccr & UDCCR_ACN) >> UDCCR_ACN_S; - config_change = (config != udc->config); - pxa27x_change_configuration(udc, config); - - interface = (udccr & UDCCR_AIN) >> UDCCR_AIN_S; - alternate = (udccr & UDCCR_AAISN) >> UDCCR_AAISN_S; - pxa27x_change_interface(udc, interface, alternate); - - if (config_change) - update_pxa_ep_matches(udc); - udc_set_mask_UDCCR(udc, UDCCR_SMAC); -} - -/** - * irq_udc_reset - Handle IRQ "UDC Reset" - * @udc: udc device - */ -static void irq_udc_reset(struct pxa_udc *udc) -{ - u32 udccr = udc_readl(udc, UDCCR); - struct pxa_ep *ep = &udc->pxa_ep[0]; - - dev_info(udc->dev, "USB reset\n"); - udc_writel(udc, UDCISR1, UDCISR1_IRRS); - udc->stats.irqs_reset++; - - if ((udccr & UDCCR_UDA) == 0) { - dev_dbg(udc->dev, "USB reset start\n"); - stop_activity(udc, udc->driver); - } - udc->gadget.speed = USB_SPEED_FULL; - memset(&udc->stats, 0, sizeof udc->stats); - - nuke(ep, -EPROTO); - udc_ep_writel(ep, UDCCSR, UDCCSR0_FTF | UDCCSR0_OPC); - ep0_idle(udc); -} - -/** - * pxa_udc_irq - Main irq handler - * @irq: irq number - * @_dev: udc device - * - * Handles all udc interrupts - */ -static irqreturn_t pxa_udc_irq(int irq, void *_dev) -{ - struct pxa_udc *udc = _dev; - u32 udcisr0 = udc_readl(udc, UDCISR0); - u32 udcisr1 = udc_readl(udc, UDCISR1); - u32 udccr = udc_readl(udc, UDCCR); - u32 udcisr1_spec; - - dev_vdbg(udc->dev, "Interrupt, UDCISR0:0x%08x, UDCISR1:0x%08x, " - "UDCCR:0x%08x\n", udcisr0, udcisr1, udccr); - - udcisr1_spec = udcisr1 & 0xf8000000; - if (unlikely(udcisr1_spec & UDCISR1_IRSU)) - irq_udc_suspend(udc); - if (unlikely(udcisr1_spec & UDCISR1_IRRU)) - irq_udc_resume(udc); - if (unlikely(udcisr1_spec & UDCISR1_IRCC)) - irq_udc_reconfig(udc); - if (unlikely(udcisr1_spec & UDCISR1_IRRS)) - irq_udc_reset(udc); - - if ((udcisr0 & UDCCISR0_EP_MASK) | (udcisr1 & UDCCISR1_EP_MASK)) - irq_handle_data(irq, udc); - - return IRQ_HANDLED; -} - -static struct pxa_udc memory = { - .gadget = { - .ops = &pxa_udc_ops, - .ep0 = &memory.udc_usb_ep[0].usb_ep, - .name = driver_name, - .dev = { - .bus_id = "gadget", - }, - }, - - .udc_usb_ep = { - USB_EP_CTRL, - USB_EP_OUT_BULK(1), - USB_EP_IN_BULK(2), - USB_EP_IN_ISO(3), - USB_EP_OUT_ISO(4), - USB_EP_IN_INT(5), - }, - - .pxa_ep = { - PXA_EP_CTRL, - /* Endpoints for gadget zero */ - PXA_EP_OUT_BULK(1, 1, 3, 0, 0), - PXA_EP_IN_BULK(2, 2, 3, 0, 0), - /* Endpoints for ether gadget, file storage gadget */ - PXA_EP_OUT_BULK(3, 1, 1, 0, 0), - PXA_EP_IN_BULK(4, 2, 1, 0, 0), - PXA_EP_IN_ISO(5, 3, 1, 0, 0), - PXA_EP_OUT_ISO(6, 4, 1, 0, 0), - PXA_EP_IN_INT(7, 5, 1, 0, 0), - /* Endpoints for RNDIS, serial */ - PXA_EP_OUT_BULK(8, 1, 2, 0, 0), - PXA_EP_IN_BULK(9, 2, 2, 0, 0), - PXA_EP_IN_INT(10, 5, 2, 0, 0), - /* - * All the following endpoints are only for completion. They - * won't never work, as multiple interfaces are really broken on - * the pxa. - */ - PXA_EP_OUT_BULK(11, 1, 2, 1, 0), - PXA_EP_IN_BULK(12, 2, 2, 1, 0), - /* Endpoint for CDC Ether */ - PXA_EP_OUT_BULK(13, 1, 1, 1, 1), - PXA_EP_IN_BULK(14, 2, 1, 1, 1), - } -}; - -/** - * pxa_udc_probe - probes the udc device - * @_dev: platform device - * - * Perform basic init : allocates udc clock, creates sysfs files, requests - * irq. - */ -static int __init pxa_udc_probe(struct platform_device *pdev) -{ - struct resource *regs; - struct pxa_udc *udc = &memory; - int retval; - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) - return -ENXIO; - udc->irq = platform_get_irq(pdev, 0); - if (udc->irq < 0) - return udc->irq; - - udc->dev = &pdev->dev; - udc->mach = pdev->dev.platform_data; - - udc->clk = clk_get(&pdev->dev, "UDCCLK"); - if (IS_ERR(udc->clk)) { - retval = PTR_ERR(udc->clk); - goto err_clk; - } - - retval = -ENOMEM; - udc->regs = ioremap(regs->start, regs->end - regs->start + 1); - if (!udc->regs) { - dev_err(&pdev->dev, "Unable to map UDC I/O memory\n"); - goto err_map; - } - - device_initialize(&udc->gadget.dev); - udc->gadget.dev.parent = &pdev->dev; - udc->gadget.dev.dma_mask = NULL; - - the_controller = udc; - platform_set_drvdata(pdev, udc); - udc_init_data(udc); - pxa_eps_setup(udc); - - /* irq setup after old hardware state is cleaned up */ - retval = request_irq(udc->irq, pxa_udc_irq, - IRQF_SHARED, driver_name, udc); - if (retval != 0) { - dev_err(udc->dev, "%s: can't get irq %i, err %d\n", - driver_name, IRQ_USB, retval); - goto err_irq; - } - - pxa_init_debugfs(udc); - return 0; -err_irq: - iounmap(udc->regs); -err_map: - clk_put(udc->clk); - udc->clk = NULL; -err_clk: - return retval; -} - -/** - * pxa_udc_remove - removes the udc device driver - * @_dev: platform device - */ -static int __exit pxa_udc_remove(struct platform_device *_dev) -{ - struct pxa_udc *udc = platform_get_drvdata(_dev); - - usb_gadget_unregister_driver(udc->driver); - free_irq(udc->irq, udc); - pxa_cleanup_debugfs(udc); - - platform_set_drvdata(_dev, NULL); - the_controller = NULL; - clk_put(udc->clk); - - return 0; -} - -static void pxa_udc_shutdown(struct platform_device *_dev) -{ - struct pxa_udc *udc = platform_get_drvdata(_dev); - - udc_disable(udc); -} - -#ifdef CONFIG_PM -/** - * pxa_udc_suspend - Suspend udc device - * @_dev: platform device - * @state: suspend state - * - * Suspends udc : saves configuration registers (UDCCR*), then disables the udc - * device. - */ -static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) -{ - int i; - struct pxa_udc *udc = platform_get_drvdata(_dev); - struct pxa_ep *ep; - - ep = &udc->pxa_ep[0]; - udc->udccsr0 = udc_ep_readl(ep, UDCCSR); - for (i = 1; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - ep->udccsr_value = udc_ep_readl(ep, UDCCSR); - ep->udccr_value = udc_ep_readl(ep, UDCCR); - ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n", - ep->udccsr_value, ep->udccr_value); - } - - udc_disable(udc); - - return 0; -} - -/** - * pxa_udc_resume - Resume udc device - * @_dev: platform device - * - * Resumes udc : restores configuration registers (UDCCR*), then enables the udc - * device. - */ -static int pxa_udc_resume(struct platform_device *_dev) -{ - int i; - struct pxa_udc *udc = platform_get_drvdata(_dev); - struct pxa_ep *ep; - - ep = &udc->pxa_ep[0]; - udc_ep_writel(ep, UDCCSR, udc->udccsr0 & (UDCCSR0_FST | UDCCSR0_DME)); - for (i = 1; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - udc_ep_writel(ep, UDCCSR, ep->udccsr_value); - udc_ep_writel(ep, UDCCR, ep->udccr_value); - ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n", - ep->udccsr_value, ep->udccr_value); - } - - udc_enable(udc); - /* - * We do not handle OTG yet. - * - * OTGPH bit is set when sleep mode is entered. - * it indicates that OTG pad is retaining its state. - * Upon exit from sleep mode and before clearing OTGPH, - * Software must configure the USB OTG pad, UDC, and UHC - * to the state they were in before entering sleep mode. - * - * Should be : PSSR |= PSSR_OTGPH; - */ - - return 0; -} -#endif - -/* work with hotplug and coldplug */ -MODULE_ALIAS("platform:pxa2xx-udc"); - -static struct platform_driver udc_driver = { - .driver = { - .name = "pxa2xx-udc", - .owner = THIS_MODULE, - }, - .remove = __exit_p(pxa_udc_remove), - .shutdown = pxa_udc_shutdown, -#ifdef CONFIG_PM - .suspend = pxa_udc_suspend, - .resume = pxa_udc_resume -#endif -}; - -static int __init udc_init(void) -{ - printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION); - return platform_driver_probe(&udc_driver, pxa_udc_probe); -} -module_init(udc_init); - - -static void __exit udc_exit(void) -{ - platform_driver_unregister(&udc_driver); -} -module_exit(udc_exit); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR("Robert Jarzmik"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/gadget/pxa27x_udc.h b/trunk/drivers/usb/gadget/pxa27x_udc.h deleted file mode 100644 index 1d1b7936ee11..000000000000 --- a/trunk/drivers/usb/gadget/pxa27x_udc.h +++ /dev/null @@ -1,487 +0,0 @@ -/* - * linux/drivers/usb/gadget/pxa27x_udc.h - * Intel PXA27x on-chip full speed USB device controller - * - * Inspired by original driver by Frank Becker, David Brownell, and others. - * Copyright (C) 2008 Robert Jarzmik - * - * 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 __LINUX_USB_GADGET_PXA27X_H -#define __LINUX_USB_GADGET_PXA27X_H - -#include -#include -#include - -/* - * Register definitions - */ -/* Offsets */ -#define UDCCR 0x0000 /* UDC Control Register */ -#define UDCICR0 0x0004 /* UDC Interrupt Control Register0 */ -#define UDCICR1 0x0008 /* UDC Interrupt Control Register1 */ -#define UDCISR0 0x000C /* UDC Interrupt Status Register 0 */ -#define UDCISR1 0x0010 /* UDC Interrupt Status Register 1 */ -#define UDCFNR 0x0014 /* UDC Frame Number Register */ -#define UDCOTGICR 0x0018 /* UDC On-The-Go interrupt control */ -#define UP2OCR 0x0020 /* USB Port 2 Output Control register */ -#define UP3OCR 0x0024 /* USB Port 3 Output Control register */ -#define UDCCSRn(x) (0x0100 + ((x)<<2)) /* UDC Control/Status register */ -#define UDCBCRn(x) (0x0200 + ((x)<<2)) /* UDC Byte Count Register */ -#define UDCDRn(x) (0x0300 + ((x)<<2)) /* UDC Data Register */ -#define UDCCRn(x) (0x0400 + ((x)<<2)) /* UDC Control Register */ - -#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */ -#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation - Protocol Port Support */ -#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol - Support */ -#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol - Enable */ -#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */ -#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */ -#define UDCCR_ACN_S 11 -#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */ -#define UDCCR_AIN_S 8 -#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface - Setting Number */ -#define UDCCR_AAISN_S 5 -#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active - Configuration */ -#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration - Error */ -#define UDCCR_UDR (1 << 2) /* UDC Resume */ -#define UDCCR_UDA (1 << 1) /* UDC Active */ -#define UDCCR_UDE (1 << 0) /* UDC Enable */ - -#define UDCICR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) -#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */ -#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */ -#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */ -#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */ -#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */ -#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */ -#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */ -#define UDCICR_INT_MASK (UDCICR_FIFOERR | UDCICR_PKTCOMPL) - -#define UDCISR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) -#define UDCISR1_IRCC (1 << 31) /* IntReq - Configuration Change */ -#define UDCISR1_IRSOF (1 << 30) /* IntReq - Start of Frame */ -#define UDCISR1_IRRU (1 << 29) /* IntReq - Resume */ -#define UDCISR1_IRSU (1 << 28) /* IntReq - Suspend */ -#define UDCISR1_IRRS (1 << 27) /* IntReq - Reset */ -#define UDCISR_INT_MASK (UDCICR_FIFOERR | UDCICR_PKTCOMPL) - -#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */ -#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt - Rising Edge Interrupt Enable */ -#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt - Falling Edge Interrupt Enable */ -#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising - Edge Interrupt Enable */ -#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling - Edge Interrupt Enable */ -#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge - Interrupt Enable */ - -/* Host Port 2 field bits */ -#define UP2OCR_CPVEN (1 << 0) /* Charge Pump Vbus Enable */ -#define UP2OCR_CPVPE (1 << 1) /* Charge Pump Vbus Pulse Enable */ - /* Transceiver enablers */ -#define UP2OCR_DPPDE (1 << 2) /* D+ Pull Down Enable */ -#define UP2OCR_DMPDE (1 << 3) /* D- Pull Down Enable */ -#define UP2OCR_DPPUE (1 << 4) /* D+ Pull Up Enable */ -#define UP2OCR_DMPUE (1 << 5) /* D- Pull Up Enable */ -#define UP2OCR_DPPUBE (1 << 6) /* D+ Pull Up Bypass Enable */ -#define UP2OCR_DMPUBE (1 << 7) /* D- Pull Up Bypass Enable */ -#define UP2OCR_EXSP (1 << 8) /* External Transceiver Speed Control */ -#define UP2OCR_EXSUS (1 << 9) /* External Transceiver Speed Enable */ -#define UP2OCR_IDON (1 << 10) /* OTG ID Read Enable */ -#define UP2OCR_HXS (1 << 16) /* Transceiver Output Select */ -#define UP2OCR_HXOE (1 << 17) /* Transceiver Output Enable */ -#define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */ - -#define UDCCSR0_SA (1 << 7) /* Setup Active */ -#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */ -#define UDCCSR0_FST (1 << 5) /* Force Stall */ -#define UDCCSR0_SST (1 << 4) /* Sent Stall */ -#define UDCCSR0_DME (1 << 3) /* DMA Enable */ -#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */ -#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */ -#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */ - -#define UDCCSR_DPE (1 << 9) /* Data Packet Error */ -#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */ -#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */ -#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */ -#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */ -#define UDCCSR_FST (1 << 5) /* Force STALL */ -#define UDCCSR_SST (1 << 4) /* Sent STALL */ -#define UDCCSR_DME (1 << 3) /* DMA Enable */ -#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */ -#define UDCCSR_PC (1 << 1) /* Packet Complete */ -#define UDCCSR_FS (1 << 0) /* FIFO needs service */ - -#define UDCCONR_CN (0x03 << 25) /* Configuration Number */ -#define UDCCONR_CN_S 25 -#define UDCCONR_IN (0x07 << 22) /* Interface Number */ -#define UDCCONR_IN_S 22 -#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */ -#define UDCCONR_AISN_S 19 -#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */ -#define UDCCONR_EN_S 15 -#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */ -#define UDCCONR_ET_S 13 -#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */ -#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */ -#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */ -#define UDCCONR_ET_NU (0x00 << 13) /* Not used */ -#define UDCCONR_ED (1 << 12) /* Endpoint Direction */ -#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */ -#define UDCCONR_MPS_S 2 -#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */ -#define UDCCONR_EE (1 << 0) /* Endpoint Enable */ - -#define UDCCR_MASK_BITS (UDCCR_OEN | UDCCR_SMAC | UDCCR_UDR | UDCCR_UDE) -#define UDCCSR_WR_MASK (UDCCSR_DME | UDCCSR_FST) -#define UDC_FNR_MASK (0x7ff) -#define UDC_BCR_MASK (0x3ff) - -/* - * UDCCR = UDC Endpoint Configuration Registers - * UDCCSR = UDC Control/Status Register for this EP - * UDCBCR = UDC Byte Count Remaining (contents of OUT fifo) - * UDCDR = UDC Endpoint Data Register (the fifo) - */ -#define ofs_UDCCR(ep) (UDCCRn(ep->idx)) -#define ofs_UDCCSR(ep) (UDCCSRn(ep->idx)) -#define ofs_UDCBCR(ep) (UDCBCRn(ep->idx)) -#define ofs_UDCDR(ep) (UDCDRn(ep->idx)) - -/* Register access macros */ -#define udc_ep_readl(ep, reg) \ - __raw_readl((ep)->dev->regs + ofs_##reg(ep)) -#define udc_ep_writel(ep, reg, value) \ - __raw_writel((value), ep->dev->regs + ofs_##reg(ep)) -#define udc_ep_readb(ep, reg) \ - __raw_readb((ep)->dev->regs + ofs_##reg(ep)) -#define udc_ep_writeb(ep, reg, value) \ - __raw_writeb((value), ep->dev->regs + ofs_##reg(ep)) -#define udc_readl(dev, reg) \ - __raw_readl((dev)->regs + (reg)) -#define udc_writel(udc, reg, value) \ - __raw_writel((value), (udc)->regs + (reg)) - -#define UDCCSR_MASK (UDCCSR_FST | UDCCSR_DME) -#define UDCCISR0_EP_MASK ~0 -#define UDCCISR1_EP_MASK 0xffff -#define UDCCSR0_CTRL_REQ_MASK (UDCCSR0_OPC | UDCCSR0_SA | UDCCSR0_RNE) - -#define EPIDX(ep) (ep->idx) -#define EPADDR(ep) (ep->addr) -#define EPXFERTYPE(ep) (ep->type) -#define EPNAME(ep) (ep->name) -#define is_ep0(ep) (!ep->idx) -#define EPXFERTYPE_is_ISO(ep) (EPXFERTYPE(ep) == USB_ENDPOINT_XFER_ISOC) - -/* - * Endpoint definitions - * - * Once enabled, pxa endpoint configuration is freezed, and cannot change - * unless a reset happens or the udc is disabled. - * Therefore, we must define all pxa potential endpoint definitions needed for - * all gadget and set them up before the udc is enabled. - * - * As the architecture chosen is fully static, meaning the pxa endpoint - * configurations are set up once and for all, we must provide a way to match - * one usb endpoint (usb_ep) to several pxa endpoints. The reason is that gadget - * layer autoconf doesn't choose the usb_ep endpoint on (config, interface, alt) - * criteria, while the pxa architecture requires that. - * - * The solution is to define several pxa endpoints matching one usb_ep. Ex: - * - "ep1-in" matches pxa endpoint EPA (which is an IN ep at addr 1, when - * the udc talks on (config=3, interface=0, alt=0) - * - "ep1-in" matches pxa endpoint EPB (which is an IN ep at addr 1, when - * the udc talks on (config=3, interface=0, alt=1) - * - "ep1-in" matches pxa endpoint EPC (which is an IN ep at addr 1, when - * the udc talks on (config=2, interface=0, alt=0) - * - * We'll define the pxa endpoint by its index (EPA => idx=1, EPB => idx=2, ...) - */ - -/* - * Endpoint definition helpers - */ -#define USB_EP_DEF(addr, bname, dir, type, maxpkt) \ -{ .usb_ep = { .name = bname, .ops = &pxa_ep_ops, .maxpacket = maxpkt, }, \ - .desc = { .bEndpointAddress = addr | (dir ? USB_DIR_IN : 0), \ - .bmAttributes = type, \ - .wMaxPacketSize = maxpkt, }, \ - .dev = &memory \ -} -#define USB_EP_BULK(addr, bname, dir) \ - USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_BULK, BULK_FIFO_SIZE) -#define USB_EP_ISO(addr, bname, dir) \ - USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_ISOC, ISO_FIFO_SIZE) -#define USB_EP_INT(addr, bname, dir) \ - USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_INT, INT_FIFO_SIZE) -#define USB_EP_IN_BULK(n) USB_EP_BULK(n, "ep" #n "in-bulk", 1) -#define USB_EP_OUT_BULK(n) USB_EP_BULK(n, "ep" #n "out-bulk", 0) -#define USB_EP_IN_ISO(n) USB_EP_ISO(n, "ep" #n "in-iso", 1) -#define USB_EP_OUT_ISO(n) USB_EP_ISO(n, "ep" #n "out-iso", 0) -#define USB_EP_IN_INT(n) USB_EP_INT(n, "ep" #n "in-int", 1) -#define USB_EP_CTRL USB_EP_DEF(0, "ep0", 0, 0, EP0_FIFO_SIZE) - -#define PXA_EP_DEF(_idx, _addr, dir, _type, maxpkt, _config, iface, altset) \ -{ \ - .dev = &memory, \ - .name = "ep" #_idx, \ - .idx = _idx, .enabled = 0, \ - .dir_in = dir, .addr = _addr, \ - .config = _config, .interface = iface, .alternate = altset, \ - .type = _type, .fifo_size = maxpkt, \ -} -#define PXA_EP_BULK(_idx, addr, dir, config, iface, alt) \ - PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_BULK, BULK_FIFO_SIZE, \ - config, iface, alt) -#define PXA_EP_ISO(_idx, addr, dir, config, iface, alt) \ - PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_ISOC, ISO_FIFO_SIZE, \ - config, iface, alt) -#define PXA_EP_INT(_idx, addr, dir, config, iface, alt) \ - PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_INT, INT_FIFO_SIZE, \ - config, iface, alt) -#define PXA_EP_IN_BULK(i, adr, c, f, a) PXA_EP_BULK(i, adr, 1, c, f, a) -#define PXA_EP_OUT_BULK(i, adr, c, f, a) PXA_EP_BULK(i, adr, 0, c, f, a) -#define PXA_EP_IN_ISO(i, adr, c, f, a) PXA_EP_ISO(i, adr, 1, c, f, a) -#define PXA_EP_OUT_ISO(i, adr, c, f, a) PXA_EP_ISO(i, adr, 0, c, f, a) -#define PXA_EP_IN_INT(i, adr, c, f, a) PXA_EP_INT(i, adr, 1, c, f, a) -#define PXA_EP_CTRL PXA_EP_DEF(0, 0, 0, 0, EP0_FIFO_SIZE, 0, 0, 0) - -struct pxa27x_udc; - -struct stats { - unsigned long in_ops; - unsigned long out_ops; - unsigned long in_bytes; - unsigned long out_bytes; - unsigned long irqs; -}; - -/** - * struct udc_usb_ep - container of each usb_ep structure - * @usb_ep: usb endpoint - * @desc: usb descriptor, especially type and address - * @dev: udc managing this endpoint - * @pxa_ep: matching pxa_ep (cache of find_pxa_ep() call) - */ -struct udc_usb_ep { - struct usb_ep usb_ep; - struct usb_endpoint_descriptor desc; - struct pxa_udc *dev; - struct pxa_ep *pxa_ep; -}; - -/** - * struct pxa_ep - pxa endpoint - * @dev: udc device - * @queue: requests queue - * @lock: lock to pxa_ep data (queues and stats) - * @enabled: true when endpoint enabled (not stopped by gadget layer) - * @idx: endpoint index (1 => epA, 2 => epB, ..., 24 => epX) - * @name: endpoint name (for trace/debug purpose) - * @dir_in: 1 if IN endpoint, 0 if OUT endpoint - * @addr: usb endpoint number - * @config: configuration in which this endpoint is active - * @interface: interface in which this endpoint is active - * @alternate: altsetting in which this endpoitn is active - * @fifo_size: max packet size in the endpoint fifo - * @type: endpoint type (bulk, iso, int, ...) - * @udccsr_value: save register of UDCCSR0 for suspend/resume - * @udccr_value: save register of UDCCR for suspend/resume - * @stats: endpoint statistics - * - * The *PROBLEM* is that pxa's endpoint configuration scheme is both misdesigned - * (cares about config/interface/altsetting, thus placing needless limits on - * device capability) and full of implementation bugs forcing it to be set up - * for use more or less like a pxa255. - * - * As we define the pxa_ep statically, we must guess all needed pxa_ep for all - * gadget which may work with this udc driver. - */ -struct pxa_ep { - struct pxa_udc *dev; - - struct list_head queue; - spinlock_t lock; /* Protects this structure */ - /* (queues, stats) */ - unsigned enabled:1; - - unsigned idx:5; - char *name; - - /* - * Specific pxa endpoint data, needed for hardware initialization - */ - unsigned dir_in:1; - unsigned addr:3; - unsigned config:2; - unsigned interface:3; - unsigned alternate:3; - unsigned fifo_size; - unsigned type; - -#ifdef CONFIG_PM - u32 udccsr_value; - u32 udccr_value; -#endif - struct stats stats; -}; - -/** - * struct pxa27x_request - container of each usb_request structure - * @req: usb request - * @udc_usb_ep: usb endpoint the request was submitted on - * @in_use: sanity check if request already queued on an pxa_ep - * @queue: linked list of requests, linked on pxa_ep->queue - */ -struct pxa27x_request { - struct usb_request req; - struct udc_usb_ep *udc_usb_ep; - unsigned in_use:1; - struct list_head queue; -}; - -enum ep0_state { - WAIT_FOR_SETUP, - SETUP_STAGE, - IN_DATA_STAGE, - OUT_DATA_STAGE, - IN_STATUS_STAGE, - OUT_STATUS_STAGE, - STALL, - WAIT_ACK_SET_CONF_INTERF -}; - -static char *ep0_state_name[] = { - "WAIT_FOR_SETUP", "SETUP_STAGE", "IN_DATA_STAGE", "OUT_DATA_STAGE", - "IN_STATUS_STAGE", "OUT_STATUS_STAGE", "STALL", - "WAIT_ACK_SET_CONF_INTERF" -}; -#define EP0_STNAME(udc) ep0_state_name[(udc)->ep0state] - -#define EP0_FIFO_SIZE 16U -#define BULK_FIFO_SIZE 64U -#define ISO_FIFO_SIZE 256U -#define INT_FIFO_SIZE 16U - -struct udc_stats { - unsigned long irqs_reset; - unsigned long irqs_suspend; - unsigned long irqs_resume; - unsigned long irqs_reconfig; -}; - -#define NR_USB_ENDPOINTS (1 + 5) /* ep0 + ep1in-bulk + .. + ep3in-iso */ -#define NR_PXA_ENDPOINTS (1 + 14) /* ep0 + epA + epB + .. + epX */ - -/** - * struct pxa_udc - udc structure - * @regs: mapped IO space - * @irq: udc irq - * @clk: udc clock - * @usb_gadget: udc gadget structure - * @driver: bound gadget (zero, g_ether, g_file_storage, ...) - * @dev: device - * @mach: machine info, used to activate specific GPIO - * @ep0state: control endpoint state machine state - * @stats: statistics on udc usage - * @udc_usb_ep: array of usb endpoints offered by the gadget - * @pxa_ep: array of pxa available endpoints - * @config: UDC active configuration - * @last_interface: UDC interface of the last SET_INTERFACE host request - * @last_alternate: UDC altsetting of the last SET_INTERFACE host request - * @udccsr0: save of udccsr0 in case of suspend - * @debugfs_root: root entry of debug filesystem - * @debugfs_state: debugfs entry for "udcstate" - * @debugfs_queues: debugfs entry for "queues" - * @debugfs_eps: debugfs entry for "epstate" - */ -struct pxa_udc { - void __iomem *regs; - int irq; - struct clk *clk; - - struct usb_gadget gadget; - struct usb_gadget_driver *driver; - struct device *dev; - struct pxa2xx_udc_mach_info *mach; - - enum ep0_state ep0state; - struct udc_stats stats; - - struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS]; - struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS]; - - unsigned config:2; - unsigned last_interface:3; - unsigned last_alternate:3; - -#ifdef CONFIG_PM - unsigned udccsr0; -#endif -#ifdef CONFIG_USB_GADGET_DEBUG_FS - struct dentry *debugfs_root; - struct dentry *debugfs_state; - struct dentry *debugfs_queues; - struct dentry *debugfs_eps; -#endif -}; - -static inline struct pxa_udc *to_gadget_udc(struct usb_gadget *gadget) -{ - return container_of(gadget, struct pxa_udc, gadget); -} - -/* - * Debugging/message support - */ -#define ep_dbg(ep, fmt, arg...) \ - dev_dbg(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) -#define ep_vdbg(ep, fmt, arg...) \ - dev_vdbg(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) -#define ep_err(ep, fmt, arg...) \ - dev_err(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) -#define ep_info(ep, fmt, arg...) \ - dev_info(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) -#define ep_warn(ep, fmt, arg...) \ - dev_warn(ep->dev->dev, "%s:%s:" fmt, EPNAME(ep), __func__, ## arg) - -#endif /* __LINUX_USB_GADGET_PXA27X_H */ diff --git a/trunk/drivers/usb/gadget/serial.c b/trunk/drivers/usb/gadget/serial.c index 54cdd6f94034..8d158e5640e3 100644 --- a/trunk/drivers/usb/gadget/serial.c +++ b/trunk/drivers/usb/gadget/serial.c @@ -135,10 +135,7 @@ struct gs_port { int port_in_use; /* open/close in progress */ wait_queue_head_t port_write_wait;/* waiting to write */ struct gs_buf *port_write_buf; - struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ - u16 port_handshake_bits; -#define RS232_RTS (1 << 1) -#define RS232_DTE (1 << 0) + struct usb_cdc_line_coding port_line_coding; }; /* the device structure holds info for the USB device */ @@ -202,8 +199,6 @@ static int gs_setup_standard(struct usb_gadget *gadget, static int gs_setup_class(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl); static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req); -static void gs_setup_complete_set_line_coding(struct usb_ep *ep, - struct usb_request *req); static void gs_disconnect(struct usb_gadget *gadget); static int gs_set_config(struct gs_dev *dev, unsigned config); static void gs_reset_config(struct gs_dev *dev); @@ -411,7 +406,7 @@ static struct usb_cdc_acm_descriptor gs_acm_descriptor = { .bLength = sizeof(gs_acm_descriptor), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_ACM_TYPE, - .bmCapabilities = (1 << 1), + .bmCapabilities = 0, }; static const struct usb_cdc_union_desc gs_union_desc = { @@ -1507,8 +1502,6 @@ static int gs_setup(struct usb_gadget *gadget, u16 wValue = le16_to_cpu(ctrl->wValue); u16 wLength = le16_to_cpu(ctrl->wLength); - req->complete = gs_setup_complete; - switch (ctrl->bRequestType & USB_TYPE_MASK) { case USB_TYPE_STANDARD: ret = gs_setup_standard(gadget,ctrl); @@ -1686,14 +1679,18 @@ static int gs_setup_class(struct usb_gadget *gadget, switch (ctrl->bRequest) { case USB_CDC_REQ_SET_LINE_CODING: - if (wLength != sizeof(struct usb_cdc_line_coding)) - break; - ret = wLength; - req->complete = gs_setup_complete_set_line_coding; + /* FIXME Submit req to read the data; have its completion + * handler copy that data to port->port_line_coding (iff + * it's valid) and maybe pass it on. Until then, fail. + */ + pr_warning("gs_setup: set_line_coding " + "unuspported\n"); break; case USB_CDC_REQ_GET_LINE_CODING: - ret = min_t(int, wLength, sizeof(struct usb_cdc_line_coding)); + port = dev->dev_port[0]; /* ACM only has one port */ + ret = min(wLength, + (u16)sizeof(struct usb_cdc_line_coding)); if (port) { spin_lock(&port->port_lock); memcpy(req->buf, &port->port_line_coding, ret); @@ -1702,27 +1699,15 @@ static int gs_setup_class(struct usb_gadget *gadget, break; case USB_CDC_REQ_SET_CONTROL_LINE_STATE: - if (wLength != 0) - break; - ret = 0; - if (port) { - /* REVISIT: we currently just remember this data. - * If we change that, update whatever hardware needs - * updating. - */ - spin_lock(&port->port_lock); - port->port_handshake_bits = wValue; - spin_unlock(&port->port_lock); - } + /* FIXME Submit req to read the data; have its completion + * handler use that to set the state (iff it's valid) and + * maybe pass it on. Until then, fail. + */ + pr_warning("gs_setup: set_control_line_state " + "unuspported\n"); break; default: - /* NOTE: strictly speaking, we should accept AT-commands - * using SEND_ENCPSULATED_COMMAND/GET_ENCAPSULATED_RESPONSE. - * But our call management descriptor says we don't handle - * call management, so we should be able to get by without - * handling those "required" commands (except by stalling). - */ pr_err("gs_setup: unknown class request, " "type=%02x, request=%02x, value=%04x, " "index=%04x, length=%d\n", @@ -1734,42 +1719,6 @@ static int gs_setup_class(struct usb_gadget *gadget, return ret; } -static void gs_setup_complete_set_line_coding(struct usb_ep *ep, - struct usb_request *req) -{ - struct gs_dev *dev = ep->driver_data; - struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */ - - switch (req->status) { - case 0: - /* normal completion */ - if (req->actual != sizeof(port->port_line_coding)) - usb_ep_set_halt(ep); - else if (port) { - struct usb_cdc_line_coding *value = req->buf; - - /* REVISIT: we currently just remember this data. - * If we change that, (a) validate it first, then - * (b) update whatever hardware needs updating. - */ - spin_lock(&port->port_lock); - port->port_line_coding = *value; - spin_unlock(&port->port_lock); - } - break; - - case -ESHUTDOWN: - /* disconnect */ - gs_free_req(ep, req); - break; - - default: - /* unexpected */ - break; - } - return; -} - /* * gs_setup_complete */ @@ -1957,11 +1906,6 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) } } - /* REVISIT the ACM mode should be able to actually *issue* some - * notifications, for at least serial state change events if - * not also for network connection; say so in bmCapabilities. - */ - pr_info("gs_set_config: %s configured, %s speed %s config\n", GS_LONG_NAME, gadget->speed == USB_SPEED_HIGH ? "high" : "full", diff --git a/trunk/drivers/usb/gadget/zero.c b/trunk/drivers/usb/gadget/zero.c index fce4924dbbe8..d3d4f4048e6c 100644 --- a/trunk/drivers/usb/gadget/zero.c +++ b/trunk/drivers/usb/gadget/zero.c @@ -23,7 +23,9 @@ /* * Gadget Zero only needs two bulk endpoints, and is an example of how you * can write a hardware-agnostic gadget driver running inside a USB device. - * Some hardware details are visible, but don't affect most of the driver. + * + * Hardware details are visible (see CONFIG_USB_ZERO_* below) but don't + * affect most of the driver. * * Use it with the Linux host/master side "usbtest" driver to get a basic * functional test of your device-side usb stack, or with "usb-skeleton". @@ -35,7 +37,6 @@ * buflen=N default N=4096, buffer size used * qlen=N default N=32, how many buffers in the loopback queue * loopdefault default false, list loopback config first - * autoresume=N default N=0, seconds before triggering remote wakeup * * Many drivers will only have one configuration, letting them be much * simpler if they also don't support high speed operation (like this @@ -61,13 +62,13 @@ /*-------------------------------------------------------------------------*/ -#define DRIVER_VERSION "Earth Day 2008" +#define DRIVER_VERSION "Lughnasadh, 2007" -static const char shortname[] = "zero"; -static const char longname[] = "Gadget Zero"; +static const char shortname [] = "zero"; +static const char longname [] = "Gadget Zero"; -static const char source_sink[] = "source and sink data"; -static const char loopback[] = "loop input to output"; +static const char source_sink [] = "source and sink data"; +static const char loopback [] = "loop input to output"; /*-------------------------------------------------------------------------*/ @@ -119,16 +120,16 @@ static unsigned buflen = 4096; static unsigned qlen = 32; static unsigned pattern = 0; -module_param(buflen, uint, S_IRUGO); -module_param(qlen, uint, S_IRUGO); -module_param(pattern, uint, S_IRUGO|S_IWUSR); +module_param (buflen, uint, S_IRUGO); +module_param (qlen, uint, S_IRUGO); +module_param (pattern, uint, S_IRUGO|S_IWUSR); /* * if it's nonzero, autoresume says how many seconds to wait * before trying to wake up the host after suspend. */ static unsigned autoresume = 0; -module_param(autoresume, uint, 0); +module_param (autoresume, uint, 0); /* * Normally the "loopback" configuration is second (index 1) so @@ -137,7 +138,8 @@ module_param(autoresume, uint, 0); * Or controllers (like superh) that only support one config. */ static int loopdefault = 0; -module_param(loopdefault, bool, S_IRUGO|S_IWUSR); + +module_param (loopdefault, bool, S_IRUGO|S_IWUSR); /*-------------------------------------------------------------------------*/ @@ -174,22 +176,24 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR); #define CONFIG_SOURCE_SINK 3 #define CONFIG_LOOPBACK 2 -static struct usb_device_descriptor device_desc = { +static struct usb_device_descriptor +device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = __constant_cpu_to_le16(0x0200), + .bcdUSB = __constant_cpu_to_le16 (0x0200), .bDeviceClass = USB_CLASS_VENDOR_SPEC, - .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM), - .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM), + .idVendor = __constant_cpu_to_le16 (DRIVER_VENDOR_NUM), + .idProduct = __constant_cpu_to_le16 (DRIVER_PRODUCT_NUM), .iManufacturer = STRING_MANUFACTURER, .iProduct = STRING_PRODUCT, .iSerialNumber = STRING_SERIAL, .bNumConfigurations = 2, }; -static struct usb_config_descriptor source_sink_config = { +static struct usb_config_descriptor +source_sink_config = { .bLength = sizeof source_sink_config, .bDescriptorType = USB_DT_CONFIG, @@ -201,7 +205,8 @@ static struct usb_config_descriptor source_sink_config = { .bMaxPower = 1, /* self-powered */ }; -static struct usb_config_descriptor loopback_config = { +static struct usb_config_descriptor +loopback_config = { .bLength = sizeof loopback_config, .bDescriptorType = USB_DT_CONFIG, @@ -213,7 +218,8 @@ static struct usb_config_descriptor loopback_config = { .bMaxPower = 1, /* self-powered */ }; -static struct usb_otg_descriptor otg_descriptor = { +static struct usb_otg_descriptor +otg_descriptor = { .bLength = sizeof otg_descriptor, .bDescriptorType = USB_DT_OTG, @@ -222,7 +228,8 @@ static struct usb_otg_descriptor otg_descriptor = { /* one interface in each configuration */ -static const struct usb_interface_descriptor source_sink_intf = { +static const struct usb_interface_descriptor +source_sink_intf = { .bLength = sizeof source_sink_intf, .bDescriptorType = USB_DT_INTERFACE, @@ -231,7 +238,8 @@ static const struct usb_interface_descriptor source_sink_intf = { .iInterface = STRING_SOURCE_SINK, }; -static const struct usb_interface_descriptor loopback_intf = { +static const struct usb_interface_descriptor +loopback_intf = { .bLength = sizeof loopback_intf, .bDescriptorType = USB_DT_INTERFACE, @@ -242,7 +250,8 @@ static const struct usb_interface_descriptor loopback_intf = { /* two full speed bulk endpoints; their use is config-dependent */ -static struct usb_endpoint_descriptor fs_source_desc = { +static struct usb_endpoint_descriptor +fs_source_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -250,7 +259,8 @@ static struct usb_endpoint_descriptor fs_source_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_endpoint_descriptor fs_sink_desc = { +static struct usb_endpoint_descriptor +fs_sink_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -258,7 +268,7 @@ static struct usb_endpoint_descriptor fs_sink_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static const struct usb_descriptor_header *fs_source_sink_function[] = { +static const struct usb_descriptor_header *fs_source_sink_function [] = { (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &source_sink_intf, (struct usb_descriptor_header *) &fs_sink_desc, @@ -266,7 +276,7 @@ static const struct usb_descriptor_header *fs_source_sink_function[] = { NULL, }; -static const struct usb_descriptor_header *fs_loopback_function[] = { +static const struct usb_descriptor_header *fs_loopback_function [] = { (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &loopback_intf, (struct usb_descriptor_header *) &fs_sink_desc, @@ -283,33 +293,36 @@ static const struct usb_descriptor_header *fs_loopback_function[] = { * for the config descriptor. */ -static struct usb_endpoint_descriptor hs_source_desc = { +static struct usb_endpoint_descriptor +hs_source_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), + .wMaxPacketSize = __constant_cpu_to_le16 (512), }; -static struct usb_endpoint_descriptor hs_sink_desc = { +static struct usb_endpoint_descriptor +hs_sink_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), + .wMaxPacketSize = __constant_cpu_to_le16 (512), }; -static struct usb_qualifier_descriptor dev_qualifier = { +static struct usb_qualifier_descriptor +dev_qualifier = { .bLength = sizeof dev_qualifier, .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - .bcdUSB = __constant_cpu_to_le16(0x0200), + .bcdUSB = __constant_cpu_to_le16 (0x0200), .bDeviceClass = USB_CLASS_VENDOR_SPEC, .bNumConfigurations = 2, }; -static const struct usb_descriptor_header *hs_source_sink_function[] = { +static const struct usb_descriptor_header *hs_source_sink_function [] = { (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &source_sink_intf, (struct usb_descriptor_header *) &hs_source_desc, @@ -317,7 +330,7 @@ static const struct usb_descriptor_header *hs_source_sink_function[] = { NULL, }; -static const struct usb_descriptor_header *hs_loopback_function[] = { +static const struct usb_descriptor_header *hs_loopback_function [] = { (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &loopback_intf, (struct usb_descriptor_header *) &hs_source_desc, @@ -342,7 +355,7 @@ static char serial[] = "0123456789.0123456789.0123456789"; /* static strings, in UTF-8 */ -static struct usb_string strings[] = { +static struct usb_string strings [] = { { STRING_MANUFACTURER, manufacturer, }, { STRING_PRODUCT, longname, }, { STRING_SERIAL, serial, }, @@ -351,7 +364,7 @@ static struct usb_string strings[] = { { } /* end of list */ }; -static struct usb_gadget_strings stringtab = { +static struct usb_gadget_strings stringtab = { .language = 0x0409, /* en-us */ .strings = strings, }; @@ -374,7 +387,8 @@ static struct usb_gadget_strings stringtab = { * high bandwidth modes at high speed. (Maybe work like Intel's test * device?) */ -static int config_buf(struct usb_gadget *gadget, +static int +config_buf (struct usb_gadget *gadget, u8 *buf, u8 type, unsigned index) { int is_source_sink; @@ -405,7 +419,7 @@ static int config_buf(struct usb_gadget *gadget, if (!gadget_is_otg(gadget)) function++; - len = usb_gadget_config_buf(is_source_sink + len = usb_gadget_config_buf (is_source_sink ? &source_sink_config : &loopback_config, buf, USB_BUFSIZ, function); @@ -417,26 +431,27 @@ static int config_buf(struct usb_gadget *gadget, /*-------------------------------------------------------------------------*/ -static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length) +static struct usb_request * +alloc_ep_req (struct usb_ep *ep, unsigned length) { struct usb_request *req; - req = usb_ep_alloc_request(ep, GFP_ATOMIC); + req = usb_ep_alloc_request (ep, GFP_ATOMIC); if (req) { req->length = length; req->buf = kmalloc(length, GFP_ATOMIC); if (!req->buf) { - usb_ep_free_request(ep, req); + usb_ep_free_request (ep, req); req = NULL; } } return req; } -static void free_ep_req(struct usb_ep *ep, struct usb_request *req) +static void free_ep_req (struct usb_ep *ep, struct usb_request *req) { kfree(req->buf); - usb_ep_free_request(ep, req); + usb_ep_free_request (ep, req); } /*-------------------------------------------------------------------------*/ @@ -457,7 +472,7 @@ static void free_ep_req(struct usb_ep *ep, struct usb_request *req) /* optionally require specific source/sink data patterns */ static int -check_read_data( +check_read_data ( struct zero_dev *dev, struct usb_ep *ep, struct usb_request *req @@ -483,8 +498,8 @@ check_read_data( continue; break; } - ERROR(dev, "bad OUT byte, buf[%d] = %d\n", i, *buf); - usb_ep_set_halt(ep); + ERROR (dev, "bad OUT byte, buf [%d] = %d\n", i, *buf); + usb_ep_set_halt (ep); return -EINVAL; } return 0; @@ -497,7 +512,7 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) switch (pattern) { case 0: - memset(req->buf, 0, req->length); + memset (req->buf, 0, req->length); break; case 1: for (i = 0; i < req->length; i++) @@ -510,7 +525,7 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) * irq delay between end of one request and start of the next. * that prevents using hardware dma queues. */ -static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) +static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) { struct zero_dev *dev = ep->driver_data; int status = req->status; @@ -519,8 +534,8 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) case 0: /* normal completion? */ if (ep == dev->out_ep) { - check_read_data(dev, ep, req); - memset(req->buf, 0x55, req->length); + check_read_data (dev, ep, req); + memset (req->buf, 0x55, req->length); } else reinit_write_data(ep, req); break; @@ -529,11 +544,11 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) case -ECONNABORTED: /* hardware forced ep reset */ case -ECONNRESET: /* request dequeued */ case -ESHUTDOWN: /* disconnect from host */ - VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status, + VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status, req->actual, req->length); if (ep == dev->out_ep) - check_read_data(dev, ep, req); - free_ep_req(ep, req); + check_read_data (dev, ep, req); + free_ep_req (ep, req); return; case -EOVERFLOW: /* buffer overrun on read means that @@ -542,18 +557,18 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) */ default: #if 1 - DBG(dev, "%s complete --> %d, %d/%d\n", ep->name, + DBG (dev, "%s complete --> %d, %d/%d\n", ep->name, status, req->actual, req->length); #endif case -EREMOTEIO: /* short read */ break; } - status = usb_ep_queue(ep, req, GFP_ATOMIC); + status = usb_ep_queue (ep, req, GFP_ATOMIC); if (status) { - ERROR(dev, "kill %s: resubmit %d bytes --> %d\n", + ERROR (dev, "kill %s: resubmit %d bytes --> %d\n", ep->name, req->length, status); - usb_ep_set_halt(ep); + usb_ep_set_halt (ep); /* FIXME recover later ... somehow */ } } @@ -563,24 +578,24 @@ static struct usb_request *source_sink_start_ep(struct usb_ep *ep) struct usb_request *req; int status; - req = alloc_ep_req(ep, buflen); + req = alloc_ep_req (ep, buflen); if (!req) return NULL; - memset(req->buf, 0, req->length); + memset (req->buf, 0, req->length); req->complete = source_sink_complete; - if (strcmp(ep->name, EP_IN_NAME) == 0) + if (strcmp (ep->name, EP_IN_NAME) == 0) reinit_write_data(ep, req); else - memset(req->buf, 0x55, req->length); + memset (req->buf, 0x55, req->length); status = usb_ep_queue(ep, req, GFP_ATOMIC); if (status) { struct zero_dev *dev = ep->driver_data; - ERROR(dev, "start %s --> %d\n", ep->name, status); - free_ep_req(ep, req); + ERROR (dev, "start %s --> %d\n", ep->name, status); + free_ep_req (ep, req); req = NULL; } @@ -593,34 +608,34 @@ static int set_source_sink_config(struct zero_dev *dev) struct usb_ep *ep; struct usb_gadget *gadget = dev->gadget; - gadget_for_each_ep(ep, gadget) { + gadget_for_each_ep (ep, gadget) { const struct usb_endpoint_descriptor *d; /* one endpoint writes (sources) zeroes in (to the host) */ - if (strcmp(ep->name, EP_IN_NAME) == 0) { - d = ep_desc(gadget, &hs_source_desc, &fs_source_desc); - result = usb_ep_enable(ep, d); + if (strcmp (ep->name, EP_IN_NAME) == 0) { + d = ep_desc (gadget, &hs_source_desc, &fs_source_desc); + result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; if (source_sink_start_ep(ep) != NULL) { dev->in_ep = ep; continue; } - usb_ep_disable(ep); + usb_ep_disable (ep); result = -EIO; } /* one endpoint reads (sinks) anything out (from the host) */ - } else if (strcmp(ep->name, EP_OUT_NAME) == 0) { - d = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc); - result = usb_ep_enable(ep, d); + } else if (strcmp (ep->name, EP_OUT_NAME) == 0) { + d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc); + result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; if (source_sink_start_ep(ep) != NULL) { dev->out_ep = ep; continue; } - usb_ep_disable(ep); + usb_ep_disable (ep); result = -EIO; } @@ -629,11 +644,11 @@ static int set_source_sink_config(struct zero_dev *dev) continue; /* stop on error */ - ERROR(dev, "can't start %s, result %d\n", ep->name, result); + ERROR (dev, "can't start %s, result %d\n", ep->name, result); break; } if (result == 0) - DBG(dev, "buflen %d\n", buflen); + DBG (dev, "buflen %d\n", buflen); /* caller is responsible for cleanup on error */ return result; @@ -641,7 +656,7 @@ static int set_source_sink_config(struct zero_dev *dev) /*-------------------------------------------------------------------------*/ -static void loopback_complete(struct usb_ep *ep, struct usb_request *req) +static void loopback_complete (struct usb_ep *ep, struct usb_request *req) { struct zero_dev *dev = ep->driver_data; int status = req->status; @@ -653,19 +668,19 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) /* loop this OUT packet back IN to the host */ req->zero = (req->actual < req->length); req->length = req->actual; - status = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); + status = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC); if (status == 0) return; /* "should never get here" */ - ERROR(dev, "can't loop %s to %s: %d\n", + ERROR (dev, "can't loop %s to %s: %d\n", ep->name, dev->in_ep->name, status); } /* queue the buffer for some later OUT packet */ req->length = buflen; - status = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); + status = usb_ep_queue (dev->out_ep, req, GFP_ATOMIC); if (status == 0) return; @@ -673,7 +688,7 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) /* FALLTHROUGH */ default: - ERROR(dev, "%s loop complete --> %d, %d/%d\n", ep->name, + ERROR (dev, "%s loop complete --> %d, %d/%d\n", ep->name, status, req->actual, req->length); /* FALLTHROUGH */ @@ -685,7 +700,7 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) case -ECONNABORTED: /* hardware forced ep reset */ case -ECONNRESET: /* request dequeued */ case -ESHUTDOWN: /* disconnect from host */ - free_ep_req(ep, req); + free_ep_req (ep, req); return; } } @@ -696,13 +711,13 @@ static int set_loopback_config(struct zero_dev *dev) struct usb_ep *ep; struct usb_gadget *gadget = dev->gadget; - gadget_for_each_ep(ep, gadget) { + gadget_for_each_ep (ep, gadget) { const struct usb_endpoint_descriptor *d; /* one endpoint writes data back IN to the host */ - if (strcmp(ep->name, EP_IN_NAME) == 0) { - d = ep_desc(gadget, &hs_source_desc, &fs_source_desc); - result = usb_ep_enable(ep, d); + if (strcmp (ep->name, EP_IN_NAME) == 0) { + d = ep_desc (gadget, &hs_source_desc, &fs_source_desc); + result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; dev->in_ep = ep; @@ -710,9 +725,9 @@ static int set_loopback_config(struct zero_dev *dev) } /* one endpoint just reads OUT packets */ - } else if (strcmp(ep->name, EP_OUT_NAME) == 0) { - d = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc); - result = usb_ep_enable(ep, d); + } else if (strcmp (ep->name, EP_OUT_NAME) == 0) { + d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc); + result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; dev->out_ep = ep; @@ -724,7 +739,7 @@ static int set_loopback_config(struct zero_dev *dev) continue; /* stop on error */ - ERROR(dev, "can't enable %s, result %d\n", ep->name, result); + ERROR (dev, "can't enable %s, result %d\n", ep->name, result); break; } @@ -738,19 +753,19 @@ static int set_loopback_config(struct zero_dev *dev) ep = dev->out_ep; for (i = 0; i < qlen && result == 0; i++) { - req = alloc_ep_req(ep, buflen); + req = alloc_ep_req (ep, buflen); if (req) { req->complete = loopback_complete; - result = usb_ep_queue(ep, req, GFP_ATOMIC); + result = usb_ep_queue (ep, req, GFP_ATOMIC); if (result) - DBG(dev, "%s queue req --> %d\n", + DBG (dev, "%s queue req --> %d\n", ep->name, result); } else result = -ENOMEM; } } if (result == 0) - DBG(dev, "qlen %d, buflen %d\n", qlen, buflen); + DBG (dev, "qlen %d, buflen %d\n", qlen, buflen); /* caller is responsible for cleanup on error */ return result; @@ -758,26 +773,26 @@ static int set_loopback_config(struct zero_dev *dev) /*-------------------------------------------------------------------------*/ -static void zero_reset_config(struct zero_dev *dev) +static void zero_reset_config (struct zero_dev *dev) { if (dev->config == 0) return; - DBG(dev, "reset config\n"); + DBG (dev, "reset config\n"); /* just disable endpoints, forcing completion of pending i/o. * all our completion handlers free their requests in this case. */ if (dev->in_ep) { - usb_ep_disable(dev->in_ep); + usb_ep_disable (dev->in_ep); dev->in_ep = NULL; } if (dev->out_ep) { - usb_ep_disable(dev->out_ep); + usb_ep_disable (dev->out_ep); dev->out_ep = NULL; } dev->config = 0; - del_timer(&dev->resume); + del_timer (&dev->resume); } /* change our operational config. this code must agree with the code @@ -798,12 +813,12 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) if (number == dev->config) return 0; - if (gadget_is_sa1100(gadget) && dev->config) { + if (gadget_is_sa1100 (gadget) && dev->config) { /* tx fifo is full, but we can't clear it...*/ ERROR(dev, "can't change configurations\n"); return -ESPIPE; } - zero_reset_config(dev); + zero_reset_config (dev); switch (number) { case CONFIG_SOURCE_SINK: @@ -822,7 +837,7 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) if (!result && (!dev->in_ep || !dev->out_ep)) result = -ENODEV; if (result) - zero_reset_config(dev); + zero_reset_config (dev); else { char *speed; @@ -834,7 +849,7 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) } dev->config = number; - INFO(dev, "%s speed config #%d: %s\n", speed, number, + INFO (dev, "%s speed config #%d: %s\n", speed, number, (number == CONFIG_SOURCE_SINK) ? source_sink : loopback); } @@ -843,10 +858,10 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) /*-------------------------------------------------------------------------*/ -static void zero_setup_complete(struct usb_ep *ep, struct usb_request *req) +static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req) { if (req->status || req->actual != req->length) - DBG((struct zero_dev *) ep->driver_data, + DBG ((struct zero_dev *) ep->driver_data, "setup complete --> %d, %d/%d\n", req->status, req->actual, req->length); } @@ -859,9 +874,9 @@ static void zero_setup_complete(struct usb_ep *ep, struct usb_request *req) * the work is in config-specific setup. */ static int -zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) { - struct zero_dev *dev = get_gadget_data(gadget); + struct zero_dev *dev = get_gadget_data (gadget); struct usb_request *req = dev->req; int value = -EOPNOTSUPP; u16 w_index = le16_to_cpu(ctrl->wIndex); @@ -880,14 +895,14 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) switch (w_value >> 8) { case USB_DT_DEVICE: - value = min(w_length, (u16) sizeof device_desc); - memcpy(req->buf, &device_desc, value); + value = min (w_length, (u16) sizeof device_desc); + memcpy (req->buf, &device_desc, value); break; case USB_DT_DEVICE_QUALIFIER: if (!gadget_is_dualspeed(gadget)) break; - value = min(w_length, (u16) sizeof dev_qualifier); - memcpy(req->buf, &dev_qualifier, value); + value = min (w_length, (u16) sizeof dev_qualifier); + memcpy (req->buf, &dev_qualifier, value); break; case USB_DT_OTHER_SPEED_CONFIG: @@ -895,11 +910,11 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) break; // FALLTHROUGH case USB_DT_CONFIG: - value = config_buf(gadget, req->buf, + value = config_buf (gadget, req->buf, w_value >> 8, w_value & 0xff); if (value >= 0) - value = min(w_length, (u16) value); + value = min (w_length, (u16) value); break; case USB_DT_STRING: @@ -908,10 +923,10 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) * add string tables for other languages, using * any UTF-8 characters */ - value = usb_gadget_get_string(&stringtab, + value = usb_gadget_get_string (&stringtab, w_value & 0xff, req->buf); if (value >= 0) - value = min(w_length, (u16) value); + value = min (w_length, (u16) value); break; } break; @@ -921,20 +936,20 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (ctrl->bRequestType != 0) goto unknown; if (gadget->a_hnp_support) - DBG(dev, "HNP available\n"); + DBG (dev, "HNP available\n"); else if (gadget->a_alt_hnp_support) - DBG(dev, "HNP needs a different root port\n"); + DBG (dev, "HNP needs a different root port\n"); else - VDBG(dev, "HNP inactive\n"); - spin_lock(&dev->lock); + VDBG (dev, "HNP inactive\n"); + spin_lock (&dev->lock); value = zero_set_config(dev, w_value); - spin_unlock(&dev->lock); + spin_unlock (&dev->lock); break; case USB_REQ_GET_CONFIGURATION: if (ctrl->bRequestType != USB_DIR_IN) goto unknown; *(u8 *)req->buf = dev->config; - value = min(w_length, (u16) 1); + value = min (w_length, (u16) 1); break; /* until we add altsetting support, or other interfaces, @@ -944,7 +959,7 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case USB_REQ_SET_INTERFACE: if (ctrl->bRequestType != USB_RECIP_INTERFACE) goto unknown; - spin_lock(&dev->lock); + spin_lock (&dev->lock); if (dev->config && w_index == 0 && w_value == 0) { u8 config = dev->config; @@ -955,11 +970,11 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) * if we had more than one interface we couldn't * use this "reset the config" shortcut. */ - zero_reset_config(dev); + zero_reset_config (dev); zero_set_config(dev, config); value = 0; } - spin_unlock(&dev->lock); + spin_unlock (&dev->lock); break; case USB_REQ_GET_INTERFACE: if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) @@ -971,7 +986,7 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) break; } *(u8 *)req->buf = 0; - value = min(w_length, (u16) 1); + value = min (w_length, (u16) 1); break; /* @@ -1003,7 +1018,7 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) default: unknown: - VDBG(dev, + VDBG (dev, "unknown control req%02x.%02x v%04x i%04x l%d\n", ctrl->bRequestType, ctrl->bRequest, w_value, w_index, w_length); @@ -1013,11 +1028,11 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (value >= 0) { req->length = value; req->zero = value < w_length; - value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); + value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); if (value < 0) { - DBG(dev, "ep_queue --> %d\n", value); + DBG (dev, "ep_queue --> %d\n", value); req->status = 0; - zero_setup_complete(gadget->ep0, req); + zero_setup_complete (gadget->ep0, req); } } @@ -1025,26 +1040,28 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) return value; } -static void zero_disconnect(struct usb_gadget *gadget) +static void +zero_disconnect (struct usb_gadget *gadget) { - struct zero_dev *dev = get_gadget_data(gadget); + struct zero_dev *dev = get_gadget_data (gadget); unsigned long flags; - spin_lock_irqsave(&dev->lock, flags); - zero_reset_config(dev); + spin_lock_irqsave (&dev->lock, flags); + zero_reset_config (dev); /* a more significant application might have some non-usb * activities to quiesce here, saving resources like power * or pushing the notification up a network stack. */ - spin_unlock_irqrestore(&dev->lock, flags); + spin_unlock_irqrestore (&dev->lock, flags); /* next we may get setup() calls to enumerate new connections; * or an unbind() during shutdown (including removing module). */ } -static void zero_autoresume(unsigned long _dev) +static void +zero_autoresume (unsigned long _dev) { struct zero_dev *dev = (struct zero_dev *) _dev; int status; @@ -1053,30 +1070,32 @@ static void zero_autoresume(unsigned long _dev) * more significant than just a timer firing... */ if (dev->gadget->speed != USB_SPEED_UNKNOWN) { - status = usb_gadget_wakeup(dev->gadget); - DBG(dev, "wakeup --> %d\n", status); + status = usb_gadget_wakeup (dev->gadget); + DBG (dev, "wakeup --> %d\n", status); } } /*-------------------------------------------------------------------------*/ -static void zero_unbind(struct usb_gadget *gadget) +static void /* __init_or_exit */ +zero_unbind (struct usb_gadget *gadget) { - struct zero_dev *dev = get_gadget_data(gadget); + struct zero_dev *dev = get_gadget_data (gadget); - DBG(dev, "unbind\n"); + DBG (dev, "unbind\n"); /* we've already been disconnected ... no i/o is active */ if (dev->req) { dev->req->length = USB_BUFSIZ; - free_ep_req(gadget->ep0, dev->req); + free_ep_req (gadget->ep0, dev->req); } - del_timer_sync(&dev->resume); - kfree(dev); - set_gadget_data(gadget, NULL); + del_timer_sync (&dev->resume); + kfree (dev); + set_gadget_data (gadget, NULL); } -static int __init zero_bind(struct usb_gadget *gadget) +static int __init +zero_bind (struct usb_gadget *gadget) { struct zero_dev *dev; struct usb_ep *ep; @@ -1092,8 +1111,8 @@ static int __init zero_bind(struct usb_gadget *gadget) * autoconfigure on any sane usb controller driver, * but there may also be important quirks to address. */ - usb_ep_autoconfig_reset(gadget); - ep = usb_ep_autoconfig(gadget, &fs_source_desc); + usb_ep_autoconfig_reset (gadget); + ep = usb_ep_autoconfig (gadget, &fs_source_desc); if (!ep) { autoconf_fail: pr_err("%s: can't autoconfigure on %s\n", @@ -1103,15 +1122,15 @@ static int __init zero_bind(struct usb_gadget *gadget) EP_IN_NAME = ep->name; ep->driver_data = ep; /* claim */ - ep = usb_ep_autoconfig(gadget, &fs_sink_desc); + ep = usb_ep_autoconfig (gadget, &fs_sink_desc); if (!ep) goto autoconf_fail; EP_OUT_NAME = ep->name; ep->driver_data = ep; /* claim */ - gcnum = usb_gadget_controller_number(gadget); + gcnum = usb_gadget_controller_number (gadget); if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); + device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum); else { /* gadget zero is so simple (for now, no altsettings) that * it SHOULD NOT have problems with bulk-capable hardware. @@ -1122,7 +1141,7 @@ static int __init zero_bind(struct usb_gadget *gadget) */ pr_warning("%s: controller '%s' not recognized\n", shortname, gadget->name); - device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); + device_desc.bcdDevice = __constant_cpu_to_le16 (0x9999); } @@ -1130,16 +1149,12 @@ static int __init zero_bind(struct usb_gadget *gadget) dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; - spin_lock_init(&dev->lock); + spin_lock_init (&dev->lock); dev->gadget = gadget; - set_gadget_data(gadget, dev); - - init_timer(&dev->resume); - dev->resume.function = zero_autoresume; - dev->resume.data = (unsigned long) dev; + set_gadget_data (gadget, dev); /* preallocate control response and buffer */ - dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); + dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL); if (!dev->req) goto enomem; dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL); @@ -1167,8 +1182,11 @@ static int __init zero_bind(struct usb_gadget *gadget) loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - usb_gadget_set_selfpowered(gadget); + usb_gadget_set_selfpowered (gadget); + init_timer (&dev->resume); + dev->resume.function = zero_autoresume; + dev->resume.data = (unsigned long) dev; if (autoresume) { source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; @@ -1176,43 +1194,45 @@ static int __init zero_bind(struct usb_gadget *gadget) gadget->ep0->driver_data = dev; - INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname); - INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, + INFO (dev, "%s, version: " DRIVER_VERSION "\n", longname); + INFO (dev, "using %s, OUT %s IN %s\n", gadget->name, EP_OUT_NAME, EP_IN_NAME); - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", + snprintf (manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); return 0; enomem: - zero_unbind(gadget); + zero_unbind (gadget); return -ENOMEM; } /*-------------------------------------------------------------------------*/ -static void zero_suspend(struct usb_gadget *gadget) +static void +zero_suspend (struct usb_gadget *gadget) { - struct zero_dev *dev = get_gadget_data(gadget); + struct zero_dev *dev = get_gadget_data (gadget); if (gadget->speed == USB_SPEED_UNKNOWN) return; if (autoresume) { - mod_timer(&dev->resume, jiffies + (HZ * autoresume)); - DBG(dev, "suspend, wakeup in %d seconds\n", autoresume); + mod_timer (&dev->resume, jiffies + (HZ * autoresume)); + DBG (dev, "suspend, wakeup in %d seconds\n", autoresume); } else - DBG(dev, "suspend\n"); + DBG (dev, "suspend\n"); } -static void zero_resume(struct usb_gadget *gadget) +static void +zero_resume (struct usb_gadget *gadget) { - struct zero_dev *dev = get_gadget_data(gadget); + struct zero_dev *dev = get_gadget_data (gadget); - DBG(dev, "resume\n"); - del_timer(&dev->resume); + DBG (dev, "resume\n"); + del_timer (&dev->resume); } @@ -1244,15 +1264,15 @@ MODULE_AUTHOR("David Brownell"); MODULE_LICENSE("GPL"); -static int __init init(void) +static int __init init (void) { - return usb_gadget_register_driver(&zero_driver); + return usb_gadget_register_driver (&zero_driver); } -module_init(init); +module_init (init); -static void __exit cleanup(void) +static void __exit cleanup (void) { - usb_gadget_unregister_driver(&zero_driver); + usb_gadget_unregister_driver (&zero_driver); } -module_exit(cleanup); +module_exit (cleanup); diff --git a/trunk/drivers/usb/host/Kconfig b/trunk/drivers/usb/host/Kconfig index 33b467a8352d..0b87480dd713 100644 --- a/trunk/drivers/usb/host/Kconfig +++ b/trunk/drivers/usb/host/Kconfig @@ -4,19 +4,6 @@ comment "USB Host Controller Drivers" depends on USB -config USB_C67X00_HCD - tristate "Cypress C67x00 HCD support" - depends on USB - help - The Cypress C67x00 (EZ-Host/EZ-OTG) chips are dual-role - host/peripheral/OTG USB controllers. - - Enable this option to support this chip in host controller mode. - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called c67x00. - config USB_EHCI_HCD tristate "EHCI HCD (USB 2.0) support" depends on USB && USB_ARCH_HAS_EHCI @@ -108,32 +95,6 @@ config USB_ISP116X_HCD To compile this driver as a module, choose M here: the module will be called isp116x-hcd. -config USB_ISP1760_HCD - tristate "ISP 1760 HCD support" - depends on USB && EXPERIMENTAL - ---help--- - The ISP1760 chip is a USB 2.0 host controller. - - This driver does not support isochronous transfers or OTG. - - To compile this driver as a module, choose M here: the - module will be called isp1760-hcd. - -config USB_ISP1760_PCI - bool "Support for the PCI bus" - depends on USB_ISP1760_HCD && PCI - ---help--- - Enables support for the device present on the PCI bus. - This should only be required if you happen to have the eval kit from - NXP and you are going to test it. - -config USB_ISP1760_OF - bool "Support for the OF platform bus" - depends on USB_ISP1760_HCD && OF - ---help--- - Enables support for the device present on the PowerPC - OpenFirmware platform bus. - config USB_OHCI_HCD tristate "OHCI HCD support" depends on USB && USB_ARCH_HAS_OHCI diff --git a/trunk/drivers/usb/host/Makefile b/trunk/drivers/usb/host/Makefile index f1edda2dcfde..bb8e9d44f371 100644 --- a/trunk/drivers/usb/host/Makefile +++ b/trunk/drivers/usb/host/Makefile @@ -6,8 +6,6 @@ ifeq ($(CONFIG_USB_DEBUG),y) EXTRA_CFLAGS += -DDEBUG endif -isp1760-objs := isp1760-hcd.o isp1760-if.o - obj-$(CONFIG_PCI) += pci-quirks.o obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o @@ -18,4 +16,4 @@ obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o -obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o + diff --git a/trunk/drivers/usb/host/isp1760-hcd.c b/trunk/drivers/usb/host/isp1760-hcd.c deleted file mode 100644 index 4ba96c1e060c..000000000000 --- a/trunk/drivers/usb/host/isp1760-hcd.c +++ /dev/null @@ -1,2231 +0,0 @@ -/* - * Driver for the NXP ISP1760 chip - * - * However, the code might contain some bugs. What doesn't work for sure is: - * - ISO - * - OTG - e The interrupt line is configured as active low, level. - * - * (c) 2007 Sebastian Siewior - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../core/hcd.h" -#include "isp1760-hcd.h" - -static struct kmem_cache *qtd_cachep; -static struct kmem_cache *qh_cachep; - -struct isp1760_hcd { - u32 hcs_params; - spinlock_t lock; - struct inter_packet_info atl_ints[32]; - struct inter_packet_info int_ints[32]; - struct memory_chunk memory_pool[BLOCKS]; - - /* periodic schedule support */ -#define DEFAULT_I_TDPS 1024 - unsigned periodic_size; - unsigned i_thresh; - unsigned long reset_done; - unsigned long next_statechange; -}; - -static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) -{ - return (struct isp1760_hcd *) (hcd->hcd_priv); -} -static inline struct usb_hcd *priv_to_hcd(struct isp1760_hcd *priv) -{ - return container_of((void *) priv, struct usb_hcd, hcd_priv); -} - -/* Section 2.2 Host Controller Capability Registers */ -#define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */ -#define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */ -#define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */ -#define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */ -#define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */ -#define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */ -#define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */ - -/* Section 2.3 Host Controller Operational Registers */ -#define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */ -#define CMD_RESET (1<<1) /* reset HC not bus */ -#define CMD_RUN (1<<0) /* start/stop HC */ -#define STS_PCD (1<<2) /* port change detect */ -#define FLAG_CF (1<<0) /* true: we'll support "high speed" */ - -#define PORT_OWNER (1<<13) /* true: companion hc owns this port */ -#define PORT_POWER (1<<12) /* true: has power (see PPC) */ -#define PORT_USB11(x) (((x) & (3 << 10)) == (1 << 10)) /* USB 1.1 device */ -#define PORT_RESET (1<<8) /* reset port */ -#define PORT_SUSPEND (1<<7) /* suspend port */ -#define PORT_RESUME (1<<6) /* resume it */ -#define PORT_PE (1<<2) /* port enable */ -#define PORT_CSC (1<<1) /* connect status change */ -#define PORT_CONNECT (1<<0) /* device connected */ -#define PORT_RWC_BITS (PORT_CSC) - -struct isp1760_qtd { - struct isp1760_qtd *hw_next; - u8 packet_type; - u8 toggle; - - void *data_buffer; - /* the rest is HCD-private */ - struct list_head qtd_list; - struct urb *urb; - size_t length; - - /* isp special*/ - u32 status; -#define URB_COMPLETE_NOTIFY (1 << 0) -#define URB_ENQUEUED (1 << 1) -#define URB_TYPE_ATL (1 << 2) -#define URB_TYPE_INT (1 << 3) -}; - -struct isp1760_qh { - /* first part defined by EHCI spec */ - struct list_head qtd_list; - struct isp1760_hcd *priv; - - /* periodic schedule info */ - unsigned short period; /* polling interval */ - struct usb_device *dev; - - u32 toggle; - u32 ping; -}; - -#define ehci_port_speed(priv, portsc) (1 << USB_PORT_FEAT_HIGHSPEED) - -static unsigned int isp1760_readl(__u32 __iomem *regs) -{ - return readl(regs); -} - -static void isp1760_writel(const unsigned int val, __u32 __iomem *regs) -{ - writel(val, regs); -} - -/* - * The next two copy via MMIO data to/from the device. memcpy_{to|from}io() - * doesn't quite work because some people have to enforce 32-bit access - */ -static void priv_read_copy(struct isp1760_hcd *priv, u32 *src, - __u32 __iomem *dst, u32 offset, u32 len) -{ - struct usb_hcd *hcd = priv_to_hcd(priv); - u32 val; - u8 *buff8; - - if (!src) { - printk(KERN_ERR "ERROR: buffer: %p len: %d\n", src, len); - return; - } - isp1760_writel(offset, hcd->regs + HC_MEMORY_REG); - /* XXX - * 90nsec delay, the spec says something how this could be avoided. - */ - mdelay(1); - - while (len >= 4) { - *src = __raw_readl(dst); - len -= 4; - src++; - dst++; - } - - if (!len) - return; - - /* in case we have 3, 2 or 1 by left. The dst buffer may not be fully - * allocated. - */ - val = isp1760_readl(dst); - - buff8 = (u8 *)src; - while (len) { - - *buff8 = val; - val >>= 8; - len--; - buff8++; - } -} - -static void priv_write_copy(const struct isp1760_hcd *priv, const u32 *src, - __u32 __iomem *dst, u32 len) -{ - while (len >= 4) { - __raw_writel(*src, dst); - len -= 4; - src++; - dst++; - } - - if (!len) - return; - /* in case we have 3, 2 or 1 by left. The buffer is allocated and the - * extra bytes should not be read by the HW - */ - - __raw_writel(*src, dst); -} - -/* memory management of the 60kb on the chip from 0x1000 to 0xffff */ -static void init_memory(struct isp1760_hcd *priv) -{ - int i; - u32 payload; - - payload = 0x1000; - for (i = 0; i < BLOCK_1_NUM; i++) { - priv->memory_pool[i].start = payload; - priv->memory_pool[i].size = BLOCK_1_SIZE; - priv->memory_pool[i].free = 1; - payload += priv->memory_pool[i].size; - } - - - for (i = BLOCK_1_NUM; i < BLOCK_1_NUM + BLOCK_2_NUM; i++) { - priv->memory_pool[i].start = payload; - priv->memory_pool[i].size = BLOCK_2_SIZE; - priv->memory_pool[i].free = 1; - payload += priv->memory_pool[i].size; - } - - - for (i = BLOCK_1_NUM + BLOCK_2_NUM; i < BLOCKS; i++) { - priv->memory_pool[i].start = payload; - priv->memory_pool[i].size = BLOCK_3_SIZE; - priv->memory_pool[i].free = 1; - payload += priv->memory_pool[i].size; - } - - BUG_ON(payload - priv->memory_pool[i - 1].size > PAYLOAD_SIZE); -} - -static u32 alloc_mem(struct isp1760_hcd *priv, u32 size) -{ - int i; - - if (!size) - return ISP1760_NULL_POINTER; - - for (i = 0; i < BLOCKS; i++) { - if (priv->memory_pool[i].size >= size && - priv->memory_pool[i].free) { - - priv->memory_pool[i].free = 0; - return priv->memory_pool[i].start; - } - } - - printk(KERN_ERR "ISP1760 MEM: can not allocate %d bytes of memory\n", - size); - printk(KERN_ERR "Current memory map:\n"); - for (i = 0; i < BLOCKS; i++) { - printk(KERN_ERR "Pool %2d size %4d status: %d\n", - i, priv->memory_pool[i].size, - priv->memory_pool[i].free); - } - /* XXX maybe -ENOMEM could be possible */ - BUG(); - return 0; -} - -static void free_mem(struct isp1760_hcd *priv, u32 mem) -{ - int i; - - if (mem == ISP1760_NULL_POINTER) - return; - - for (i = 0; i < BLOCKS; i++) { - if (priv->memory_pool[i].start == mem) { - - BUG_ON(priv->memory_pool[i].free); - - priv->memory_pool[i].free = 1; - return ; - } - } - - printk(KERN_ERR "Trying to free not-here-allocated memory :%08x\n", - mem); - BUG(); -} - -static void isp1760_init_regs(struct usb_hcd *hcd) -{ - isp1760_writel(0, hcd->regs + HC_BUFFER_STATUS_REG); - isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); - isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + - HC_INT_PTD_SKIPMAP_REG); - isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + - HC_ISO_PTD_SKIPMAP_REG); - - isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + - HC_ATL_PTD_DONEMAP_REG); - isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + - HC_INT_PTD_DONEMAP_REG); - isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + - HC_ISO_PTD_DONEMAP_REG); -} - -static int handshake(struct isp1760_hcd *priv, void __iomem *ptr, - u32 mask, u32 done, int usec) -{ - u32 result; - - do { - result = isp1760_readl(ptr); - if (result == ~0) - return -ENODEV; - result &= mask; - if (result == done) - return 0; - udelay(1); - usec--; - } while (usec > 0); - return -ETIMEDOUT; -} - -/* reset a non-running (STS_HALT == 1) controller */ -static int ehci_reset(struct isp1760_hcd *priv) -{ - int retval; - struct usb_hcd *hcd = priv_to_hcd(priv); - u32 command = isp1760_readl(hcd->regs + HC_USBCMD); - - command |= CMD_RESET; - isp1760_writel(command, hcd->regs + HC_USBCMD); - hcd->state = HC_STATE_HALT; - priv->next_statechange = jiffies; - retval = handshake(priv, hcd->regs + HC_USBCMD, - CMD_RESET, 0, 250 * 1000); - return retval; -} - -static void qh_destroy(struct isp1760_qh *qh) -{ - BUG_ON(!list_empty(&qh->qtd_list)); - kmem_cache_free(qh_cachep, qh); -} - -static struct isp1760_qh *isp1760_qh_alloc(struct isp1760_hcd *priv, - gfp_t flags) -{ - struct isp1760_qh *qh; - - qh = kmem_cache_zalloc(qh_cachep, flags); - if (!qh) - return qh; - - INIT_LIST_HEAD(&qh->qtd_list); - qh->priv = priv; - return qh; -} - -/* magic numbers that can affect system performance */ -#define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ -#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ -#define EHCI_TUNE_RL_TT 0 -#define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ -#define EHCI_TUNE_MULT_TT 1 -#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ - -/* one-time init, only for memory state */ -static int priv_init(struct usb_hcd *hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - u32 hcc_params; - - spin_lock_init(&priv->lock); - - /* - * hw default: 1K periodic list heads, one per frame. - * periodic_size can shrink by USBCMD update if hcc_params allows. - */ - priv->periodic_size = DEFAULT_I_TDPS; - - /* controllers may cache some of the periodic schedule ... */ - hcc_params = isp1760_readl(hcd->regs + HC_HCCPARAMS); - /* full frame cache */ - if (HCC_ISOC_CACHE(hcc_params)) - priv->i_thresh = 8; - else /* N microframes cached */ - priv->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); - - return 0; -} - -static int isp1760_hc_setup(struct usb_hcd *hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - int result; - u32 scratch; - - isp1760_writel(0xdeadbabe, hcd->regs + HC_SCRATCH_REG); - scratch = isp1760_readl(hcd->regs + HC_SCRATCH_REG); - if (scratch != 0xdeadbabe) { - printk(KERN_ERR "ISP1760: Scratch test failed.\n"); - return -ENODEV; - } - - /* pre reset */ - isp1760_init_regs(hcd); - - /* reset */ - isp1760_writel(SW_RESET_RESET_ALL, hcd->regs + HC_RESET_REG); - mdelay(100); - - isp1760_writel(SW_RESET_RESET_HC, hcd->regs + HC_RESET_REG); - mdelay(100); - - result = ehci_reset(priv); - if (result) - return result; - - /* Step 11 passed */ - - isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_REG); - isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_ENABLE); - - /* ATL reset */ - scratch = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); - isp1760_writel(scratch | ALL_ATX_RESET, hcd->regs + HC_HW_MODE_CTRL); - mdelay(10); - isp1760_writel(scratch, hcd->regs + HC_HW_MODE_CTRL); - - isp1760_writel(PORT1_POWER | PORT1_INIT2, hcd->regs + HC_PORT1_CTRL); - mdelay(10); - - priv->hcs_params = isp1760_readl(hcd->regs + HC_HCSPARAMS); - - return priv_init(hcd); -} - -static void isp1760_init_maps(struct usb_hcd *hcd) -{ - /*set last maps, for iso its only 1, else 32 tds bitmap*/ - isp1760_writel(0x80000000, hcd->regs + HC_ATL_PTD_LASTPTD_REG); - isp1760_writel(0x80000000, hcd->regs + HC_INT_PTD_LASTPTD_REG); - isp1760_writel(0x00000001, hcd->regs + HC_ISO_PTD_LASTPTD_REG); -} - -static void isp1760_enable_interrupts(struct usb_hcd *hcd) -{ - isp1760_writel(0, hcd->regs + HC_ATL_IRQ_MASK_AND_REG); - isp1760_writel(0, hcd->regs + HC_ATL_IRQ_MASK_OR_REG); - isp1760_writel(0, hcd->regs + HC_INT_IRQ_MASK_AND_REG); - isp1760_writel(0, hcd->regs + HC_INT_IRQ_MASK_OR_REG); - isp1760_writel(0, hcd->regs + HC_ISO_IRQ_MASK_AND_REG); - isp1760_writel(0xffffffff, hcd->regs + HC_ISO_IRQ_MASK_OR_REG); - /* step 23 passed */ -} - -static int isp1760_run(struct usb_hcd *hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - int retval; - u32 temp; - u32 command; - u32 chipid; - - hcd->uses_new_polling = 1; - hcd->poll_rh = 0; - - hcd->state = HC_STATE_RUNNING; - isp1760_enable_interrupts(hcd); - temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); - temp |= FINAL_HW_CONFIG; - isp1760_writel(temp, hcd->regs + HC_HW_MODE_CTRL); - - command = isp1760_readl(hcd->regs + HC_USBCMD); - command &= ~(CMD_LRESET|CMD_RESET); - command |= CMD_RUN; - isp1760_writel(command, hcd->regs + HC_USBCMD); - - retval = handshake(priv, hcd->regs + HC_USBCMD, CMD_RUN, CMD_RUN, - 250 * 1000); - if (retval) - return retval; - - /* - * XXX - * Spec says to write FLAG_CF as last config action, priv code grabs - * the semaphore while doing so. - */ - down_write(&ehci_cf_port_reset_rwsem); - isp1760_writel(FLAG_CF, hcd->regs + HC_CONFIGFLAG); - - retval = handshake(priv, hcd->regs + HC_CONFIGFLAG, FLAG_CF, FLAG_CF, - 250 * 1000); - up_write(&ehci_cf_port_reset_rwsem); - if (retval) - return retval; - - chipid = isp1760_readl(hcd->regs + HC_CHIP_ID_REG); - isp1760_info(priv, "USB ISP %04x HW rev. %d started\n", chipid & 0xffff, - chipid >> 16); - - /* PTD Register Init Part 2, Step 28 */ - /* enable INTs */ - isp1760_init_maps(hcd); - - /* GRR this is run-once init(), being done every time the HC starts. - * So long as they're part of class devices, we can't do it init() - * since the class device isn't created that early. - */ - return 0; -} - -static u32 base_to_chip(u32 base) -{ - return ((base - 0x400) >> 3); -} - -static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct isp1760_qtd *qtd, struct urb *urb, - u32 payload, struct ptd *ptd) -{ - u32 dw0; - u32 dw1; - u32 dw2; - u32 dw3; - u32 maxpacket; - u32 multi; - u32 pid_code; - u32 rl = RL_COUNTER; - u32 nak = NAK_COUNTER; - - /* according to 3.6.2, max packet len can not be > 0x400 */ - maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); - multi = 1 + ((maxpacket >> 11) & 0x3); - maxpacket &= 0x7ff; - - /* DW0 */ - dw0 = PTD_VALID; - dw0 |= PTD_LENGTH(qtd->length); - dw0 |= PTD_MAXPACKET(maxpacket); - dw0 |= PTD_ENDPOINT(usb_pipeendpoint(urb->pipe)); - dw1 = usb_pipeendpoint(urb->pipe) >> 1; - - /* DW1 */ - dw1 |= PTD_DEVICE_ADDR(usb_pipedevice(urb->pipe)); - - pid_code = qtd->packet_type; - dw1 |= PTD_PID_TOKEN(pid_code); - - if (usb_pipebulk(urb->pipe)) - dw1 |= PTD_TRANS_BULK; - else if (usb_pipeint(urb->pipe)) - dw1 |= PTD_TRANS_INT; - - if (urb->dev->speed != USB_SPEED_HIGH) { - /* split transaction */ - - dw1 |= PTD_TRANS_SPLIT; - if (urb->dev->speed == USB_SPEED_LOW) - dw1 |= PTD_SE_USB_LOSPEED; - - dw1 |= PTD_PORT_NUM(urb->dev->ttport); - dw1 |= PTD_HUB_NUM(urb->dev->tt->hub->devnum); - - /* SE bit for Split INT transfers */ - if (usb_pipeint(urb->pipe) && - (urb->dev->speed == USB_SPEED_LOW)) - dw1 |= 2 << 16; - - dw3 = 0; - rl = 0; - nak = 0; - } else { - dw0 |= PTD_MULTI(multi); - if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) - dw3 = qh->ping; - else - dw3 = 0; - } - /* DW2 */ - dw2 = 0; - dw2 |= PTD_DATA_START_ADDR(base_to_chip(payload)); - dw2 |= PTD_RL_CNT(rl); - dw3 |= PTD_NAC_CNT(nak); - - /* DW3 */ - if (usb_pipecontrol(urb->pipe)) - dw3 |= PTD_DATA_TOGGLE(qtd->toggle); - else - dw3 |= qh->toggle; - - - dw3 |= PTD_ACTIVE; - /* Cerr */ - dw3 |= PTD_CERR(ERR_COUNTER); - - memset(ptd, 0, sizeof(*ptd)); - - ptd->dw0 = cpu_to_le32(dw0); - ptd->dw1 = cpu_to_le32(dw1); - ptd->dw2 = cpu_to_le32(dw2); - ptd->dw3 = cpu_to_le32(dw3); -} - -static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct isp1760_qtd *qtd, struct urb *urb, - u32 payload, struct ptd *ptd) -{ - u32 maxpacket; - u32 multi; - u32 numberofusofs; - u32 i; - u32 usofmask, usof; - u32 period; - - maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); - multi = 1 + ((maxpacket >> 11) & 0x3); - maxpacket &= 0x7ff; - /* length of the data per uframe */ - maxpacket = multi * maxpacket; - - numberofusofs = urb->transfer_buffer_length / maxpacket; - if (urb->transfer_buffer_length % maxpacket) - numberofusofs += 1; - - usofmask = 1; - usof = 0; - for (i = 0; i < numberofusofs; i++) { - usof |= usofmask; - usofmask <<= 1; - } - - if (urb->dev->speed != USB_SPEED_HIGH) { - /* split */ - ptd->dw5 = __constant_cpu_to_le32(0x1c); - - if (qh->period >= 32) - period = qh->period / 2; - else - period = qh->period; - - } else { - - if (qh->period >= 8) - period = qh->period/8; - else - period = qh->period; - - if (period >= 32) - period = 16; - - if (qh->period >= 8) { - /* millisecond period */ - period = (period << 3); - } else { - /* usof based tranmsfers */ - /* minimum 4 usofs */ - usof = 0x11; - } - } - - ptd->dw2 |= cpu_to_le32(period); - ptd->dw4 = cpu_to_le32(usof); -} - -static void transform_into_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct isp1760_qtd *qtd, struct urb *urb, - u32 payload, struct ptd *ptd) -{ - transform_into_atl(priv, qh, qtd, urb, payload, ptd); - transform_add_int(priv, qh, qtd, urb, payload, ptd); -} - -static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len, - u32 token) -{ - int count; - - qtd->data_buffer = databuffer; - qtd->packet_type = GET_QTD_TOKEN_TYPE(token); - qtd->toggle = GET_DATA_TOGGLE(token); - - if (len > HC_ATL_PL_SIZE) - count = HC_ATL_PL_SIZE; - else - count = len; - - qtd->length = count; - return count; -} - -static int check_error(struct ptd *ptd) -{ - int error = 0; - u32 dw3; - - dw3 = le32_to_cpu(ptd->dw3); - if (dw3 & DW3_HALT_BIT) - error = -EPIPE; - - if (dw3 & DW3_ERROR_BIT) { - printk(KERN_ERR "error bit is set in DW3\n"); - error = -EPIPE; - } - - if (dw3 & DW3_QTD_ACTIVE) { - printk(KERN_ERR "transfer active bit is set DW3\n"); - printk(KERN_ERR "nak counter: %d, rl: %d\n", (dw3 >> 19) & 0xf, - (le32_to_cpu(ptd->dw2) >> 25) & 0xf); - } - - return error; -} - -static void check_int_err_status(u32 dw4) -{ - u32 i; - - dw4 >>= 8; - - for (i = 0; i < 8; i++) { - switch (dw4 & 0x7) { - case INT_UNDERRUN: - printk(KERN_ERR "ERROR: under run , %d\n", i); - break; - - case INT_EXACT: - printk(KERN_ERR "ERROR: transaction error, %d\n", i); - break; - - case INT_BABBLE: - printk(KERN_ERR "ERROR: babble error, %d\n", i); - break; - } - dw4 >>= 3; - } -} - -static void enqueue_one_qtd(struct isp1760_qtd *qtd, struct isp1760_hcd *priv, - u32 payload) -{ - u32 token; - struct usb_hcd *hcd = priv_to_hcd(priv); - - token = qtd->packet_type; - - if (qtd->length && (qtd->length <= HC_ATL_PL_SIZE)) { - switch (token) { - case IN_PID: - break; - case OUT_PID: - case SETUP_PID: - priv_write_copy(priv, qtd->data_buffer, - hcd->regs + payload, - qtd->length); - } - } -} - -static void enqueue_one_atl_qtd(u32 atl_regs, u32 payload, - struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct urb *urb, u32 slot, struct isp1760_qtd *qtd) -{ - struct ptd ptd; - struct usb_hcd *hcd = priv_to_hcd(priv); - - transform_into_atl(priv, qh, qtd, urb, payload, &ptd); - priv_write_copy(priv, (u32 *)&ptd, hcd->regs + atl_regs, sizeof(ptd)); - enqueue_one_qtd(qtd, priv, payload); - - priv->atl_ints[slot].urb = urb; - priv->atl_ints[slot].qh = qh; - priv->atl_ints[slot].qtd = qtd; - priv->atl_ints[slot].data_buffer = qtd->data_buffer; - priv->atl_ints[slot].payload = payload; - qtd->status |= URB_ENQUEUED | URB_TYPE_ATL; - qtd->status |= slot << 16; -} - -static void enqueue_one_int_qtd(u32 int_regs, u32 payload, - struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct urb *urb, u32 slot, struct isp1760_qtd *qtd) -{ - struct ptd ptd; - struct usb_hcd *hcd = priv_to_hcd(priv); - - transform_into_int(priv, qh, qtd, urb, payload, &ptd); - priv_write_copy(priv, (u32 *)&ptd, hcd->regs + int_regs, sizeof(ptd)); - enqueue_one_qtd(qtd, priv, payload); - - priv->int_ints[slot].urb = urb; - priv->int_ints[slot].qh = qh; - priv->int_ints[slot].qtd = qtd; - priv->int_ints[slot].data_buffer = qtd->data_buffer; - priv->int_ints[slot].payload = payload; - qtd->status |= URB_ENQUEUED | URB_TYPE_INT; - qtd->status |= slot << 16; -} - -void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, - struct isp1760_qtd *qtd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - u32 skip_map, or_map; - u32 queue_entry; - u32 slot; - u32 atl_regs, payload; - u32 buffstatus; - - skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); - - BUG_ON(!skip_map); - slot = __ffs(skip_map); - queue_entry = 1 << slot; - - atl_regs = ATL_REGS_OFFSET + slot * sizeof(struct ptd); - - payload = alloc_mem(priv, qtd->length); - - enqueue_one_atl_qtd(atl_regs, payload, priv, qh, qtd->urb, slot, qtd); - - or_map = isp1760_readl(hcd->regs + HC_ATL_IRQ_MASK_OR_REG); - or_map |= queue_entry; - isp1760_writel(or_map, hcd->regs + HC_ATL_IRQ_MASK_OR_REG); - - skip_map &= ~queue_entry; - isp1760_writel(skip_map, hcd->regs + HC_ATL_PTD_SKIPMAP_REG); - - buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); - buffstatus |= ATL_BUFFER; - isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); -} - -void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, - struct isp1760_qtd *qtd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - u32 skip_map, or_map; - u32 queue_entry; - u32 slot; - u32 int_regs, payload; - u32 buffstatus; - - skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); - - BUG_ON(!skip_map); - slot = __ffs(skip_map); - queue_entry = 1 << slot; - - int_regs = INT_REGS_OFFSET + slot * sizeof(struct ptd); - - payload = alloc_mem(priv, qtd->length); - - enqueue_one_int_qtd(int_regs, payload, priv, qh, qtd->urb, slot, qtd); - - or_map = isp1760_readl(hcd->regs + HC_INT_IRQ_MASK_OR_REG); - or_map |= queue_entry; - isp1760_writel(or_map, hcd->regs + HC_INT_IRQ_MASK_OR_REG); - - skip_map &= ~queue_entry; - isp1760_writel(skip_map, hcd->regs + HC_INT_PTD_SKIPMAP_REG); - - buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); - buffstatus |= INT_BUFFER; - isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); -} - -static void isp1760_urb_done(struct isp1760_hcd *priv, struct urb *urb, int status) -__releases(priv->lock) -__acquires(priv->lock) -{ - if (!urb->unlinked) { - if (status == -EINPROGRESS) - status = 0; - } - - /* complete() can reenter this HCD */ - usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb); - spin_unlock(&priv->lock); - usb_hcd_giveback_urb(priv_to_hcd(priv), urb, status); - spin_lock(&priv->lock); -} - -static void isp1760_qtd_free(struct isp1760_qtd *qtd) -{ - kmem_cache_free(qtd_cachep, qtd); -} - -static struct isp1760_qtd *clean_this_qtd(struct isp1760_qtd *qtd) -{ - struct isp1760_qtd *tmp_qtd; - - tmp_qtd = qtd->hw_next; - list_del(&qtd->qtd_list); - isp1760_qtd_free(qtd); - return tmp_qtd; -} - -/* - * Remove this QTD from the QH list and free its memory. If this QTD - * isn't the last one than remove also his successor(s). - * Returns the QTD which is part of an new URB and should be enqueued. - */ -static struct isp1760_qtd *clean_up_qtdlist(struct isp1760_qtd *qtd) -{ - struct isp1760_qtd *tmp_qtd; - int last_one; - - do { - tmp_qtd = qtd->hw_next; - last_one = qtd->status & URB_COMPLETE_NOTIFY; - list_del(&qtd->qtd_list); - isp1760_qtd_free(qtd); - qtd = tmp_qtd; - } while (!last_one && qtd); - - return qtd; -} - -static void do_atl_int(struct usb_hcd *usb_hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); - u32 done_map, skip_map; - struct ptd ptd; - struct urb *urb = NULL; - u32 atl_regs_base; - u32 atl_regs; - u32 queue_entry; - u32 payload; - u32 length; - u32 or_map; - u32 status = -EINVAL; - int error; - struct isp1760_qtd *qtd; - struct isp1760_qh *qh; - u32 rl; - u32 nakcount; - - done_map = isp1760_readl(usb_hcd->regs + - HC_ATL_PTD_DONEMAP_REG); - skip_map = isp1760_readl(usb_hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); - - or_map = isp1760_readl(usb_hcd->regs + HC_ATL_IRQ_MASK_OR_REG); - or_map &= ~done_map; - isp1760_writel(or_map, usb_hcd->regs + HC_ATL_IRQ_MASK_OR_REG); - - atl_regs_base = ATL_REGS_OFFSET; - while (done_map) { - u32 dw1; - u32 dw2; - u32 dw3; - - status = 0; - - queue_entry = __ffs(done_map); - done_map &= ~(1 << queue_entry); - skip_map |= 1 << queue_entry; - - atl_regs = atl_regs_base + queue_entry * sizeof(struct ptd); - - urb = priv->atl_ints[queue_entry].urb; - qtd = priv->atl_ints[queue_entry].qtd; - qh = priv->atl_ints[queue_entry].qh; - payload = priv->atl_ints[queue_entry].payload; - - if (!qh) { - printk(KERN_ERR "qh is 0\n"); - continue; - } - priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + atl_regs, - atl_regs, sizeof(ptd)); - - dw1 = le32_to_cpu(ptd.dw1); - dw2 = le32_to_cpu(ptd.dw2); - dw3 = le32_to_cpu(ptd.dw3); - rl = (dw2 >> 25) & 0x0f; - nakcount = (dw3 >> 19) & 0xf; - - /* Transfer Error, *but* active and no HALT -> reload */ - if ((dw3 & DW3_ERROR_BIT) && (dw3 & DW3_QTD_ACTIVE) && - !(dw3 & DW3_HALT_BIT)) { - - /* according to ppriv code, we have to - * reload this one if trasfered bytes != requested bytes - * else act like everything went smooth.. - * XXX This just doesn't feel right and hasn't - * triggered so far. - */ - - length = PTD_XFERRED_LENGTH(dw3); - printk(KERN_ERR "Should reload now.... transfered %d " - "of %zu\n", length, qtd->length); - BUG(); - } - - if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) { - u32 buffstatus; - - /* XXX - * NAKs are handled in HW by the chip. Usually if the - * device is not able to send data fast enough. - * This did not trigger for a long time now. - */ - printk(KERN_ERR "Reloading ptd %p/%p... qh %p readed: " - "%d of %d done: %08x cur: %08x\n", qtd, - urb, qh, PTD_XFERRED_LENGTH(dw3), - qtd->length, done_map, - (1 << queue_entry)); - - /* RL counter = ERR counter */ - dw3 &= ~(0xf << 19); - dw3 |= rl << 19; - dw3 &= ~(3 << (55 - 32)); - dw3 |= ERR_COUNTER << (55 - 32); - - /* - * It is not needed to write skip map back because it - * is unchanged. Just make sure that this entry is - * unskipped once it gets written to the HW. - */ - skip_map &= ~(1 << queue_entry); - or_map = isp1760_readl(usb_hcd->regs + - HC_ATL_IRQ_MASK_OR_REG); - or_map |= 1 << queue_entry; - isp1760_writel(or_map, usb_hcd->regs + - HC_ATL_IRQ_MASK_OR_REG); - - ptd.dw3 = cpu_to_le32(dw3); - priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + - atl_regs, sizeof(ptd)); - - ptd.dw0 |= __constant_cpu_to_le32(PTD_VALID); - priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + - atl_regs, sizeof(ptd)); - - buffstatus = isp1760_readl(usb_hcd->regs + - HC_BUFFER_STATUS_REG); - buffstatus |= ATL_BUFFER; - isp1760_writel(buffstatus, usb_hcd->regs + - HC_BUFFER_STATUS_REG); - continue; - } - - error = check_error(&ptd); - if (error) { - status = error; - priv->atl_ints[queue_entry].qh->toggle = 0; - priv->atl_ints[queue_entry].qh->ping = 0; - urb->status = -EPIPE; - -#if 0 - printk(KERN_ERR "Error in %s().\n", __func__); - printk(KERN_ERR "IN dw0: %08x dw1: %08x dw2: %08x " - "dw3: %08x dw4: %08x dw5: %08x dw6: " - "%08x dw7: %08x\n", - ptd.dw0, ptd.dw1, ptd.dw2, ptd.dw3, - ptd.dw4, ptd.dw5, ptd.dw6, ptd.dw7); -#endif - } else { - if (usb_pipetype(urb->pipe) == PIPE_BULK) { - priv->atl_ints[queue_entry].qh->toggle = dw3 & - (1 << 25); - priv->atl_ints[queue_entry].qh->ping = dw3 & - (1 << 26); - } - } - - length = PTD_XFERRED_LENGTH(dw3); - if (length) { - switch (DW1_GET_PID(dw1)) { - case IN_PID: - priv_read_copy(priv, - priv->atl_ints[queue_entry].data_buffer, - usb_hcd->regs + payload, payload, - length); - - case OUT_PID: - - urb->actual_length += length; - - case SETUP_PID: - break; - } - } - - priv->atl_ints[queue_entry].data_buffer = NULL; - priv->atl_ints[queue_entry].urb = NULL; - priv->atl_ints[queue_entry].qtd = NULL; - priv->atl_ints[queue_entry].qh = NULL; - - free_mem(priv, payload); - - isp1760_writel(skip_map, usb_hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); - - if (urb->status == -EPIPE) { - /* HALT was received */ - - qtd = clean_up_qtdlist(qtd); - isp1760_urb_done(priv, urb, urb->status); - - } else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) { - /* short BULK received */ - - printk(KERN_ERR "short bulk, %d instead %d\n", length, - qtd->length); - if (urb->transfer_flags & URB_SHORT_NOT_OK) { - urb->status = -EREMOTEIO; - printk(KERN_ERR "not okey\n"); - } - - if (urb->status == -EINPROGRESS) - urb->status = 0; - - qtd = clean_up_qtdlist(qtd); - - isp1760_urb_done(priv, urb, urb->status); - - } else if (qtd->status & URB_COMPLETE_NOTIFY) { - /* that was the last qtd of that URB */ - - if (urb->status == -EINPROGRESS) - urb->status = 0; - - qtd = clean_this_qtd(qtd); - isp1760_urb_done(priv, urb, urb->status); - - } else { - /* next QTD of this URB */ - - qtd = clean_this_qtd(qtd); - BUG_ON(!qtd); - } - - if (qtd) - enqueue_an_ATL_packet(usb_hcd, qh, qtd); - - skip_map = isp1760_readl(usb_hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); - } -} - -static void do_intl_int(struct usb_hcd *usb_hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); - u32 done_map, skip_map; - struct ptd ptd; - struct urb *urb = NULL; - u32 int_regs; - u32 int_regs_base; - u32 payload; - u32 length; - u32 or_map; - int error; - u32 queue_entry; - struct isp1760_qtd *qtd; - struct isp1760_qh *qh; - - done_map = isp1760_readl(usb_hcd->regs + - HC_INT_PTD_DONEMAP_REG); - skip_map = isp1760_readl(usb_hcd->regs + - HC_INT_PTD_SKIPMAP_REG); - - or_map = isp1760_readl(usb_hcd->regs + HC_INT_IRQ_MASK_OR_REG); - or_map &= ~done_map; - isp1760_writel(or_map, usb_hcd->regs + HC_INT_IRQ_MASK_OR_REG); - - int_regs_base = INT_REGS_OFFSET; - - while (done_map) { - u32 dw1; - u32 dw3; - - queue_entry = __ffs(done_map); - done_map &= ~(1 << queue_entry); - skip_map |= 1 << queue_entry; - - int_regs = int_regs_base + queue_entry * sizeof(struct ptd); - urb = priv->int_ints[queue_entry].urb; - qtd = priv->int_ints[queue_entry].qtd; - qh = priv->int_ints[queue_entry].qh; - payload = priv->int_ints[queue_entry].payload; - - if (!qh) { - printk(KERN_ERR "(INT) qh is 0\n"); - continue; - } - - priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + int_regs, - int_regs, sizeof(ptd)); - dw1 = le32_to_cpu(ptd.dw1); - dw3 = le32_to_cpu(ptd.dw3); - check_int_err_status(le32_to_cpu(ptd.dw4)); - - error = check_error(&ptd); - if (error) { -#if 0 - printk(KERN_ERR "Error in %s().\n", __func__); - printk(KERN_ERR "IN dw0: %08x dw1: %08x dw2: %08x " - "dw3: %08x dw4: %08x dw5: %08x dw6: " - "%08x dw7: %08x\n", - ptd.dw0, ptd.dw1, ptd.dw2, ptd.dw3, - ptd.dw4, ptd.dw5, ptd.dw6, ptd.dw7); -#endif - urb->status = -EPIPE; - priv->int_ints[queue_entry].qh->toggle = 0; - priv->int_ints[queue_entry].qh->ping = 0; - - } else { - priv->int_ints[queue_entry].qh->toggle = - dw3 & (1 << 25); - priv->int_ints[queue_entry].qh->ping = dw3 & (1 << 26); - } - - if (urb->dev->speed != USB_SPEED_HIGH) - length = PTD_XFERRED_LENGTH_LO(dw3); - else - length = PTD_XFERRED_LENGTH(dw3); - - if (length) { - switch (DW1_GET_PID(dw1)) { - case IN_PID: - priv_read_copy(priv, - priv->int_ints[queue_entry].data_buffer, - usb_hcd->regs + payload , payload, - length); - case OUT_PID: - - urb->actual_length += length; - - case SETUP_PID: - break; - } - } - - priv->int_ints[queue_entry].data_buffer = NULL; - priv->int_ints[queue_entry].urb = NULL; - priv->int_ints[queue_entry].qtd = NULL; - priv->int_ints[queue_entry].qh = NULL; - - isp1760_writel(skip_map, usb_hcd->regs + - HC_INT_PTD_SKIPMAP_REG); - free_mem(priv, payload); - - if (urb->status == -EPIPE) { - /* HALT received */ - - qtd = clean_up_qtdlist(qtd); - isp1760_urb_done(priv, urb, urb->status); - - } else if (qtd->status & URB_COMPLETE_NOTIFY) { - - if (urb->status == -EINPROGRESS) - urb->status = 0; - - qtd = clean_this_qtd(qtd); - isp1760_urb_done(priv, urb, urb->status); - - } else { - /* next QTD of this URB */ - - qtd = clean_this_qtd(qtd); - BUG_ON(!qtd); - } - - if (qtd) - enqueue_an_INT_packet(usb_hcd, qh, qtd); - - skip_map = isp1760_readl(usb_hcd->regs + - HC_INT_PTD_SKIPMAP_REG); - } -} - -#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) -static struct isp1760_qh *qh_make(struct isp1760_hcd *priv, struct urb *urb, - gfp_t flags) -{ - struct isp1760_qh *qh; - int is_input, type; - - qh = isp1760_qh_alloc(priv, flags); - if (!qh) - return qh; - - /* - * init endpoint/device data for this QH - */ - is_input = usb_pipein(urb->pipe); - type = usb_pipetype(urb->pipe); - - if (type == PIPE_INTERRUPT) { - - if (urb->dev->speed == USB_SPEED_HIGH) { - - qh->period = urb->interval >> 3; - if (qh->period == 0 && urb->interval != 1) { - /* NOTE interval 2 or 4 uframes could work. - * But interval 1 scheduling is simpler, and - * includes high bandwidth. - */ - printk(KERN_ERR "intr period %d uframes, NYET!", - urb->interval); - qh_destroy(qh); - return NULL; - } - } else { - qh->period = urb->interval; - } - } - - /* support for tt scheduling, and access to toggles */ - qh->dev = urb->dev; - - if (!usb_pipecontrol(urb->pipe)) - usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input, - 1); - return qh; -} - -/* - * For control/bulk/interrupt, return QH with these TDs appended. - * Allocates and initializes the QH if necessary. - * Returns null if it can't allocate a QH it needs to. - * If the QH has TDs (urbs) already, that's great. - */ -static struct isp1760_qh *qh_append_tds(struct isp1760_hcd *priv, - struct urb *urb, struct list_head *qtd_list, int epnum, - void **ptr) -{ - struct isp1760_qh *qh; - struct isp1760_qtd *qtd; - struct isp1760_qtd *prev_qtd; - - qh = (struct isp1760_qh *)*ptr; - if (!qh) { - /* can't sleep here, we have priv->lock... */ - qh = qh_make(priv, urb, GFP_ATOMIC); - if (!qh) - return qh; - *ptr = qh; - } - - qtd = list_entry(qtd_list->next, struct isp1760_qtd, - qtd_list); - if (!list_empty(&qh->qtd_list)) - prev_qtd = list_entry(qh->qtd_list.prev, - struct isp1760_qtd, qtd_list); - else - prev_qtd = NULL; - - list_splice(qtd_list, qh->qtd_list.prev); - if (prev_qtd) { - BUG_ON(prev_qtd->hw_next); - prev_qtd->hw_next = qtd; - } - - urb->hcpriv = qh; - return qh; -} - -static void qtd_list_free(struct isp1760_hcd *priv, struct urb *urb, - struct list_head *qtd_list) -{ - struct list_head *entry, *temp; - - list_for_each_safe(entry, temp, qtd_list) { - struct isp1760_qtd *qtd; - - qtd = list_entry(entry, struct isp1760_qtd, qtd_list); - list_del(&qtd->qtd_list); - isp1760_qtd_free(qtd); - } -} - -static int isp1760_prepare_enqueue(struct isp1760_hcd *priv, struct urb *urb, - struct list_head *qtd_list, gfp_t mem_flags, packet_enqueue *p) -{ - struct isp1760_qtd *qtd; - int epnum; - unsigned long flags; - struct isp1760_qh *qh = NULL; - int rc; - int qh_busy; - - qtd = list_entry(qtd_list->next, struct isp1760_qtd, qtd_list); - epnum = urb->ep->desc.bEndpointAddress; - - spin_lock_irqsave(&priv->lock, flags); - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &priv_to_hcd(priv)->flags)) { - rc = -ESHUTDOWN; - goto done; - } - rc = usb_hcd_link_urb_to_ep(priv_to_hcd(priv), urb); - if (rc) - goto done; - - qh = urb->ep->hcpriv; - if (qh) - qh_busy = !list_empty(&qh->qtd_list); - else - qh_busy = 0; - - qh = qh_append_tds(priv, urb, qtd_list, epnum, &urb->ep->hcpriv); - if (!qh) { - usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb); - rc = -ENOMEM; - goto done; - } - - if (!qh_busy) - p(priv_to_hcd(priv), qh, qtd); - -done: - spin_unlock_irqrestore(&priv->lock, flags); - if (!qh) - qtd_list_free(priv, urb, qtd_list); - return rc; -} - -static struct isp1760_qtd *isp1760_qtd_alloc(struct isp1760_hcd *priv, - gfp_t flags) -{ - struct isp1760_qtd *qtd; - - qtd = kmem_cache_zalloc(qtd_cachep, flags); - if (qtd) - INIT_LIST_HEAD(&qtd->qtd_list); - - return qtd; -} - -/* - * create a list of filled qtds for this URB; won't link into qh. - */ -static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, - struct urb *urb, struct list_head *head, gfp_t flags) -{ - struct isp1760_qtd *qtd, *qtd_prev; - void *buf; - int len, maxpacket; - int is_input; - u32 token; - - /* - * URBs map to sequences of QTDs: one logical transaction - */ - qtd = isp1760_qtd_alloc(priv, flags); - if (!qtd) - return NULL; - - list_add_tail(&qtd->qtd_list, head); - qtd->urb = urb; - urb->status = -EINPROGRESS; - - token = 0; - /* for split transactions, SplitXState initialized to zero */ - - len = urb->transfer_buffer_length; - is_input = usb_pipein(urb->pipe); - if (usb_pipecontrol(urb->pipe)) { - /* SETUP pid */ - qtd_fill(qtd, urb->setup_packet, - sizeof(struct usb_ctrlrequest), - token | SETUP_PID); - - /* ... and always at least one more pid */ - token ^= DATA_TOGGLE; - qtd_prev = qtd; - qtd = isp1760_qtd_alloc(priv, flags); - if (!qtd) - goto cleanup; - qtd->urb = urb; - qtd_prev->hw_next = qtd; - list_add_tail(&qtd->qtd_list, head); - - /* for zero length DATA stages, STATUS is always IN */ - if (len == 0) - token |= IN_PID; - } - - /* - * data transfer stage: buffer setup - */ - buf = urb->transfer_buffer; - - if (is_input) - token |= IN_PID; - else - token |= OUT_PID; - - maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input)); - - /* - * buffer gets wrapped in one or more qtds; - * last one may be "short" (including zero len) - * and may serve as a control status ack - */ - for (;;) { - int this_qtd_len; - - if (!buf && len) { - /* XXX This looks like usb storage / SCSI bug */ - printk(KERN_ERR "buf is null, dma is %08lx len is %d\n", - (long unsigned)urb->transfer_dma, len); - WARN_ON(1); - } - - this_qtd_len = qtd_fill(qtd, buf, len, token); - len -= this_qtd_len; - buf += this_qtd_len; - - /* qh makes control packets use qtd toggle; maybe switch it */ - if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0) - token ^= DATA_TOGGLE; - - if (len <= 0) - break; - - qtd_prev = qtd; - qtd = isp1760_qtd_alloc(priv, flags); - if (!qtd) - goto cleanup; - qtd->urb = urb; - qtd_prev->hw_next = qtd; - list_add_tail(&qtd->qtd_list, head); - } - - /* - * control requests may need a terminating data "status" ack; - * bulk ones may need a terminating short packet (zero length). - */ - if (urb->transfer_buffer_length != 0) { - int one_more = 0; - - if (usb_pipecontrol(urb->pipe)) { - one_more = 1; - /* "in" <--> "out" */ - token ^= IN_PID; - /* force DATA1 */ - token |= DATA_TOGGLE; - } else if (usb_pipebulk(urb->pipe) - && (urb->transfer_flags & URB_ZERO_PACKET) - && !(urb->transfer_buffer_length % maxpacket)) { - one_more = 1; - } - if (one_more) { - qtd_prev = qtd; - qtd = isp1760_qtd_alloc(priv, flags); - if (!qtd) - goto cleanup; - qtd->urb = urb; - qtd_prev->hw_next = qtd; - list_add_tail(&qtd->qtd_list, head); - - /* never any data in such packets */ - qtd_fill(qtd, NULL, 0, token); - } - } - - qtd->status = URB_COMPLETE_NOTIFY; - return head; - -cleanup: - qtd_list_free(priv, urb, head); - return NULL; -} - -static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, - gfp_t mem_flags) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - struct list_head qtd_list; - packet_enqueue *pe; - - INIT_LIST_HEAD(&qtd_list); - - switch (usb_pipetype(urb->pipe)) { - case PIPE_CONTROL: - case PIPE_BULK: - - if (!qh_urb_transaction(priv, urb, &qtd_list, mem_flags)) - return -ENOMEM; - pe = enqueue_an_ATL_packet; - break; - - case PIPE_INTERRUPT: - if (!qh_urb_transaction(priv, urb, &qtd_list, mem_flags)) - return -ENOMEM; - pe = enqueue_an_INT_packet; - break; - - case PIPE_ISOCHRONOUS: - printk(KERN_ERR "PIPE_ISOCHRONOUS ain't supported\n"); - default: - return -EPIPE; - } - - isp1760_prepare_enqueue(priv, urb, &qtd_list, mem_flags, pe); - return 0; -} - -static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, - int status) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - struct inter_packet_info *ints; - u32 i; - u32 reg_base, or_reg, skip_reg; - int flags; - struct ptd ptd; - - switch (usb_pipetype(urb->pipe)) { - case PIPE_ISOCHRONOUS: - return -EPIPE; - break; - - case PIPE_INTERRUPT: - ints = priv->int_ints; - reg_base = INT_REGS_OFFSET; - or_reg = HC_INT_IRQ_MASK_OR_REG; - skip_reg = HC_INT_PTD_SKIPMAP_REG; - break; - - default: - ints = priv->atl_ints; - reg_base = ATL_REGS_OFFSET; - or_reg = HC_ATL_IRQ_MASK_OR_REG; - skip_reg = HC_ATL_PTD_SKIPMAP_REG; - break; - } - - memset(&ptd, 0, sizeof(ptd)); - spin_lock_irqsave(&priv->lock, flags); - - for (i = 0; i < 32; i++) { - if (ints->urb == urb) { - u32 skip_map; - u32 or_map; - struct isp1760_qtd *qtd; - - skip_map = isp1760_readl(hcd->regs + skip_reg); - skip_map |= 1 << i; - isp1760_writel(skip_map, hcd->regs + skip_reg); - - or_map = isp1760_readl(hcd->regs + or_reg); - or_map &= ~(1 << i); - isp1760_writel(or_map, hcd->regs + or_reg); - - priv_write_copy(priv, (u32 *)&ptd, hcd->regs + reg_base - + i * sizeof(ptd), sizeof(ptd)); - qtd = ints->qtd; - - clean_up_qtdlist(qtd); - - free_mem(priv, ints->payload); - - ints->urb = NULL; - ints->qh = NULL; - ints->qtd = NULL; - ints->data_buffer = NULL; - ints->payload = 0; - - isp1760_urb_done(priv, urb, status); - break; - } - ints++; - } - - spin_unlock_irqrestore(&priv->lock, flags); - return 0; -} - -static irqreturn_t isp1760_irq(struct usb_hcd *usb_hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); - u32 imask; - irqreturn_t irqret = IRQ_NONE; - - spin_lock(&priv->lock); - - if (!(usb_hcd->state & HC_STATE_RUNNING)) - goto leave; - - imask = isp1760_readl(usb_hcd->regs + HC_INTERRUPT_REG); - if (unlikely(!imask)) - goto leave; - - isp1760_writel(imask, usb_hcd->regs + HC_INTERRUPT_REG); - if (imask & HC_ATL_INT) - do_atl_int(usb_hcd); - - if (imask & HC_INTL_INT) - do_intl_int(usb_hcd); - - irqret = IRQ_HANDLED; -leave: - spin_unlock(&priv->lock); - return irqret; -} - -static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - u32 temp, status = 0; - u32 mask; - int retval = 1; - unsigned long flags; - - /* if !USB_SUSPEND, root hub timers won't get shut down ... */ - if (!HC_IS_RUNNING(hcd->state)) - return 0; - - /* init status to no-changes */ - buf[0] = 0; - mask = PORT_CSC; - - spin_lock_irqsave(&priv->lock, flags); - temp = isp1760_readl(hcd->regs + HC_PORTSC1); - - if (temp & PORT_OWNER) { - if (temp & PORT_CSC) { - temp &= ~PORT_CSC; - isp1760_writel(temp, hcd->regs + HC_PORTSC1); - goto done; - } - } - - /* - * Return status information even for ports with OWNER set. - * Otherwise khubd wouldn't see the disconnect event when a - * high-speed device is switched over to the companion - * controller by the user. - */ - - if ((temp & mask) != 0 - || ((temp & PORT_RESUME) != 0 - && time_after_eq(jiffies, - priv->reset_done))) { - buf [0] |= 1 << (0 + 1); - status = STS_PCD; - } - /* FIXME autosuspend idle root hubs */ -done: - spin_unlock_irqrestore(&priv->lock, flags); - return status ? retval : 0; -} - -static void isp1760_hub_descriptor(struct isp1760_hcd *priv, - struct usb_hub_descriptor *desc) -{ - int ports = HCS_N_PORTS(priv->hcs_params); - u16 temp; - - desc->bDescriptorType = 0x29; - /* priv 1.0, 2.3.9 says 20ms max */ - desc->bPwrOn2PwrGood = 10; - desc->bHubContrCurrent = 0; - - desc->bNbrPorts = ports; - temp = 1 + (ports / 8); - desc->bDescLength = 7 + 2 * temp; - - /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ - memset(&desc->bitmap[0], 0, temp); - memset(&desc->bitmap[temp], 0xff, temp); - - /* per-port overcurrent reporting */ - temp = 0x0008; - if (HCS_PPC(priv->hcs_params)) - /* per-port power control */ - temp |= 0x0001; - else - /* no power switching */ - temp |= 0x0002; - desc->wHubCharacteristics = cpu_to_le16(temp); -} - -#define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) - -static int check_reset_complete(struct isp1760_hcd *priv, int index, - u32 __iomem *status_reg, int port_status) -{ - if (!(port_status & PORT_CONNECT)) - return port_status; - - /* if reset finished and it's still not enabled -- handoff */ - if (!(port_status & PORT_PE)) { - - printk(KERN_ERR "port %d full speed --> companion\n", - index + 1); - - port_status |= PORT_OWNER; - port_status &= ~PORT_RWC_BITS; - isp1760_writel(port_status, status_reg); - - } else - printk(KERN_ERR "port %d high speed\n", index + 1); - - return port_status; -} - -static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, - u16 wValue, u16 wIndex, char *buf, u16 wLength) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - int ports = HCS_N_PORTS(priv->hcs_params); - u32 __iomem *status_reg = hcd->regs + HC_PORTSC1; - u32 temp, status; - unsigned long flags; - int retval = 0; - unsigned selector; - - /* - * FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR. - * HCS_INDICATOR may say we can change LEDs to off/amber/green. - * (track current state ourselves) ... blink for diagnostics, - * power, "this is the one", etc. EHCI spec supports this. - */ - - spin_lock_irqsave(&priv->lock, flags); - switch (typeReq) { - case ClearHubFeature: - switch (wValue) { - case C_HUB_LOCAL_POWER: - case C_HUB_OVER_CURRENT: - /* no hub-wide feature/status flags */ - break; - default: - goto error; - } - break; - case ClearPortFeature: - if (!wIndex || wIndex > ports) - goto error; - wIndex--; - temp = isp1760_readl(status_reg); - - /* - * Even if OWNER is set, so the port is owned by the - * companion controller, khubd needs to be able to clear - * the port-change status bits (especially - * USB_PORT_FEAT_C_CONNECTION). - */ - - switch (wValue) { - case USB_PORT_FEAT_ENABLE: - isp1760_writel(temp & ~PORT_PE, status_reg); - break; - case USB_PORT_FEAT_C_ENABLE: - /* XXX error? */ - break; - case USB_PORT_FEAT_SUSPEND: - if (temp & PORT_RESET) - goto error; - - if (temp & PORT_SUSPEND) { - if ((temp & PORT_PE) == 0) - goto error; - /* resume signaling for 20 msec */ - temp &= ~(PORT_RWC_BITS); - isp1760_writel(temp | PORT_RESUME, - status_reg); - priv->reset_done = jiffies + - msecs_to_jiffies(20); - } - break; - case USB_PORT_FEAT_C_SUSPEND: - /* we auto-clear this feature */ - break; - case USB_PORT_FEAT_POWER: - if (HCS_PPC(priv->hcs_params)) - isp1760_writel(temp & ~PORT_POWER, status_reg); - break; - case USB_PORT_FEAT_C_CONNECTION: - isp1760_writel(temp | PORT_CSC, - status_reg); - break; - case USB_PORT_FEAT_C_OVER_CURRENT: - /* XXX error ?*/ - break; - case USB_PORT_FEAT_C_RESET: - /* GetPortStatus clears reset */ - break; - default: - goto error; - } - isp1760_readl(hcd->regs + HC_USBCMD); - break; - case GetHubDescriptor: - isp1760_hub_descriptor(priv, (struct usb_hub_descriptor *) - buf); - break; - case GetHubStatus: - /* no hub-wide feature/status flags */ - memset(buf, 0, 4); - break; - case GetPortStatus: - if (!wIndex || wIndex > ports) - goto error; - wIndex--; - status = 0; - temp = isp1760_readl(status_reg); - - /* wPortChange bits */ - if (temp & PORT_CSC) - status |= 1 << USB_PORT_FEAT_C_CONNECTION; - - - /* whoever resumes must GetPortStatus to complete it!! */ - if (temp & PORT_RESUME) { - printk(KERN_ERR "Port resume should be skipped.\n"); - - /* Remote Wakeup received? */ - if (!priv->reset_done) { - /* resume signaling for 20 msec */ - priv->reset_done = jiffies - + msecs_to_jiffies(20); - /* check the port again */ - mod_timer(&priv_to_hcd(priv)->rh_timer, - priv->reset_done); - } - - /* resume completed? */ - else if (time_after_eq(jiffies, - priv->reset_done)) { - status |= 1 << USB_PORT_FEAT_C_SUSPEND; - priv->reset_done = 0; - - /* stop resume signaling */ - temp = isp1760_readl(status_reg); - isp1760_writel( - temp & ~(PORT_RWC_BITS | PORT_RESUME), - status_reg); - retval = handshake(priv, status_reg, - PORT_RESUME, 0, 2000 /* 2msec */); - if (retval != 0) { - isp1760_err(priv, - "port %d resume error %d\n", - wIndex + 1, retval); - goto error; - } - temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); - } - } - - /* whoever resets must GetPortStatus to complete it!! */ - if ((temp & PORT_RESET) - && time_after_eq(jiffies, - priv->reset_done)) { - status |= 1 << USB_PORT_FEAT_C_RESET; - priv->reset_done = 0; - - /* force reset to complete */ - isp1760_writel(temp & ~PORT_RESET, - status_reg); - /* REVISIT: some hardware needs 550+ usec to clear - * this bit; seems too long to spin routinely... - */ - retval = handshake(priv, status_reg, - PORT_RESET, 0, 750); - if (retval != 0) { - isp1760_err(priv, "port %d reset error %d\n", - wIndex + 1, retval); - goto error; - } - - /* see what we found out */ - temp = check_reset_complete(priv, wIndex, status_reg, - isp1760_readl(status_reg)); - } - /* - * Even if OWNER is set, there's no harm letting khubd - * see the wPortStatus values (they should all be 0 except - * for PORT_POWER anyway). - */ - - if (temp & PORT_OWNER) - printk(KERN_ERR "Warning: PORT_OWNER is set\n"); - - if (temp & PORT_CONNECT) { - status |= 1 << USB_PORT_FEAT_CONNECTION; - /* status may be from integrated TT */ - status |= ehci_port_speed(priv, temp); - } - if (temp & PORT_PE) - status |= 1 << USB_PORT_FEAT_ENABLE; - if (temp & (PORT_SUSPEND|PORT_RESUME)) - status |= 1 << USB_PORT_FEAT_SUSPEND; - if (temp & PORT_RESET) - status |= 1 << USB_PORT_FEAT_RESET; - if (temp & PORT_POWER) - status |= 1 << USB_PORT_FEAT_POWER; - - put_unaligned(cpu_to_le32(status), (__le32 *) buf); - break; - case SetHubFeature: - switch (wValue) { - case C_HUB_LOCAL_POWER: - case C_HUB_OVER_CURRENT: - /* no hub-wide feature/status flags */ - break; - default: - goto error; - } - break; - case SetPortFeature: - selector = wIndex >> 8; - wIndex &= 0xff; - if (!wIndex || wIndex > ports) - goto error; - wIndex--; - temp = isp1760_readl(status_reg); - if (temp & PORT_OWNER) - break; - -/* temp &= ~PORT_RWC_BITS; */ - switch (wValue) { - case USB_PORT_FEAT_ENABLE: - isp1760_writel(temp | PORT_PE, status_reg); - break; - - case USB_PORT_FEAT_SUSPEND: - if ((temp & PORT_PE) == 0 - || (temp & PORT_RESET) != 0) - goto error; - - isp1760_writel(temp | PORT_SUSPEND, status_reg); - break; - case USB_PORT_FEAT_POWER: - if (HCS_PPC(priv->hcs_params)) - isp1760_writel(temp | PORT_POWER, - status_reg); - break; - case USB_PORT_FEAT_RESET: - if (temp & PORT_RESUME) - goto error; - /* line status bits may report this as low speed, - * which can be fine if this root hub has a - * transaction translator built in. - */ - if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT - && PORT_USB11(temp)) { - temp |= PORT_OWNER; - } else { - temp |= PORT_RESET; - temp &= ~PORT_PE; - - /* - * caller must wait, then call GetPortStatus - * usb 2.0 spec says 50 ms resets on root - */ - priv->reset_done = jiffies + - msecs_to_jiffies(50); - } - isp1760_writel(temp, status_reg); - break; - default: - goto error; - } - isp1760_readl(hcd->regs + HC_USBCMD); - break; - - default: -error: - /* "stall" on error */ - retval = -EPIPE; - } - spin_unlock_irqrestore(&priv->lock, flags); - return retval; -} - -static void isp1760_endpoint_disable(struct usb_hcd *usb_hcd, - struct usb_host_endpoint *ep) -{ - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); - struct isp1760_qh *qh; - struct isp1760_qtd *qtd; - u32 flags; - - spin_lock_irqsave(&priv->lock, flags); - qh = ep->hcpriv; - if (!qh) - goto out; - - ep->hcpriv = NULL; - do { - /* more than entry might get removed */ - if (list_empty(&qh->qtd_list)) - break; - - qtd = list_first_entry(&qh->qtd_list, struct isp1760_qtd, - qtd_list); - - if (qtd->status & URB_ENQUEUED) { - - spin_unlock_irqrestore(&priv->lock, flags); - isp1760_urb_dequeue(usb_hcd, qtd->urb, -ECONNRESET); - spin_lock_irqsave(&priv->lock, flags); - } else { - struct urb *urb; - - urb = qtd->urb; - clean_up_qtdlist(qtd); - isp1760_urb_done(priv, urb, -ECONNRESET); - } - } while (1); - - qh_destroy(qh); - /* remove requests and leak them. - * ATL are pretty fast done, INT could take a while... - * The latter shoule be removed - */ -out: - spin_unlock_irqrestore(&priv->lock, flags); -} - -static int isp1760_get_frame(struct usb_hcd *hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - u32 fr; - - fr = isp1760_readl(hcd->regs + HC_FRINDEX); - return (fr >> 3) % priv->periodic_size; -} - -static void isp1760_stop(struct usb_hcd *hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - - isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, - NULL, 0); - mdelay(20); - - spin_lock_irq(&priv->lock); - ehci_reset(priv); - /* Disable IRQ */ - isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL); - spin_unlock_irq(&priv->lock); - - isp1760_writel(0, hcd->regs + HC_CONFIGFLAG); -} - -static void isp1760_shutdown(struct usb_hcd *hcd) -{ - u32 command; - - isp1760_stop(hcd); - isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL); - - command = isp1760_readl(hcd->regs + HC_USBCMD); - command &= ~CMD_RUN; - isp1760_writel(command, hcd->regs + HC_USBCMD); -} - -static const struct hc_driver isp1760_hc_driver = { - .description = "isp1760-hcd", - .product_desc = "NXP ISP1760 USB Host Controller", - .hcd_priv_size = sizeof(struct isp1760_hcd), - .irq = isp1760_irq, - .flags = HCD_MEMORY | HCD_USB2, - .reset = isp1760_hc_setup, - .start = isp1760_run, - .stop = isp1760_stop, - .shutdown = isp1760_shutdown, - .urb_enqueue = isp1760_urb_enqueue, - .urb_dequeue = isp1760_urb_dequeue, - .endpoint_disable = isp1760_endpoint_disable, - .get_frame_number = isp1760_get_frame, - .hub_status_data = isp1760_hub_status_data, - .hub_control = isp1760_hub_control, -}; - -int __init init_kmem_once(void) -{ - qtd_cachep = kmem_cache_create("isp1760_qtd", - sizeof(struct isp1760_qtd), 0, SLAB_TEMPORARY | - SLAB_MEM_SPREAD, NULL); - - if (!qtd_cachep) - return -ENOMEM; - - qh_cachep = kmem_cache_create("isp1760_qh", sizeof(struct isp1760_qh), - 0, SLAB_TEMPORARY | SLAB_MEM_SPREAD, NULL); - - if (!qh_cachep) { - kmem_cache_destroy(qtd_cachep); - return -ENOMEM; - } - - return 0; -} - -void deinit_kmem_cache(void) -{ - kmem_cache_destroy(qtd_cachep); - kmem_cache_destroy(qh_cachep); -} - -struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, - u64 irqflags, struct device *dev, const char *busname) -{ - struct usb_hcd *hcd; - struct isp1760_hcd *priv; - int ret; - - if (usb_disabled()) - return ERR_PTR(-ENODEV); - - /* prevent usb-core allocating DMA pages */ - dev->dma_mask = NULL; - - hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev->bus_id); - if (!hcd) - return ERR_PTR(-ENOMEM); - - priv = hcd_to_priv(hcd); - init_memory(priv); - hcd->regs = ioremap(res_start, res_len); - if (!hcd->regs) { - ret = -EIO; - goto err_put; - } - - ret = usb_add_hcd(hcd, irq, irqflags); - if (ret) - goto err_unmap; - - hcd->irq = irq; - hcd->rsrc_start = res_start; - hcd->rsrc_len = res_len; - - return hcd; - -err_unmap: - iounmap(hcd->regs); - -err_put: - usb_put_hcd(hcd); - - return ERR_PTR(ret); -} - -MODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP"); -MODULE_AUTHOR("Sebastian Siewior "); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/usb/host/isp1760-hcd.h b/trunk/drivers/usb/host/isp1760-hcd.h deleted file mode 100644 index 3d86d0f6b147..000000000000 --- a/trunk/drivers/usb/host/isp1760-hcd.h +++ /dev/null @@ -1,206 +0,0 @@ -#ifndef _ISP1760_HCD_H_ -#define _ISP1760_HCD_H_ - -/* exports for if */ -struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, - u64 irqflags, struct device *dev, const char *busname); -int init_kmem_once(void); -void deinit_kmem_cache(void); - -/* EHCI capability registers */ -#define HC_CAPLENGTH 0x00 -#define HC_HCSPARAMS 0x04 -#define HC_HCCPARAMS 0x08 - -/* EHCI operational registers */ -#define HC_USBCMD 0x20 -#define HC_USBSTS 0x24 -#define HC_FRINDEX 0x2c -#define HC_CONFIGFLAG 0x60 -#define HC_PORTSC1 0x64 -#define HC_ISO_PTD_DONEMAP_REG 0x130 -#define HC_ISO_PTD_SKIPMAP_REG 0x134 -#define HC_ISO_PTD_LASTPTD_REG 0x138 -#define HC_INT_PTD_DONEMAP_REG 0x140 -#define HC_INT_PTD_SKIPMAP_REG 0x144 -#define HC_INT_PTD_LASTPTD_REG 0x148 -#define HC_ATL_PTD_DONEMAP_REG 0x150 -#define HC_ATL_PTD_SKIPMAP_REG 0x154 -#define HC_ATL_PTD_LASTPTD_REG 0x158 - -/* Configuration Register */ -#define HC_HW_MODE_CTRL 0x300 -#define ALL_ATX_RESET (1 << 31) -#define HW_DATA_BUS_32BIT (1 << 8) -#define HW_DACK_POL_HIGH (1 << 6) -#define HW_DREQ_POL_HIGH (1 << 5) -#define HW_INTR_HIGH_ACT (1 << 2) -#define HW_INTR_EDGE_TRIG (1 << 1) -#define HW_GLOBAL_INTR_EN (1 << 0) - -#define HC_CHIP_ID_REG 0x304 -#define HC_SCRATCH_REG 0x308 - -#define HC_RESET_REG 0x30c -#define SW_RESET_RESET_HC (1 << 1) -#define SW_RESET_RESET_ALL (1 << 0) - -#define HC_BUFFER_STATUS_REG 0x334 -#define ATL_BUFFER 0x1 -#define INT_BUFFER 0x2 -#define ISO_BUFFER 0x4 -#define BUFFER_MAP 0x7 - -#define HC_MEMORY_REG 0x33c -#define HC_PORT1_CTRL 0x374 -#define PORT1_POWER (3 << 3) -#define PORT1_INIT1 (1 << 7) -#define PORT1_INIT2 (1 << 23) - -/* Interrupt Register */ -#define HC_INTERRUPT_REG 0x310 - -#define HC_INTERRUPT_ENABLE 0x314 -#define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT | HC_EOT_INT) -#define FINAL_HW_CONFIG (HW_GLOBAL_INTR_EN | HW_DATA_BUS_32BIT) - -#define HC_ISO_INT (1 << 9) -#define HC_ATL_INT (1 << 8) -#define HC_INTL_INT (1 << 7) -#define HC_EOT_INT (1 << 3) -#define HC_SOT_INT (1 << 1) - -#define HC_ISO_IRQ_MASK_OR_REG 0x318 -#define HC_INT_IRQ_MASK_OR_REG 0x31C -#define HC_ATL_IRQ_MASK_OR_REG 0x320 -#define HC_ISO_IRQ_MASK_AND_REG 0x324 -#define HC_INT_IRQ_MASK_AND_REG 0x328 -#define HC_ATL_IRQ_MASK_AND_REG 0x32C - -/* Register sets */ -#define HC_BEGIN_OF_ATL 0x0c00 -#define HC_BEGIN_OF_INT 0x0800 -#define HC_BEGIN_OF_ISO 0x0400 -#define HC_BEGIN_OF_PAYLOAD 0x1000 - -/* urb state*/ -#define DELETE_URB (0x0008) -#define NO_TRANSFER_ACTIVE (0xffffffff) - -#define ATL_REGS_OFFSET (0xc00) -#define INT_REGS_OFFSET (0x800) - -/* Philips Transfer Descriptor (PTD) */ -struct ptd { - __le32 dw0; - __le32 dw1; - __le32 dw2; - __le32 dw3; - __le32 dw4; - __le32 dw5; - __le32 dw6; - __le32 dw7; -}; - -struct inter_packet_info { - void *data_buffer; - u32 payload; -#define PTD_FIRE_NEXT (1 << 0) -#define PTD_URB_FINISHED (1 << 1) - struct urb *urb; - struct isp1760_qh *qh; - struct isp1760_qtd *qtd; -}; - - -typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, - struct isp1760_qtd *qtd); - -#define isp1760_info(priv, fmt, args...) \ - dev_info(priv_to_hcd(priv)->self.controller, fmt, ##args) - -#define isp1760_err(priv, fmt, args...) \ - dev_err(priv_to_hcd(priv)->self.controller, fmt, ##args) - -/* chip memory management */ -struct memory_chunk { - unsigned int start; - unsigned int size; - unsigned int free; -}; - -/* - * 60kb divided in: - * - 32 blocks @ 256 bytes - * - 20 blocks @ 1024 bytes - * - 4 blocks @ 8192 bytes - */ - -#define BLOCK_1_NUM 32 -#define BLOCK_2_NUM 20 -#define BLOCK_3_NUM 4 - -#define BLOCK_1_SIZE 256 -#define BLOCK_2_SIZE 1024 -#define BLOCK_3_SIZE 8192 -#define BLOCKS (BLOCK_1_NUM + BLOCK_2_NUM + BLOCK_3_NUM) -#define PAYLOAD_SIZE 0xf000 - -/* I saw if some reloads if the pointer was negative */ -#define ISP1760_NULL_POINTER (0x400) - -/* ATL */ -/* DW0 */ -#define PTD_VALID 1 -#define PTD_LENGTH(x) (((u32) x) << 3) -#define PTD_MAXPACKET(x) (((u32) x) << 18) -#define PTD_MULTI(x) (((u32) x) << 29) -#define PTD_ENDPOINT(x) (((u32) x) << 31) -/* DW1 */ -#define PTD_DEVICE_ADDR(x) (((u32) x) << 3) -#define PTD_PID_TOKEN(x) (((u32) x) << 10) -#define PTD_TRANS_BULK ((u32) 2 << 12) -#define PTD_TRANS_INT ((u32) 3 << 12) -#define PTD_TRANS_SPLIT ((u32) 1 << 14) -#define PTD_SE_USB_LOSPEED ((u32) 2 << 16) -#define PTD_PORT_NUM(x) (((u32) x) << 18) -#define PTD_HUB_NUM(x) (((u32) x) << 25) -#define PTD_PING(x) (((u32) x) << 26) -/* DW2 */ -#define PTD_RL_CNT(x) (((u32) x) << 25) -#define PTD_DATA_START_ADDR(x) (((u32) x) << 8) -#define BASE_ADDR 0x1000 -/* DW3 */ -#define PTD_CERR(x) (((u32) x) << 23) -#define PTD_NAC_CNT(x) (((u32) x) << 19) -#define PTD_ACTIVE ((u32) 1 << 31) -#define PTD_DATA_TOGGLE(x) (((u32) x) << 25) - -#define DW3_HALT_BIT (1 << 30) -#define DW3_ERROR_BIT (1 << 28) -#define DW3_QTD_ACTIVE (1 << 31) - -#define INT_UNDERRUN (1 << 2) -#define INT_BABBLE (1 << 1) -#define INT_EXACT (1 << 0) - -#define DW1_GET_PID(x) (((x) >> 10) & 0x3) -#define PTD_XFERRED_LENGTH(x) ((x) & 0x7fff) -#define PTD_XFERRED_LENGTH_LO(x) ((x) & 0x7ff) - -#define SETUP_PID (2) -#define IN_PID (1) -#define OUT_PID (0) -#define GET_QTD_TOKEN_TYPE(x) ((x) & 0x3) - -#define DATA_TOGGLE (1 << 31) -#define GET_DATA_TOGGLE(x) ((x) >> 31) - -/* Errata 1 */ -#define RL_COUNTER (0) -#define NAK_COUNTER (0) -#define ERR_COUNTER (2) - -#define HC_ATL_PL_SIZE (8192) - -#endif diff --git a/trunk/drivers/usb/host/isp1760-if.c b/trunk/drivers/usb/host/isp1760-if.c deleted file mode 100644 index 73fb2a38f1e4..000000000000 --- a/trunk/drivers/usb/host/isp1760-if.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Glue code for the ISP1760 driver and bus - * Currently there is support for - * - OpenFirmware - * - PCI - * - * (c) 2007 Sebastian Siewior - * - */ - -#include -#include - -#include "../core/hcd.h" -#include "isp1760-hcd.h" - -#ifdef CONFIG_USB_ISP1760_OF -#include -#include -#endif - -#ifdef CONFIG_USB_ISP1760_PCI -#include -#endif - -#ifdef CONFIG_USB_ISP1760_OF -static int of_isp1760_probe(struct of_device *dev, - const struct of_device_id *match) -{ - struct usb_hcd *hcd; - struct device_node *dp = dev->node; - struct resource *res; - struct resource memory; - struct of_irq oirq; - int virq; - u64 res_len; - int ret; - - ret = of_address_to_resource(dp, 0, &memory); - if (ret) - return -ENXIO; - - res = request_mem_region(memory.start, memory.end - memory.start + 1, - dev->dev.bus_id); - if (!res) - return -EBUSY; - - res_len = memory.end - memory.start + 1; - - if (of_irq_map_one(dp, 0, &oirq)) { - ret = -ENODEV; - goto release_reg; - } - - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); - - hcd = isp1760_register(memory.start, res_len, virq, - IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev->dev.bus_id); - if (IS_ERR(hcd)) { - ret = PTR_ERR(hcd); - goto release_reg; - } - - dev_set_drvdata(&dev->dev, hcd); - return ret; - -release_reg: - release_mem_region(memory.start, memory.end - memory.start + 1); - return ret; -} - -static int of_isp1760_remove(struct of_device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(&dev->dev); - - dev_set_drvdata(&dev->dev, NULL); - - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); - return 0; -} - -static struct of_device_id of_isp1760_match[] = { - { - .compatible = "nxp,usb-isp1760", - }, - { }, -}; -MODULE_DEVICE_TABLE(of, of_isp1760_match); - -static struct of_platform_driver isp1760_of_driver = { - .name = "nxp-isp1760", - .match_table = of_isp1760_match, - .probe = of_isp1760_probe, - .remove = of_isp1760_remove, -}; -#endif - -#ifdef CONFIG_USB_ISP1760_PCI -static u32 nxp_pci_io_base; -static u32 iolength; -static u32 pci_mem_phy0; -static u32 length; -static u8 *chip_addr; -static u8 *iobase; - -static int __devinit isp1761_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - u8 latency, limit; - __u32 reg_data; - int retry_count; - int length; - int status = 1; - struct usb_hcd *hcd; - - if (usb_disabled()) - return -ENODEV; - - if (pci_enable_device(dev) < 0) - return -ENODEV; - - if (!dev->irq) - return -ENODEV; - - /* Grab the PLX PCI mem maped port start address we need */ - nxp_pci_io_base = pci_resource_start(dev, 0); - iolength = pci_resource_len(dev, 0); - - if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) { - printk(KERN_ERR "request region #1\n"); - return -EBUSY; - } - - iobase = ioremap_nocache(nxp_pci_io_base, iolength); - if (!iobase) { - printk(KERN_ERR "ioremap #1\n"); - release_mem_region(nxp_pci_io_base, iolength); - return -ENOMEM; - } - /* Grab the PLX PCI shared memory of the ISP 1761 we need */ - pci_mem_phy0 = pci_resource_start(dev, 3); - length = pci_resource_len(dev, 3); - - if (length < 0xffff) { - printk(KERN_ERR "memory length for this resource is less than " - "required\n"); - release_mem_region(nxp_pci_io_base, iolength); - iounmap(iobase); - return -ENOMEM; - } - - if (!request_mem_region(pci_mem_phy0, length, "ISP-PCI")) { - printk(KERN_ERR "host controller already in use\n"); - release_mem_region(nxp_pci_io_base, iolength); - iounmap(iobase); - return -EBUSY; - } - - /* bad pci latencies can contribute to overruns */ - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency); - if (latency) { - pci_read_config_byte(dev, PCI_MAX_LAT, &limit); - if (limit && limit < latency) - pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit); - } - - /* Try to check whether we can access Scratch Register of - * Host Controller or not. The initial PCI access is retried until - * local init for the PCI bridge is completed - */ - retry_count = 20; - reg_data = 0; - while ((reg_data != 0xFACE) && retry_count) { - /*by default host is in 16bit mode, so - * io operations at this stage must be 16 bit - * */ - writel(0xface, chip_addr + HC_SCRATCH_REG); - udelay(100); - reg_data = readl(chip_addr + HC_SCRATCH_REG); - retry_count--; - } - - /* Host Controller presence is detected by writing to scratch register - * and reading back and checking the contents are same or not - */ - if (reg_data != 0xFACE) { - err("scratch register mismatch %x", reg_data); - goto clean; - } - - pci_set_master(dev); - - status = readl(iobase + 0x68); - status |= 0x900; - writel(status, iobase + 0x68); - - dev->dev.dma_mask = NULL; - hcd = isp1760_register(pci_mem_phy0, length, dev->irq, - IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev->dev.bus_id); - pci_set_drvdata(dev, hcd); - if (!hcd) - return 0; -clean: - status = -ENODEV; - iounmap(iobase); - release_mem_region(pci_mem_phy0, length); - release_mem_region(nxp_pci_io_base, iolength); - return status; -} -static void isp1761_pci_remove(struct pci_dev *dev) -{ - struct usb_hcd *hcd; - - hcd = pci_get_drvdata(dev); - - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); - - pci_disable_device(dev); - - iounmap(iobase); - iounmap(chip_addr); - - release_mem_region(nxp_pci_io_base, iolength); - release_mem_region(pci_mem_phy0, length); -} - -static void isp1761_pci_shutdown(struct pci_dev *dev) -{ - printk(KERN_ERR "ips1761_pci_shutdown\n"); -} - -static const struct pci_device_id isp1760_plx [] = { { - /* handle any USB 2.0 EHCI controller */ - PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_OTHER << 8) | (0x06 << 16)), ~0), - .driver_data = 0, -}, -{ /* end: all zeroes */ } -}; -MODULE_DEVICE_TABLE(pci, isp1760_plx); - -static struct pci_driver isp1761_pci_driver = { - .name = "isp1760", - .id_table = isp1760_plx, - .probe = isp1761_pci_probe, - .remove = isp1761_pci_remove, - .shutdown = isp1761_pci_shutdown, -}; -#endif - -static int __init isp1760_init(void) -{ - int ret; - - init_kmem_once(); - -#ifdef CONFIG_USB_ISP1760_OF - ret = of_register_platform_driver(&isp1760_of_driver); - if (ret) { - deinit_kmem_cache(); - return ret; - } -#endif -#ifdef CONFIG_USB_ISP1760_PCI - ret = pci_register_driver(&isp1761_pci_driver); - if (ret) - goto unreg_of; -#endif - return ret; - -#ifdef CONFIG_USB_ISP1760_PCI -unreg_of: -#endif -#ifdef CONFIG_USB_ISP1760_OF - of_unregister_platform_driver(&isp1760_of_driver); -#endif - deinit_kmem_cache(); - return ret; -} -module_init(isp1760_init); - -static void __exit isp1760_exit(void) -{ -#ifdef CONFIG_USB_ISP1760_OF - of_unregister_platform_driver(&isp1760_of_driver); -#endif -#ifdef CONFIG_USB_ISP1760_PCI - pci_unregister_driver(&isp1761_pci_driver); -#endif - deinit_kmem_cache(); -} -module_exit(isp1760_exit); diff --git a/trunk/drivers/usb/host/ohci-hub.c b/trunk/drivers/usb/host/ohci-hub.c index 79a78029f896..17dc2eccda83 100644 --- a/trunk/drivers/usb/host/ohci-hub.c +++ b/trunk/drivers/usb/host/ohci-hub.c @@ -613,7 +613,7 @@ static void start_hnp(struct ohci_hcd *ohci); static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port) { __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port]; - u32 temp = 0; + u32 temp; u16 now = ohci_readl(ohci, &ohci->regs->fmnumber); u16 reset_done = now + PORT_RESET_MSEC; int limit_1 = DIV_ROUND_UP(PORT_RESET_MSEC, PORT_RESET_HW_MSEC); diff --git a/trunk/drivers/usb/host/uhci-hcd.c b/trunk/drivers/usb/host/uhci-hcd.c index 3a7bfe7a8874..d3e0d8aa3980 100644 --- a/trunk/drivers/usb/host/uhci-hcd.c +++ b/trunk/drivers/usb/host/uhci-hcd.c @@ -234,7 +234,7 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) return 0; } -static int global_suspend_mode_is_broken(struct uhci_hcd *uhci) +static int remote_wakeup_is_broken(struct uhci_hcd *uhci) { int port; const char *sys_info; @@ -261,60 +261,27 @@ __releases(uhci->lock) __acquires(uhci->lock) { int auto_stop; - int int_enable, egsm_enable, wakeup_enable; + int int_enable, egsm_enable; struct usb_device *rhdev = uhci_to_hcd(uhci)->self.root_hub; auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); dev_dbg(&rhdev->dev, "%s%s\n", __func__, (auto_stop ? " (auto-stop)" : "")); - /* Start off by assuming Resume-Detect interrupts and EGSM work - * and that remote wakeups should be enabled. + /* Enable resume-detect interrupts if they work. + * Then enter Global Suspend mode if _it_ works, still configured. */ egsm_enable = USBCMD_EGSM; - uhci->RD_enable = 1; + uhci->working_RD = 1; int_enable = USBINTR_RESUME; - wakeup_enable = 1; - - /* In auto-stop mode wakeups must always be detected, but - * Resume-Detect interrupts may be prohibited. (In the absence - * of CONFIG_PM, they are always disallowed.) - */ - if (auto_stop) { - if (!device_may_wakeup(&rhdev->dev)) - int_enable = 0; - - /* In bus-suspend mode wakeups may be disabled, but if they are - * allowed then so are Resume-Detect interrupts. - */ - } else { + if (remote_wakeup_is_broken(uhci)) + egsm_enable = 0; + if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable || #ifdef CONFIG_PM - if (!rhdev->do_remote_wakeup) - wakeup_enable = 0; + (!auto_stop && !rhdev->do_remote_wakeup) || #endif - } - - /* EGSM causes the root hub to echo a 'K' signal (resume) out any - * port which requests a remote wakeup. According to the USB spec, - * every hub is supposed to do this. But if we are ignoring - * remote-wakeup requests anyway then there's no point to it. - * We also shouldn't enable EGSM if it's broken. - */ - if (!wakeup_enable || global_suspend_mode_is_broken(uhci)) - egsm_enable = 0; - - /* If we're ignoring wakeup events then there's no reason to - * enable Resume-Detect interrupts. We also shouldn't enable - * them if they are broken or disallowed. - * - * This logic may lead us to enabling RD but not EGSM. The UHCI - * spec foolishly says that RD works only when EGSM is on, but - * there's no harm in enabling it anyway -- perhaps some chips - * will implement it! - */ - if (!wakeup_enable || resume_detect_interrupts_are_broken(uhci) || - !int_enable) - uhci->RD_enable = int_enable = 0; + (auto_stop && !device_may_wakeup(&rhdev->dev))) + uhci->working_RD = int_enable = 0; outw(int_enable, uhci->io_addr + USBINTR); outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD); @@ -341,11 +308,7 @@ __acquires(uhci->lock) uhci->rh_state = new_state; uhci->is_stopped = UHCI_IS_STOPPED; - - /* If interrupts don't work and remote wakeup is enabled then - * the suspended root hub needs to be polled. - */ - uhci_to_hcd(uhci)->poll_rh = (!int_enable && wakeup_enable); + uhci_to_hcd(uhci)->poll_rh = !int_enable; uhci_scan_schedule(uhci); uhci_fsbr_off(uhci); @@ -381,12 +344,9 @@ __acquires(uhci->lock) * for 20 ms. */ if (uhci->rh_state == UHCI_RH_SUSPENDED) { - unsigned egsm; - - /* Keep EGSM on if it was set before */ - egsm = inw(uhci->io_addr + USBCMD) & USBCMD_EGSM; uhci->rh_state = UHCI_RH_RESUMING; - outw(USBCMD_FGR | USBCMD_CF | egsm, uhci->io_addr + USBCMD); + outw(USBCMD_FGR | USBCMD_EGSM | USBCMD_CF, + uhci->io_addr + USBCMD); spin_unlock_irq(&uhci->lock); msleep(20); spin_lock_irq(&uhci->lock); @@ -841,10 +801,8 @@ static int uhci_pci_resume(struct usb_hcd *hcd) spin_unlock_irq(&uhci->lock); - /* If interrupts don't work and remote wakeup is enabled then - * the suspended root hub needs to be polled. - */ - if (!uhci->RD_enable && hcd->self.root_hub->do_remote_wakeup) { + if (!uhci->working_RD) { + /* Suspended root hub needs to be polled */ hcd->poll_rh = 1; usb_hcd_poll_rh_status(hcd); } diff --git a/trunk/drivers/usb/host/uhci-hcd.h b/trunk/drivers/usb/host/uhci-hcd.h index 7d01c5677f92..340d6ed3e6e9 100644 --- a/trunk/drivers/usb/host/uhci-hcd.h +++ b/trunk/drivers/usb/host/uhci-hcd.h @@ -400,9 +400,8 @@ struct uhci_hcd { unsigned int scan_in_progress:1; /* Schedule scan is running */ unsigned int need_rescan:1; /* Redo the schedule scan */ unsigned int dead:1; /* Controller has died */ - unsigned int RD_enable:1; /* Suspended root hub with - Resume-Detect interrupts - enabled */ + unsigned int working_RD:1; /* Suspended root hub doesn't + need to be polled */ unsigned int is_initialized:1; /* Data structure is usable */ unsigned int fsbr_is_on:1; /* FSBR is turned on */ unsigned int fsbr_is_wanted:1; /* Does any URB want FSBR? */ diff --git a/trunk/drivers/usb/misc/ldusb.c b/trunk/drivers/usb/misc/ldusb.c index 7aafd53fbcab..11580e81e2c6 100644 --- a/trunk/drivers/usb/misc/ldusb.c +++ b/trunk/drivers/usb/misc/ldusb.c @@ -148,7 +148,7 @@ MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in /* Structure to hold all of our device specific stuff */ struct ld_usb { - struct mutex mutex; /* locks this structure */ + struct semaphore sem; /* locks this structure */ struct usb_interface* intf; /* save off the usb interface pointer */ int open_count; /* number of times this port has been opened */ @@ -319,7 +319,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) return -ENODEV; /* lock this device */ - if (mutex_lock_interruptible(&dev->mutex)) + if (down_interruptible(&dev->sem)) return -ERESTARTSYS; /* allow opening only once */ @@ -358,7 +358,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) file->private_data = dev; unlock_exit: - mutex_unlock(&dev->mutex); + up(&dev->sem); return retval; } @@ -378,7 +378,7 @@ static int ld_usb_release(struct inode *inode, struct file *file) goto exit; } - if (mutex_lock_interruptible(&dev->mutex)) { + if (down_interruptible(&dev->sem)) { retval = -ERESTARTSYS; goto exit; } @@ -389,7 +389,7 @@ static int ld_usb_release(struct inode *inode, struct file *file) } if (dev->intf == NULL) { /* the device was unplugged before the file was released */ - mutex_unlock(&dev->mutex); + up(&dev->sem); /* unlock here as ld_usb_delete frees dev */ ld_usb_delete(dev); goto exit; @@ -402,7 +402,7 @@ static int ld_usb_release(struct inode *inode, struct file *file) dev->open_count = 0; unlock_exit: - mutex_unlock(&dev->mutex); + up(&dev->sem); exit: return retval; @@ -448,7 +448,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, goto exit; /* lock this object */ - if (mutex_lock_interruptible(&dev->mutex)) { + if (down_interruptible(&dev->sem)) { retval = -ERESTARTSYS; goto exit; } @@ -505,7 +505,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, unlock_exit: /* unlock the device */ - mutex_unlock(&dev->mutex); + up(&dev->sem); exit: return retval; @@ -528,7 +528,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, goto exit; /* lock this object */ - if (mutex_lock_interruptible(&dev->mutex)) { + if (down_interruptible(&dev->sem)) { retval = -ERESTARTSYS; goto exit; } @@ -602,7 +602,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, unlock_exit: /* unlock the device */ - mutex_unlock(&dev->mutex); + up(&dev->sem); exit: return retval; @@ -651,7 +651,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * dev_err(&intf->dev, "Out of memory\n"); goto exit; } - mutex_init(&dev->mutex); + init_MUTEX(&dev->sem); spin_lock_init(&dev->rbsl); dev->intf = intf; init_waitqueue_head(&dev->read_wait); @@ -765,15 +765,15 @@ static void ld_usb_disconnect(struct usb_interface *intf) /* give back our minor */ usb_deregister_dev(intf, &ld_usb_class); - mutex_lock(&dev->mutex); + down(&dev->sem); /* if the device is not opened, then we clean up right now */ if (!dev->open_count) { - mutex_unlock(&dev->mutex); + up(&dev->sem); ld_usb_delete(dev); } else { dev->intf = NULL; - mutex_unlock(&dev->mutex); + up(&dev->sem); } dev_info(&intf->dev, "LD USB Device #%d now disconnected\n", diff --git a/trunk/drivers/usb/misc/usbtest.c b/trunk/drivers/usb/misc/usbtest.c index 742be3c35947..a51983854ca0 100644 --- a/trunk/drivers/usb/misc/usbtest.c +++ b/trunk/drivers/usb/misc/usbtest.c @@ -79,10 +79,30 @@ static struct usb_device *testdev_to_usbdev (struct usbtest_dev *test) /* set up all urbs so they can be used with either bulk or interrupt */ #define INTERRUPT_RATE 1 /* msec/transfer */ -#define ERROR(tdev, fmt, args...) \ - dev_err(&(tdev)->intf->dev , fmt , ## args) -#define WARN(tdev, fmt, args...) \ - dev_warn(&(tdev)->intf->dev , fmt , ## args) +#define xprintk(tdev,level,fmt,args...) \ + dev_printk(level , &(tdev)->intf->dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while (0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while (0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) /*-------------------------------------------------------------------------*/ @@ -216,7 +236,7 @@ static struct urb *simple_alloc_urb ( static unsigned pattern = 0; module_param (pattern, uint, S_IRUGO); -MODULE_PARM_DESC(pattern, "i/o pattern (0 == zeroes)"); +// MODULE_PARM_DESC (pattern, "i/o pattern (0 == zeroes)"); static inline void simple_fill_buf (struct urb *urb) { @@ -237,7 +257,7 @@ static inline void simple_fill_buf (struct urb *urb) } } -static inline int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb) +static inline int simple_check_buf (struct urb *urb) { unsigned i; u8 expected; @@ -265,7 +285,7 @@ static inline int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb) } if (*buf == expected) continue; - ERROR(tdev, "buf[%d] = %d (not %d)\n", i, *buf, expected); + dbg ("buf[%d] = %d (not %d)", i, *buf, expected); return -EINVAL; } return 0; @@ -279,7 +299,6 @@ static void simple_free_urb (struct urb *urb) } static int simple_io ( - struct usbtest_dev *tdev, struct urb *urb, int iterations, int vary, @@ -305,7 +324,7 @@ static int simple_io ( retval = urb->status; urb->dev = udev; if (retval == 0 && usb_pipein (urb->pipe)) - retval = simple_check_buf(tdev, urb); + retval = simple_check_buf (urb); if (vary) { int len = urb->transfer_buffer_length; @@ -322,7 +341,7 @@ static int simple_io ( urb->transfer_buffer_length = max; if (expected != retval) - dev_err(&udev->dev, + dev_dbg (&udev->dev, "%s failed, iterations left %d, status %d (not %d)\n", label, iterations, retval, expected); return retval; @@ -338,7 +357,7 @@ static int simple_io ( static void free_sglist (struct scatterlist *sg, int nents) { unsigned i; - + if (!sg) return; for (i = 0; i < nents; i++) { @@ -396,7 +415,7 @@ alloc_sglist (int nents, int max, int vary) } static int perform_sglist ( - struct usbtest_dev *tdev, + struct usb_device *udev, unsigned iterations, int pipe, struct usb_sg_request *req, @@ -404,7 +423,6 @@ static int perform_sglist ( int nents ) { - struct usb_device *udev = testdev_to_usbdev(tdev); int retval = 0; while (retval == 0 && iterations-- > 0) { @@ -413,7 +431,7 @@ static int perform_sglist ( ? (INTERRUPT_RATE << 3) : INTERRUPT_RATE, sg, nents, 0, GFP_KERNEL); - + if (retval) break; usb_sg_wait (req); @@ -428,8 +446,7 @@ static int perform_sglist ( // failure if retval is as we expected ... if (retval) - ERROR(tdev, "perform_sglist failed, " - "iterations left %d, status %d\n", + dbg ("perform_sglist failed, iterations left %d, status %d", iterations, retval); return retval; } @@ -488,28 +505,28 @@ static int set_altsetting (struct usbtest_dev *dev, int alternate) alternate); } -static int is_good_config(struct usbtest_dev *tdev, int len) +static int is_good_config (char *buf, int len) { struct usb_config_descriptor *config; - + if (len < sizeof *config) return 0; - config = (struct usb_config_descriptor *) tdev->buf; + config = (struct usb_config_descriptor *) buf; switch (config->bDescriptorType) { case USB_DT_CONFIG: case USB_DT_OTHER_SPEED_CONFIG: if (config->bLength != 9) { - ERROR(tdev, "bogus config descriptor length\n"); + dbg ("bogus config descriptor length"); return 0; } /* this bit 'must be 1' but often isn't */ if (!realworld && !(config->bmAttributes & 0x80)) { - ERROR(tdev, "high bit of config attributes not set\n"); + dbg ("high bit of config attributes not set"); return 0; } if (config->bmAttributes & 0x1f) { /* reserved == 0 */ - ERROR(tdev, "reserved config bits set\n"); + dbg ("reserved config bits set"); return 0; } break; @@ -521,7 +538,7 @@ static int is_good_config(struct usbtest_dev *tdev, int len) return 1; if (le16_to_cpu(config->wTotalLength) >= TBUF_SIZE) /* max partial read */ return 1; - ERROR(tdev, "bogus config descriptor read size\n"); + dbg ("bogus config descriptor read size"); return 0; } @@ -554,7 +571,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) /* 9.2.3 constrains the range here */ alt = iface->altsetting [i].desc.bAlternateSetting; if (alt < 0 || alt >= iface->num_altsetting) { - dev_err(&iface->dev, + dev_dbg (&iface->dev, "invalid alt [%d].bAltSetting = %d\n", i, alt); } @@ -566,7 +583,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) /* [9.4.10] set_interface */ retval = set_altsetting (dev, alt); if (retval) { - dev_err(&iface->dev, "can't set_interface = %d, %d\n", + dev_dbg (&iface->dev, "can't set_interface = %d, %d\n", alt, retval); return retval; } @@ -574,7 +591,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) /* [9.4.4] get_interface always works */ retval = get_altsetting (dev); if (retval != alt) { - dev_err(&iface->dev, "get alt should be %d, was %d\n", + dev_dbg (&iface->dev, "get alt should be %d, was %d\n", alt, retval); return (retval < 0) ? retval : -EDOM; } @@ -594,7 +611,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) USB_DIR_IN | USB_RECIP_DEVICE, 0, 0, dev->buf, 1, USB_CTRL_GET_TIMEOUT); if (retval != 1 || dev->buf [0] != expected) { - dev_err(&iface->dev, "get config --> %d %d (1 %d)\n", + dev_dbg (&iface->dev, "get config --> %d %d (1 %d)\n", retval, dev->buf[0], expected); return (retval < 0) ? retval : -EDOM; } @@ -604,7 +621,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) retval = usb_get_descriptor (udev, USB_DT_DEVICE, 0, dev->buf, sizeof udev->descriptor); if (retval != sizeof udev->descriptor) { - dev_err(&iface->dev, "dev descriptor --> %d\n", retval); + dev_dbg (&iface->dev, "dev descriptor --> %d\n", retval); return (retval < 0) ? retval : -EDOM; } @@ -612,8 +629,8 @@ static int ch9_postconfig (struct usbtest_dev *dev) for (i = 0; i < udev->descriptor.bNumConfigurations; i++) { retval = usb_get_descriptor (udev, USB_DT_CONFIG, i, dev->buf, TBUF_SIZE); - if (!is_good_config(dev, retval)) { - dev_err(&iface->dev, + if (!is_good_config (dev->buf, retval)) { + dev_dbg (&iface->dev, "config [%d] descriptor --> %d\n", i, retval); return (retval < 0) ? retval : -EDOM; @@ -633,14 +650,14 @@ static int ch9_postconfig (struct usbtest_dev *dev) sizeof (struct usb_qualifier_descriptor)); if (retval == -EPIPE) { if (udev->speed == USB_SPEED_HIGH) { - dev_err(&iface->dev, + dev_dbg (&iface->dev, "hs dev qualifier --> %d\n", retval); return (retval < 0) ? retval : -EDOM; } /* usb2.0 but not high-speed capable; fine */ } else if (retval != sizeof (struct usb_qualifier_descriptor)) { - dev_err(&iface->dev, "dev qualifier --> %d\n", retval); + dev_dbg (&iface->dev, "dev qualifier --> %d\n", retval); return (retval < 0) ? retval : -EDOM; } else d = (struct usb_qualifier_descriptor *) dev->buf; @@ -652,8 +669,8 @@ static int ch9_postconfig (struct usbtest_dev *dev) retval = usb_get_descriptor (udev, USB_DT_OTHER_SPEED_CONFIG, i, dev->buf, TBUF_SIZE); - if (!is_good_config(dev, retval)) { - dev_err(&iface->dev, + if (!is_good_config (dev->buf, retval)) { + dev_dbg (&iface->dev, "other speed config --> %d\n", retval); return (retval < 0) ? retval : -EDOM; @@ -666,7 +683,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) /* [9.4.5] get_status always works */ retval = usb_get_status (udev, USB_RECIP_DEVICE, 0, dev->buf); if (retval != 2) { - dev_err(&iface->dev, "get dev status --> %d\n", retval); + dev_dbg (&iface->dev, "get dev status --> %d\n", retval); return (retval < 0) ? retval : -EDOM; } @@ -676,11 +693,11 @@ static int ch9_postconfig (struct usbtest_dev *dev) retval = usb_get_status (udev, USB_RECIP_INTERFACE, iface->altsetting [0].desc.bInterfaceNumber, dev->buf); if (retval != 2) { - dev_err(&iface->dev, "get interface status --> %d\n", retval); + dev_dbg (&iface->dev, "get interface status --> %d\n", retval); return (retval < 0) ? retval : -EDOM; } // FIXME get status for each endpoint in the interface - + return 0; } @@ -735,9 +752,8 @@ static void ctrl_complete (struct urb *urb) */ if (subcase->number > 0) { if ((subcase->number - ctx->last) != 1) { - ERROR(ctx->dev, - "subcase %d completed out of order, last %d\n", - subcase->number, ctx->last); + dbg ("subcase %d completed out of order, last %d", + subcase->number, ctx->last); status = -EDOM; ctx->last = subcase->number; goto error; @@ -761,7 +777,7 @@ static void ctrl_complete (struct urb *urb) else if (subcase->number == 12 && status == -EPIPE) status = 0; else - ERROR(ctx->dev, "subtest %d error, status %d\n", + dbg ("subtest %d error, status %d", subcase->number, status); } @@ -772,12 +788,9 @@ static void ctrl_complete (struct urb *urb) int i; ctx->status = status; - ERROR(ctx->dev, "control queue %02x.%02x, err %d, " - "%d left, subcase %d, len %d/%d\n", + info ("control queue %02x.%02x, err %d, %d left", reqp->bRequestType, reqp->bRequest, - status, ctx->count, subcase->number, - urb->actual_length, - urb->transfer_buffer_length); + status, ctx->count); /* FIXME this "unlink everything" exit route should * be a separate test case. @@ -786,8 +799,7 @@ static void ctrl_complete (struct urb *urb) /* unlink whatever's still pending */ for (i = 1; i < ctx->param->sglen; i++) { struct urb *u = ctx->urb [ - (i + subcase->number) - % ctx->param->sglen]; + (i + subcase->number) % ctx->param->sglen]; if (u == urb || !u->dev) continue; @@ -800,8 +812,7 @@ static void ctrl_complete (struct urb *urb) case -EIDRM: continue; default: - ERROR(ctx->dev, "urb unlink --> %d\n", - status); + dbg ("urb unlink --> %d", status); } } status = ctx->status; @@ -811,15 +822,14 @@ static void ctrl_complete (struct urb *urb) /* resubmit if we need to, else mark this as done */ if ((status == 0) && (ctx->pending < ctx->count)) { if ((status = usb_submit_urb (urb, GFP_ATOMIC)) != 0) { - ERROR(ctx->dev, - "can't resubmit ctrl %02x.%02x, err %d\n", + dbg ("can't resubmit ctrl %02x.%02x, err %d", reqp->bRequestType, reqp->bRequest, status); urb->dev = NULL; } else ctx->pending++; } else urb->dev = NULL; - + /* signal completion when nothing's queued */ if (ctx->pending == 0) complete (&ctx->complete); @@ -908,11 +918,11 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) req.wValue = cpu_to_le16 (USB_DT_INTERFACE << 8); // interface == 0 len = sizeof (struct usb_interface_descriptor); - expected = -EPIPE; + expected = EPIPE; break; // NOTE: two consecutive stalls in the queue here. // that tests fault recovery a bit more aggressively. - case 8: // clear endpoint halt (MAY STALL) + case 8: // clear endpoint halt (USUALLY STALLS) req.bRequest = USB_REQ_CLEAR_FEATURE; req.bRequestType = USB_RECIP_ENDPOINT; // wValue 0 == ep halt @@ -955,7 +965,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) break; case 14: // short read; try to fill the last packet req.wValue = cpu_to_le16 ((USB_DT_DEVICE << 8) | 0); - /* device descriptor size == 18 bytes */ + // device descriptor size == 18 bytes len = udev->descriptor.bMaxPacketSize0; switch (len) { case 8: len = 24; break; @@ -964,7 +974,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) expected = -EREMOTEIO; break; default: - ERROR(dev, "bogus number of ctrl queue testcases!\n"); + err ("bogus number of ctrl queue testcases!"); context.status = -EINVAL; goto cleanup; } @@ -993,7 +1003,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) for (i = 0; i < param->sglen; i++) { context.status = usb_submit_urb (urb [i], GFP_ATOMIC); if (context.status != 0) { - ERROR(dev, "can't submit urb[%d], status %d\n", + dbg ("can't submit urb[%d], status %d", i, context.status); context.count = context.pending; break; @@ -1060,7 +1070,7 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async) * due to errors, or is just NAKing requests. */ if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0) { - dev_err(&dev->intf->dev, "submit fail %d\n", retval); + dev_dbg (&dev->intf->dev, "submit fail %d\n", retval); return retval; } @@ -1077,13 +1087,13 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async) * "normal" drivers would prevent resubmission, but * since we're testing unlink paths, we can't. */ - ERROR(dev, "unlink retry\n"); + dev_dbg (&dev->intf->dev, "unlink retry\n"); goto retry; } } else usb_kill_urb (urb); if (!(retval == 0 || retval == -EINPROGRESS)) { - dev_err(&dev->intf->dev, "unlink fail %d\n", retval); + dev_dbg (&dev->intf->dev, "unlink fail %d\n", retval); return retval; } @@ -1111,7 +1121,7 @@ static int unlink_simple (struct usbtest_dev *dev, int pipe, int len) /*-------------------------------------------------------------------------*/ -static int verify_not_halted(struct usbtest_dev *tdev, int ep, struct urb *urb) +static int verify_not_halted (int ep, struct urb *urb) { int retval; u16 status; @@ -1119,21 +1129,20 @@ static int verify_not_halted(struct usbtest_dev *tdev, int ep, struct urb *urb) /* shouldn't look or act halted */ retval = usb_get_status (urb->dev, USB_RECIP_ENDPOINT, ep, &status); if (retval < 0) { - ERROR(tdev, "ep %02x couldn't get no-halt status, %d\n", - ep, retval); + dbg ("ep %02x couldn't get no-halt status, %d", ep, retval); return retval; } if (status != 0) { - ERROR(tdev, "ep %02x bogus status: %04x != 0\n", ep, status); + dbg ("ep %02x bogus status: %04x != 0", ep, status); return -EINVAL; } - retval = simple_io(tdev, urb, 1, 0, 0, __func__); + retval = simple_io (urb, 1, 0, 0, __func__); if (retval != 0) return -EINVAL; return 0; } -static int verify_halted(struct usbtest_dev *tdev, int ep, struct urb *urb) +static int verify_halted (int ep, struct urb *urb) { int retval; u16 status; @@ -1141,30 +1150,29 @@ static int verify_halted(struct usbtest_dev *tdev, int ep, struct urb *urb) /* should look and act halted */ retval = usb_get_status (urb->dev, USB_RECIP_ENDPOINT, ep, &status); if (retval < 0) { - ERROR(tdev, "ep %02x couldn't get halt status, %d\n", - ep, retval); + dbg ("ep %02x couldn't get halt status, %d", ep, retval); return retval; } le16_to_cpus(&status); if (status != 1) { - ERROR(tdev, "ep %02x bogus status: %04x != 1\n", ep, status); + dbg ("ep %02x bogus status: %04x != 1", ep, status); return -EINVAL; } - retval = simple_io(tdev, urb, 1, 0, -EPIPE, __func__); + retval = simple_io (urb, 1, 0, -EPIPE, __func__); if (retval != -EPIPE) return -EINVAL; - retval = simple_io(tdev, urb, 1, 0, -EPIPE, "verify_still_halted"); + retval = simple_io (urb, 1, 0, -EPIPE, "verify_still_halted"); if (retval != -EPIPE) return -EINVAL; return 0; } -static int test_halt(struct usbtest_dev *tdev, int ep, struct urb *urb) +static int test_halt (int ep, struct urb *urb) { int retval; /* shouldn't look or act halted now */ - retval = verify_not_halted(tdev, ep, urb); + retval = verify_not_halted (ep, urb); if (retval < 0) return retval; @@ -1174,20 +1182,20 @@ static int test_halt(struct usbtest_dev *tdev, int ep, struct urb *urb) USB_ENDPOINT_HALT, ep, NULL, 0, USB_CTRL_SET_TIMEOUT); if (retval < 0) { - ERROR(tdev, "ep %02x couldn't set halt, %d\n", ep, retval); + dbg ("ep %02x couldn't set halt, %d", ep, retval); return retval; } - retval = verify_halted(tdev, ep, urb); + retval = verify_halted (ep, urb); if (retval < 0) return retval; /* clear halt (tests API + protocol), verify it worked */ retval = usb_clear_halt (urb->dev, urb->pipe); if (retval < 0) { - ERROR(tdev, "ep %02x couldn't clear halt, %d\n", ep, retval); + dbg ("ep %02x couldn't clear halt, %d", ep, retval); return retval; } - retval = verify_not_halted(tdev, ep, urb); + retval = verify_not_halted (ep, urb); if (retval < 0) return retval; @@ -1209,7 +1217,7 @@ static int halt_simple (struct usbtest_dev *dev) if (dev->in_pipe) { ep = usb_pipeendpoint (dev->in_pipe) | USB_DIR_IN; urb->pipe = dev->in_pipe; - retval = test_halt(dev, ep, urb); + retval = test_halt (ep, urb); if (retval < 0) goto done; } @@ -1217,7 +1225,7 @@ static int halt_simple (struct usbtest_dev *dev) if (dev->out_pipe) { ep = usb_pipeendpoint (dev->out_pipe); urb->pipe = dev->out_pipe; - retval = test_halt(dev, ep, urb); + retval = test_halt (ep, urb); } done: simple_free_urb (urb); @@ -1267,7 +1275,7 @@ static int ctrl_out (struct usbtest_dev *dev, if (retval != len) { what = "write"; if (retval >= 0) { - ERROR(dev, "ctrl_out, wlen %d (expected %d)\n", + INFO(dev, "ctrl_out, wlen %d (expected %d)\n", retval, len); retval = -EBADMSG; } @@ -1281,7 +1289,7 @@ static int ctrl_out (struct usbtest_dev *dev, if (retval != len) { what = "read"; if (retval >= 0) { - ERROR(dev, "ctrl_out, rlen %d (expected %d)\n", + INFO(dev, "ctrl_out, rlen %d (expected %d)\n", retval, len); retval = -EBADMSG; } @@ -1291,7 +1299,7 @@ static int ctrl_out (struct usbtest_dev *dev, /* fail if we can't verify */ for (j = 0; j < len; j++) { if (buf [j] != (u8) (i + j)) { - ERROR(dev, "ctrl_out, byte %d is %d not %d\n", + INFO (dev, "ctrl_out, byte %d is %d not %d\n", j, buf [j], (u8) i + j); retval = -EBADMSG; break; @@ -1313,7 +1321,7 @@ static int ctrl_out (struct usbtest_dev *dev, } if (retval < 0) - ERROR (dev, "ctrl_out %s failed, code %d, count %d\n", + INFO (dev, "ctrl_out %s failed, code %d, count %d\n", what, retval, i); kfree (buf); @@ -1358,7 +1366,7 @@ static void iso_callback (struct urb *urb) case 0: goto done; default: - dev_err(&ctx->dev->intf->dev, + dev_dbg (&ctx->dev->intf->dev, "iso resubmit err %d\n", status); /* FALLTHROUGH */ @@ -1373,7 +1381,7 @@ static void iso_callback (struct urb *urb) ctx->pending--; if (ctx->pending == 0) { if (ctx->errors) - dev_err(&ctx->dev->intf->dev, + dev_dbg (&ctx->dev->intf->dev, "iso test, %lu errors out of %lu\n", ctx->errors, ctx->packet_count); complete (&ctx->done); @@ -1450,7 +1458,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, memset (urbs, 0, sizeof urbs); udev = testdev_to_usbdev (dev); - dev_info(&dev->intf->dev, + dev_dbg (&dev->intf->dev, "... iso period %d %sframes, wMaxPacket %04x\n", 1 << (desc->bInterval - 1), (udev->speed == USB_SPEED_HIGH) ? "micro" : "", @@ -1467,7 +1475,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, urbs [i]->context = &context; } packets *= param->iterations; - dev_info(&dev->intf->dev, + dev_dbg (&dev->intf->dev, "... total %lu msec (%lu packets)\n", (packets * (1 << (desc->bInterval - 1))) / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), @@ -1529,13 +1537,6 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, * except indirectly by consuming USB bandwidth and CPU resources for test * threads and request completion. But the only way to know that for sure * is to test when HC queues are in use by many devices. - * - * WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(), - * it locks out usbcore in certain code paths. Notably, if you disconnect - * the device-under-test, khubd will wait block forever waiting for the - * ioctl to complete ... so that usb_disconnect() can abort the pending - * urbs and then call usbtest_disconnect(). To abort a test, you're best - * off just killing the userspace task and waiting for it to exit. */ static int @@ -1574,7 +1575,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) * altsettings; force a default so most tests don't need to check. */ if (dev->info->alt >= 0) { - int res; + int res; if (intf->altsetting->desc.bInterfaceNumber) { mutex_unlock(&dev->lock); @@ -1603,7 +1604,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) switch (param->test_num) { case 0: - dev_info(&intf->dev, "TEST 0: NOP\n"); + dev_dbg (&intf->dev, "TEST 0: NOP\n"); retval = 0; break; @@ -1611,7 +1612,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) case 1: if (dev->out_pipe == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 1: write %d bytes %u times\n", param->length, param->iterations); urb = simple_alloc_urb (udev, dev->out_pipe, param->length); @@ -1620,13 +1621,13 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk sink (maybe accepts short writes) - retval = simple_io(dev, urb, param->iterations, 0, 0, "test1"); + retval = simple_io (urb, param->iterations, 0, 0, "test1"); simple_free_urb (urb); break; case 2: if (dev->in_pipe == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 2: read %d bytes %u times\n", param->length, param->iterations); urb = simple_alloc_urb (udev, dev->in_pipe, param->length); @@ -1635,13 +1636,13 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk source (maybe generates short writes) - retval = simple_io(dev, urb, param->iterations, 0, 0, "test2"); + retval = simple_io (urb, param->iterations, 0, 0, "test2"); simple_free_urb (urb); break; case 3: if (dev->out_pipe == 0 || param->vary == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 3: write/%d 0..%d bytes %u times\n", param->vary, param->length, param->iterations); urb = simple_alloc_urb (udev, dev->out_pipe, param->length); @@ -1650,14 +1651,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk sink (maybe accepts short writes) - retval = simple_io(dev, urb, param->iterations, param->vary, + retval = simple_io (urb, param->iterations, param->vary, 0, "test3"); simple_free_urb (urb); break; case 4: if (dev->in_pipe == 0 || param->vary == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 4: read/%d 0..%d bytes %u times\n", param->vary, param->length, param->iterations); urb = simple_alloc_urb (udev, dev->in_pipe, param->length); @@ -1666,7 +1667,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk source (maybe generates short writes) - retval = simple_io(dev, urb, param->iterations, param->vary, + retval = simple_io (urb, param->iterations, param->vary, 0, "test4"); simple_free_urb (urb); break; @@ -1675,7 +1676,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) case 5: if (dev->out_pipe == 0 || param->sglen == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 5: write %d sglists %d entries of %d bytes\n", param->iterations, param->sglen, param->length); @@ -1685,7 +1686,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk sink (maybe accepts short writes) - retval = perform_sglist(dev, param->iterations, dev->out_pipe, + retval = perform_sglist (udev, param->iterations, dev->out_pipe, &req, sg, param->sglen); free_sglist (sg, param->sglen); break; @@ -1693,7 +1694,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) case 6: if (dev->in_pipe == 0 || param->sglen == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 6: read %d sglists %d entries of %d bytes\n", param->iterations, param->sglen, param->length); @@ -1703,14 +1704,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk source (maybe generates short writes) - retval = perform_sglist(dev, param->iterations, dev->in_pipe, + retval = perform_sglist (udev, param->iterations, dev->in_pipe, &req, sg, param->sglen); free_sglist (sg, param->sglen); break; case 7: if (dev->out_pipe == 0 || param->sglen == 0 || param->vary == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 7: write/%d %d sglists %d entries 0..%d bytes\n", param->vary, param->iterations, param->sglen, param->length); @@ -1720,14 +1721,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk sink (maybe accepts short writes) - retval = perform_sglist(dev, param->iterations, dev->out_pipe, + retval = perform_sglist (udev, param->iterations, dev->out_pipe, &req, sg, param->sglen); free_sglist (sg, param->sglen); break; case 8: if (dev->in_pipe == 0 || param->sglen == 0 || param->vary == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 8: read/%d %d sglists %d entries 0..%d bytes\n", param->vary, param->iterations, param->sglen, param->length); @@ -1737,7 +1738,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk source (maybe generates short writes) - retval = perform_sglist(dev, param->iterations, dev->in_pipe, + retval = perform_sglist (udev, param->iterations, dev->in_pipe, &req, sg, param->sglen); free_sglist (sg, param->sglen); break; @@ -1745,14 +1746,13 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) /* non-queued sanity tests for control (chapter 9 subset) */ case 9: retval = 0; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 9: ch9 (subset) control tests, %d times\n", param->iterations); for (i = param->iterations; retval == 0 && i--; /* NOP */) retval = ch9_postconfig (dev); if (retval) - dev_err(&intf->dev, "ch9 subset failed, " - "iterations left %d\n", i); + dbg ("ch9 subset failed, iterations left %d", i); break; /* queued control messaging */ @@ -1760,7 +1760,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) if (param->sglen == 0) break; retval = 0; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 10: queue %d control calls, %d times\n", param->sglen, param->iterations); @@ -1772,26 +1772,26 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) if (dev->in_pipe == 0 || !param->length) break; retval = 0; - dev_info(&intf->dev, "TEST 11: unlink %d reads of %d\n", + dev_dbg (&intf->dev, "TEST 11: unlink %d reads of %d\n", param->iterations, param->length); for (i = param->iterations; retval == 0 && i--; /* NOP */) retval = unlink_simple (dev, dev->in_pipe, param->length); if (retval) - dev_err(&intf->dev, "unlink reads failed %d, " + dev_dbg (&intf->dev, "unlink reads failed %d, " "iterations left %d\n", retval, i); break; case 12: if (dev->out_pipe == 0 || !param->length) break; retval = 0; - dev_info(&intf->dev, "TEST 12: unlink %d writes of %d\n", + dev_dbg (&intf->dev, "TEST 12: unlink %d writes of %d\n", param->iterations, param->length); for (i = param->iterations; retval == 0 && i--; /* NOP */) retval = unlink_simple (dev, dev->out_pipe, param->length); if (retval) - dev_err(&intf->dev, "unlink writes failed %d, " + dev_dbg (&intf->dev, "unlink writes failed %d, " "iterations left %d\n", retval, i); break; @@ -1800,24 +1800,24 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) if (dev->out_pipe == 0 && dev->in_pipe == 0) break; retval = 0; - dev_info(&intf->dev, "TEST 13: set/clear %d halts\n", + dev_dbg (&intf->dev, "TEST 13: set/clear %d halts\n", param->iterations); for (i = param->iterations; retval == 0 && i--; /* NOP */) retval = halt_simple (dev); - + if (retval) - ERROR(dev, "halts failed, iterations left %d\n", i); + DBG (dev, "halts failed, iterations left %d\n", i); break; /* control write tests */ case 14: if (!dev->info->ctrl_out) break; - dev_info(&intf->dev, "TEST 14: %d ep0out, %d..%d vary %d\n", + dev_dbg (&intf->dev, "TEST 14: %d ep0out, %d..%d vary %d\n", param->iterations, realworld ? 1 : 0, param->length, param->vary); - retval = ctrl_out(dev, param->iterations, + retval = ctrl_out (dev, param->iterations, param->length, param->vary); break; @@ -1825,7 +1825,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) case 15: if (dev->out_iso_pipe == 0 || param->sglen == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 15: write %d iso, %d entries of %d bytes\n", param->iterations, param->sglen, param->length); @@ -1838,7 +1838,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) case 16: if (dev->in_iso_pipe == 0 || param->sglen == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 16: read %d iso, %d entries of %d bytes\n", param->iterations, param->sglen, param->length); @@ -1898,8 +1898,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) return -ENODEV; if (product && le16_to_cpu(udev->descriptor.idProduct) != (u16)product) return -ENODEV; - dev_info(&intf->dev, "matched module params, " - "vend=0x%04x prod=0x%04x\n", + dbg ("matched module params, vend=0x%04x prod=0x%04x", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct)); } @@ -1941,8 +1940,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) status = get_endpoints (dev, intf); if (status < 0) { - WARN(dev, "couldn't get endpoints, %d\n", - status); + dbg ("couldn't get endpoints, %d\n", status); return status; } /* may find bulk or ISO pipes */ @@ -2084,9 +2082,21 @@ static struct usbtest_info generic_info = { }; #endif +// FIXME remove this +static struct usbtest_info hact_info = { + .name = "FX2/hact", + //.ep_in = 6, + .ep_out = 2, + .alt = -1, +}; + static struct usb_device_id id_table [] = { + { USB_DEVICE (0x0547, 0x1002), + .driver_info = (unsigned long) &hact_info, + }, + /*-------------------------------------------------------------*/ /* EZ-USB devices which download firmware to replace (or in our @@ -2175,7 +2185,7 @@ static int __init usbtest_init (void) { #ifdef GENERIC if (vendor) - pr_debug("params: vend=0x%04x prod=0x%04x\n", vendor, product); + dbg ("params: vend=0x%04x prod=0x%04x", vendor, product); #endif return usb_register (&usbtest_driver); } diff --git a/trunk/drivers/usb/serial/aircable.c b/trunk/drivers/usb/serial/aircable.c index db6f97a93c02..9b1bb347dc2d 100644 --- a/trunk/drivers/usb/serial/aircable.c +++ b/trunk/drivers/usb/serial/aircable.c @@ -147,7 +147,7 @@ static void serial_buf_free(struct circ_buf *cb) */ static int serial_buf_data_avail(struct circ_buf *cb) { - return CIRC_CNT(cb->head, cb->tail, AIRCABLE_BUF_SIZE); + return CIRC_CNT(cb->head,cb->tail,AIRCABLE_BUF_SIZE); } /* @@ -171,7 +171,7 @@ static int serial_buf_put(struct circ_buf *cb, const char *buf, int count) cb->head = (cb->head + c) & (AIRCABLE_BUF_SIZE-1); buf += c; count -= c; - ret = c; + ret= c; } return ret; } @@ -197,7 +197,7 @@ static int serial_buf_get(struct circ_buf *cb, char *buf, int count) cb->tail = (cb->tail + c) & (AIRCABLE_BUF_SIZE-1); buf += c; count -= c; - ret = c; + ret= c; } return ret; } @@ -208,7 +208,7 @@ static void aircable_send(struct usb_serial_port *port) { int count, result; struct aircable_private *priv = usb_get_serial_port_data(port); - unsigned char *buf; + unsigned char* buf; __le16 *dbuf; dbg("%s - port %d", __func__, port->number); if (port->write_urb_busy) @@ -229,8 +229,7 @@ static void aircable_send(struct usb_serial_port *port) buf[1] = TX_HEADER_1; dbuf = (__le16 *)&buf[2]; *dbuf = cpu_to_le16((u16)count); - serial_buf_get(priv->tx_buf, buf + HCI_HEADER_LENGTH, - MAX_HCI_FRAMESIZE); + serial_buf_get(priv->tx_buf,buf + HCI_HEADER_LENGTH, MAX_HCI_FRAMESIZE); memcpy(port->write_urb->transfer_buffer, buf, count + HCI_HEADER_LENGTH); @@ -262,7 +261,7 @@ static void aircable_read(struct work_struct *work) struct tty_struct *tty; unsigned char *data; int count; - if (priv->rx_flags & THROTTLED) { + if (priv->rx_flags & THROTTLED){ if (priv->rx_flags & ACTUALLY_THROTTLED) schedule_work(&priv->rx_work); return; @@ -283,10 +282,10 @@ static void aircable_read(struct work_struct *work) count = min(64, serial_buf_data_avail(priv->rx_buf)); if (count <= 0) - return; /* We have finished sending everything. */ + return; //We have finished sending everything. tty_prepare_flip_string(tty, &data, count); - if (!data) { + if (!data){ err("%s- kzalloc(%d) failed.", __func__, count); return; } @@ -305,10 +304,9 @@ static void aircable_read(struct work_struct *work) static int aircable_probe(struct usb_serial *serial, const struct usb_device_id *id) { - struct usb_host_interface *iface_desc = serial->interface-> - cur_altsetting; + struct usb_host_interface *iface_desc = serial->interface->cur_altsetting; struct usb_endpoint_descriptor *endpoint; - int num_bulk_out = 0; + int num_bulk_out=0; int i; for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { @@ -327,13 +325,13 @@ static int aircable_probe(struct usb_serial *serial, return 0; } -static int aircable_attach(struct usb_serial *serial) +static int aircable_attach (struct usb_serial *serial) { struct usb_serial_port *port = serial->port[0]; struct aircable_private *priv; priv = kzalloc(sizeof(struct aircable_private), GFP_KERNEL); - if (!priv) { + if (!priv){ err("%s- kmalloc(%Zd) failed.", __func__, sizeof(struct aircable_private)); return -ENOMEM; @@ -394,7 +392,7 @@ static int aircable_write(struct usb_serial_port *port, usb_serial_debug_data(debug, &port->dev, __func__, count, source); - if (!count) { + if (!count){ dbg("%s - write request of 0 bytes", __func__); return count; } @@ -420,31 +418,31 @@ static void aircable_write_bulk_callback(struct urb *urb) /* This has been taken from cypress_m8.c cypress_write_int_callback */ switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - port->write_urb_busy = 0; - return; - default: - /* error in the urb, so we have to resubmit it */ - dbg("%s - Overflow in write", __func__); - dbg("%s - nonzero write bulk status received: %d", - __func__, status); - port->write_urb->transfer_buffer_length = 1; - port->write_urb->dev = port->serial->dev; - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, - "%s - failed resubmitting write urb, error %d\n", - __func__, result); - else + case 0: + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", + __func__, status); + port->write_urb_busy = 0; return; + default: + /* error in the urb, so we have to resubmit it */ + dbg("%s - Overflow in write", __func__); + dbg("%s - nonzero write bulk status received: %d", + __func__, status); + port->write_urb->transfer_buffer_length = 1; + port->write_urb->dev = port->serial->dev; + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); + if (result) + dev_err(&urb->dev->dev, + "%s - failed resubmitting write urb, error %d\n", + __func__, result); + else + return; } port->write_urb_busy = 0; @@ -474,11 +472,11 @@ static void aircable_read_bulk_callback(struct urb *urb) dbg("%s - caught -EPROTO, resubmitting the urb", __func__); usb_fill_bulk_urb(port->read_urb, port->serial->dev, - usb_rcvbulkpipe(port->serial->dev, - port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, - port->read_urb->transfer_buffer_length, - aircable_read_bulk_callback, port); + usb_rcvbulkpipe(port->serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + aircable_read_bulk_callback, port); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) @@ -492,7 +490,7 @@ static void aircable_read_bulk_callback(struct urb *urb) } usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, urb->transfer_buffer); + urb->actual_length,urb->transfer_buffer); tty = port->tty; if (tty && urb->actual_length) { @@ -509,9 +507,9 @@ static void aircable_read_bulk_callback(struct urb *urb) no_packages = urb->actual_length / (HCI_COMPLETE_FRAME); if (urb->actual_length % HCI_COMPLETE_FRAME != 0) - no_packages++; + no_packages+=1; - for (i = 0; i < no_packages; i++) { + for (i = 0; i < no_packages ;i++) { if (remaining > (HCI_COMPLETE_FRAME)) package_length = HCI_COMPLETE_FRAME; else @@ -531,7 +529,7 @@ static void aircable_read_bulk_callback(struct urb *urb) if (port->open_count) { usb_fill_bulk_urb(port->read_urb, port->serial->dev, usb_rcvbulkpipe(port->serial->dev, - port->bulk_in_endpointAddress), + port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, aircable_read_bulk_callback, port); @@ -604,7 +602,7 @@ static struct usb_serial_driver aircable_device = { .unthrottle = aircable_unthrottle, }; -static int __init aircable_init(void) +static int __init aircable_init (void) { int retval; retval = usb_serial_register(&aircable_device); @@ -621,7 +619,7 @@ static int __init aircable_init(void) return retval; } -static void __exit aircable_exit(void) +static void __exit aircable_exit (void) { usb_deregister(&aircable_driver); usb_serial_deregister(&aircable_device); diff --git a/trunk/drivers/usb/serial/airprime.c b/trunk/drivers/usb/serial/airprime.c index 0798c14ce787..725b6b94c274 100644 --- a/trunk/drivers/usb/serial/airprime.c +++ b/trunk/drivers/usb/serial/airprime.c @@ -68,9 +68,8 @@ static int airprime_send_setup(struct usb_serial_port *port) val |= 0x02; return usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - 0x22, 0x21, val, 0, NULL, 0, - USB_CTRL_SET_TIMEOUT); + usb_rcvctrlpipe(serial->dev, 0), + 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); } return 0; @@ -91,19 +90,17 @@ static void airprime_read_bulk_callback(struct urb *urb) __func__, status); return; } - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); tty = port->tty; if (tty && urb->actual_length) { - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); + tty_insert_flip_string (tty, data, urb->actual_length); + tty_flip_buffer_push (tty); } - result = usb_submit_urb(urb, GFP_ATOMIC); + result = usb_submit_urb (urb, GFP_ATOMIC); if (result) - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", + dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); return; } @@ -118,7 +115,7 @@ static void airprime_write_bulk_callback(struct urb *urb) dbg("%s - port %d", __func__, port->number); /* free up the transfer buffer, as usb_free_urb() does not do this */ - kfree(urb->transfer_buffer); + kfree (urb->transfer_buffer); if (status) dbg("%s - nonzero write bulk status received: %d", @@ -174,7 +171,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) } usb_fill_bulk_urb(urb, serial->dev, usb_rcvbulkpipe(serial->dev, - port->bulk_out_endpointAddress), + port->bulk_out_endpointAddress), buffer, buffer_size, airprime_read_bulk_callback, port); result = usb_submit_urb(urb, GFP_KERNEL); @@ -186,8 +183,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) __func__, i, port->number, result); goto errout; } - /* remember this urb so we can kill it when the - port is closed */ + /* remember this urb so we can kill it when the port is closed */ priv->read_urbp[i] = urb; } @@ -196,22 +192,22 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) goto out; errout: - /* some error happened, cancel any submitted urbs and clean up - anything that got allocated successfully */ + /* some error happened, cancel any submitted urbs and clean up anything that + got allocated successfully */ while (i-- != 0) { urb = priv->read_urbp[i]; buffer = urb->transfer_buffer; - usb_kill_urb(urb); - usb_free_urb(urb); - kfree(buffer); + usb_kill_urb (urb); + usb_free_urb (urb); + kfree (buffer); } out: return result; } -static void airprime_close(struct usb_serial_port *port, struct file *filp) +static void airprime_close(struct usb_serial_port *port, struct file * filp) { struct airprime_private *priv = usb_get_serial_port_data(port); int i; @@ -224,16 +220,16 @@ static void airprime_close(struct usb_serial_port *port, struct file *filp) mutex_lock(&port->serial->disc_mutex); if (!port->serial->disconnected) airprime_send_setup(port); - mutex_unlock(&port->serial->disc_mutex); + mutex_lock(&port->serial->disc_mutex); for (i = 0; i < NUM_READ_URBS; ++i) { - usb_kill_urb(priv->read_urbp[i]); - kfree(priv->read_urbp[i]->transfer_buffer); - usb_free_urb(priv->read_urbp[i]); + usb_kill_urb (priv->read_urbp[i]); + kfree (priv->read_urbp[i]->transfer_buffer); + usb_free_urb (priv->read_urbp[i]); } /* free up private structure */ - kfree(priv); + kfree (priv); usb_set_serial_port_data(port, NULL); } @@ -263,10 +259,10 @@ static int airprime_write(struct usb_serial_port *port, urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { dev_err(&port->dev, "no more free urbs\n"); - kfree(buffer); + kfree (buffer); return -ENOMEM; } - memcpy(buffer, buf, count); + memcpy (buffer, buf, count); usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); @@ -283,7 +279,7 @@ static int airprime_write(struct usb_serial_port *port, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __func__, status); count = status; - kfree(buffer); + kfree (buffer); } else { spin_lock_irqsave(&priv->lock, flags); ++priv->outstanding_urbs; @@ -291,7 +287,7 @@ static int airprime_write(struct usb_serial_port *port, } /* we are done with this urb, so let the host driver * really free it when it is finished with it */ - usb_free_urb(urb); + usb_free_urb (urb); return count; } @@ -319,10 +315,8 @@ static int __init airprime_init(void) { int retval; - airprime_device.num_ports = endpoints; - if (endpoints < 0 || endpoints >= MAX_BULK_EPS) - airprime_device.num_ports = NUM_BULK_EPS; - + airprime_device.num_ports = + (endpoints > 0 && endpoints <= MAX_BULK_EPS) ? endpoints : NUM_BULK_EPS; retval = usb_serial_register(&airprime_device); if (retval) return retval; @@ -347,7 +341,6 @@ MODULE_LICENSE("GPL"); module_param(debug, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug enabled"); module_param(buffer_size, int, 0); -MODULE_PARM_DESC(buffer_size, - "Size of the transfer buffers in bytes (default 4096)"); +MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers in bytes (default 4096)"); module_param(endpoints, int, 0); MODULE_PARM_DESC(endpoints, "Number of bulk EPs to configure (default 3)"); diff --git a/trunk/drivers/usb/serial/ark3116.c b/trunk/drivers/usb/serial/ark3116.c index 77895c8f8f31..599ab2e548a7 100644 --- a/trunk/drivers/usb/serial/ark3116.c +++ b/trunk/drivers/usb/serial/ark3116.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include static int debug; @@ -246,29 +246,29 @@ static void ark3116_set_termios(struct usb_serial_port *port, baud = tty_get_baud_rate(port->tty); switch (baud) { - case 75: - case 150: - case 300: - case 600: - case 1200: - case 1800: - case 2400: - case 4800: - case 9600: - case 19200: - case 38400: - case 57600: - case 115200: - case 230400: - case 460800: - /* Report the resulting rate back to the caller */ - tty_encode_baud_rate(port->tty, baud, baud); - break; - /* set 9600 as default (if given baudrate is invalid for example) */ - default: - tty_encode_baud_rate(port->tty, 9600, 9600); - case 0: - baud = 9600; + case 75: + case 150: + case 300: + case 600: + case 1200: + case 1800: + case 2400: + case 4800: + case 9600: + case 19200: + case 38400: + case 57600: + case 115200: + case 230400: + case 460800: + /* Report the resulting rate back to the caller */ + tty_encode_baud_rate(port->tty, baud, baud); + break; + /* set 9600 as default (if given baudrate is invalid for example) */ + default: + tty_encode_baud_rate(port->tty, 9600, 9600); + case 0: + baud = 9600; } /* @@ -380,19 +380,19 @@ static int ark3116_ioctl(struct usb_serial_port *port, struct file *file, switch (cmd) { case TIOCGSERIAL: /* XXX: Some of these values are probably wrong. */ - memset(&serstruct, 0, sizeof(serstruct)); + memset(&serstruct, 0, sizeof (serstruct)); serstruct.type = PORT_16654; serstruct.line = port->serial->minor; serstruct.port = port->number; serstruct.custom_divisor = 0; serstruct.baud_base = 460800; - if (copy_to_user(user_arg, &serstruct, sizeof(serstruct))) + if (copy_to_user(user_arg, &serstruct, sizeof (serstruct))) return -EFAULT; return 0; case TIOCSSERIAL: - if (copy_from_user(&serstruct, user_arg, sizeof(serstruct))) + if (copy_from_user(&serstruct, user_arg, sizeof (serstruct))) return -EFAULT; return 0; default: diff --git a/trunk/drivers/usb/serial/ch341.c b/trunk/drivers/usb/serial/ch341.c index ba28fdc9ccd2..d947d955bceb 100644 --- a/trunk/drivers/usb/serial/ch341.c +++ b/trunk/drivers/usb/serial/ch341.c @@ -130,7 +130,7 @@ static int ch341_get_status(struct usb_device *dev) return -ENOMEM; r = ch341_control_in(dev, 0x95, 0x0706, 0, buffer, size); - if (r < 0) + if ( r < 0) goto out; /* Not having the datasheet for the CH341, we ignore the bytes returned diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 5b349ece7247..c7329f43d9c9 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -133,14 +133,6 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_3_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_4_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_5_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_6_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_7_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, diff --git a/trunk/drivers/usb/serial/ftdi_sio.h b/trunk/drivers/usb/serial/ftdi_sio.h index 504edf8c3a3f..6da539ede0ee 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.h +++ b/trunk/drivers/usb/serial/ftdi_sio.h @@ -40,17 +40,6 @@ /* AlphaMicro Components AMC-232USB01 device */ #define FTDI_AMC232_PID 0xFF00 /* Product Id */ -/* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ -/* the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ -#define FTDI_SCS_DEVICE_1_PID 0xD011 /* SCS Tracker / DSP TNC */ -#define FTDI_SCS_DEVICE_2_PID 0xD012 -#define FTDI_SCS_DEVICE_3_PID 0xD013 -#define FTDI_SCS_DEVICE_4_PID 0xD014 -#define FTDI_SCS_DEVICE_5_PID 0xD015 -#define FTDI_SCS_DEVICE_6_PID 0xD016 -#define FTDI_SCS_DEVICE_7_PID 0xD017 - /* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ #define FTDI_ACTZWAVE_PID 0xF2D0 diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index 78f2f6db494d..6bcb82d3911a 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -1713,7 +1713,7 @@ static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file, { struct moschip_port *mos7840_port; unsigned int mcr; - int status; + unsigned int status; dbg("%s - port %d", __func__, port->number); @@ -1740,10 +1740,11 @@ static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file, mos7840_port->shadowMCR = mcr; + status = 0; status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr); if (status < 0) { dbg("setting MODEM_CONTROL_REGISTER Failed\n"); - return status; + return -1; } return 0; diff --git a/trunk/drivers/usb/storage/Kconfig b/trunk/drivers/usb/storage/Kconfig index 3d9249632ae1..0f6d234d699b 100644 --- a/trunk/drivers/usb/storage/Kconfig +++ b/trunk/drivers/usb/storage/Kconfig @@ -123,8 +123,7 @@ config USB_STORAGE_ALAUDA config USB_STORAGE_ONETOUCH bool "Support OneTouch Button on Maxtor Hard Drives" - depends on USB_STORAGE - depends on INPUT=y || INPUT=USB_STORAGE + depends on USB_STORAGE && INPUT_EVDEV help Say Y here to include additional code to support the Maxtor OneTouch USB hard drive's onetouch button. diff --git a/trunk/drivers/usb/storage/cypress_atacb.c b/trunk/drivers/usb/storage/cypress_atacb.c index 898e67d30e56..d88824b3511c 100644 --- a/trunk/drivers/usb/storage/cypress_atacb.c +++ b/trunk/drivers/usb/storage/cypress_atacb.c @@ -46,7 +46,7 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) } memcpy(save_cmnd, srb->cmnd, sizeof(save_cmnd)); - memset(srb->cmnd, 0, MAX_COMMAND_SIZE); + memset(srb->cmnd, 0, sizeof(srb->cmnd)); /* check if we support the command */ if (save_cmnd[1] >> 5) /* MULTIPLE_COUNT */ diff --git a/trunk/drivers/usb/storage/isd200.c b/trunk/drivers/usb/storage/isd200.c index 3addcd8f827b..971d13dd5e65 100644 --- a/trunk/drivers/usb/storage/isd200.c +++ b/trunk/drivers/usb/storage/isd200.c @@ -292,7 +292,6 @@ struct isd200_info { /* maximum number of LUNs supported */ unsigned char MaxLUNs; - unsigned char cmnd[BLK_MAX_CDB]; struct scsi_cmnd srb; struct scatterlist sg; }; @@ -451,7 +450,6 @@ static int isd200_action( struct us_data *us, int action, memset(&ata, 0, sizeof(ata)); memset(&srb_dev, 0, sizeof(srb_dev)); - srb->cmnd = info->cmnd; srb->device = &srb_dev; ++srb->serial_number; diff --git a/trunk/drivers/usb/storage/libusual.c b/trunk/drivers/usb/storage/libusual.c index d617e8ae6b00..a28d49122e7a 100644 --- a/trunk/drivers/usb/storage/libusual.c +++ b/trunk/drivers/usb/storage/libusual.c @@ -135,7 +135,7 @@ static int usu_probe(struct usb_interface *intf, stat[type].fls |= USU_MOD_FL_THREAD; spin_unlock_irqrestore(&usu_lock, flags); - task = kthread_run(usu_probe_thread, (void*)type, "libusual_%ld", type); + task = kthread_run(usu_probe_thread, (void*)type, "libusual_%d", type); if (IS_ERR(task)) { rc = PTR_ERR(task); printk(KERN_WARNING "libusual: " diff --git a/trunk/drivers/usb/storage/onetouch.c b/trunk/drivers/usb/storage/onetouch.c index 98b89ea9e312..dfd42fe9e5f0 100644 --- a/trunk/drivers/usb/storage/onetouch.c +++ b/trunk/drivers/usb/storage/onetouch.c @@ -38,7 +38,7 @@ #include "onetouch.h" #include "debug.h" -static void onetouch_release_input(void *onetouch_); +void onetouch_release_input(void *onetouch_); struct usb_onetouch { char name[128]; @@ -223,7 +223,7 @@ int onetouch_connect_input(struct us_data *ss) return error; } -static void onetouch_release_input(void *onetouch_) +void onetouch_release_input(void *onetouch_) { struct usb_onetouch *onetouch = (struct usb_onetouch *) onetouch_; diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index a0ed889230aa..732bf52a775e 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -44,8 +44,7 @@ * running with this patch. * Send your submission to either Phil Dibowitz or * Alan Stern , and don't forget to CC: the - * USB development list and the USB storage list - * + * USB development list . */ /* patch submitted by Vivian Bregier @@ -558,13 +557,6 @@ UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, US_FL_SINGLE_LUN), #endif -/* Reported by Dmitry Khlystov */ -UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, - "Samsung", - "YP-U3", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_MAX_SECTORS_64), - /* Reported by Bob Sass -- only rev 1.33 tested */ UNUSUAL_DEV( 0x050d, 0x0115, 0x0133, 0x0133, "Belkin", @@ -1208,17 +1200,6 @@ UNUSUAL_DEV( 0x084d, 0x0011, 0x0110, 0x0110, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_BULK32), -/* Andrew Lunn - * PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL - * on LUN 4. - * Note: Vend:Prod clash with "Ltd Maxell WS30 Slim Digital Camera" -*/ -UNUSUAL_DEV( 0x0851, 0x1543, 0x0200, 0x0200, - "PanDigital", - "Photo Frame", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_NOT_LOCKABLE), - /* Submitted by Jan De Luyck */ UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000, "CITIZEN", @@ -1361,13 +1342,6 @@ UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), -/* Reported by Rohan Hart */ -UNUSUAL_DEV( 0x2770, 0x915d, 0x0010, 0x0010, - "INTOVA", - "Pixtreme", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - /* * Entry for Jenoptik JD 5200z3 * diff --git a/trunk/drivers/usb/storage/usb.c b/trunk/drivers/usb/storage/usb.c index e268aacb773a..a856effad3bd 100644 --- a/trunk/drivers/usb/storage/usb.c +++ b/trunk/drivers/usb/storage/usb.c @@ -539,8 +539,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) " has %s in unusual_devs.h (kernel" " %s)\n" " Please send a copy of this message to " - " and " - "\n", + "\n", le16_to_cpu(ddesc->idVendor), le16_to_cpu(ddesc->idProduct), le16_to_cpu(ddesc->bcdDevice), diff --git a/trunk/drivers/virtio/virtio.c b/trunk/drivers/virtio/virtio.c index 13866789b356..b535483bc556 100644 --- a/trunk/drivers/virtio/virtio.c +++ b/trunk/drivers/virtio/virtio.c @@ -80,51 +80,19 @@ static void add_status(struct virtio_device *dev, unsigned status) dev->config->set_status(dev, dev->config->get_status(dev) | status); } -void virtio_check_driver_offered_feature(const struct virtio_device *vdev, - unsigned int fbit) -{ - unsigned int i; - struct virtio_driver *drv = container_of(vdev->dev.driver, - struct virtio_driver, driver); - - for (i = 0; i < drv->feature_table_size; i++) - if (drv->feature_table[i] == fbit) - return; - BUG(); -} -EXPORT_SYMBOL_GPL(virtio_check_driver_offered_feature); - static int virtio_dev_probe(struct device *_d) { - int err, i; + int err; struct virtio_device *dev = container_of(_d,struct virtio_device,dev); struct virtio_driver *drv = container_of(dev->dev.driver, struct virtio_driver, driver); - u32 device_features; - /* We have a driver! */ add_status(dev, VIRTIO_CONFIG_S_DRIVER); - - /* Figure out what features the device supports. */ - device_features = dev->config->get_features(dev); - - /* Features supported by both device and driver into dev->features. */ - memset(dev->features, 0, sizeof(dev->features)); - for (i = 0; i < drv->feature_table_size; i++) { - unsigned int f = drv->feature_table[i]; - BUG_ON(f >= 32); - if (device_features & (1 << f)) - set_bit(f, dev->features); - } - err = drv->probe(dev); if (err) add_status(dev, VIRTIO_CONFIG_S_FAILED); - else { + else add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); - /* They should never have set feature bits beyond 32 */ - dev->config->set_features(dev, dev->features[0]); - } return err; } @@ -146,8 +114,6 @@ static int virtio_dev_remove(struct device *_d) int register_virtio_driver(struct virtio_driver *driver) { - /* Catch this early. */ - BUG_ON(driver->feature_table_size && !driver->feature_table); driver->driver.bus = &virtio_bus; driver->driver.probe = virtio_dev_probe; driver->driver.remove = virtio_dev_remove; diff --git a/trunk/drivers/virtio/virtio_balloon.c b/trunk/drivers/virtio/virtio_balloon.c index bfef604160d1..0b3efc31ee6d 100644 --- a/trunk/drivers/virtio/virtio_balloon.c +++ b/trunk/drivers/virtio/virtio_balloon.c @@ -155,9 +155,9 @@ static void virtballoon_changed(struct virtio_device *vdev) static inline s64 towards_target(struct virtio_balloon *vb) { u32 v; - vb->vdev->config->get(vb->vdev, - offsetof(struct virtio_balloon_config, num_pages), - &v, sizeof(v)); + __virtio_config_val(vb->vdev, + offsetof(struct virtio_balloon_config, num_pages), + &v); return v - vb->num_pages; } @@ -227,7 +227,7 @@ static int virtballoon_probe(struct virtio_device *vdev) } vb->tell_host_first - = virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); + = vdev->config->feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); return 0; @@ -259,11 +259,7 @@ static void virtballoon_remove(struct virtio_device *vdev) kfree(vb); } -static unsigned int features[] = { VIRTIO_BALLOON_F_MUST_TELL_HOST }; - static struct virtio_driver virtio_balloon = { - .feature_table = features, - .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, .driver.owner = THIS_MODULE, .id_table = id_table, diff --git a/trunk/drivers/virtio/virtio_pci.c b/trunk/drivers/virtio/virtio_pci.c index 27e9fc9117cd..c0df924766a7 100644 --- a/trunk/drivers/virtio/virtio_pci.c +++ b/trunk/drivers/virtio/virtio_pci.c @@ -87,22 +87,23 @@ static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) return container_of(vdev, struct virtio_pci_device, vdev); } -/* virtio config->get_features() implementation */ -static u32 vp_get_features(struct virtio_device *vdev) -{ - struct virtio_pci_device *vp_dev = to_vp_device(vdev); - - /* When someone needs more than 32 feature bits, we'll need to - * steal a bit to indicate that the rest are somewhere else. */ - return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); -} - -/* virtio config->set_features() implementation */ -static void vp_set_features(struct virtio_device *vdev, u32 features) +/* virtio config->feature() implementation */ +static bool vp_feature(struct virtio_device *vdev, unsigned bit) { struct virtio_pci_device *vp_dev = to_vp_device(vdev); + u32 mask; + + /* Since this function is supposed to have the side effect of + * enabling a queried feature, we simulate that by doing a read + * from the host feature bitmask and then writing to the guest + * feature bitmask */ + mask = ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); + if (mask & (1 << bit)) { + mask |= (1 << bit); + iowrite32(mask, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); + } - iowrite32(features, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); + return !!(mask & (1 << bit)); } /* virtio config->get() implementation */ @@ -144,14 +145,14 @@ static void vp_set_status(struct virtio_device *vdev, u8 status) struct virtio_pci_device *vp_dev = to_vp_device(vdev); /* We should never be setting status to 0. */ BUG_ON(status == 0); - iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); + return iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); } static void vp_reset(struct virtio_device *vdev) { struct virtio_pci_device *vp_dev = to_vp_device(vdev); /* 0 status means a reset. */ - iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); + return iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); } /* the notify function used when creating a virt queue */ @@ -292,6 +293,7 @@ static void vp_del_vq(struct virtqueue *vq) } static struct virtio_config_ops virtio_pci_config_ops = { + .feature = vp_feature, .get = vp_get, .set = vp_set, .get_status = vp_get_status, @@ -299,8 +301,6 @@ static struct virtio_config_ops virtio_pci_config_ops = { .reset = vp_reset, .find_vq = vp_find_vq, .del_vq = vp_del_vq, - .get_features = vp_get_features, - .set_features = vp_set_features, }; /* the PCI probing function */ diff --git a/trunk/drivers/virtio/virtio_ring.c b/trunk/drivers/virtio/virtio_ring.c index 937a49d6772c..c2fa5c630813 100644 --- a/trunk/drivers/virtio/virtio_ring.c +++ b/trunk/drivers/virtio/virtio_ring.c @@ -184,11 +184,6 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len) START_USE(vq); - if (unlikely(vq->broken)) { - END_USE(vq); - return NULL; - } - if (!more_used(vq)) { pr_debug("No more buffers in queue\n"); END_USE(vq); diff --git a/trunk/fs/anon_inodes.c b/trunk/fs/anon_inodes.c index 977ef208c051..f42be069e085 100644 --- a/trunk/fs/anon_inodes.c +++ b/trunk/fs/anon_inodes.c @@ -57,6 +57,9 @@ static struct dentry_operations anon_inodefs_dentry_operations = { * anonymous inode, and a dentry that describe the "class" * of the file * + * @pfd: [out] pointer to the file descriptor + * @dpinode: [out] pointer to the inode + * @pfile: [out] pointer to the file struct * @name: [in] name of the "class" of the new file * @fops [in] file operations for the new file * @priv [in] private data for the new file (will be file's private_data) @@ -65,9 +68,10 @@ static struct dentry_operations anon_inodefs_dentry_operations = { * that do not need to have a full-fledged inode in order to operate correctly. * All the files created with anon_inode_getfd() will share a single inode, * hence saving memory and avoiding code duplication for the file/inode/dentry - * setup. Returns new descriptor or -error. + * setup. */ -int anon_inode_getfd(const char *name, const struct file_operations *fops, +int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, + const char *name, const struct file_operations *fops, void *priv) { struct qstr this; @@ -121,7 +125,10 @@ int anon_inode_getfd(const char *name, const struct file_operations *fops, fd_install(fd, file); - return fd; + *pfd = fd; + *pinode = anon_inode_inode; + *pfile = file; + return 0; err_dput: dput(dentry); diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index 332a869d2c53..139dc93c092d 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/dnotify.c b/trunk/fs/dnotify.c index 676073b8dda5..eaecc4cfe540 100644 --- a/trunk/fs/dnotify.c +++ b/trunk/fs/dnotify.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include int dir_notify_enable __read_mostly = 1; diff --git a/trunk/fs/eventfd.c b/trunk/fs/eventfd.c index 343942deeec1..a9f130cd50ac 100644 --- a/trunk/fs/eventfd.c +++ b/trunk/fs/eventfd.c @@ -200,8 +200,10 @@ struct file *eventfd_fget(int fd) asmlinkage long sys_eventfd(unsigned int count) { - int fd; + int error, fd; struct eventfd_ctx *ctx; + struct file *file; + struct inode *inode; ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -214,9 +216,12 @@ asmlinkage long sys_eventfd(unsigned int count) * When we call this, the initialization must be complete, since * anon_inode_getfd() will install the fd. */ - fd = anon_inode_getfd("[eventfd]", &eventfd_fops, ctx); - if (fd < 0) - kfree(ctx); - return fd; + error = anon_inode_getfd(&fd, &inode, &file, "[eventfd]", + &eventfd_fops, ctx); + if (!error) + return fd; + + kfree(ctx); + return error; } diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index 990c01d2d66b..221086fef174 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -1050,6 +1050,8 @@ asmlinkage long sys_epoll_create(int size) { int error, fd = -1; struct eventpoll *ep; + struct inode *inode; + struct file *file; DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n", current, size)); @@ -1059,24 +1061,29 @@ asmlinkage long sys_epoll_create(int size) * structure ( "struct eventpoll" ). */ error = -EINVAL; - if (size <= 0 || (error = ep_alloc(&ep)) < 0) { - fd = error; + if (size <= 0 || (error = ep_alloc(&ep)) != 0) goto error_return; - } /* * Creates all the items needed to setup an eventpoll file. That is, - * a file structure and a free file descriptor. + * a file structure, and inode and a free file descriptor. */ - fd = anon_inode_getfd("[eventpoll]", &eventpoll_fops, ep); - if (fd < 0) - ep_free(ep); + error = anon_inode_getfd(&fd, &inode, &file, "[eventpoll]", + &eventpoll_fops, ep); + if (error) + goto error_free; -error_return: DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", current, size, fd)); return fd; + +error_free: + ep_free(ep); +error_return: + DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", + current, size, error)); + return error; } /* diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index aeaa9791d8be..9f9f931ef949 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include diff --git a/trunk/fs/fcntl.c b/trunk/fs/fcntl.c index bfd776509a72..3f3ac630ccde 100644 --- a/trunk/fs/fcntl.c +++ b/trunk/fs/fcntl.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/file.c b/trunk/fs/file.c index 4c6f0ea12c41..5110acb1c9ef 100644 --- a/trunk/fs/file.c +++ b/trunk/fs/file.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -150,16 +149,8 @@ static struct fdtable * alloc_fdtable(unsigned int nr) nr /= (1024 / sizeof(struct file *)); nr = roundup_pow_of_two(nr + 1); nr *= (1024 / sizeof(struct file *)); - /* - * Note that this can drive nr *below* what we had passed if sysctl_nr_open - * had been set lower between the check in expand_files() and here. Deal - * with that in caller, it's cheaper that way. - * - * We make sure that nr remains a multiple of BITS_PER_LONG - otherwise - * bitmaps handling below becomes unpleasant, to put it mildly... - */ - if (unlikely(nr > sysctl_nr_open)) - nr = ((sysctl_nr_open - 1) | (BITS_PER_LONG - 1)) + 1; + if (nr > sysctl_nr_open) + nr = sysctl_nr_open; fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL); if (!fdt) @@ -207,16 +198,6 @@ static int expand_fdtable(struct files_struct *files, int nr) spin_lock(&files->file_lock); if (!new_fdt) return -ENOMEM; - /* - * extremely unlikely race - sysctl_nr_open decreased between the check in - * caller and alloc_fdtable(). Cheaper to catch it here... - */ - if (unlikely(new_fdt->max_fds <= nr)) { - free_fdarr(new_fdt); - free_fdset(new_fdt); - kfree(new_fdt); - return -EMFILE; - } /* * Check again since another task may have expanded the fd table while * we dropped the lock diff --git a/trunk/fs/file_table.c b/trunk/fs/file_table.c index 83084225b4c3..7a0a9b872251 100644 --- a/trunk/fs/file_table.c +++ b/trunk/fs/file_table.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/locks.c b/trunk/fs/locks.c index 663c069b59b3..44d9a6a7ec50 100644 --- a/trunk/fs/locks.c +++ b/trunk/fs/locks.c @@ -116,7 +116,6 @@ #include #include -#include #include #include #include diff --git a/trunk/fs/ocfs2/cluster/sys.c b/trunk/fs/ocfs2/cluster/sys.c index bc702dab5d1f..98429fd68499 100644 --- a/trunk/fs/ocfs2/cluster/sys.c +++ b/trunk/fs/ocfs2/cluster/sys.c @@ -65,7 +65,7 @@ int o2cb_sys_init(void) { int ret; - o2cb_kset = kset_create_and_add("o2cb", NULL, fs_kobj); + o2cb_kset = kset_create_and_add("o2cb", NULL, NULL); if (!o2cb_kset) return -ENOMEM; diff --git a/trunk/fs/ocfs2/dlm/dlmdebug.c b/trunk/fs/ocfs2/dlm/dlmdebug.c index 1b81dcba175d..5f6d858770a2 100644 --- a/trunk/fs/ocfs2/dlm/dlmdebug.c +++ b/trunk/fs/ocfs2/dlm/dlmdebug.c @@ -44,8 +44,7 @@ #define MLOG_MASK_PREFIX ML_DLM #include "cluster/masklog.h" -static int stringify_lockname(const char *lockname, int locklen, char *buf, - int len); +int stringify_lockname(const char *lockname, int locklen, char *buf, int len); void dlm_print_one_lock_resource(struct dlm_lock_resource *res) { @@ -252,8 +251,7 @@ EXPORT_SYMBOL_GPL(dlm_errname); * * For more on lockname formats, please refer to dlmglue.c and ocfs2_lockid.h. */ -static int stringify_lockname(const char *lockname, int locklen, char *buf, - int len) +int stringify_lockname(const char *lockname, int locklen, char *buf, int len) { int out = 0; __be64 inode_blkno_be; @@ -370,7 +368,7 @@ static void dlm_debug_free(struct kref *kref) kfree(dc); } -static void dlm_debug_put(struct dlm_debug_ctxt *dc) +void dlm_debug_put(struct dlm_debug_ctxt *dc) { if (dc) kref_put(&dc->debug_refcnt, dlm_debug_free); diff --git a/trunk/fs/ocfs2/file.c b/trunk/fs/ocfs2/file.c index 57e0d30cde98..9154c82d3258 100644 --- a/trunk/fs/ocfs2/file.c +++ b/trunk/fs/ocfs2/file.c @@ -1048,10 +1048,6 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) mlog_entry("(0x%p, '%.*s')\n", dentry, dentry->d_name.len, dentry->d_name.name); - /* ensuring we don't even attempt to truncate a symlink */ - if (S_ISLNK(inode->i_mode)) - attr->ia_valid &= ~ATTR_SIZE; - if (attr->ia_valid & ATTR_MODE) mlog(0, "mode change: %d\n", attr->ia_mode); if (attr->ia_valid & ATTR_UID) diff --git a/trunk/fs/ocfs2/localalloc.c b/trunk/fs/ocfs2/localalloc.c index be774bdc8b36..ce0dc147602a 100644 --- a/trunk/fs/ocfs2/localalloc.c +++ b/trunk/fs/ocfs2/localalloc.c @@ -260,7 +260,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) bh = osb->local_alloc_bh; alloc = (struct ocfs2_dinode *) bh->b_data; - alloc_copy = kmalloc(bh->b_size, GFP_NOFS); + alloc_copy = kmalloc(bh->b_size, GFP_KERNEL); if (!alloc_copy) { status = -ENOMEM; goto out_commit; @@ -931,7 +931,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, * local alloc shutdown won't try to double free main bitmap * bits. Make a copy so the sync function knows which bits to * free. */ - alloc_copy = kmalloc(osb->local_alloc_bh->b_size, GFP_NOFS); + alloc_copy = kmalloc(osb->local_alloc_bh->b_size, GFP_KERNEL); if (!alloc_copy) { status = -ENOMEM; mlog_errno(status); diff --git a/trunk/fs/ocfs2/stack_o2cb.c b/trunk/fs/ocfs2/stack_o2cb.c index bbd1667aa7d3..ac1d74c63bf5 100644 --- a/trunk/fs/ocfs2/stack_o2cb.c +++ b/trunk/fs/ocfs2/stack_o2cb.c @@ -385,7 +385,7 @@ static int o2cb_cluster_this_node(unsigned int *node) return 0; } -static struct ocfs2_stack_operations o2cb_stack_ops = { +struct ocfs2_stack_operations o2cb_stack_ops = { .connect = o2cb_cluster_connect, .disconnect = o2cb_cluster_disconnect, .hangup = o2cb_cluster_hangup, diff --git a/trunk/fs/ocfs2/stack_user.c b/trunk/fs/ocfs2/stack_user.c index b503772cd0ec..7428663f9cbb 100644 --- a/trunk/fs/ocfs2/stack_user.c +++ b/trunk/fs/ocfs2/stack_user.c @@ -635,7 +635,7 @@ static const struct file_operations ocfs2_control_fops = { .owner = THIS_MODULE, }; -static struct miscdevice ocfs2_control_device = { +struct miscdevice ocfs2_control_device = { .minor = MISC_DYNAMIC_MINOR, .name = "ocfs2_control", .fops = &ocfs2_control_fops, diff --git a/trunk/fs/ocfs2/symlink.c b/trunk/fs/ocfs2/symlink.c index ba9dbb51d25b..7134007ba22f 100644 --- a/trunk/fs/ocfs2/symlink.c +++ b/trunk/fs/ocfs2/symlink.c @@ -167,11 +167,9 @@ const struct inode_operations ocfs2_symlink_inode_operations = { .readlink = page_readlink, .follow_link = ocfs2_follow_link, .getattr = ocfs2_getattr, - .setattr = ocfs2_setattr, }; const struct inode_operations ocfs2_fast_symlink_inode_operations = { .readlink = ocfs2_readlink, .follow_link = ocfs2_follow_link, .getattr = ocfs2_getattr, - .setattr = ocfs2_setattr, }; diff --git a/trunk/fs/open.c b/trunk/fs/open.c index a1450086e92f..7af1f05d5978 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/proc/array.c b/trunk/fs/proc/array.c index dca997a93bff..c135cbdd9127 100644 --- a/trunk/fs/proc/array.c +++ b/trunk/fs/proc/array.c @@ -73,7 +73,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 808cbdc193d3..fcf02f2deeba 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/select.c b/trunk/fs/select.c index 8dda969614a9..2c292146e246 100644 --- a/trunk/fs/select.c +++ b/trunk/fs/select.c @@ -21,7 +21,6 @@ #include #include /* for STICKY_TIMEOUTS */ #include -#include #include #include @@ -299,7 +298,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout) #define MAX_SELECT_SECONDS \ ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) -int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, +static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s64 *timeout) { fd_set_bits fds; diff --git a/trunk/fs/signalfd.c b/trunk/fs/signalfd.c index 619725644c75..8ead0db35933 100644 --- a/trunk/fs/signalfd.c +++ b/trunk/fs/signalfd.c @@ -207,8 +207,11 @@ static const struct file_operations signalfd_fops = { asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask) { + int error; sigset_t sigmask; struct signalfd_ctx *ctx; + struct file *file; + struct inode *inode; if (sizemask != sizeof(sigset_t) || copy_from_user(&sigmask, user_mask, sizeof(sigmask))) @@ -227,11 +230,12 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas * When we call this, the initialization must be complete, since * anon_inode_getfd() will install the fd. */ - ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx); - if (ufd < 0) - kfree(ctx); + error = anon_inode_getfd(&ufd, &inode, &file, "[signalfd]", + &signalfd_fops, ctx); + if (error) + goto err_fdalloc; } else { - struct file *file = fget(ufd); + file = fget(ufd); if (!file) return -EBADF; ctx = file->private_data; @@ -248,4 +252,9 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas } return ufd; + +err_fdalloc: + kfree(ctx); + return error; } + diff --git a/trunk/fs/timerfd.c b/trunk/fs/timerfd.c index d87d354ec424..5400524e9cb1 100644 --- a/trunk/fs/timerfd.c +++ b/trunk/fs/timerfd.c @@ -181,8 +181,10 @@ static struct file *timerfd_fget(int fd) asmlinkage long sys_timerfd_create(int clockid, int flags) { - int ufd; + int error, ufd; struct timerfd_ctx *ctx; + struct file *file; + struct inode *inode; if (flags) return -EINVAL; @@ -198,9 +200,12 @@ asmlinkage long sys_timerfd_create(int clockid, int flags) ctx->clockid = clockid; hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); - ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx); - if (ufd < 0) + error = anon_inode_getfd(&ufd, &inode, &file, "[timerfd]", + &timerfd_fops, ctx); + if (error) { kfree(ctx); + return error; + } return ufd; } diff --git a/trunk/include/asm-ia64/cpu.h b/trunk/include/asm-ia64/cpu.h index fcca30b9f110..e87fa3210a2b 100644 --- a/trunk/include/asm-ia64/cpu.h +++ b/trunk/include/asm-ia64/cpu.h @@ -14,8 +14,8 @@ DECLARE_PER_CPU(struct ia64_cpu, cpu_devices); DECLARE_PER_CPU(int, cpu_state); -#ifdef CONFIG_HOTPLUG_CPU extern int arch_register_cpu(int num); +#ifdef CONFIG_HOTPLUG_CPU extern void arch_unregister_cpu(int); #endif diff --git a/trunk/include/asm-ia64/thread_info.h b/trunk/include/asm-ia64/thread_info.h index 2422ac61658a..f30e05583869 100644 --- a/trunk/include/asm-ia64/thread_info.h +++ b/trunk/include/asm-ia64/thread_info.h @@ -108,11 +108,13 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk); #define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */ #define TIF_FREEZE 20 /* is freezing for suspend */ #define TIF_RESTORE_RSE 21 /* user RBS is newer than kernel RBS */ +#define TIF_RESTORE_SIGMASK 22 /* restore signal mask in do_signal() */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SYSCALL_TRACEAUDIT (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP) +#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) @@ -129,18 +131,7 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk); #define TIF_WORK_MASK (TIF_ALLWORK_MASK&~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)) #define TS_POLLING 1 /* true if in idle loop and not sleeping */ -#define TS_RESTORE_SIGMASK 2 /* restore signal mask in do_signal() */ #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) -#ifndef __ASSEMBLY__ -#define HAVE_SET_RESTORE_SIGMASK 1 -static inline void set_restore_sigmask(void) -{ - struct thread_info *ti = current_thread_info(); - ti->status |= TS_RESTORE_SIGMASK; - set_bit(TIF_SIGPENDING, &ti->flags); -} -#endif /* !__ASSEMBLY__ */ - #endif /* _ASM_IA64_THREAD_INFO_H */ diff --git a/trunk/include/asm-powerpc/ps3.h b/trunk/include/asm-powerpc/ps3.h index 81ffe3b3c1ce..9e8ed6824e15 100644 --- a/trunk/include/asm-powerpc/ps3.h +++ b/trunk/include/asm-powerpc/ps3.h @@ -178,6 +178,9 @@ enum ps3_cpu_binding { PS3_BINDING_CPU_1 = 1, }; +int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, + unsigned int *virq); +int ps3_virq_destroy(unsigned int virq); int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, unsigned int *virq); int ps3_irq_plug_destroy(unsigned int virq); diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index b7d81b2a9041..78fade0a1e35 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -346,11 +346,6 @@ unifdef-y += videodev.h unifdef-y += virtio_config.h unifdef-y += virtio_blk.h unifdef-y += virtio_net.h -unifdef-y += virtio_9p.h -unifdef-y += virtio_balloon.h -unifdef-y += virtio_console.h -unifdef-y += virtio_pci.h -unifdef-y += virtio_ring.h unifdef-y += vt.h unifdef-y += wait.h unifdef-y += wanrouter.h diff --git a/trunk/include/linux/anon_inodes.h b/trunk/include/linux/anon_inodes.h index 6129e58ca7c9..b2e1ba325b9a 100644 --- a/trunk/include/linux/anon_inodes.h +++ b/trunk/include/linux/anon_inodes.h @@ -8,7 +8,8 @@ #ifndef _LINUX_ANON_INODES_H #define _LINUX_ANON_INODES_H -int anon_inode_getfd(const char *name, const struct file_operations *fops, +int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, + const char *name, const struct file_operations *fops, void *priv); #endif /* _LINUX_ANON_INODES_H */ diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index 8c23e3dfe3ac..832fb0eb2933 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -380,12 +380,6 @@ struct device { /* Get the wakeup routines, which depend on struct device */ #include -static inline const char *dev_name(struct device *dev) -{ - /* will be changed into kobject_name(&dev->kobj) in the near future */ - return dev->bus_id; -} - #ifdef CONFIG_NUMA static inline int dev_to_node(struct device *dev) { @@ -484,7 +478,7 @@ extern void sysdev_shutdown(void); extern const char *dev_driver_string(struct device *dev); #define dev_printk(level, dev, format, arg...) \ printk(level "%s %s: " format , dev_driver_string(dev) , \ - dev_name(dev) , ## arg) + (dev)->bus_id , ## arg) #define dev_emerg(dev, format, arg...) \ dev_printk(KERN_EMERG , dev , format , ## arg) diff --git a/trunk/include/linux/fdtable.h b/trunk/include/linux/fdtable.h deleted file mode 100644 index a118f3c0b240..000000000000 --- a/trunk/include/linux/fdtable.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * descriptor table internals; you almost certainly want file.h instead. - */ - -#ifndef __LINUX_FDTABLE_H -#define __LINUX_FDTABLE_H - -#include -#include -#include -#include -#include -#include - -/* - * The default fd array needs to be at least BITS_PER_LONG, - * as this is the granularity returned by copy_fdset(). - */ -#define NR_OPEN_DEFAULT BITS_PER_LONG - -/* - * The embedded_fd_set is a small fd_set, - * suitable for most tasks (which open <= BITS_PER_LONG files) - */ -struct embedded_fd_set { - unsigned long fds_bits[1]; -}; - -struct fdtable { - unsigned int max_fds; - struct file ** fd; /* current fd array */ - fd_set *close_on_exec; - fd_set *open_fds; - struct rcu_head rcu; - struct fdtable *next; -}; - -/* - * Open file table structure - */ -struct files_struct { - /* - * read mostly part - */ - atomic_t count; - struct fdtable *fdt; - struct fdtable fdtab; - /* - * written part on a separate cache line in SMP - */ - spinlock_t file_lock ____cacheline_aligned_in_smp; - int next_fd; - struct embedded_fd_set close_on_exec_init; - struct embedded_fd_set open_fds_init; - struct file * fd_array[NR_OPEN_DEFAULT]; -}; - -#define files_fdtable(files) (rcu_dereference((files)->fdt)) - -extern struct kmem_cache *filp_cachep; - -struct file_operations; -struct vfsmount; -struct dentry; - -extern int expand_files(struct files_struct *, int nr); -extern void free_fdtable_rcu(struct rcu_head *rcu); -extern void __init files_defer_init(void); - -static inline void free_fdtable(struct fdtable *fdt) -{ - call_rcu(&fdt->rcu, free_fdtable_rcu); -} - -static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd) -{ - struct file * file = NULL; - struct fdtable *fdt = files_fdtable(files); - - if (fd < fdt->max_fds) - file = rcu_dereference(fdt->fd[fd]); - return file; -} - -/* - * Check whether the specified fd has an open file. - */ -#define fcheck(fd) fcheck_files(current->files, fd) - -struct task_struct; - -struct files_struct *get_files_struct(struct task_struct *); -void put_files_struct(struct files_struct *fs); -void reset_files_struct(struct files_struct *); -int unshare_files(struct files_struct **); - -extern struct kmem_cache *files_cachep; - -#endif /* __LINUX_FDTABLE_H */ diff --git a/trunk/include/linux/file.h b/trunk/include/linux/file.h index 27c64bdc68c9..69baf5a4f0a5 100644 --- a/trunk/include/linux/file.h +++ b/trunk/include/linux/file.h @@ -5,11 +5,59 @@ #ifndef __LINUX_FILE_H #define __LINUX_FILE_H +#include +#include #include +#include +#include #include -#include -struct file; +/* + * The default fd array needs to be at least BITS_PER_LONG, + * as this is the granularity returned by copy_fdset(). + */ +#define NR_OPEN_DEFAULT BITS_PER_LONG + +/* + * The embedded_fd_set is a small fd_set, + * suitable for most tasks (which open <= BITS_PER_LONG files) + */ +struct embedded_fd_set { + unsigned long fds_bits[1]; +}; + +struct fdtable { + unsigned int max_fds; + struct file ** fd; /* current fd array */ + fd_set *close_on_exec; + fd_set *open_fds; + struct rcu_head rcu; + struct fdtable *next; +}; + +/* + * Open file table structure + */ +struct files_struct { + /* + * read mostly part + */ + atomic_t count; + struct fdtable *fdt; + struct fdtable fdtab; + /* + * written part on a separate cache line in SMP + */ + spinlock_t file_lock ____cacheline_aligned_in_smp; + int next_fd; + struct embedded_fd_set close_on_exec_init; + struct embedded_fd_set open_fds_init; + struct file * fd_array[NR_OPEN_DEFAULT]; +}; + +#define files_fdtable(files) (rcu_dereference((files)->fdt)) + +extern struct kmem_cache *filp_cachep; extern void __fput(struct file *); extern void fput(struct file *); @@ -37,7 +85,41 @@ extern void put_filp(struct file *); extern int get_unused_fd(void); extern int get_unused_fd_flags(int flags); extern void put_unused_fd(unsigned int fd); +struct kmem_cache; + +extern int expand_files(struct files_struct *, int nr); +extern void free_fdtable_rcu(struct rcu_head *rcu); +extern void __init files_defer_init(void); + +static inline void free_fdtable(struct fdtable *fdt) +{ + call_rcu(&fdt->rcu, free_fdtable_rcu); +} + +static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd) +{ + struct file * file = NULL; + struct fdtable *fdt = files_fdtable(files); + + if (fd < fdt->max_fds) + file = rcu_dereference(fdt->fd[fd]); + return file; +} + +/* + * Check whether the specified fd has an open file. + */ +#define fcheck(fd) fcheck_files(current->files, fd) extern void fd_install(unsigned int fd, struct file *file); +struct task_struct; + +struct files_struct *get_files_struct(struct task_struct *); +void put_files_struct(struct files_struct *fs); +void reset_files_struct(struct files_struct *); +int unshare_files(struct files_struct **); + +extern struct kmem_cache *files_cachep; + #endif /* __LINUX_FILE_H */ diff --git a/trunk/include/linux/init_task.h b/trunk/include/linux/init_task.h index b24c2875aa05..bf6b8a61f8db 100644 --- a/trunk/include/linux/init_task.h +++ b/trunk/include/linux/init_task.h @@ -1,7 +1,7 @@ #ifndef _LINUX__INIT_TASK_H #define _LINUX__INIT_TASK_H -#include +#include #include #include #include diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index 552e0ec269c9..1883a85625dd 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -61,7 +61,6 @@ typedef void (*irq_flow_handler_t)(unsigned int irq, #define IRQ_WAKEUP 0x00100000 /* IRQ triggers system wakeup */ #define IRQ_MOVE_PENDING 0x00200000 /* need to re-target IRQ destination */ #define IRQ_NO_BALANCING 0x00400000 /* IRQ is excluded from balancing */ -#define IRQ_SPURIOUS_DISABLED 0x00800000 /* IRQ was disabled by the spurious trap */ #ifdef CONFIG_IRQ_PER_CPU # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) diff --git a/trunk/include/linux/poll.h b/trunk/include/linux/poll.h index ef453828877a..16d813b364ef 100644 --- a/trunk/include/linux/poll.h +++ b/trunk/include/linux/poll.h @@ -117,8 +117,6 @@ void zero_fd_set(unsigned long nr, unsigned long *fdset) extern int do_select(int n, fd_set_bits *fds, s64 *timeout); extern int do_sys_poll(struct pollfd __user * ufds, unsigned int nfds, s64 *timeout); -extern int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, s64 *timeout); #endif /* KERNEL */ diff --git a/trunk/include/linux/rio.h b/trunk/include/linux/rio.h index dc0c75556c63..c1c99c9643d3 100644 --- a/trunk/include/linux/rio.h +++ b/trunk/include/linux/rio.h @@ -161,8 +161,6 @@ enum rio_phy_type { * @ops: configuration space functions * @id: Port ID, unique among all ports * @index: Port index, unique among all port interfaces of the same type - * @sys_size: RapidIO common transport system size - * @phy_type: RapidIO phy type * @name: Port name string * @priv: Master port private data */ diff --git a/trunk/include/linux/usb/c67x00.h b/trunk/include/linux/usb/c67x00.h deleted file mode 100644 index 83c6b45470ca..000000000000 --- a/trunk/include/linux/usb/c67x00.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * usb_c67x00.h: platform definitions for the Cypress C67X00 USB chip - * - * Copyright (C) 2006-2008 Barco N.V. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#ifndef _LINUX_USB_C67X00_H -#define _LINUX_USB_C67X00_H - -/* SIE configuration */ -#define C67X00_SIE_UNUSED 0 -#define C67X00_SIE_HOST 1 -#define C67X00_SIE_PERIPHERAL_A 2 /* peripheral on A port */ -#define C67X00_SIE_PERIPHERAL_B 3 /* peripheral on B port */ - -#define c67x00_sie_config(config, n) (((config)>>(4*(n)))&0x3) - -#define C67X00_SIE1_UNUSED (C67X00_SIE_UNUSED << 0) -#define C67X00_SIE1_HOST (C67X00_SIE_HOST << 0) -#define C67X00_SIE1_PERIPHERAL_A (C67X00_SIE_PERIPHERAL_A << 0) -#define C67X00_SIE1_PERIPHERAL_B (C67X00_SIE_PERIPHERAL_B << 0) - -#define C67X00_SIE2_UNUSED (C67X00_SIE_UNUSED << 4) -#define C67X00_SIE2_HOST (C67X00_SIE_HOST << 4) -#define C67X00_SIE2_PERIPHERAL_A (C67X00_SIE_PERIPHERAL_A << 4) -#define C67X00_SIE2_PERIPHERAL_B (C67X00_SIE_PERIPHERAL_B << 4) - -struct c67x00_platform_data { - int sie_config; /* SIEs config (C67X00_SIEx_*) */ - unsigned long hpi_regstep; /* Step between HPI registers */ -}; - -#endif /* _LINUX_USB_C67X00_H */ diff --git a/trunk/include/linux/usb/ch9.h b/trunk/include/linux/usb/ch9.h index 73a2f4eb1f7a..7e0d3084f76c 100644 --- a/trunk/include/linux/usb/ch9.h +++ b/trunk/include/linux/usb/ch9.h @@ -455,7 +455,7 @@ struct usb_encryption_descriptor { /*-------------------------------------------------------------------------*/ -/* USB_DT_BOS: group of device-level capabilities */ +/* USB_DT_BOS: group of wireless capabilities */ struct usb_bos_descriptor { __u8 bLength; __u8 bDescriptorType; @@ -501,16 +501,6 @@ struct usb_wireless_cap_descriptor { /* Ultra Wide Band */ __u8 bReserved; } __attribute__((packed)); -#define USB_CAP_TYPE_EXT 2 - -struct usb_ext_cap_descriptor { /* Link Power Management */ - __u8 bLength; - __u8 bDescriptorType; - __u8 bDevCapabilityType; - __u8 bmAttributes; -#define USB_LPM_SUPPORT (1 << 1) /* supports LPM */ -} __attribute__((packed)); - /*-------------------------------------------------------------------------*/ /* USB_DT_WIRELESS_ENDPOINT_COMP: companion descriptor associated with diff --git a/trunk/include/linux/usb/gadget.h b/trunk/include/linux/usb/gadget.h index cf468fbdbf8e..d8128f7102c9 100644 --- a/trunk/include/linux/usb/gadget.h +++ b/trunk/include/linux/usb/gadget.h @@ -114,8 +114,6 @@ struct usb_ep_ops { int (*dequeue) (struct usb_ep *ep, struct usb_request *req); int (*set_halt) (struct usb_ep *ep, int value); - int (*set_wedge) (struct usb_ep *ep); - int (*fifo_status) (struct usb_ep *ep); void (*fifo_flush) (struct usb_ep *ep); }; @@ -350,25 +348,6 @@ static inline int usb_ep_clear_halt(struct usb_ep *ep) return ep->ops->set_halt(ep, 0); } -/** - * usb_ep_set_wedge - sets the halt feature and ignores clear requests - * @ep: the endpoint being wedged - * - * Use this to stall an endpoint and ignore CLEAR_FEATURE(HALT_ENDPOINT) - * requests. If the gadget driver clears the halt status, it will - * automatically unwedge the endpoint. - * - * Returns zero on success, else negative errno. - */ -static inline int -usb_ep_set_wedge(struct usb_ep *ep) -{ - if (ep->ops->set_wedge) - return ep->ops->set_wedge(ep); - else - return ep->ops->set_halt(ep, 1); -} - /** * usb_ep_fifo_status - returns number of bytes in fifo, or error * @ep: the endpoint whose fifo status is being checked. diff --git a/trunk/include/linux/virtio.h b/trunk/include/linux/virtio.h index 06005fa9e982..e7d10845b3c1 100644 --- a/trunk/include/linux/virtio.h +++ b/trunk/include/linux/virtio.h @@ -76,7 +76,6 @@ struct virtqueue_ops { * @dev: underlying device. * @id: the device type identification (used to match it with a driver). * @config: the configuration ops for this device. - * @features: the features supported by both driver and device. * @priv: private pointer for the driver's use. */ struct virtio_device @@ -85,8 +84,6 @@ struct virtio_device struct device dev; struct virtio_device_id id; struct virtio_config_ops *config; - /* Note that this is a Linux set_bit-style bitmap. */ - unsigned long features[1]; void *priv; }; @@ -97,8 +94,6 @@ void unregister_virtio_device(struct virtio_device *dev); * virtio_driver - operations for a virtio I/O driver * @driver: underlying device driver (populate name and owner). * @id_table: the ids serviced by this driver. - * @feature_table: an array of feature numbers supported by this device. - * @feature_table_size: number of entries in the feature table array. * @probe: the function to call when a device is found. Returns a token for * remove, or PTR_ERR(). * @remove: the function when a device is removed. @@ -108,8 +103,6 @@ void unregister_virtio_device(struct virtio_device *dev); struct virtio_driver { struct device_driver driver; const struct virtio_device_id *id_table; - const unsigned int *feature_table; - unsigned int feature_table_size; int (*probe)(struct virtio_device *dev); void (*remove)(struct virtio_device *dev); void (*config_changed)(struct virtio_device *dev); diff --git a/trunk/include/linux/virtio_blk.h b/trunk/include/linux/virtio_blk.h index d4695a3356d0..bca0b10d7947 100644 --- a/trunk/include/linux/virtio_blk.h +++ b/trunk/include/linux/virtio_blk.h @@ -9,7 +9,6 @@ #define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */ #define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */ #define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */ -#define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */ struct virtio_blk_config { @@ -19,12 +18,6 @@ struct virtio_blk_config __le32 size_max; /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */ __le32 seg_max; - /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */ - struct virtio_blk_geometry { - __le16 cylinders; - __u8 heads; - __u8 sectors; - } geometry; } __attribute__((packed)); /* These two define direction. */ @@ -48,8 +41,13 @@ struct virtio_blk_outhdr __u64 sector; }; -/* And this is the final byte of the write scatter-gather list. */ #define VIRTIO_BLK_S_OK 0 #define VIRTIO_BLK_S_IOERR 1 #define VIRTIO_BLK_S_UNSUPP 2 + +/* This is the first element of the write scatter-gather list */ +struct virtio_blk_inhdr +{ + unsigned char status; +}; #endif /* _LINUX_VIRTIO_BLK_H */ diff --git a/trunk/include/linux/virtio_config.h b/trunk/include/linux/virtio_config.h index 50db245c81ad..d581b2914b34 100644 --- a/trunk/include/linux/virtio_config.h +++ b/trunk/include/linux/virtio_config.h @@ -16,20 +16,27 @@ #define VIRTIO_CONFIG_S_FAILED 0x80 #ifdef __KERNEL__ -#include +struct virtio_device; /** * virtio_config_ops - operations for configuring a virtio device + * @feature: search for a feature in this config + * vdev: the virtio_device + * bit: the feature bit + * Returns true if the feature is supported. Acknowledges the feature + * so the host can see it. * @get: read the value of a configuration field * vdev: the virtio_device * offset: the offset of the configuration field * buf: the buffer to write the field value into. * len: the length of the buffer + * Note that contents are conventionally little-endian. * @set: write the value of a configuration field * vdev: the virtio_device * offset: the offset of the configuration field * buf: the buffer to read the field value from. * len: the length of the buffer + * Note that contents are conventionally little-endian. * @get_status: read the status byte * vdev: the virtio_device * Returns the status byte @@ -45,15 +52,10 @@ * callback: the virqtueue callback * Returns the new virtqueue or ERR_PTR() (eg. -ENOENT). * @del_vq: free a virtqueue found by find_vq(). - * @get_features: get the array of feature bits for this device. - * vdev: the virtio_device - * Returns the first 32 feature bits (all we currently need). - * @set_features: confirm what device features we'll be using. - * vdev: the virtio_device - * feature: the first 32 feature bits */ struct virtio_config_ops { + bool (*feature)(struct virtio_device *vdev, unsigned bit); void (*get)(struct virtio_device *vdev, unsigned offset, void *buf, unsigned len); void (*set)(struct virtio_device *vdev, unsigned offset, @@ -65,52 +67,43 @@ struct virtio_config_ops unsigned index, void (*callback)(struct virtqueue *)); void (*del_vq)(struct virtqueue *vq); - u32 (*get_features)(struct virtio_device *vdev); - void (*set_features)(struct virtio_device *vdev, u32 features); }; -/* If driver didn't advertise the feature, it will never appear. */ -void virtio_check_driver_offered_feature(const struct virtio_device *vdev, - unsigned int fbit); - /** - * virtio_has_feature - helper to determine if this device has this feature. - * @vdev: the device - * @fbit: the feature bit - */ -static inline bool virtio_has_feature(const struct virtio_device *vdev, - unsigned int fbit) -{ - /* Did you forget to fix assumptions on max features? */ - if (__builtin_constant_p(fbit)) - BUILD_BUG_ON(fbit >= 32); - - virtio_check_driver_offered_feature(vdev, fbit); - return test_bit(fbit, vdev->features); -} - -/** - * virtio_config_val - look for a feature and get a virtio config entry. + * virtio_config_val - look for a feature and get a single virtio config. * @vdev: the virtio device * @fbit: the feature bit * @offset: the type to search for. * @val: a pointer to the value to fill in. * * The return value is -ENOENT if the feature doesn't exist. Otherwise - * the config value is copied into whatever is pointed to by v. */ -#define virtio_config_val(vdev, fbit, offset, v) \ - virtio_config_buf((vdev), (fbit), (offset), (v), sizeof(v)) - -static inline int virtio_config_buf(struct virtio_device *vdev, - unsigned int fbit, - unsigned int offset, - void *buf, unsigned len) -{ - if (!virtio_has_feature(vdev, fbit)) - return -ENOENT; + * the value is endian-corrected and returned in v. */ +#define virtio_config_val(vdev, fbit, offset, v) ({ \ + int _err; \ + if ((vdev)->config->feature((vdev), (fbit))) { \ + __virtio_config_val((vdev), (offset), (v)); \ + _err = 0; \ + } else \ + _err = -ENOENT; \ + _err; \ +}) - vdev->config->get(vdev, offset, buf, len); - return 0; -} +/** + * __virtio_config_val - get a single virtio config without feature check. + * @vdev: the virtio device + * @offset: the type to search for. + * @val: a pointer to the value to fill in. + * + * The value is endian-corrected and returned in v. */ +#define __virtio_config_val(vdev, offset, v) do { \ + BUILD_BUG_ON(sizeof(*(v)) != 1 && sizeof(*(v)) != 2 \ + && sizeof(*(v)) != 4 && sizeof(*(v)) != 8); \ + (vdev)->config->get((vdev), (offset), (v), sizeof(*(v))); \ + switch (sizeof(*(v))) { \ + case 2: le16_to_cpus((__u16 *) v); break; \ + case 4: le32_to_cpus((__u32 *) v); break; \ + case 8: le64_to_cpus((__u64 *) v); break; \ + } \ +} while(0) #endif /* __KERNEL__ */ #endif /* _LINUX_VIRTIO_CONFIG_H */ diff --git a/trunk/include/linux/virtio_net.h b/trunk/include/linux/virtio_net.h index 9405aa6cdf26..1ea3351df609 100644 --- a/trunk/include/linux/virtio_net.h +++ b/trunk/include/linux/virtio_net.h @@ -6,18 +6,9 @@ #define VIRTIO_ID_NET 1 /* The feature bitmap for virtio net */ -#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */ -#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */ +#define VIRTIO_NET_F_CSUM 0 /* Can handle pkts w/ partial csum */ #define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */ -#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */ -#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */ -#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */ -#define VIRTIO_NET_F_GUEST_ECN 9 /* Guest can handle TSO[6] w/ ECN in. */ -#define VIRTIO_NET_F_GUEST_UFO 10 /* Guest can handle UFO in. */ -#define VIRTIO_NET_F_HOST_TSO4 11 /* Host can handle TSOv4 in. */ -#define VIRTIO_NET_F_HOST_TSO6 12 /* Host can handle TSOv6 in. */ -#define VIRTIO_NET_F_HOST_ECN 13 /* Host can handle TSO[6] w/ ECN in. */ -#define VIRTIO_NET_F_HOST_UFO 14 /* Host can handle UFO in. */ +#define VIRTIO_NET_F_GSO 6 /* Can handle pkts w/ any GSO type */ struct virtio_net_config { diff --git a/trunk/include/scsi/scsi.h b/trunk/include/scsi/scsi.h index 32742c4563de..1f74bcd603fe 100644 --- a/trunk/include/scsi/scsi.h +++ b/trunk/include/scsi/scsi.h @@ -29,6 +29,13 @@ #define SCSI_MAX_SG_CHAIN_SEGMENTS SCSI_MAX_SG_SEGMENTS #endif +/* + * SCSI command lengths + */ + +extern const unsigned char scsi_command_size[8]; +#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7] + /* * Special value for scanning to specify scanning or rescanning of all * possible channels, (target) ids, or luns on a given shost. @@ -102,7 +109,6 @@ #define MODE_SENSE_10 0x5a #define PERSISTENT_RESERVE_IN 0x5e #define PERSISTENT_RESERVE_OUT 0x5f -#define VARIABLE_LENGTH_CMD 0x7f #define REPORT_LUNS 0xa0 #define MAINTENANCE_IN 0xa3 #define MOVE_MEDIUM 0xa5 @@ -129,38 +135,6 @@ #define ATA_16 0x85 /* 16-byte pass-thru */ #define ATA_12 0xa1 /* 12-byte pass-thru */ -/* - * SCSI command lengths - */ - -#define SCSI_MAX_VARLEN_CDB_SIZE 260 - -/* defined in T10 SCSI Primary Commands-2 (SPC2) */ -struct scsi_varlen_cdb_hdr { - u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */ - u8 control; - u8 misc[5]; - u8 additional_cdb_length; /* total cdb length - 8 */ - __be16 service_action; - /* service specific data follows */ -}; - -static inline unsigned -scsi_varlen_cdb_length(const void *hdr) -{ - return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8; -} - -extern const unsigned char scsi_command_size_tbl[8]; -#define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7] - -static inline unsigned -scsi_command_size(const unsigned char *cmnd) -{ - return (cmnd[0] == VARIABLE_LENGTH_CMD) ? - scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]); -} - /* * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft * T10/1561-D Revision 4 Draft dated 7th November 2002. diff --git a/trunk/include/scsi/scsi_cmnd.h b/trunk/include/scsi/scsi_cmnd.h index 3e46dfae8194..8d20e60a94b7 100644 --- a/trunk/include/scsi/scsi_cmnd.h +++ b/trunk/include/scsi/scsi_cmnd.h @@ -7,28 +7,10 @@ #include #include #include -#include struct Scsi_Host; struct scsi_device; -/* - * MAX_COMMAND_SIZE is: - * The longest fixed-length SCSI CDB as per the SCSI standard. - * fixed-length means: commands that their size can be determined - * by their opcode and the CDB does not carry a length specifier, (unlike - * the VARIABLE_LENGTH_CMD(0x7f) command). This is actually not exactly - * true and the SCSI standard also defines extended commands and - * vendor specific commands that can be bigger than 16 bytes. The kernel - * will support these using the same infrastructure used for VARLEN CDB's. - * So in effect MAX_COMMAND_SIZE means the maximum size command scsi-ml - * supports without specifying a cmd_len by ULD's - */ -#define MAX_COMMAND_SIZE 16 -#if (MAX_COMMAND_SIZE > BLK_MAX_CDB) -# error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB -#endif - struct scsi_data_buffer { struct sg_table table; unsigned length; @@ -78,11 +60,12 @@ struct scsi_cmnd { int allowed; int timeout_per_command; - unsigned short cmd_len; + unsigned char cmd_len; enum dma_data_direction sc_data_direction; /* These elements define the operation we are about to perform */ - unsigned char *cmnd; +#define MAX_COMMAND_SIZE 16 + unsigned char cmnd[MAX_COMMAND_SIZE]; struct timer_list eh_timeout; /* Used to time out the command. */ diff --git a/trunk/include/scsi/scsi_eh.h b/trunk/include/scsi/scsi_eh.h index 2a9add21267d..d3a133b4a072 100644 --- a/trunk/include/scsi/scsi_eh.h +++ b/trunk/include/scsi/scsi_eh.h @@ -75,11 +75,11 @@ struct scsi_eh_save { int result; enum dma_data_direction data_direction; unsigned char cmd_len; - unsigned char *cmnd; + unsigned char cmnd[MAX_COMMAND_SIZE]; struct scsi_data_buffer sdb; struct request *next_rq; + /* new command support */ - unsigned char eh_cmnd[BLK_MAX_CDB]; struct scatterlist sense_sgl; }; diff --git a/trunk/include/scsi/scsi_host.h b/trunk/include/scsi/scsi_host.h index 1834fdfe82a7..d967d6dc7a28 100644 --- a/trunk/include/scsi/scsi_host.h +++ b/trunk/include/scsi/scsi_host.h @@ -573,11 +573,13 @@ struct Scsi_Host { /* * The maximum length of SCSI commands that this host can accept. * Probably 12 for most host adapters, but could be 16 for others. - * or 260 if the driver supports variable length cdbs. * For drivers that don't set this field, a value of 12 is - * assumed. + * assumed. I am leaving this as a number rather than a bit + * because you never know what subsequent SCSI standards might do + * (i.e. could there be a 20 byte or a 24-byte command a few years + * down the road?). */ - unsigned short max_cmd_len; + unsigned char max_cmd_len; int this_id; int can_queue; diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 1510f78a0ffa..d3ad54677f9c 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 933e60ebccae..2bb675af4de3 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index 46d6611a33bb..46e4ad1723f0 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -150,26 +150,6 @@ void disable_irq(unsigned int irq) } EXPORT_SYMBOL(disable_irq); -static void __enable_irq(struct irq_desc *desc, unsigned int irq) -{ - switch (desc->depth) { - case 0: - printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); - WARN_ON(1); - break; - case 1: { - unsigned int status = desc->status & ~IRQ_DISABLED; - - /* Prevent probing on this irq: */ - desc->status = status | IRQ_NOPROBE; - check_irq_resend(desc, irq); - /* fall-through */ - } - default: - desc->depth--; - } -} - /** * enable_irq - enable handling of an irq * @irq: Interrupt to enable @@ -189,7 +169,22 @@ void enable_irq(unsigned int irq) return; spin_lock_irqsave(&desc->lock, flags); - __enable_irq(desc, irq); + switch (desc->depth) { + case 0: + printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); + WARN_ON(1); + break; + case 1: { + unsigned int status = desc->status & ~IRQ_DISABLED; + + /* Prevent probing on this irq: */ + desc->status = status | IRQ_NOPROBE; + check_irq_resend(desc, irq); + /* fall-through */ + } + default: + desc->depth--; + } spin_unlock_irqrestore(&desc->lock, flags); } EXPORT_SYMBOL(enable_irq); @@ -370,7 +365,7 @@ int setup_irq(unsigned int irq, struct irqaction *new) compat_irq_chip_set_default_handler(desc); desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING | - IRQ_INPROGRESS | IRQ_SPURIOUS_DISABLED); + IRQ_INPROGRESS); if (!(desc->status & IRQ_NOAUTOEN)) { desc->depth = 0; @@ -386,16 +381,6 @@ int setup_irq(unsigned int irq, struct irqaction *new) /* Reset broken irq detection when installing new handler */ desc->irq_count = 0; desc->irqs_unhandled = 0; - - /* - * Check whether we disabled the irq via the spurious handler - * before. Reenable it and give it another chance. - */ - if (shared && (desc->status & IRQ_SPURIOUS_DISABLED)) { - desc->status &= ~IRQ_SPURIOUS_DISABLED; - __enable_irq(desc, irq); - } - spin_unlock_irqrestore(&desc->lock, flags); new->irq = irq; diff --git a/trunk/kernel/irq/spurious.c b/trunk/kernel/irq/spurious.c index c66d3f10e853..088dabbf2d6a 100644 --- a/trunk/kernel/irq/spurious.c +++ b/trunk/kernel/irq/spurious.c @@ -209,8 +209,8 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc, * Now kill the IRQ */ printk(KERN_EMERG "Disabling IRQ #%d\n", irq); - desc->status |= IRQ_DISABLED | IRQ_SPURIOUS_DISABLED; - desc->depth++; + desc->status |= IRQ_DISABLED; + desc->depth = 1; desc->chip->disable(irq); } desc->irqs_unhandled = 0; diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 8df97d3dfda8..e2764047ec03 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 1c864c0efe2b..1b50a6ebc55f 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index e89338e2b043..c82cf15730a1 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -834,9 +834,16 @@ static const struct file_operations kvm_vcpu_fops = { */ static int create_vcpu_fd(struct kvm_vcpu *vcpu) { - int fd = anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu); - if (fd < 0) + int fd, r; + struct inode *inode; + struct file *file; + + r = anon_inode_getfd(&fd, &inode, &file, + "kvm-vcpu", &kvm_vcpu_fops, vcpu); + if (r) { kvm_put_kvm(vcpu->kvm); + return r; + } return fd; } @@ -1161,15 +1168,19 @@ static const struct file_operations kvm_vm_fops = { static int kvm_dev_ioctl_create_vm(void) { - int fd; + int fd, r; + struct inode *inode; + struct file *file; struct kvm *kvm; kvm = kvm_create_vm(); if (IS_ERR(kvm)) return PTR_ERR(kvm); - fd = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm); - if (fd < 0) + r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm); + if (r) { kvm_put_kvm(kvm); + return r; + } return fd; }