From a019e2a0c92c5223085fafceeb3c3bb505278612 Mon Sep 17 00:00:00 2001 From: Mark Huang Date: Sat, 20 Aug 2005 22:50:46 +0000 Subject: [PATCH] - sync fedora branch --- drivers/char/busmouse.c | 456 --- drivers/char/busmouse.h | 27 - drivers/i2c/i2c-sensor.c | 167 - drivers/media/dvb/dibusb/dvb-dibusb-pid.c | 80 - drivers/message/fusion/ascq_tbl.c | 2416 ------------- drivers/message/fusion/ascq_tbl.sh | 109 - drivers/message/fusion/isense.c | 119 - drivers/message/fusion/isense.h | 95 - drivers/message/fusion/scsi3.h | 707 ---- drivers/message/fusion/scsiops.c | 309 -- drivers/message/i2o/i2o_core.c | 3978 --------------------- drivers/mtd/maps/chestnut.c | 91 - drivers/scsi/dc390.h | 32 - drivers/usb/host/ohci-omap.h | 57 - drivers/usb/media/pwc-ctrl.c | 1644 --------- drivers/usb/media/pwc-if.c | 2193 ------------ drivers/usb/media/pwc-ioctl.h | 279 -- drivers/usb/media/pwc-misc.c | 146 - drivers/usb/media/pwc-uncompress.c | 180 - drivers/usb/media/pwc-uncompress.h | 84 - drivers/usb/media/pwc.h | 271 -- drivers/usb/media/pwc_kiara.h | 270 -- drivers/usb/media/pwc_nala.h | 66 - drivers/usb/media/pwc_timon.h | 270 -- 24 files changed, 14046 deletions(-) delete mode 100644 drivers/char/busmouse.c delete mode 100644 drivers/char/busmouse.h delete mode 100644 drivers/i2c/i2c-sensor.c delete mode 100644 drivers/media/dvb/dibusb/dvb-dibusb-pid.c delete mode 100644 drivers/message/fusion/ascq_tbl.c delete mode 100644 drivers/message/fusion/ascq_tbl.sh delete mode 100644 drivers/message/fusion/isense.c delete mode 100644 drivers/message/fusion/isense.h delete mode 100644 drivers/message/fusion/scsi3.h delete mode 100644 drivers/message/fusion/scsiops.c delete mode 100644 drivers/message/i2o/i2o_core.c delete mode 100644 drivers/mtd/maps/chestnut.c delete mode 100644 drivers/scsi/dc390.h delete mode 100644 drivers/usb/host/ohci-omap.h delete mode 100644 drivers/usb/media/pwc-ctrl.c delete mode 100644 drivers/usb/media/pwc-if.c delete mode 100644 drivers/usb/media/pwc-ioctl.h delete mode 100644 drivers/usb/media/pwc-misc.c delete mode 100644 drivers/usb/media/pwc-uncompress.c delete mode 100644 drivers/usb/media/pwc-uncompress.h delete mode 100644 drivers/usb/media/pwc.h delete mode 100644 drivers/usb/media/pwc_kiara.h delete mode 100644 drivers/usb/media/pwc_nala.h delete mode 100644 drivers/usb/media/pwc_timon.h diff --git a/drivers/char/busmouse.c b/drivers/char/busmouse.c deleted file mode 100644 index b0416f721..000000000 --- a/drivers/char/busmouse.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * linux/drivers/char/busmouse.c - * - * Copyright (C) 1995 - 1998 Russell King - * Protocol taken from original busmouse.c - * read() waiting taken from psaux.c - * - * Medium-level interface for quadrature or bus mice. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "busmouse.h" - -/* Uncomment this if your mouse drivers expect the kernel to - * return with EAGAIN if the mouse does not have any events - * available, even if the mouse is opened in blocking mode. - * Please report use of this "feature" to the author using the - * above address. - */ -/*#define BROKEN_MOUSE*/ - -struct busmouse_data { - struct miscdevice miscdev; - struct busmouse *ops; - spinlock_t lock; - - wait_queue_head_t wait; - struct fasync_struct *fasyncptr; - char active; - char buttons; - char ready; - int dxpos; - int dypos; -}; - -#define NR_MICE 15 -#define FIRST_MOUSE 0 -#define DEV_TO_MOUSE(inode) MINOR_TO_MOUSE(iminor(inode)) -#define MINOR_TO_MOUSE(minor) ((minor) - FIRST_MOUSE) - -/* - * List of mice and guarding semaphore. You must take the semaphore - * before you take the misc device semaphore if you need both - */ - -static struct busmouse_data *busmouse_data[NR_MICE]; -static DECLARE_MUTEX(mouse_sem); - -/** - * busmouse_add_movement - notification of a change of mouse position - * @mousedev: mouse number - * @dx: delta X movement - * @dy: delta Y movement - * @buttons: new button state - * - * Updates the mouse position and button information. The mousedev - * parameter is the value returned from register_busmouse. The - * movement information is updated, and the new button state is - * saved. A waiting user thread is woken. - */ - -void busmouse_add_movementbuttons(int mousedev, int dx, int dy, int buttons) -{ - struct busmouse_data *mse = busmouse_data[mousedev]; - int changed; - - spin_lock(&mse->lock); - changed = (dx != 0 || dy != 0 || mse->buttons != buttons); - - if (changed) { - add_mouse_randomness((buttons << 16) + (dy << 8) + dx); - - mse->buttons = buttons; - mse->dxpos += dx; - mse->dypos += dy; - mse->ready = 1; - - /* - * keep dx/dy reasonable, but still able to track when X (or - * whatever) must page or is busy (i.e. long waits between - * reads) - */ - if (mse->dxpos < -2048) - mse->dxpos = -2048; - if (mse->dxpos > 2048) - mse->dxpos = 2048; - if (mse->dypos < -2048) - mse->dypos = -2048; - if (mse->dypos > 2048) - mse->dypos = 2048; - } - - spin_unlock(&mse->lock); - - if (changed) { - wake_up(&mse->wait); - - kill_fasync(&mse->fasyncptr, SIGIO, POLL_IN); - } -} - -/** - * busmouse_add_movement - notification of a change of mouse position - * @mousedev: mouse number - * @dx: delta X movement - * @dy: delta Y movement - * - * Updates the mouse position. The mousedev parameter is the value - * returned from register_busmouse. The movement information is - * updated, and a waiting user thread is woken. - */ - -void busmouse_add_movement(int mousedev, int dx, int dy) -{ - struct busmouse_data *mse = busmouse_data[mousedev]; - - busmouse_add_movementbuttons(mousedev, dx, dy, mse->buttons); -} - -/** - * busmouse_add_buttons - notification of a change of button state - * @mousedev: mouse number - * @clear: mask of buttons to clear - * @eor: mask of buttons to change - * - * Updates the button state. The mousedev parameter is the value - * returned from register_busmouse. The buttons are updated by: - * new_state = (old_state & ~clear) ^ eor - * A waiting user thread is woken up. - */ - -void busmouse_add_buttons(int mousedev, int clear, int eor) -{ - struct busmouse_data *mse = busmouse_data[mousedev]; - - busmouse_add_movementbuttons(mousedev, 0, 0, (mse->buttons & ~clear) ^ eor); -} - -static int busmouse_fasync(int fd, struct file *filp, int on) -{ - struct busmouse_data *mse = (struct busmouse_data *)filp->private_data; - int retval; - - retval = fasync_helper(fd, filp, on, &mse->fasyncptr); - if (retval < 0) - return retval; - return 0; -} - -static int busmouse_release(struct inode *inode, struct file *file) -{ - struct busmouse_data *mse = (struct busmouse_data *)file->private_data; - int ret = 0; - - lock_kernel(); - busmouse_fasync(-1, file, 0); - - down(&mouse_sem); /* to protect mse->active */ - if (--mse->active == 0) { - if (mse->ops->release) - ret = mse->ops->release(inode, file); - module_put(mse->ops->owner); - mse->ready = 0; - } - unlock_kernel(); - up( &mouse_sem); - - return ret; -} - -static int busmouse_open(struct inode *inode, struct file *file) -{ - struct busmouse_data *mse; - unsigned int mousedev; - int ret; - - mousedev = DEV_TO_MOUSE(inode); - if (mousedev >= NR_MICE) - return -EINVAL; - - down(&mouse_sem); - mse = busmouse_data[mousedev]; - ret = -ENODEV; - if (!mse || !mse->ops) /* shouldn't happen, but... */ - goto end; - - if (!try_module_get(mse->ops->owner)) - goto end; - - ret = 0; - if (mse->ops->open) { - ret = mse->ops->open(inode, file); - if (ret) - module_put(mse->ops->owner); - } - - if (ret) - goto end; - - file->private_data = mse; - - if (mse->active++) - goto end; - - spin_lock_irq(&mse->lock); - - mse->ready = 0; - mse->dxpos = 0; - mse->dypos = 0; - mse->buttons = mse->ops->init_button_state; - - spin_unlock_irq(&mse->lock); -end: - up(&mouse_sem); - return ret; -} - -static ssize_t busmouse_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) -{ - return -EINVAL; -} - -static ssize_t busmouse_read(struct file *file, char *buffer, size_t count, loff_t *ppos) -{ - struct busmouse_data *mse = (struct busmouse_data *)file->private_data; - DECLARE_WAITQUEUE(wait, current); - int dxpos, dypos, buttons; - - if (count < 3) - return -EINVAL; - - spin_lock_irq(&mse->lock); - - if (!mse->ready) { -#ifdef BROKEN_MOUSE - spin_unlock_irq(&mse->lock); - return -EAGAIN; -#else - if (file->f_flags & O_NONBLOCK) { - spin_unlock_irq(&mse->lock); - return -EAGAIN; - } - - add_wait_queue(&mse->wait, &wait); -repeat: - set_current_state(TASK_INTERRUPTIBLE); - if (!mse->ready && !signal_pending(current)) { - spin_unlock_irq(&mse->lock); - schedule(); - spin_lock_irq(&mse->lock); - goto repeat; - } - - current->state = TASK_RUNNING; - remove_wait_queue(&mse->wait, &wait); - - if (signal_pending(current)) { - spin_unlock_irq(&mse->lock); - return -ERESTARTSYS; - } -#endif - } - - dxpos = mse->dxpos; - dypos = mse->dypos; - buttons = mse->buttons; - - if (dxpos < -127) - dxpos =- 127; - if (dxpos > 127) - dxpos = 127; - if (dypos < -127) - dypos =- 127; - if (dypos > 127) - dypos = 127; - - mse->dxpos -= dxpos; - mse->dypos -= dypos; - - /* This is something that many drivers have apparantly - * forgotten... If the X and Y positions still contain - * information, we still have some info ready for the - * user program... - */ - mse->ready = mse->dxpos || mse->dypos; - - spin_unlock_irq(&mse->lock); - - /* Write out data to the user. Format is: - * byte 0 - identifer (0x80) and (inverted) mouse buttons - * byte 1 - X delta position +/- 127 - * byte 2 - Y delta position +/- 127 - */ - if (put_user((char)buttons | 128, buffer) || - put_user((char)dxpos, buffer + 1) || - put_user((char)dypos, buffer + 2)) - return -EFAULT; - - if (count > 3 && clear_user(buffer + 3, count - 3)) - return -EFAULT; - - file->f_dentry->d_inode->i_atime = CURRENT_TIME; - - return count; -} - -/* No kernel lock held - fine */ -static unsigned int busmouse_poll(struct file *file, poll_table *wait) -{ - struct busmouse_data *mse = (struct busmouse_data *)file->private_data; - - poll_wait(file, &mse->wait, wait); - - if (mse->ready) - return POLLIN | POLLRDNORM; - - return 0; -} - -struct file_operations busmouse_fops= -{ - .owner = THIS_MODULE, - .read = busmouse_read, - .write = busmouse_write, - .poll = busmouse_poll, - .open = busmouse_open, - .release = busmouse_release, - .fasync = busmouse_fasync, -}; - -/** - * register_busmouse - register a bus mouse interface - * @ops: busmouse structure for the mouse - * - * Registers a mouse with the driver. The return is mouse number on - * success and a negative errno code on an error. The passed ops - * structure most not be freed until the mouser is unregistered - */ - -int register_busmouse(struct busmouse *ops) -{ - unsigned int msedev = MINOR_TO_MOUSE(ops->minor); - struct busmouse_data *mse; - int ret = -EINVAL; - - if (msedev >= NR_MICE) { - printk(KERN_ERR "busmouse: trying to allocate mouse on minor %d\n", - ops->minor); - goto out; - } - - ret = -ENOMEM; - mse = kmalloc(sizeof(*mse), GFP_KERNEL); - if (!mse) - goto out; - - down(&mouse_sem); - ret = -EBUSY; - if (busmouse_data[msedev]) - goto freemem; - - memset(mse, 0, sizeof(*mse)); - - mse->miscdev.minor = ops->minor; - mse->miscdev.name = ops->name; - mse->miscdev.fops = &busmouse_fops; - mse->ops = ops; - mse->lock = (spinlock_t)SPIN_LOCK_UNLOCKED; - init_waitqueue_head(&mse->wait); - - - ret = misc_register(&mse->miscdev); - - if (ret < 0) - goto freemem; - - busmouse_data[msedev] = mse; - ret = msedev; -out: - up(&mouse_sem); - return ret; - - -freemem: - kfree(mse); - goto out; -} - -/** - * unregister_busmouse - unregister a bus mouse interface - * @mousedev: Mouse number to release - * - * Unregister a previously installed mouse handler. The mousedev - * passed is the return code from a previous call to register_busmouse - */ - - -int unregister_busmouse(int mousedev) -{ - int err = -EINVAL; - - if (mousedev < 0) - return 0; - if (mousedev >= NR_MICE) { - printk(KERN_ERR "busmouse: trying to free mouse on" - " mousedev %d\n", mousedev); - return -EINVAL; - } - - down(&mouse_sem); - - if (!busmouse_data[mousedev]) { - printk(KERN_WARNING "busmouse: trying to free free mouse" - " on mousedev %d\n", mousedev); - goto fail; - } - - if (busmouse_data[mousedev]->active) { - printk(KERN_ERR "busmouse: trying to free active mouse" - " on mousedev %d\n", mousedev); - goto fail; - } - - err = misc_deregister(&busmouse_data[mousedev]->miscdev); - - kfree(busmouse_data[mousedev]); - busmouse_data[mousedev] = NULL; -fail: - up(&mouse_sem); - return err; -} - -EXPORT_SYMBOL(busmouse_add_movementbuttons); -EXPORT_SYMBOL(busmouse_add_movement); -EXPORT_SYMBOL(busmouse_add_buttons); -EXPORT_SYMBOL(register_busmouse); -EXPORT_SYMBOL(unregister_busmouse); - -MODULE_ALIAS_MISCDEV(BUSMOUSE_MINOR); -MODULE_LICENSE("GPL"); diff --git a/drivers/char/busmouse.h b/drivers/char/busmouse.h deleted file mode 100644 index 487c4820d..000000000 --- a/drivers/char/busmouse.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * linux/drivers/char/busmouse.h - * - * Copyright (C) 1995 - 1998 Russell King - * - * Prototypes for generic busmouse interface - */ -#ifndef BUSMOUSE_H -#define BUSMOUSE_H - -struct busmouse { - int minor; - const char *name; - struct module *owner; - int (*open)(struct inode * inode, struct file * file); - int (*release)(struct inode * inode, struct file * file); - int init_button_state; -}; - -extern void busmouse_add_movementbuttons(int mousedev, int dx, int dy, int buttons); -extern void busmouse_add_movement(int mousedev, int dx, int dy); -extern void busmouse_add_buttons(int mousedev, int clear, int eor); - -extern int register_busmouse(struct busmouse *ops); -extern int unregister_busmouse(int mousedev); - -#endif diff --git a/drivers/i2c/i2c-sensor.c b/drivers/i2c/i2c-sensor.c deleted file mode 100644 index b9714c6ec..000000000 --- a/drivers/i2c/i2c-sensor.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - i2c-sensor.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 1998 - 2001 Frodo Looijaard and - Mark D. Studebaker - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* Very inefficient for ISA detects, and won't work for 10-bit addresses! */ -int i2c_detect(struct i2c_adapter *adapter, - struct i2c_address_data *address_data, - int (*found_proc) (struct i2c_adapter *, int, int)) -{ - int addr, i, found, j, err; - struct i2c_force_data *this_force; - int is_isa = i2c_is_isa_adapter(adapter); - int adapter_id = - is_isa ? ANY_I2C_ISA_BUS : i2c_adapter_id(adapter); - - /* Forget it if we can't probe using SMBUS_QUICK */ - if ((!is_isa) && - !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) - return -1; - - for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) { - if (!is_isa && i2c_check_addr(adapter, addr)) - continue; - - /* If it is in one of the force entries, we don't do any - detection at all */ - found = 0; - for (i = 0; !found && (this_force = address_data->forces + i, this_force->force); i++) { - for (j = 0; !found && (this_force->force[j] != I2C_CLIENT_END); j += 2) { - if ( ((adapter_id == this_force->force[j]) || - ((this_force->force[j] == ANY_I2C_BUS) && !is_isa)) && - (addr == this_force->force[j + 1]) ) { - dev_dbg(&adapter->dev, "found force parameter for adapter %d, addr %04x\n", adapter_id, addr); - if ((err = found_proc(adapter, addr, this_force->kind))) - return err; - found = 1; - } - } - } - if (found) - continue; - - /* If this address is in one of the ignores, we can forget about it - right now */ - for (i = 0; !found && (address_data->ignore[i] != I2C_CLIENT_END); i += 2) { - if ( ((adapter_id == address_data->ignore[i]) || - ((address_data->ignore[i] == ANY_I2C_BUS) && - !is_isa)) && - (addr == address_data->ignore[i + 1])) { - dev_dbg(&adapter->dev, "found ignore parameter for adapter %d, addr %04x\n", adapter_id, addr); - found = 1; - } - } - for (i = 0; !found && (address_data->ignore_range[i] != I2C_CLIENT_END); i += 3) { - if ( ((adapter_id == address_data->ignore_range[i]) || - ((address_data-> ignore_range[i] == ANY_I2C_BUS) & - !is_isa)) && - (addr >= address_data->ignore_range[i + 1]) && - (addr <= address_data->ignore_range[i + 2])) { - dev_dbg(&adapter->dev, "found ignore_range parameter for adapter %d, addr %04x\n", adapter_id, addr); - found = 1; - } - } - if (found) - continue; - - /* Now, we will do a detection, but only if it is in the normal or - probe entries */ - if (is_isa) { - for (i = 0; !found && (address_data->normal_isa[i] != I2C_CLIENT_ISA_END); i += 1) { - if (addr == address_data->normal_isa[i]) { - dev_dbg(&adapter->dev, "found normal isa entry for adapter %d, addr %04x\n", adapter_id, addr); - found = 1; - } - } - for (i = 0; !found && (address_data->normal_isa_range[i] != I2C_CLIENT_ISA_END); i += 3) { - if ((addr >= address_data->normal_isa_range[i]) && - (addr <= address_data->normal_isa_range[i + 1]) && - ((addr - address_data->normal_isa_range[i]) % address_data->normal_isa_range[i + 2] == 0)) { - dev_dbg(&adapter->dev, "found normal isa_range entry for adapter %d, addr %04x", adapter_id, addr); - found = 1; - } - } - } else { - for (i = 0; !found && (address_data->normal_i2c[i] != I2C_CLIENT_END); i += 1) { - if (addr == address_data->normal_i2c[i]) { - found = 1; - dev_dbg(&adapter->dev, "found normal i2c entry for adapter %d, addr %02x", adapter_id, addr); - } - } - for (i = 0; !found && (address_data->normal_i2c_range[i] != I2C_CLIENT_END); i += 2) { - if ((addr >= address_data->normal_i2c_range[i]) && - (addr <= address_data->normal_i2c_range[i + 1])) { - dev_dbg(&adapter->dev, "found normal i2c_range entry for adapter %d, addr %04x\n", adapter_id, addr); - found = 1; - } - } - } - - for (i = 0; - !found && (address_data->probe[i] != I2C_CLIENT_END); - i += 2) { - if (((adapter_id == address_data->probe[i]) || - ((address_data-> - probe[i] == ANY_I2C_BUS) && !is_isa)) - && (addr == address_data->probe[i + 1])) { - dev_dbg(&adapter->dev, "found probe parameter for adapter %d, addr %04x\n", adapter_id, addr); - found = 1; - } - } - for (i = 0; !found && (address_data->probe_range[i] != I2C_CLIENT_END); i += 3) { - if ( ((adapter_id == address_data->probe_range[i]) || - ((address_data->probe_range[i] == ANY_I2C_BUS) && !is_isa)) && - (addr >= address_data->probe_range[i + 1]) && - (addr <= address_data->probe_range[i + 2])) { - found = 1; - dev_dbg(&adapter->dev, "found probe_range parameter for adapter %d, addr %04x\n", adapter_id, addr); - } - } - if (!found) - continue; - - /* OK, so we really should examine this address. First check - whether there is some client here at all! */ - if (is_isa || - (i2c_smbus_xfer (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) >= 0)) - if ((err = found_proc(adapter, addr, -1))) - return err; - } - return 0; -} - -EXPORT_SYMBOL(i2c_detect); - -MODULE_AUTHOR("Frodo Looijaard "); -MODULE_DESCRIPTION("i2c-sensor driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-pid.c b/drivers/media/dvb/dibusb/dvb-dibusb-pid.c deleted file mode 100644 index 91a39541d..000000000 --- a/drivers/media/dvb/dibusb/dvb-dibusb-pid.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * dvb-dibusb-pid.c is part of the driver for mobile USB Budget DVB-T devices - * based on reference design made by DiBcom (http://www.dibcom.fr/) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * see dvb-dibusb-core.c for more copyright details. - * - * This file contains functions for initializing and handling the internal - * pid-list. This pid-list mirrors the information currently stored in the - * devices pid-list. - */ -#include "dvb-dibusb.h" - -int dibusb_pid_list_init(struct usb_dibusb *dib) -{ - int i; - dib->pid_list = kmalloc(sizeof(struct dibusb_pid) * dib->dibdev->dev_cl->demod->pid_filter_count,GFP_KERNEL); - if (dib->pid_list == NULL) - return -ENOMEM; - - deb_xfer("initializing %d pids for the pid_list.\n",dib->dibdev->dev_cl->demod->pid_filter_count); - - dib->pid_list_lock = SPIN_LOCK_UNLOCKED; - memset(dib->pid_list,0,dib->dibdev->dev_cl->demod->pid_filter_count*(sizeof(struct dibusb_pid))); - for (i=0; i < dib->dibdev->dev_cl->demod->pid_filter_count; i++) { - dib->pid_list[i].index = i; - dib->pid_list[i].pid = 0; - dib->pid_list[i].active = 0; - } - - dib->init_state |= DIBUSB_STATE_PIDLIST; - return 0; -} - -void dibusb_pid_list_exit(struct usb_dibusb *dib) -{ - if (dib->init_state & DIBUSB_STATE_PIDLIST) - kfree(dib->pid_list); - dib->init_state &= ~DIBUSB_STATE_PIDLIST; -} - -/* fetch a pid from pid_list and set it on or off */ -int dibusb_ctrl_pid(struct usb_dibusb *dib, struct dvb_demux_feed *dvbdmxfeed , int onoff) -{ - int i,ret = -1; - unsigned long flags; - u16 pid = dvbdmxfeed->pid; - - if (onoff) { - spin_lock_irqsave(&dib->pid_list_lock,flags); - for (i=0; i < dib->dibdev->dev_cl->demod->pid_filter_count; i++) - if (!dib->pid_list[i].active) { - dib->pid_list[i].pid = pid; - dib->pid_list[i].active = 1; - ret = i; - break; - } - dvbdmxfeed->priv = &dib->pid_list[ret]; - spin_unlock_irqrestore(&dib->pid_list_lock,flags); - - if (dib->xfer_ops.pid_ctrl != NULL) - dib->xfer_ops.pid_ctrl(dib->fe,dib->pid_list[ret].index,dib->pid_list[ret].pid,1); - } else { - struct dibusb_pid *dpid = dvbdmxfeed->priv; - - if (dib->xfer_ops.pid_ctrl != NULL) - dib->xfer_ops.pid_ctrl(dib->fe,dpid->index,0,0); - - dpid->pid = 0; - dpid->active = 0; - ret = dpid->index; - } - - /* a free pid from the list */ - deb_info("setting pid: %5d %04x at index %d '%s'\n",pid,pid,ret,onoff ? "on" : "off"); - - return ret; -} - diff --git a/drivers/message/fusion/ascq_tbl.c b/drivers/message/fusion/ascq_tbl.c deleted file mode 100644 index 210c4e74b..000000000 --- a/drivers/message/fusion/ascq_tbl.c +++ /dev/null @@ -1,2416 +0,0 @@ -#ifndef SCSI_ASCQ_TBL_C_INCLUDED -#define SCSI_ASCQ_TBL_C_INCLUDED - -/* AuToMaGiCaLlY generated from: "t10.org/asc-num.txt" - ******************************************************************************* - * File: ASC-NUM.TXT - * - * SCSI ASC/ASCQ Assignments - * Numeric Sorted Listing - * as of 5/18/00 - * - * D - DIRECT ACCESS DEVICE (SBC-2) device column key - * .T - SEQUENTIAL ACCESS DEVICE (SSC) ------------------- - * . L - PRINTER DEVICE (SSC) blank = reserved - * . P - PROCESSOR DEVICE (SPC) not blank = allowed - * . .W - WRITE ONCE READ MULTIPLE DEVICE (SBC-2) - * . . R - CD DEVICE (MMC) - * . . S - SCANNER DEVICE (SCSI-2) - * . . .O - OPTICAL MEMORY DEVICE (SBC-2) - * . . . M - MEDIA CHANGER DEVICE (SMC) - * . . . C - COMMUNICATION DEVICE (SCSI-2) - * . . . .A - STORAGE ARRAY DEVICE (SCC) - * . . . . E - ENCLOSURE SERVICES DEVICE (SES) - * . . . . B - SIMPLIFIED DIRECT-ACCESS DEVICE (RBC) - * . . . . .K - OPTICAL CARD READER/WRITER DEVICE (OCRW) - * ASC/ASCQ DTLPWRSOMCAEBK Description - * ------- -------------- ---------------------------------------------------- - */ - -static char SenseDevTypes001[] = "DTLPWRSOMCAEBK"; -static char SenseDevTypes002[] = ".T............"; -static char SenseDevTypes003[] = ".T....S......."; -static char SenseDevTypes004[] = ".TL...S......."; -static char SenseDevTypes005[] = ".....R........"; -static char SenseDevTypes006[] = "DTL.WRSOM.AEBK"; -static char SenseDevTypes007[] = "D...W..O....BK"; -static char SenseDevTypes008[] = "D...WR.OM...BK"; -static char SenseDevTypes009[] = "DTL.W.SO....BK"; -static char SenseDevTypes010[] = "DTL..R.O....B."; -static char SenseDevTypes011[] = "DT..W..OMCA.BK"; -static char SenseDevTypes012[] = ".............."; -static char SenseDevTypes013[] = "DTL.WRSOMCAEBK"; -static char SenseDevTypes014[] = "DTL.WRSOM...BK"; -static char SenseDevTypes015[] = "DT...R.OM...BK"; -static char SenseDevTypes016[] = "DTLPWRSO.C...K"; -static char SenseDevTypes017[] = "DT..WR.O....B."; -static char SenseDevTypes018[] = "....WR.O.....K"; -static char SenseDevTypes019[] = "....WR.O......"; -static char SenseDevTypes020[] = ".T...RS......."; -static char SenseDevTypes021[] = ".............K"; -static char SenseDevTypes022[] = "DT..W..O....B."; -static char SenseDevTypes023[] = "DT..WRSO....BK"; -static char SenseDevTypes024[] = "DT..W.SO....BK"; -static char SenseDevTypes025[] = "....WR.O....B."; -static char SenseDevTypes026[] = "....W..O....B."; -static char SenseDevTypes027[] = "DT.....O....BK"; -static char SenseDevTypes028[] = "DTL.WRSO....BK"; -static char SenseDevTypes029[] = "DT..WR.O....BK"; -static char SenseDevTypes030[] = "DT..W..O....BK"; -static char SenseDevTypes031[] = "D...WR.O....BK"; -static char SenseDevTypes032[] = "D......O.....K"; -static char SenseDevTypes033[] = "D......O....BK"; -static char SenseDevTypes034[] = "DT..WR.OM...BK"; -static char SenseDevTypes035[] = "D............."; -static char SenseDevTypes036[] = "DTLPWRSOMCAE.K"; -static char SenseDevTypes037[] = "DTLPWRSOMCA.BK"; -static char SenseDevTypes038[] = ".T...R........"; -static char SenseDevTypes039[] = "DT..WR.OM...B."; -static char SenseDevTypes040[] = "DTL.WRSOMCAE.K"; -static char SenseDevTypes041[] = "DTLPWRSOMCAE.."; -static char SenseDevTypes042[] = "......S......."; -static char SenseDevTypes043[] = "............B."; -static char SenseDevTypes044[] = "DTLPWRSO.CA..K"; -static char SenseDevTypes045[] = "DT...R.......K"; -static char SenseDevTypes046[] = "D.L..R.O....B."; -static char SenseDevTypes047[] = "..L..........."; -static char SenseDevTypes048[] = ".TL..........."; -static char SenseDevTypes049[] = "DTLPWRSOMC..BK"; -static char SenseDevTypes050[] = "DT..WR.OMCAEBK"; -static char SenseDevTypes051[] = "DT..WR.OMCAEB."; -static char SenseDevTypes052[] = ".T...R.O......"; -static char SenseDevTypes053[] = "...P.........."; -static char SenseDevTypes054[] = "DTLPWRSOM.AE.K"; -static char SenseDevTypes055[] = "DTLPWRSOM.AE.."; -static char SenseDevTypes056[] = ".......O......"; -static char SenseDevTypes057[] = "DTLPWRSOM...BK"; -static char SenseDevTypes058[] = "DT..WR.O..A.BK"; -static char SenseDevTypes059[] = "DTLPWRSOM....K"; -static char SenseDevTypes060[] = "D......O......"; -static char SenseDevTypes061[] = ".....R......B."; -static char SenseDevTypes062[] = "D...........B."; -static char SenseDevTypes063[] = "............BK"; -static char SenseDevTypes064[] = "..........A..."; - -static ASCQ_Table_t ASCQ_Table[] = { - { - 0x00, 0x00, - SenseDevTypes001, - "NO ADDITIONAL SENSE INFORMATION" - }, - { - 0x00, 0x01, - SenseDevTypes002, - "FILEMARK DETECTED" - }, - { - 0x00, 0x02, - SenseDevTypes003, - "END-OF-PARTITION/MEDIUM DETECTED" - }, - { - 0x00, 0x03, - SenseDevTypes002, - "SETMARK DETECTED" - }, - { - 0x00, 0x04, - SenseDevTypes003, - "BEGINNING-OF-PARTITION/MEDIUM DETECTED" - }, - { - 0x00, 0x05, - SenseDevTypes004, - "END-OF-DATA DETECTED" - }, - { - 0x00, 0x06, - SenseDevTypes001, - "I/O PROCESS TERMINATED" - }, - { - 0x00, 0x11, - SenseDevTypes005, - "AUDIO PLAY OPERATION IN PROGRESS" - }, - { - 0x00, 0x12, - SenseDevTypes005, - "AUDIO PLAY OPERATION PAUSED" - }, - { - 0x00, 0x13, - SenseDevTypes005, - "AUDIO PLAY OPERATION SUCCESSFULLY COMPLETED" - }, - { - 0x00, 0x14, - SenseDevTypes005, - "AUDIO PLAY OPERATION STOPPED DUE TO ERROR" - }, - { - 0x00, 0x15, - SenseDevTypes005, - "NO CURRENT AUDIO STATUS TO RETURN" - }, - { - 0x00, 0x16, - SenseDevTypes001, - "OPERATION IN PROGRESS" - }, - { - 0x00, 0x17, - SenseDevTypes006, - "CLEANING REQUESTED" - }, - { - 0x01, 0x00, - SenseDevTypes007, - "NO INDEX/SECTOR SIGNAL" - }, - { - 0x02, 0x00, - SenseDevTypes008, - "NO SEEK COMPLETE" - }, - { - 0x03, 0x00, - SenseDevTypes009, - "PERIPHERAL DEVICE WRITE FAULT" - }, - { - 0x03, 0x01, - SenseDevTypes002, - "NO WRITE CURRENT" - }, - { - 0x03, 0x02, - SenseDevTypes002, - "EXCESSIVE WRITE ERRORS" - }, - { - 0x04, 0x00, - SenseDevTypes001, - "LOGICAL UNIT NOT READY, CAUSE NOT REPORTABLE" - }, - { - 0x04, 0x01, - SenseDevTypes001, - "LOGICAL UNIT IS IN PROCESS OF BECOMING READY" - }, - { - 0x04, 0x02, - SenseDevTypes001, - "LOGICAL UNIT NOT READY, INITIALIZING CMD. REQUIRED" - }, - { - 0x04, 0x03, - SenseDevTypes001, - "LOGICAL UNIT NOT READY, MANUAL INTERVENTION REQUIRED" - }, - { - 0x04, 0x04, - SenseDevTypes010, - "LOGICAL UNIT NOT READY, FORMAT IN PROGRESS" - }, - { - 0x04, 0x05, - SenseDevTypes011, - "LOGICAL UNIT NOT READY, REBUILD IN PROGRESS" - }, - { - 0x04, 0x06, - SenseDevTypes011, - "LOGICAL UNIT NOT READY, RECALCULATION IN PROGRESS" - }, - { - 0x04, 0x07, - SenseDevTypes001, - "LOGICAL UNIT NOT READY, OPERATION IN PROGRESS" - }, - { - 0x04, 0x08, - SenseDevTypes005, - "LOGICAL UNIT NOT READY, LONG WRITE IN PROGRESS" - }, - { - 0x04, 0x09, - SenseDevTypes001, - "LOGICAL UNIT NOT READY, SELF-TEST IN PROGRESS" - }, - { - 0x04, 0x10, - SenseDevTypes012, - "auxiliary memory code 2 (99-148) [proposed]" - }, - { - 0x05, 0x00, - SenseDevTypes013, - "LOGICAL UNIT DOES NOT RESPOND TO SELECTION" - }, - { - 0x06, 0x00, - SenseDevTypes008, - "NO REFERENCE POSITION FOUND" - }, - { - 0x07, 0x00, - SenseDevTypes014, - "MULTIPLE PERIPHERAL DEVICES SELECTED" - }, - { - 0x08, 0x00, - SenseDevTypes013, - "LOGICAL UNIT COMMUNICATION FAILURE" - }, - { - 0x08, 0x01, - SenseDevTypes013, - "LOGICAL UNIT COMMUNICATION TIME-OUT" - }, - { - 0x08, 0x02, - SenseDevTypes013, - "LOGICAL UNIT COMMUNICATION PARITY ERROR" - }, - { - 0x08, 0x03, - SenseDevTypes015, - "LOGICAL UNIT COMMUNICATION CRC ERROR (ULTRA-DMA/32)" - }, - { - 0x08, 0x04, - SenseDevTypes016, - "UNREACHABLE COPY TARGET" - }, - { - 0x09, 0x00, - SenseDevTypes017, - "TRACK FOLLOWING ERROR" - }, - { - 0x09, 0x01, - SenseDevTypes018, - "TRACKING SERVO FAILURE" - }, - { - 0x09, 0x02, - SenseDevTypes018, - "FOCUS SERVO FAILURE" - }, - { - 0x09, 0x03, - SenseDevTypes019, - "SPINDLE SERVO FAILURE" - }, - { - 0x09, 0x04, - SenseDevTypes017, - "HEAD SELECT FAULT" - }, - { - 0x0A, 0x00, - SenseDevTypes001, - "ERROR LOG OVERFLOW" - }, - { - 0x0B, 0x00, - SenseDevTypes001, - "WARNING" - }, - { - 0x0B, 0x01, - SenseDevTypes001, - "WARNING - SPECIFIED TEMPERATURE EXCEEDED" - }, - { - 0x0B, 0x02, - SenseDevTypes001, - "WARNING - ENCLOSURE DEGRADED" - }, - { - 0x0C, 0x00, - SenseDevTypes020, - "WRITE ERROR" - }, - { - 0x0C, 0x01, - SenseDevTypes021, - "WRITE ERROR - RECOVERED WITH AUTO REALLOCATION" - }, - { - 0x0C, 0x02, - SenseDevTypes007, - "WRITE ERROR - AUTO REALLOCATION FAILED" - }, - { - 0x0C, 0x03, - SenseDevTypes007, - "WRITE ERROR - RECOMMEND REASSIGNMENT" - }, - { - 0x0C, 0x04, - SenseDevTypes022, - "COMPRESSION CHECK MISCOMPARE ERROR" - }, - { - 0x0C, 0x05, - SenseDevTypes022, - "DATA EXPANSION OCCURRED DURING COMPRESSION" - }, - { - 0x0C, 0x06, - SenseDevTypes022, - "BLOCK NOT COMPRESSIBLE" - }, - { - 0x0C, 0x07, - SenseDevTypes005, - "WRITE ERROR - RECOVERY NEEDED" - }, - { - 0x0C, 0x08, - SenseDevTypes005, - "WRITE ERROR - RECOVERY FAILED" - }, - { - 0x0C, 0x09, - SenseDevTypes005, - "WRITE ERROR - LOSS OF STREAMING" - }, - { - 0x0C, 0x0A, - SenseDevTypes005, - "WRITE ERROR - PADDING BLOCKS ADDED" - }, - { - 0x0C, 0x0B, - SenseDevTypes012, - "auxiliary memory code 4 (99-148) [proposed]" - }, - { - 0x10, 0x00, - SenseDevTypes007, - "ID CRC OR ECC ERROR" - }, - { - 0x11, 0x00, - SenseDevTypes023, - "UNRECOVERED READ ERROR" - }, - { - 0x11, 0x01, - SenseDevTypes023, - "READ RETRIES EXHAUSTED" - }, - { - 0x11, 0x02, - SenseDevTypes023, - "ERROR TOO LONG TO CORRECT" - }, - { - 0x11, 0x03, - SenseDevTypes024, - "MULTIPLE READ ERRORS" - }, - { - 0x11, 0x04, - SenseDevTypes007, - "UNRECOVERED READ ERROR - AUTO REALLOCATE FAILED" - }, - { - 0x11, 0x05, - SenseDevTypes025, - "L-EC UNCORRECTABLE ERROR" - }, - { - 0x11, 0x06, - SenseDevTypes025, - "CIRC UNRECOVERED ERROR" - }, - { - 0x11, 0x07, - SenseDevTypes026, - "DATA RE-SYNCHRONIZATION ERROR" - }, - { - 0x11, 0x08, - SenseDevTypes002, - "INCOMPLETE BLOCK READ" - }, - { - 0x11, 0x09, - SenseDevTypes002, - "NO GAP FOUND" - }, - { - 0x11, 0x0A, - SenseDevTypes027, - "MISCORRECTED ERROR" - }, - { - 0x11, 0x0B, - SenseDevTypes007, - "UNRECOVERED READ ERROR - RECOMMEND REASSIGNMENT" - }, - { - 0x11, 0x0C, - SenseDevTypes007, - "UNRECOVERED READ ERROR - RECOMMEND REWRITE THE DATA" - }, - { - 0x11, 0x0D, - SenseDevTypes017, - "DE-COMPRESSION CRC ERROR" - }, - { - 0x11, 0x0E, - SenseDevTypes017, - "CANNOT DECOMPRESS USING DECLARED ALGORITHM" - }, - { - 0x11, 0x0F, - SenseDevTypes005, - "ERROR READING UPC/EAN NUMBER" - }, - { - 0x11, 0x10, - SenseDevTypes005, - "ERROR READING ISRC NUMBER" - }, - { - 0x11, 0x11, - SenseDevTypes005, - "READ ERROR - LOSS OF STREAMING" - }, - { - 0x11, 0x12, - SenseDevTypes012, - "auxiliary memory code 3 (99-148) [proposed]" - }, - { - 0x12, 0x00, - SenseDevTypes007, - "ADDRESS MARK NOT FOUND FOR ID FIELD" - }, - { - 0x13, 0x00, - SenseDevTypes007, - "ADDRESS MARK NOT FOUND FOR DATA FIELD" - }, - { - 0x14, 0x00, - SenseDevTypes028, - "RECORDED ENTITY NOT FOUND" - }, - { - 0x14, 0x01, - SenseDevTypes029, - "RECORD NOT FOUND" - }, - { - 0x14, 0x02, - SenseDevTypes002, - "FILEMARK OR SETMARK NOT FOUND" - }, - { - 0x14, 0x03, - SenseDevTypes002, - "END-OF-DATA NOT FOUND" - }, - { - 0x14, 0x04, - SenseDevTypes002, - "BLOCK SEQUENCE ERROR" - }, - { - 0x14, 0x05, - SenseDevTypes030, - "RECORD NOT FOUND - RECOMMEND REASSIGNMENT" - }, - { - 0x14, 0x06, - SenseDevTypes030, - "RECORD NOT FOUND - DATA AUTO-REALLOCATED" - }, - { - 0x15, 0x00, - SenseDevTypes014, - "RANDOM POSITIONING ERROR" - }, - { - 0x15, 0x01, - SenseDevTypes014, - "MECHANICAL POSITIONING ERROR" - }, - { - 0x15, 0x02, - SenseDevTypes029, - "POSITIONING ERROR DETECTED BY READ OF MEDIUM" - }, - { - 0x16, 0x00, - SenseDevTypes007, - "DATA SYNCHRONIZATION MARK ERROR" - }, - { - 0x16, 0x01, - SenseDevTypes007, - "DATA SYNC ERROR - DATA REWRITTEN" - }, - { - 0x16, 0x02, - SenseDevTypes007, - "DATA SYNC ERROR - RECOMMEND REWRITE" - }, - { - 0x16, 0x03, - SenseDevTypes007, - "DATA SYNC ERROR - DATA AUTO-REALLOCATED" - }, - { - 0x16, 0x04, - SenseDevTypes007, - "DATA SYNC ERROR - RECOMMEND REASSIGNMENT" - }, - { - 0x17, 0x00, - SenseDevTypes023, - "RECOVERED DATA WITH NO ERROR CORRECTION APPLIED" - }, - { - 0x17, 0x01, - SenseDevTypes023, - "RECOVERED DATA WITH RETRIES" - }, - { - 0x17, 0x02, - SenseDevTypes029, - "RECOVERED DATA WITH POSITIVE HEAD OFFSET" - }, - { - 0x17, 0x03, - SenseDevTypes029, - "RECOVERED DATA WITH NEGATIVE HEAD OFFSET" - }, - { - 0x17, 0x04, - SenseDevTypes025, - "RECOVERED DATA WITH RETRIES AND/OR CIRC APPLIED" - }, - { - 0x17, 0x05, - SenseDevTypes031, - "RECOVERED DATA USING PREVIOUS SECTOR ID" - }, - { - 0x17, 0x06, - SenseDevTypes007, - "RECOVERED DATA WITHOUT ECC - DATA AUTO-REALLOCATED" - }, - { - 0x17, 0x07, - SenseDevTypes031, - "RECOVERED DATA WITHOUT ECC - RECOMMEND REASSIGNMENT" - }, - { - 0x17, 0x08, - SenseDevTypes031, - "RECOVERED DATA WITHOUT ECC - RECOMMEND REWRITE" - }, - { - 0x17, 0x09, - SenseDevTypes031, - "RECOVERED DATA WITHOUT ECC - DATA REWRITTEN" - }, - { - 0x18, 0x00, - SenseDevTypes029, - "RECOVERED DATA WITH ERROR CORRECTION APPLIED" - }, - { - 0x18, 0x01, - SenseDevTypes031, - "RECOVERED DATA WITH ERROR CORR. & RETRIES APPLIED" - }, - { - 0x18, 0x02, - SenseDevTypes031, - "RECOVERED DATA - DATA AUTO-REALLOCATED" - }, - { - 0x18, 0x03, - SenseDevTypes005, - "RECOVERED DATA WITH CIRC" - }, - { - 0x18, 0x04, - SenseDevTypes005, - "RECOVERED DATA WITH L-EC" - }, - { - 0x18, 0x05, - SenseDevTypes031, - "RECOVERED DATA - RECOMMEND REASSIGNMENT" - }, - { - 0x18, 0x06, - SenseDevTypes031, - "RECOVERED DATA - RECOMMEND REWRITE" - }, - { - 0x18, 0x07, - SenseDevTypes007, - "RECOVERED DATA WITH ECC - DATA REWRITTEN" - }, - { - 0x19, 0x00, - SenseDevTypes032, - "DEFECT LIST ERROR" - }, - { - 0x19, 0x01, - SenseDevTypes032, - "DEFECT LIST NOT AVAILABLE" - }, - { - 0x19, 0x02, - SenseDevTypes032, - "DEFECT LIST ERROR IN PRIMARY LIST" - }, - { - 0x19, 0x03, - SenseDevTypes032, - "DEFECT LIST ERROR IN GROWN LIST" - }, - { - 0x1A, 0x00, - SenseDevTypes001, - "PARAMETER LIST LENGTH ERROR" - }, - { - 0x1B, 0x00, - SenseDevTypes001, - "SYNCHRONOUS DATA TRANSFER ERROR" - }, - { - 0x1C, 0x00, - SenseDevTypes033, - "DEFECT LIST NOT FOUND" - }, - { - 0x1C, 0x01, - SenseDevTypes033, - "PRIMARY DEFECT LIST NOT FOUND" - }, - { - 0x1C, 0x02, - SenseDevTypes033, - "GROWN DEFECT LIST NOT FOUND" - }, - { - 0x1D, 0x00, - SenseDevTypes029, - "MISCOMPARE DURING VERIFY OPERATION" - }, - { - 0x1E, 0x00, - SenseDevTypes007, - "RECOVERED ID WITH ECC CORRECTION" - }, - { - 0x1F, 0x00, - SenseDevTypes032, - "PARTIAL DEFECT LIST TRANSFER" - }, - { - 0x20, 0x00, - SenseDevTypes001, - "INVALID COMMAND OPERATION CODE" - }, - { - 0x20, 0x01, - SenseDevTypes012, - "access controls code 1 (99-314) [proposed]" - }, - { - 0x20, 0x02, - SenseDevTypes012, - "access controls code 2 (99-314) [proposed]" - }, - { - 0x20, 0x03, - SenseDevTypes012, - "access controls code 3 (99-314) [proposed]" - }, - { - 0x21, 0x00, - SenseDevTypes034, - "LOGICAL BLOCK ADDRESS OUT OF RANGE" - }, - { - 0x21, 0x01, - SenseDevTypes034, - "INVALID ELEMENT ADDRESS" - }, - { - 0x22, 0x00, - SenseDevTypes035, - "ILLEGAL FUNCTION (USE 20 00, 24 00, OR 26 00)" - }, - { - 0x24, 0x00, - SenseDevTypes001, - "INVALID FIELD IN CDB" - }, - { - 0x24, 0x01, - SenseDevTypes001, - "CDB DECRYPTION ERROR" - }, - { - 0x25, 0x00, - SenseDevTypes001, - "LOGICAL UNIT NOT SUPPORTED" - }, - { - 0x26, 0x00, - SenseDevTypes001, - "INVALID FIELD IN PARAMETER LIST" - }, - { - 0x26, 0x01, - SenseDevTypes001, - "PARAMETER NOT SUPPORTED" - }, - { - 0x26, 0x02, - SenseDevTypes001, - "PARAMETER VALUE INVALID" - }, - { - 0x26, 0x03, - SenseDevTypes036, - "THRESHOLD PARAMETERS NOT SUPPORTED" - }, - { - 0x26, 0x04, - SenseDevTypes001, - "INVALID RELEASE OF PERSISTENT RESERVATION" - }, - { - 0x26, 0x05, - SenseDevTypes037, - "DATA DECRYPTION ERROR" - }, - { - 0x26, 0x06, - SenseDevTypes016, - "TOO MANY TARGET DESCRIPTORS" - }, - { - 0x26, 0x07, - SenseDevTypes016, - "UNSUPPORTED TARGET DESCRIPTOR TYPE CODE" - }, - { - 0x26, 0x08, - SenseDevTypes016, - "TOO MANY SEGMENT DESCRIPTORS" - }, - { - 0x26, 0x09, - SenseDevTypes016, - "UNSUPPORTED SEGMENT DESCRIPTOR TYPE CODE" - }, - { - 0x26, 0x0A, - SenseDevTypes016, - "UNEXPECTED INEXACT SEGMENT" - }, - { - 0x26, 0x0B, - SenseDevTypes016, - "INLINE DATA LENGTH EXCEEDED" - }, - { - 0x26, 0x0C, - SenseDevTypes016, - "INVALID OPERATION FOR COPY SOURCE OR DESTINATION" - }, - { - 0x26, 0x0D, - SenseDevTypes016, - "COPY SEGMENT GRANULARITY VIOLATION" - }, - { - 0x27, 0x00, - SenseDevTypes029, - "WRITE PROTECTED" - }, - { - 0x27, 0x01, - SenseDevTypes029, - "HARDWARE WRITE PROTECTED" - }, - { - 0x27, 0x02, - SenseDevTypes029, - "LOGICAL UNIT SOFTWARE WRITE PROTECTED" - }, - { - 0x27, 0x03, - SenseDevTypes038, - "ASSOCIATED WRITE PROTECT" - }, - { - 0x27, 0x04, - SenseDevTypes038, - "PERSISTENT WRITE PROTECT" - }, - { - 0x27, 0x05, - SenseDevTypes038, - "PERMANENT WRITE PROTECT" - }, - { - 0x28, 0x00, - SenseDevTypes001, - "NOT READY TO READY CHANGE, MEDIUM MAY HAVE CHANGED" - }, - { - 0x28, 0x01, - SenseDevTypes039, - "IMPORT OR EXPORT ELEMENT ACCESSED" - }, - { - 0x29, 0x00, - SenseDevTypes001, - "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED" - }, - { - 0x29, 0x01, - SenseDevTypes001, - "POWER ON OCCURRED" - }, - { - 0x29, 0x02, - SenseDevTypes001, - "SCSI BUS RESET OCCURRED" - }, - { - 0x29, 0x03, - SenseDevTypes001, - "BUS DEVICE RESET FUNCTION OCCURRED" - }, - { - 0x29, 0x04, - SenseDevTypes001, - "DEVICE INTERNAL RESET" - }, - { - 0x29, 0x05, - SenseDevTypes001, - "TRANSCEIVER MODE CHANGED TO SINGLE-ENDED" - }, - { - 0x29, 0x06, - SenseDevTypes001, - "TRANSCEIVER MODE CHANGED TO LVD" - }, - { - 0x2A, 0x00, - SenseDevTypes013, - "PARAMETERS CHANGED" - }, - { - 0x2A, 0x01, - SenseDevTypes013, - "MODE PARAMETERS CHANGED" - }, - { - 0x2A, 0x02, - SenseDevTypes040, - "LOG PARAMETERS CHANGED" - }, - { - 0x2A, 0x03, - SenseDevTypes036, - "RESERVATIONS PREEMPTED" - }, - { - 0x2A, 0x04, - SenseDevTypes041, - "RESERVATIONS RELEASED" - }, - { - 0x2A, 0x05, - SenseDevTypes041, - "REGISTRATIONS PREEMPTED" - }, - { - 0x2B, 0x00, - SenseDevTypes016, - "COPY CANNOT EXECUTE SINCE HOST CANNOT DISCONNECT" - }, - { - 0x2C, 0x00, - SenseDevTypes001, - "COMMAND SEQUENCE ERROR" - }, - { - 0x2C, 0x01, - SenseDevTypes042, - "TOO MANY WINDOWS SPECIFIED" - }, - { - 0x2C, 0x02, - SenseDevTypes042, - "INVALID COMBINATION OF WINDOWS SPECIFIED" - }, - { - 0x2C, 0x03, - SenseDevTypes005, - "CURRENT PROGRAM AREA IS NOT EMPTY" - }, - { - 0x2C, 0x04, - SenseDevTypes005, - "CURRENT PROGRAM AREA IS EMPTY" - }, - { - 0x2C, 0x05, - SenseDevTypes043, - "ILLEGAL POWER CONDITION REQUEST" - }, - { - 0x2D, 0x00, - SenseDevTypes002, - "OVERWRITE ERROR ON UPDATE IN PLACE" - }, - { - 0x2E, 0x00, - SenseDevTypes044, - "ERROR DETECTED BY THIRD PARTY TEMPORARY INITIATOR" - }, - { - 0x2E, 0x01, - SenseDevTypes044, - "THIRD PARTY DEVICE FAILURE" - }, - { - 0x2E, 0x02, - SenseDevTypes044, - "COPY TARGET DEVICE NOT REACHABLE" - }, - { - 0x2E, 0x03, - SenseDevTypes044, - "INCORRECT COPY TARGET DEVICE TYPE" - }, - { - 0x2E, 0x04, - SenseDevTypes044, - "COPY TARGET DEVICE DATA UNDERRUN" - }, - { - 0x2E, 0x05, - SenseDevTypes044, - "COPY TARGET DEVICE DATA OVERRUN" - }, - { - 0x2F, 0x00, - SenseDevTypes001, - "COMMANDS CLEARED BY ANOTHER INITIATOR" - }, - { - 0x30, 0x00, - SenseDevTypes034, - "INCOMPATIBLE MEDIUM INSTALLED" - }, - { - 0x30, 0x01, - SenseDevTypes029, - "CANNOT READ MEDIUM - UNKNOWN FORMAT" - }, - { - 0x30, 0x02, - SenseDevTypes029, - "CANNOT READ MEDIUM - INCOMPATIBLE FORMAT" - }, - { - 0x30, 0x03, - SenseDevTypes045, - "CLEANING CARTRIDGE INSTALLED" - }, - { - 0x30, 0x04, - SenseDevTypes029, - "CANNOT WRITE MEDIUM - UNKNOWN FORMAT" - }, - { - 0x30, 0x05, - SenseDevTypes029, - "CANNOT WRITE MEDIUM - INCOMPATIBLE FORMAT" - }, - { - 0x30, 0x06, - SenseDevTypes017, - "CANNOT FORMAT MEDIUM - INCOMPATIBLE MEDIUM" - }, - { - 0x30, 0x07, - SenseDevTypes006, - "CLEANING FAILURE" - }, - { - 0x30, 0x08, - SenseDevTypes005, - "CANNOT WRITE - APPLICATION CODE MISMATCH" - }, - { - 0x30, 0x09, - SenseDevTypes005, - "CURRENT SESSION NOT FIXATED FOR APPEND" - }, - { - 0x31, 0x00, - SenseDevTypes029, - "MEDIUM FORMAT CORRUPTED" - }, - { - 0x31, 0x01, - SenseDevTypes046, - "FORMAT COMMAND FAILED" - }, - { - 0x32, 0x00, - SenseDevTypes007, - "NO DEFECT SPARE LOCATION AVAILABLE" - }, - { - 0x32, 0x01, - SenseDevTypes007, - "DEFECT LIST UPDATE FAILURE" - }, - { - 0x33, 0x00, - SenseDevTypes002, - "TAPE LENGTH ERROR" - }, - { - 0x34, 0x00, - SenseDevTypes001, - "ENCLOSURE FAILURE" - }, - { - 0x35, 0x00, - SenseDevTypes001, - "ENCLOSURE SERVICES FAILURE" - }, - { - 0x35, 0x01, - SenseDevTypes001, - "UNSUPPORTED ENCLOSURE FUNCTION" - }, - { - 0x35, 0x02, - SenseDevTypes001, - "ENCLOSURE SERVICES UNAVAILABLE" - }, - { - 0x35, 0x03, - SenseDevTypes001, - "ENCLOSURE SERVICES TRANSFER FAILURE" - }, - { - 0x35, 0x04, - SenseDevTypes001, - "ENCLOSURE SERVICES TRANSFER REFUSED" - }, - { - 0x36, 0x00, - SenseDevTypes047, - "RIBBON, INK, OR TONER FAILURE" - }, - { - 0x37, 0x00, - SenseDevTypes013, - "ROUNDED PARAMETER" - }, - { - 0x38, 0x00, - SenseDevTypes043, - "EVENT STATUS NOTIFICATION" - }, - { - 0x38, 0x02, - SenseDevTypes043, - "ESN - POWER MANAGEMENT CLASS EVENT" - }, - { - 0x38, 0x04, - SenseDevTypes043, - "ESN - MEDIA CLASS EVENT" - }, - { - 0x38, 0x06, - SenseDevTypes043, - "ESN - DEVICE BUSY CLASS EVENT" - }, - { - 0x39, 0x00, - SenseDevTypes040, - "SAVING PARAMETERS NOT SUPPORTED" - }, - { - 0x3A, 0x00, - SenseDevTypes014, - "MEDIUM NOT PRESENT" - }, - { - 0x3A, 0x01, - SenseDevTypes034, - "MEDIUM NOT PRESENT - TRAY CLOSED" - }, - { - 0x3A, 0x02, - SenseDevTypes034, - "MEDIUM NOT PRESENT - TRAY OPEN" - }, - { - 0x3A, 0x03, - SenseDevTypes039, - "MEDIUM NOT PRESENT - LOADABLE" - }, - { - 0x3A, 0x04, - SenseDevTypes039, - "MEDIUM NOT PRESENT - MEDIUM AUXILIARY MEMORY ACCESSIBLE" - }, - { - 0x3B, 0x00, - SenseDevTypes048, - "SEQUENTIAL POSITIONING ERROR" - }, - { - 0x3B, 0x01, - SenseDevTypes002, - "TAPE POSITION ERROR AT BEGINNING-OF-MEDIUM" - }, - { - 0x3B, 0x02, - SenseDevTypes002, - "TAPE POSITION ERROR AT END-OF-MEDIUM" - }, - { - 0x3B, 0x03, - SenseDevTypes047, - "TAPE OR ELECTRONIC VERTICAL FORMS UNIT NOT READY" - }, - { - 0x3B, 0x04, - SenseDevTypes047, - "SLEW FAILURE" - }, - { - 0x3B, 0x05, - SenseDevTypes047, - "PAPER JAM" - }, - { - 0x3B, 0x06, - SenseDevTypes047, - "FAILED TO SENSE TOP-OF-FORM" - }, - { - 0x3B, 0x07, - SenseDevTypes047, - "FAILED TO SENSE BOTTOM-OF-FORM" - }, - { - 0x3B, 0x08, - SenseDevTypes002, - "REPOSITION ERROR" - }, - { - 0x3B, 0x09, - SenseDevTypes042, - "READ PAST END OF MEDIUM" - }, - { - 0x3B, 0x0A, - SenseDevTypes042, - "READ PAST BEGINNING OF MEDIUM" - }, - { - 0x3B, 0x0B, - SenseDevTypes042, - "POSITION PAST END OF MEDIUM" - }, - { - 0x3B, 0x0C, - SenseDevTypes003, - "POSITION PAST BEGINNING OF MEDIUM" - }, - { - 0x3B, 0x0D, - SenseDevTypes034, - "MEDIUM DESTINATION ELEMENT FULL" - }, - { - 0x3B, 0x0E, - SenseDevTypes034, - "MEDIUM SOURCE ELEMENT EMPTY" - }, - { - 0x3B, 0x0F, - SenseDevTypes005, - "END OF MEDIUM REACHED" - }, - { - 0x3B, 0x11, - SenseDevTypes034, - "MEDIUM MAGAZINE NOT ACCESSIBLE" - }, - { - 0x3B, 0x12, - SenseDevTypes034, - "MEDIUM MAGAZINE REMOVED" - }, - { - 0x3B, 0x13, - SenseDevTypes034, - "MEDIUM MAGAZINE INSERTED" - }, - { - 0x3B, 0x14, - SenseDevTypes034, - "MEDIUM MAGAZINE LOCKED" - }, - { - 0x3B, 0x15, - SenseDevTypes034, - "MEDIUM MAGAZINE UNLOCKED" - }, - { - 0x3B, 0x16, - SenseDevTypes005, - "MECHANICAL POSITIONING OR CHANGER ERROR" - }, - { - 0x3D, 0x00, - SenseDevTypes036, - "INVALID BITS IN IDENTIFY MESSAGE" - }, - { - 0x3E, 0x00, - SenseDevTypes001, - "LOGICAL UNIT HAS NOT SELF-CONFIGURED YET" - }, - { - 0x3E, 0x01, - SenseDevTypes001, - "LOGICAL UNIT FAILURE" - }, - { - 0x3E, 0x02, - SenseDevTypes001, - "TIMEOUT ON LOGICAL UNIT" - }, - { - 0x3E, 0x03, - SenseDevTypes001, - "LOGICAL UNIT FAILED SELF-TEST" - }, - { - 0x3E, 0x04, - SenseDevTypes001, - "LOGICAL UNIT UNABLE TO UPDATE SELF-TEST LOG" - }, - { - 0x3F, 0x00, - SenseDevTypes001, - "TARGET OPERATING CONDITIONS HAVE CHANGED" - }, - { - 0x3F, 0x01, - SenseDevTypes001, - "MICROCODE HAS BEEN CHANGED" - }, - { - 0x3F, 0x02, - SenseDevTypes049, - "CHANGED OPERATING DEFINITION" - }, - { - 0x3F, 0x03, - SenseDevTypes001, - "INQUIRY DATA HAS CHANGED" - }, - { - 0x3F, 0x04, - SenseDevTypes050, - "COMPONENT DEVICE ATTACHED" - }, - { - 0x3F, 0x05, - SenseDevTypes050, - "DEVICE IDENTIFIER CHANGED" - }, - { - 0x3F, 0x06, - SenseDevTypes051, - "REDUNDANCY GROUP CREATED OR MODIFIED" - }, - { - 0x3F, 0x07, - SenseDevTypes051, - "REDUNDANCY GROUP DELETED" - }, - { - 0x3F, 0x08, - SenseDevTypes051, - "SPARE CREATED OR MODIFIED" - }, - { - 0x3F, 0x09, - SenseDevTypes051, - "SPARE DELETED" - }, - { - 0x3F, 0x0A, - SenseDevTypes050, - "VOLUME SET CREATED OR MODIFIED" - }, - { - 0x3F, 0x0B, - SenseDevTypes050, - "VOLUME SET DELETED" - }, - { - 0x3F, 0x0C, - SenseDevTypes050, - "VOLUME SET DEASSIGNED" - }, - { - 0x3F, 0x0D, - SenseDevTypes050, - "VOLUME SET REASSIGNED" - }, - { - 0x3F, 0x0E, - SenseDevTypes041, - "REPORTED LUNS DATA HAS CHANGED" - }, - { - 0x3F, 0x0F, - SenseDevTypes001, - "ECHO BUFFER OVERWRITTEN" - }, - { - 0x3F, 0x10, - SenseDevTypes039, - "MEDIUM LOADABLE" - }, - { - 0x3F, 0x11, - SenseDevTypes039, - "MEDIUM AUXILIARY MEMORY ACCESSIBLE" - }, - { - 0x40, 0x00, - SenseDevTypes035, - "RAM FAILURE (SHOULD USE 40 NN)" - }, - { - 0x40, 0xFF, - SenseDevTypes001, - "DIAGNOSTIC FAILURE ON COMPONENT NN (80H-FFH)" - }, - { - 0x41, 0x00, - SenseDevTypes035, - "DATA PATH FAILURE (SHOULD USE 40 NN)" - }, - { - 0x42, 0x00, - SenseDevTypes035, - "POWER-ON OR SELF-TEST FAILURE (SHOULD USE 40 NN)" - }, - { - 0x43, 0x00, - SenseDevTypes001, - "MESSAGE ERROR" - }, - { - 0x44, 0x00, - SenseDevTypes001, - "INTERNAL TARGET FAILURE" - }, - { - 0x45, 0x00, - SenseDevTypes001, - "SELECT OR RESELECT FAILURE" - }, - { - 0x46, 0x00, - SenseDevTypes049, - "UNSUCCESSFUL SOFT RESET" - }, - { - 0x47, 0x00, - SenseDevTypes001, - "SCSI PARITY ERROR" - }, - { - 0x47, 0x01, - SenseDevTypes001, - "DATA PHASE CRC ERROR DETECTED" - }, - { - 0x47, 0x02, - SenseDevTypes001, - "SCSI PARITY ERROR DETECTED DURING ST DATA PHASE" - }, - { - 0x47, 0x03, - SenseDevTypes001, - "INFORMATION UNIT CRC ERROR DETECTED" - }, - { - 0x47, 0x04, - SenseDevTypes001, - "ASYNCHRONOUS INFORMATION PROTECTION ERROR DETECTED" - }, - { - 0x48, 0x00, - SenseDevTypes001, - "INITIATOR DETECTED ERROR MESSAGE RECEIVED" - }, - { - 0x49, 0x00, - SenseDevTypes001, - "INVALID MESSAGE ERROR" - }, - { - 0x4A, 0x00, - SenseDevTypes001, - "COMMAND PHASE ERROR" - }, - { - 0x4B, 0x00, - SenseDevTypes001, - "DATA PHASE ERROR" - }, - { - 0x4C, 0x00, - SenseDevTypes001, - "LOGICAL UNIT FAILED SELF-CONFIGURATION" - }, - { - 0x4D, 0xFF, - SenseDevTypes001, - "TAGGED OVERLAPPED COMMANDS (NN = QUEUE TAG)" - }, - { - 0x4E, 0x00, - SenseDevTypes001, - "OVERLAPPED COMMANDS ATTEMPTED" - }, - { - 0x50, 0x00, - SenseDevTypes002, - "WRITE APPEND ERROR" - }, - { - 0x50, 0x01, - SenseDevTypes002, - "WRITE APPEND POSITION ERROR" - }, - { - 0x50, 0x02, - SenseDevTypes002, - "POSITION ERROR RELATED TO TIMING" - }, - { - 0x51, 0x00, - SenseDevTypes052, - "ERASE FAILURE" - }, - { - 0x52, 0x00, - SenseDevTypes002, - "CARTRIDGE FAULT" - }, - { - 0x53, 0x00, - SenseDevTypes014, - "MEDIA LOAD OR EJECT FAILED" - }, - { - 0x53, 0x01, - SenseDevTypes002, - "UNLOAD TAPE FAILURE" - }, - { - 0x53, 0x02, - SenseDevTypes034, - "MEDIUM REMOVAL PREVENTED" - }, - { - 0x54, 0x00, - SenseDevTypes053, - "SCSI TO HOST SYSTEM INTERFACE FAILURE" - }, - { - 0x55, 0x00, - SenseDevTypes053, - "SYSTEM RESOURCE FAILURE" - }, - { - 0x55, 0x01, - SenseDevTypes033, - "SYSTEM BUFFER FULL" - }, - { - 0x55, 0x02, - SenseDevTypes054, - "INSUFFICIENT RESERVATION RESOURCES" - }, - { - 0x55, 0x03, - SenseDevTypes041, - "INSUFFICIENT RESOURCES" - }, - { - 0x55, 0x04, - SenseDevTypes055, - "INSUFFICIENT REGISTRATION RESOURCES" - }, - { - 0x55, 0x05, - SenseDevTypes012, - "access controls code 4 (99-314) [proposed]" - }, - { - 0x55, 0x06, - SenseDevTypes012, - "auxiliary memory code 1 (99-148) [proposed]" - }, - { - 0x57, 0x00, - SenseDevTypes005, - "UNABLE TO RECOVER TABLE-OF-CONTENTS" - }, - { - 0x58, 0x00, - SenseDevTypes056, - "GENERATION DOES NOT EXIST" - }, - { - 0x59, 0x00, - SenseDevTypes056, - "UPDATED BLOCK READ" - }, - { - 0x5A, 0x00, - SenseDevTypes057, - "OPERATOR REQUEST OR STATE CHANGE INPUT" - }, - { - 0x5A, 0x01, - SenseDevTypes034, - "OPERATOR MEDIUM REMOVAL REQUEST" - }, - { - 0x5A, 0x02, - SenseDevTypes058, - "OPERATOR SELECTED WRITE PROTECT" - }, - { - 0x5A, 0x03, - SenseDevTypes058, - "OPERATOR SELECTED WRITE PERMIT" - }, - { - 0x5B, 0x00, - SenseDevTypes059, - "LOG EXCEPTION" - }, - { - 0x5B, 0x01, - SenseDevTypes059, - "THRESHOLD CONDITION MET" - }, - { - 0x5B, 0x02, - SenseDevTypes059, - "LOG COUNTER AT MAXIMUM" - }, - { - 0x5B, 0x03, - SenseDevTypes059, - "LOG LIST CODES EXHAUSTED" - }, - { - 0x5C, 0x00, - SenseDevTypes060, - "RPL STATUS CHANGE" - }, - { - 0x5C, 0x01, - SenseDevTypes060, - "SPINDLES SYNCHRONIZED" - }, - { - 0x5C, 0x02, - SenseDevTypes060, - "SPINDLES NOT SYNCHRONIZED" - }, - { - 0x5D, 0x00, - SenseDevTypes001, - "FAILURE PREDICTION THRESHOLD EXCEEDED" - }, - { - 0x5D, 0x01, - SenseDevTypes061, - "MEDIA FAILURE PREDICTION THRESHOLD EXCEEDED" - }, - { - 0x5D, 0x02, - SenseDevTypes005, - "LOGICAL UNIT FAILURE PREDICTION THRESHOLD EXCEEDED" - }, - { - 0x5D, 0x10, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE" - }, - { - 0x5D, 0x11, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x12, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x13, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x14, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS" - }, - { - 0x5D, 0x15, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH" - }, - { - 0x5D, 0x16, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH" - }, - { - 0x5D, 0x17, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE CHANNEL PARAMETRICS" - }, - { - 0x5D, 0x18, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE CONTROLLER DETECTED" - }, - { - 0x5D, 0x19, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE" - }, - { - 0x5D, 0x1A, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE SEEK TIME PERFORMANCE" - }, - { - 0x5D, 0x1B, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE SPIN-UP RETRY COUNT" - }, - { - 0x5D, 0x1C, - SenseDevTypes062, - "HARDWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT" - }, - { - 0x5D, 0x20, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE GENERAL HARD DRIVE FAILURE" - }, - { - 0x5D, 0x21, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x22, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE DATA ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x23, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE SEEK ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x24, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE TOO MANY BLOCK REASSIGNS" - }, - { - 0x5D, 0x25, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE ACCESS TIMES TOO HIGH" - }, - { - 0x5D, 0x26, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE START UNIT TIMES TOO HIGH" - }, - { - 0x5D, 0x27, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE CHANNEL PARAMETRICS" - }, - { - 0x5D, 0x28, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE CONTROLLER DETECTED" - }, - { - 0x5D, 0x29, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE THROUGHPUT PERFORMANCE" - }, - { - 0x5D, 0x2A, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE SEEK TIME PERFORMANCE" - }, - { - 0x5D, 0x2B, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE SPIN-UP RETRY COUNT" - }, - { - 0x5D, 0x2C, - SenseDevTypes062, - "CONTROLLER IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT" - }, - { - 0x5D, 0x30, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE GENERAL HARD DRIVE FAILURE" - }, - { - 0x5D, 0x31, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x32, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE DATA ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x33, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE SEEK ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x34, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE TOO MANY BLOCK REASSIGNS" - }, - { - 0x5D, 0x35, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE ACCESS TIMES TOO HIGH" - }, - { - 0x5D, 0x36, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE START UNIT TIMES TOO HIGH" - }, - { - 0x5D, 0x37, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE CHANNEL PARAMETRICS" - }, - { - 0x5D, 0x38, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE CONTROLLER DETECTED" - }, - { - 0x5D, 0x39, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE THROUGHPUT PERFORMANCE" - }, - { - 0x5D, 0x3A, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE SEEK TIME PERFORMANCE" - }, - { - 0x5D, 0x3B, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE SPIN-UP RETRY COUNT" - }, - { - 0x5D, 0x3C, - SenseDevTypes062, - "DATA CHANNEL IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT" - }, - { - 0x5D, 0x40, - SenseDevTypes062, - "SERVO IMPENDING FAILURE GENERAL HARD DRIVE FAILURE" - }, - { - 0x5D, 0x41, - SenseDevTypes062, - "SERVO IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x42, - SenseDevTypes062, - "SERVO IMPENDING FAILURE DATA ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x43, - SenseDevTypes062, - "SERVO IMPENDING FAILURE SEEK ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x44, - SenseDevTypes062, - "SERVO IMPENDING FAILURE TOO MANY BLOCK REASSIGNS" - }, - { - 0x5D, 0x45, - SenseDevTypes062, - "SERVO IMPENDING FAILURE ACCESS TIMES TOO HIGH" - }, - { - 0x5D, 0x46, - SenseDevTypes062, - "SERVO IMPENDING FAILURE START UNIT TIMES TOO HIGH" - }, - { - 0x5D, 0x47, - SenseDevTypes062, - "SERVO IMPENDING FAILURE CHANNEL PARAMETRICS" - }, - { - 0x5D, 0x48, - SenseDevTypes062, - "SERVO IMPENDING FAILURE CONTROLLER DETECTED" - }, - { - 0x5D, 0x49, - SenseDevTypes062, - "SERVO IMPENDING FAILURE THROUGHPUT PERFORMANCE" - }, - { - 0x5D, 0x4A, - SenseDevTypes062, - "SERVO IMPENDING FAILURE SEEK TIME PERFORMANCE" - }, - { - 0x5D, 0x4B, - SenseDevTypes062, - "SERVO IMPENDING FAILURE SPIN-UP RETRY COUNT" - }, - { - 0x5D, 0x4C, - SenseDevTypes062, - "SERVO IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT" - }, - { - 0x5D, 0x50, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE" - }, - { - 0x5D, 0x51, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x52, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE DATA ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x53, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x54, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS" - }, - { - 0x5D, 0x55, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE ACCESS TIMES TOO HIGH" - }, - { - 0x5D, 0x56, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE START UNIT TIMES TOO HIGH" - }, - { - 0x5D, 0x57, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE CHANNEL PARAMETRICS" - }, - { - 0x5D, 0x58, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE CONTROLLER DETECTED" - }, - { - 0x5D, 0x59, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE THROUGHPUT PERFORMANCE" - }, - { - 0x5D, 0x5A, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE SEEK TIME PERFORMANCE" - }, - { - 0x5D, 0x5B, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE SPIN-UP RETRY COUNT" - }, - { - 0x5D, 0x5C, - SenseDevTypes062, - "SPINDLE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT" - }, - { - 0x5D, 0x60, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE" - }, - { - 0x5D, 0x61, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x62, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x63, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH" - }, - { - 0x5D, 0x64, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS" - }, - { - 0x5D, 0x65, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH" - }, - { - 0x5D, 0x66, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH" - }, - { - 0x5D, 0x67, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE CHANNEL PARAMETRICS" - }, - { - 0x5D, 0x68, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE CONTROLLER DETECTED" - }, - { - 0x5D, 0x69, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE" - }, - { - 0x5D, 0x6A, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE SEEK TIME PERFORMANCE" - }, - { - 0x5D, 0x6B, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE SPIN-UP RETRY COUNT" - }, - { - 0x5D, 0x6C, - SenseDevTypes062, - "FIRMWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT" - }, - { - 0x5D, 0xFF, - SenseDevTypes001, - "FAILURE PREDICTION THRESHOLD EXCEEDED (FALSE)" - }, - { - 0x5E, 0x00, - SenseDevTypes044, - "LOW POWER CONDITION ON" - }, - { - 0x5E, 0x01, - SenseDevTypes044, - "IDLE CONDITION ACTIVATED BY TIMER" - }, - { - 0x5E, 0x02, - SenseDevTypes044, - "STANDBY CONDITION ACTIVATED BY TIMER" - }, - { - 0x5E, 0x03, - SenseDevTypes044, - "IDLE CONDITION ACTIVATED BY COMMAND" - }, - { - 0x5E, 0x04, - SenseDevTypes044, - "STANDBY CONDITION ACTIVATED BY COMMAND" - }, - { - 0x5E, 0x41, - SenseDevTypes043, - "POWER STATE CHANGE TO ACTIVE" - }, - { - 0x5E, 0x42, - SenseDevTypes043, - "POWER STATE CHANGE TO IDLE" - }, - { - 0x5E, 0x43, - SenseDevTypes043, - "POWER STATE CHANGE TO STANDBY" - }, - { - 0x5E, 0x45, - SenseDevTypes043, - "POWER STATE CHANGE TO SLEEP" - }, - { - 0x5E, 0x47, - SenseDevTypes063, - "POWER STATE CHANGE TO DEVICE CONTROL" - }, - { - 0x60, 0x00, - SenseDevTypes042, - "LAMP FAILURE" - }, - { - 0x61, 0x00, - SenseDevTypes042, - "VIDEO ACQUISITION ERROR" - }, - { - 0x61, 0x01, - SenseDevTypes042, - "UNABLE TO ACQUIRE VIDEO" - }, - { - 0x61, 0x02, - SenseDevTypes042, - "OUT OF FOCUS" - }, - { - 0x62, 0x00, - SenseDevTypes042, - "SCAN HEAD POSITIONING ERROR" - }, - { - 0x63, 0x00, - SenseDevTypes005, - "END OF USER AREA ENCOUNTERED ON THIS TRACK" - }, - { - 0x63, 0x01, - SenseDevTypes005, - "PACKET DOES NOT FIT IN AVAILABLE SPACE" - }, - { - 0x64, 0x00, - SenseDevTypes005, - "ILLEGAL MODE FOR THIS TRACK" - }, - { - 0x64, 0x01, - SenseDevTypes005, - "INVALID PACKET SIZE" - }, - { - 0x65, 0x00, - SenseDevTypes001, - "VOLTAGE FAULT" - }, - { - 0x66, 0x00, - SenseDevTypes042, - "AUTOMATIC DOCUMENT FEEDER COVER UP" - }, - { - 0x66, 0x01, - SenseDevTypes042, - "AUTOMATIC DOCUMENT FEEDER LIFT UP" - }, - { - 0x66, 0x02, - SenseDevTypes042, - "DOCUMENT JAM IN AUTOMATIC DOCUMENT FEEDER" - }, - { - 0x66, 0x03, - SenseDevTypes042, - "DOCUMENT MISS FEED AUTOMATIC IN DOCUMENT FEEDER" - }, - { - 0x67, 0x00, - SenseDevTypes064, - "CONFIGURATION FAILURE" - }, - { - 0x67, 0x01, - SenseDevTypes064, - "CONFIGURATION OF INCAPABLE LOGICAL UNITS FAILED" - }, - { - 0x67, 0x02, - SenseDevTypes064, - "ADD LOGICAL UNIT FAILED" - }, - { - 0x67, 0x03, - SenseDevTypes064, - "MODIFICATION OF LOGICAL UNIT FAILED" - }, - { - 0x67, 0x04, - SenseDevTypes064, - "EXCHANGE OF LOGICAL UNIT FAILED" - }, - { - 0x67, 0x05, - SenseDevTypes064, - "REMOVE OF LOGICAL UNIT FAILED" - }, - { - 0x67, 0x06, - SenseDevTypes064, - "ATTACHMENT OF LOGICAL UNIT FAILED" - }, - { - 0x67, 0x07, - SenseDevTypes064, - "CREATION OF LOGICAL UNIT FAILED" - }, - { - 0x67, 0x08, - SenseDevTypes064, - "ASSIGN FAILURE OCCURRED" - }, - { - 0x67, 0x09, - SenseDevTypes064, - "MULTIPLY ASSIGNED LOGICAL UNIT" - }, - { - 0x68, 0x00, - SenseDevTypes064, - "LOGICAL UNIT NOT CONFIGURED" - }, - { - 0x69, 0x00, - SenseDevTypes064, - "DATA LOSS ON LOGICAL UNIT" - }, - { - 0x69, 0x01, - SenseDevTypes064, - "MULTIPLE LOGICAL UNIT FAILURES" - }, - { - 0x69, 0x02, - SenseDevTypes064, - "PARITY/DATA MISMATCH" - }, - { - 0x6A, 0x00, - SenseDevTypes064, - "INFORMATIONAL, REFER TO LOG" - }, - { - 0x6B, 0x00, - SenseDevTypes064, - "STATE CHANGE HAS OCCURRED" - }, - { - 0x6B, 0x01, - SenseDevTypes064, - "REDUNDANCY LEVEL GOT BETTER" - }, - { - 0x6B, 0x02, - SenseDevTypes064, - "REDUNDANCY LEVEL GOT WORSE" - }, - { - 0x6C, 0x00, - SenseDevTypes064, - "REBUILD FAILURE OCCURRED" - }, - { - 0x6D, 0x00, - SenseDevTypes064, - "RECALCULATE FAILURE OCCURRED" - }, - { - 0x6E, 0x00, - SenseDevTypes064, - "COMMAND TO LOGICAL UNIT FAILED" - }, - { - 0x6F, 0x00, - SenseDevTypes005, - "COPY PROTECTION KEY EXCHANGE FAILURE - AUTHENTICATION FAILURE" - }, - { - 0x6F, 0x01, - SenseDevTypes005, - "COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT PRESENT" - }, - { - 0x6F, 0x02, - SenseDevTypes005, - "COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT ESTABLISHED" - }, - { - 0x6F, 0x03, - SenseDevTypes005, - "READ OF SCRAMBLED SECTOR WITHOUT AUTHENTICATION" - }, - { - 0x6F, 0x04, - SenseDevTypes005, - "MEDIA REGION CODE IS MISMATCHED TO LOGICAL UNIT REGION" - }, - { - 0x6F, 0x05, - SenseDevTypes005, - "DRIVE REGION MUST BE PERMANENT/REGION RESET COUNT ERROR" - }, - { - 0x70, 0xFF, - SenseDevTypes002, - "DECOMPRESSION EXCEPTION SHORT ALGORITHM ID OF NN" - }, - { - 0x71, 0x00, - SenseDevTypes002, - "DECOMPRESSION EXCEPTION LONG ALGORITHM ID" - }, - { - 0x72, 0x00, - SenseDevTypes005, - "SESSION FIXATION ERROR" - }, - { - 0x72, 0x01, - SenseDevTypes005, - "SESSION FIXATION ERROR WRITING LEAD-IN" - }, - { - 0x72, 0x02, - SenseDevTypes005, - "SESSION FIXATION ERROR WRITING LEAD-OUT" - }, - { - 0x72, 0x03, - SenseDevTypes005, - "SESSION FIXATION ERROR - INCOMPLETE TRACK IN SESSION" - }, - { - 0x72, 0x04, - SenseDevTypes005, - "EMPTY OR PARTIALLY WRITTEN RESERVED TRACK" - }, - { - 0x72, 0x05, - SenseDevTypes005, - "NO MORE TRACK RESERVATIONS ALLOWED" - }, - { - 0x73, 0x00, - SenseDevTypes005, - "CD CONTROL ERROR" - }, - { - 0x73, 0x01, - SenseDevTypes005, - "POWER CALIBRATION AREA ALMOST FULL" - }, - { - 0x73, 0x02, - SenseDevTypes005, - "POWER CALIBRATION AREA IS FULL" - }, - { - 0x73, 0x03, - SenseDevTypes005, - "POWER CALIBRATION AREA ERROR" - }, - { - 0x73, 0x04, - SenseDevTypes005, - "PROGRAM MEMORY AREA UPDATE FAILURE" - }, - { - 0x73, 0x05, - SenseDevTypes005, - "PROGRAM MEMORY AREA IS FULL" - }, - { - 0x73, 0x06, - SenseDevTypes005, - "RMA/PMA IS FULL" - }, -}; - -static int ASCQ_TableSize = 463; - - -#endif diff --git a/drivers/message/fusion/ascq_tbl.sh b/drivers/message/fusion/ascq_tbl.sh deleted file mode 100644 index 76ba95458..000000000 --- a/drivers/message/fusion/ascq_tbl.sh +++ /dev/null @@ -1,109 +0,0 @@ -#!/bin/sh -# -# ascq_tbl.sh - Translate SCSI t10.org's "asc-num.txt" file of -# SCSI Additional Sense Code & Qualifiers (ASC/ASCQ's) -# into something useful in C, creating "ascq_tbl.c" file. -# -#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*# - -PREF_INFILE="t10.org/asc-num.txt" # From SCSI t10.org -PREF_OUTFILE="ascq_tbl.c" - -#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*# - -xlate_ascq() { - cat | awk ' - BEGIN { - DQ = "\042"; - OUTFILE = "'"${PREF_OUTFILE}"'"; - TRUE = 1; - FALSE = 0; - #debug = TRUE; - - # read and discard all lines up to and including the one that begins - # with the "magic token" of "------- -------------- ---"... - headers_gone = FALSE; - while (!headers_gone) { - if (getline <= 0) - exit 1; - header_line[++hdrs] = $0; - if (debug) - printf("header_line[%d] = :%s:\n", ++hdrs, $0); - if ($0 ~ /^------- -------------- ---/) { - headers_gone = TRUE; - } - } - outcount = 0; - } - - (NF > 1) { - ++outcount; - if (debug) - printf( "DBG: %s\n", $0 ); - ASC[outcount] = substr($0,1,2); - ASCQ[outcount] = substr($0,5,2); - devtypes = substr($0,10,14); - gsub(/ /, ".", devtypes); - DESCRIP[outcount] = substr($0,26); - - if (!(devtypes in DevTypesVoodoo)) { - DevTypesVoodoo[devtypes] = ++voodoo; - DevTypesIdx[voodoo] = devtypes; - } - DEVTYPES[outcount] = DevTypesVoodoo[devtypes]; - - # Handle 0xNN exception stuff... - if (ASCQ[outcount] == "NN" || ASCQ[outcount] == "nn") - ASCQ[outcount] = "FF"; - } - - END { - printf("#ifndef SCSI_ASCQ_TBL_C_INCLUDED\n") > OUTFILE; - printf("#define SCSI_ASCQ_TBL_C_INCLUDED\n") >> OUTFILE; - - printf("\n/* AuToMaGiCaLlY generated from: %s'"${FIN}"'%s\n", DQ, DQ) >> OUTFILE; - printf(" *******************************************************************************\n") >> OUTFILE; - for (i=1; i<=hdrs; i++) { - printf(" * %s\n", header_line[i]) >> OUTFILE; - } - printf(" */\n") >> OUTFILE; - - printf("\n") >> OUTFILE; - for (i=1; i<=voodoo; i++) { - printf("static char SenseDevTypes%03d[] = %s%s%s;\n", i, DQ, DevTypesIdx[i], DQ) >> OUTFILE; - } - - printf("\nstatic ASCQ_Table_t ASCQ_Table[] = {\n") >> OUTFILE; - for (i=1; i<=outcount; i++) { - printf(" {\n") >> OUTFILE; - printf(" 0x%s, 0x%s,\n", ASC[i], ASCQ[i]) >> OUTFILE; - printf(" SenseDevTypes%03d,\n", DEVTYPES[i]) >> OUTFILE; - printf(" %s%s%s\n", DQ, DESCRIP[i], DQ) >> OUTFILE; - printf(" },\n") >> OUTFILE; - } - printf( "};\n\n" ) >> OUTFILE; - - printf( "static int ASCQ_TableSize = %d;\n\n", outcount ) >> OUTFILE; - printf( "Total of %d ASC/ASCQ records generated\n", outcount ); - printf("\n#endif\n") >> OUTFILE; - close(OUTFILE); - }' - return -} - -#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*# - -# main() -if [ $# -lt 1 ]; then - echo "INFO: No input filename supplied - using: $PREF_INFILE" >&2 - FIN=$PREF_INFILE -else - FIN="$1" - if [ "$FIN" != "$PREF_INFILE" ]; then - echo "INFO: Ok, I'll try chewing on '$FIN' for SCSI ASC/ASCQ combos..." >&2 - fi - shift -fi - -cat $FIN | xlate_ascq -exit 0 diff --git a/drivers/message/fusion/isense.c b/drivers/message/fusion/isense.c deleted file mode 100644 index 53b5a0f22..000000000 --- a/drivers/message/fusion/isense.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * linux/drivers/message/fusion/isense.c - * Little linux driver / shim that interfaces with the Fusion MPT - * Linux base driver to provide english readable strings in SCSI - * Error Report logging output. This module implements SCSI-3 - * Opcode lookup and a sorted table of SCSI-3 ASC/ASCQ strings. - * - * Copyright (c) 1991-2004 Steven J. Ralston - * Written By: Steven J. Ralston - * (yes I wrote some of the orig. code back in 1991!) - * (mailto:sjralston1@netscape.net) - * (mailto:mpt_linux_developer@lsil.com) - * - * $Id: isense.c,v 1.33 2002/02/27 18:44:19 sralston Exp $ - */ -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* - 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; version 2 of the License. - - 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. - - NO WARRANTY - THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT - LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is - solely responsible for determining the appropriateness of using and - distributing the Program and assumes all risks associated with its - exercise of rights under this Agreement, including but not limited to - the risks and costs of program errors, damage to or loss of data, - programs or equipment, and unavailability or interruption of operations. - - DISCLAIMER OF LIABILITY - NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED - HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES - - 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 - -#define MODULEAUTHOR "Steven J. Ralston" -#define COPYRIGHT "Copyright (c) 2001-2004 " MODULEAUTHOR -#include "mptbase.h" - -#include "isense.h" - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* - * Private data... - */ - -/* - * YIKES! I don't usually #include C source files, but.. - * The following #include's pulls in our needed ASCQ_Table[] array, - * ASCQ_TableSz integer, and ScsiOpcodeString[] array! - */ -#include "ascq_tbl.c" -#include "scsiops.c" - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#define my_NAME "SCSI-3 Opcodes & ASC/ASCQ Strings" -#define my_VERSION MPT_LINUX_VERSION_COMMON -#define MYNAM "isense" - -MODULE_AUTHOR(MODULEAUTHOR); -MODULE_DESCRIPTION(my_NAME); -MODULE_LICENSE("GPL"); - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -int __init isense_init(void) -{ - show_mptmod_ver(my_NAME, my_VERSION); - - /* - * Install our handler - */ - if (mpt_register_ascqops_strings(&ASCQ_Table[0], ASCQ_TableSize, ScsiOpcodeString) != 1) - { - printk(KERN_ERR MYNAM ": ERROR: Can't register with Fusion MPT base driver!\n"); - return -EBUSY; - } - printk(KERN_INFO MYNAM ": Registered SCSI-3 Opcodes & ASC/ASCQ Strings\n"); - return 0; -} - - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -static void isense_exit(void) -{ -#ifdef MODULE - mpt_deregister_ascqops_strings(); -#endif - printk(KERN_INFO MYNAM ": Deregistered SCSI-3 Opcodes & ASC/ASCQ Strings\n"); -} - -module_init(isense_init); -module_exit(isense_exit); - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - diff --git a/drivers/message/fusion/isense.h b/drivers/message/fusion/isense.h deleted file mode 100644 index e1ce503fe..000000000 --- a/drivers/message/fusion/isense.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef ISENSE_H_INCLUDED -#define ISENSE_H_INCLUDED -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - -#ifdef __KERNEL__ -#include /* needed for u8, etc. */ -#include /* needed for strcat */ -#include /* needed for sprintf */ -#else - #ifndef U_STUFF_DEFINED - #define U_STUFF_DEFINED - typedef unsigned char u8; - typedef unsigned short u16; - typedef unsigned int u32; - #endif -#endif - -#include "scsi3.h" /* needed for all things SCSI */ - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* - * Defines and typedefs... - */ - -#ifdef __KERNEL__ -#define PrintF(x) printk x -#else -#define PrintF(x) printf x -#endif - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#define RETRY_STATUS ((int) 1) -#define PUT_STATUS ((int) 0) - -/* - * A generic structure to hold info about IO request that caused - * a Request Sense to be performed, and the resulting Sense Data. - */ -typedef struct IO_Info -{ - char *DevIDStr; /* String of chars which identifies the device. */ - u8 *cdbPtr; /* Pointer (Virtual/Logical addr) to CDB bytes of - IO request that caused ContAllegianceCond. */ - u8 *sensePtr; /* Pointer (Virtual/Logical addr) to Sense Data - returned by Request Sense operation. */ - u8 *dataPtr; /* Pointer (Virtual/Logical addr) to Data buffer - of IO request caused ContAllegianceCondition. */ - u8 *inqPtr; /* Pointer (Virtual/Logical addr) to Inquiry Data for - IO *Device* that caused ContAllegianceCondition. */ - u8 SCSIStatus; /* SCSI status byte of IO request that caused - Contingent Allegiance Condition. */ - u8 DoDisplay; /* Shall we display any messages? */ - u16 rsvd_align1; - u32 ComplCode; /* Four-byte OS-dependent completion code. */ - u32 NotifyL; /* Four-byte OS-dependent notification field. */ -} IO_Info_t; - -/* - * SCSI Additional Sense Code and Additional Sense Code Qualifier table. - */ -typedef struct ASCQ_Table -{ - u8 ASC; - u8 ASCQ; - char *DevTypes; - char *Description; -} ASCQ_Table_t; - -#if 0 -/* - * SCSI Opcodes table. - */ -typedef struct SCSI_OPS_Table -{ - u8 OpCode; - char *DevTypes; - char *ScsiCmndStr; -} SCSI_OPS_Table_t; -#endif - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* - * Public entry point prototypes - */ - -/* in scsiherr.c, needed by mptscsih.c */ -extern int mpt_ScsiHost_ErrorReport(IO_Info_t *ioop); - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#endif - diff --git a/drivers/message/fusion/scsi3.h b/drivers/message/fusion/scsi3.h deleted file mode 100644 index 100811a12..000000000 --- a/drivers/message/fusion/scsi3.h +++ /dev/null @@ -1,707 +0,0 @@ -/* - * linux/drivers/message/fusion/scsi3.h - * SCSI-3 definitions and macros. - * (Ultimately) SCSI-3 definitions; for now, inheriting - * SCSI-2 definitions. - * - * Copyright (c) 1996-2004 Steven J. Ralston - * Written By: Steven J. Ralston (19960517) - * (mailto:sjralston1@netscape.net) - * (mailto:mpt_linux_developer@lsil.com) - * - * $Id: scsi3.h,v 1.9 2002/02/27 18:45:02 sralston Exp $ - */ - -#ifndef SCSI3_H_INCLUDED -#define SCSI3_H_INCLUDED -/***************************************************************************/ - -/**************************************************************************** - * - * Includes - */ -#ifdef __KERNEL__ -#include -#else - #ifndef U_STUFF_DEFINED - #define U_STUFF_DEFINED - typedef unsigned char u8; - typedef unsigned short u16; - typedef unsigned int u32; - #endif -#endif - -/**************************************************************************** - * - * Defines - */ - -/* - * SCSI Commands - */ -#define CMD_TestUnitReady 0x00 -#define CMD_RezeroUnit 0x01 /* direct-access devices */ -#define CMD_Rewind 0x01 /* sequential-access devices */ -#define CMD_RequestSense 0x03 -#define CMD_FormatUnit 0x04 -#define CMD_ReassignBlock 0x07 -#define CMD_Read6 0x08 -#define CMD_Write6 0x0A -#define CMD_WriteFilemark 0x10 -#define CMD_Space 0x11 -#define CMD_Inquiry 0x12 -#define CMD_ModeSelect6 0x15 -#define CMD_ModeSense6 0x1A -#define CMD_Reserve6 0x16 -#define CMD_Release6 0x17 -#define CMD_Erase 0x19 -#define CMD_StartStopUnit 0x1b /* direct-access devices */ -#define CMD_LoadUnload 0x1b /* sequential-access devices */ -#define CMD_ReceiveDiagnostic 0x1C -#define CMD_SendDiagnostic 0x1D -#define CMD_ReadCapacity 0x25 -#define CMD_Read10 0x28 -#define CMD_Write10 0x2A -#define CMD_WriteVerify 0x2E -#define CMD_Verify 0x2F -#define CMD_SynchronizeCache 0x35 -#define CMD_ReadDefectData 0x37 -#define CMD_WriteBuffer 0x3B -#define CMD_ReadBuffer 0x3C -#define CMD_ReadLong 0x3E -#define CMD_LogSelect 0x4C -#define CMD_LogSense 0x4D -#define CMD_ModeSelect10 0x55 -#define CMD_Reserve10 0x56 -#define CMD_Release10 0x57 -#define CMD_ModeSense10 0x5A -#define CMD_PersistReserveIn 0x5E -#define CMD_PersistReserveOut 0x5F -#define CMD_ReportLuns 0xA0 - -/* - * Control byte field - */ -#define CONTROL_BYTE_NACA_BIT 0x04 -#define CONTROL_BYTE_Flag_BIT 0x02 -#define CONTROL_BYTE_Link_BIT 0x01 - -/* - * SCSI Messages - */ -#define MSG_COMPLETE 0x00 -#define MSG_EXTENDED 0x01 -#define MSG_SAVE_POINTERS 0x02 -#define MSG_RESTORE_POINTERS 0x03 -#define MSG_DISCONNECT 0x04 -#define MSG_IDERROR 0x05 -#define MSG_ABORT 0x06 -#define MSG_REJECT 0x07 -#define MSG_NOP 0x08 -#define MSG_PARITY_ERROR 0x09 -#define MSG_LINKED_CMD_COMPLETE 0x0a -#define MSG_LCMD_COMPLETE_W_FLG 0x0b -#define MSG_BUS_DEVICE_RESET 0x0c -#define MSG_ABORT_TAG 0x0d -#define MSG_CLEAR_QUEUE 0x0e -#define MSG_INITIATE_RECOVERY 0x0f - -#define MSG_RELEASE_RECOVRY 0x10 -#define MSG_TERMINATE_IO 0x11 - -#define MSG_SIMPLE_QUEUE 0x20 -#define MSG_HEAD_OF_QUEUE 0x21 -#define MSG_ORDERED_QUEUE 0x22 -#define MSG_IGNORE_WIDE_RESIDUE 0x23 - -#define MSG_IDENTIFY 0x80 -#define MSG_IDENTIFY_W_DISC 0xc0 - -/* - * SCSI Phases - */ -#define PHS_DATA_OUT 0x00 -#define PHS_DATA_IN 0x01 -#define PHS_COMMAND 0x02 -#define PHS_STATUS 0x03 -#define PHS_MSG_OUT 0x06 -#define PHS_MSG_IN 0x07 - -/* - * Statuses - */ -#define STS_GOOD 0x00 -#define STS_CHECK_CONDITION 0x02 -#define STS_CONDITION_MET 0x04 -#define STS_BUSY 0x08 -#define STS_INTERMEDIATE 0x10 -#define STS_INTERMEDIATE_CONDITION_MET 0x14 -#define STS_RESERVATION_CONFLICT 0x18 -#define STS_COMMAND_TERMINATED 0x22 -#define STS_TASK_SET_FULL 0x28 -#define STS_QUEUE_FULL 0x28 -#define STS_ACA_ACTIVE 0x30 - -#define STS_VALID_MASK 0x3e - -#define SCSI_STATUS(x) ((x) & STS_VALID_MASK) - -/* - * SCSI QTag Types - */ -#define QTAG_SIMPLE 0x20 -#define QTAG_HEAD_OF_Q 0x21 -#define QTAG_ORDERED 0x22 - -/* - * SCSI Sense Key Definitons - */ -#define SK_NO_SENSE 0x00 -#define SK_RECOVERED_ERROR 0x01 -#define SK_NOT_READY 0x02 -#define SK_MEDIUM_ERROR 0x03 -#define SK_HARDWARE_ERROR 0x04 -#define SK_ILLEGAL_REQUEST 0x05 -#define SK_UNIT_ATTENTION 0x06 -#define SK_DATA_PROTECT 0x07 -#define SK_BLANK_CHECK 0x08 -#define SK_VENDOR_SPECIFIC 0x09 -#define SK_COPY_ABORTED 0x0a -#define SK_ABORTED_COMMAND 0x0b -#define SK_EQUAL 0x0c -#define SK_VOLUME_OVERFLOW 0x0d -#define SK_MISCOMPARE 0x0e -#define SK_RESERVED 0x0f - - - -#define SCSI_MAX_INQUIRY_BYTES 96 -#define SCSI_STD_INQUIRY_BYTES 36 - -#undef USE_SCSI_COMPLETE_INQDATA -/* - * Structure definition for SCSI Inquiry Data - * - * NOTE: The following structure is 96 bytes in size - * iff USE_SCSI_COMPLETE_INQDATA IS defined above (i.e. w/ "#define"). - * If USE_SCSI_COMPLETE_INQDATA is NOT defined above (i.e. w/ "#undef") - * then the following structure is only 36 bytes in size. - * THE CHOICE IS YOURS! - */ -typedef struct SCSI_Inquiry_Data -{ -#ifdef USE_SCSI_COMPLETE_INQDATA - u8 InqByte[SCSI_MAX_INQUIRY_BYTES]; -#else - u8 InqByte[SCSI_STD_INQUIRY_BYTES]; -#endif - -/* - * the following structure works only for little-endian (Intel, - * LSB first (1234) byte order) systems with 4-byte ints. - * - u32 Periph_Device_Type : 5, - Periph_Qualifier : 3, - Device_Type_Modifier : 7, - Removable_Media : 1, - ANSI_Version : 3, - ECMA_Version : 3, - ISO_Version : 2, - Response_Data_Format : 4, - reserved_0 : 3, - AERC : 1 ; - u32 Additional_Length : 8, - reserved_1 :16, - SftReset : 1, - CmdQue : 1, - reserved_2 : 1, - Linked : 1, - Sync : 1, - WBus16 : 1, - WBus32 : 1, - RelAdr : 1 ; - u8 Vendor_ID[8]; - u8 Product_ID[16]; - u8 Revision_Level [4]; -#ifdef USE_SCSI_COMPLETE_INQDATA - u8 Vendor_Specific[20]; - u8 reserved_3[40]; -#endif - * - */ - -} SCSI_Inquiry_Data_t; - -#define INQ_PERIPHINFO_BYTE 0 -#define INQ_Periph_Qualifier_MASK 0xe0 -#define INQ_Periph_Device_Type_MASK 0x1f - -#define INQ_Peripheral_Qualifier(inqp) \ - (int)((*((u8*)(inqp)+INQ_PERIPHINFO_BYTE) & INQ_Periph_Qualifier_MASK) >> 5) -#define INQ_Peripheral_Device_Type(inqp) \ - (int)(*((u8*)(inqp)+INQ_PERIPHINFO_BYTE) & INQ_Periph_Device_Type_MASK) - - -#define INQ_DEVTYPEMOD_BYTE 1 -#define INQ_RMB_BIT 0x80 -#define INQ_Device_Type_Modifier_MASK 0x7f - -#define INQ_Removable_Medium(inqp) \ - (int)(*((u8*)(inqp)+INQ_DEVTYPEMOD_BYTE) & INQ_RMB_BIT) -#define INQ_Device_Type_Modifier(inqp) \ - (int)(*((u8*)(inqp)+INQ_DEVTYPEMOD_BYTE) & INQ_Device_Type_Modifier_MASK) - - -#define INQ_VERSIONINFO_BYTE 2 -#define INQ_ISO_Version_MASK 0xc0 -#define INQ_ECMA_Version_MASK 0x38 -#define INQ_ANSI_Version_MASK 0x07 - -#define INQ_ISO_Version(inqp) \ - (int)(*((u8*)(inqp)+INQ_VERSIONINFO_BYTE) & INQ_ISO_Version_MASK) -#define INQ_ECMA_Version(inqp) \ - (int)(*((u8*)(inqp)+INQ_VERSIONINFO_BYTE) & INQ_ECMA_Version_MASK) -#define INQ_ANSI_Version(inqp) \ - (int)(*((u8*)(inqp)+INQ_VERSIONINFO_BYTE) & INQ_ANSI_Version_MASK) - - -#define INQ_BYTE3 3 -#define INQ_AERC_BIT 0x80 -#define INQ_TrmTsk_BIT 0x40 -#define INQ_NormACA_BIT 0x20 -#define INQ_RDF_MASK 0x0F - -#define INQ_AER_Capable(inqp) \ - (int)(*((u8*)(inqp)+INQ_BYTE3) & INQ_AERC_BIT) -#define INQ_TrmTsk(inqp) \ - (int)(*((u8*)(inqp)+INQ_BYTE3) & INQ_TrmTsk_BIT) -#define INQ_NormACA(inqp) \ - (int)(*((u8*)(inqp)+INQ_BYTE3) & INQ_NormACA_BIT) -#define INQ_Response_Data_Format(inqp) \ - (int)(*((u8*)(inqp)+INQ_BYTE3) & INQ_RDF_MASK) - - -#define INQ_CAPABILITY_BYTE 7 -#define INQ_RelAdr_BIT 0x80 -#define INQ_WBus32_BIT 0x40 -#define INQ_WBus16_BIT 0x20 -#define INQ_Sync_BIT 0x10 -#define INQ_Linked_BIT 0x08 - /* INQ_Reserved BIT 0x40 */ -#define INQ_CmdQue_BIT 0x02 -#define INQ_SftRe_BIT 0x01 - -#define IS_RelAdr_DEV(inqp) \ - (int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_RelAdr_BIT) -#define IS_WBus32_DEV(inqp) \ - (int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_WBus32_BIT) -#define IS_WBus16_DEV(inqp) \ - (int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_WBus16_BIT) -#define IS_Sync_DEV(inqp) \ - (int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_Sync_BIT) -#define IS_Linked_DEV(inqp) \ - (int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_Linked_BIT) -#define IS_CmdQue_DEV(inqp) \ - (int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_CmdQue_BIT) -#define IS_SftRe_DEV(inqp) \ - (int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_SftRe_BIT) - -#define INQ_Width_BITS \ - (INQ_WBus32_BIT | INQ_WBus16_BIT) -#define IS_Wide_DEV(inqp) \ - (int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_Width_BITS) - - -/* - * SCSI peripheral device types - */ -#define SCSI_TYPE_DAD 0x00 /* Direct Access Device */ -#define SCSI_TYPE_SAD 0x01 /* Sequential Access Device */ -#define SCSI_TYPE_TAPE SCSI_TYPE_SAD -#define SCSI_TYPE_PRT 0x02 /* Printer */ -#define SCSI_TYPE_PROC 0x03 /* Processor */ -#define SCSI_TYPE_WORM 0x04 -#define SCSI_TYPE_CDROM 0x05 -#define SCSI_TYPE_SCAN 0x06 /* Scanner */ -#define SCSI_TYPE_OPTICAL 0x07 /* Magneto/Optical */ -#define SCSI_TYPE_CHANGER 0x08 -#define SCSI_TYPE_COMM 0x09 /* Communications device */ -#define SCSI_TYPE_UNKNOWN 0x1f -#define SCSI_TYPE_UNCONFIGURED_LUN 0x7f - -#define SCSI_TYPE_MAX_KNOWN SCSI_TYPE_COMM - -/* - * Peripheral Qualifiers - */ -#define DEVICE_PRESENT 0x00 -#define LUN_NOT_PRESENT 0x01 -#define LUN_NOT_SUPPORTED 0x03 - -/* - * ANSI Versions - */ -#ifndef SCSI_1 -#define SCSI_1 0x01 -#endif -#ifndef SCSI_2 -#define SCSI_2 0x02 -#endif -#ifndef SCSI_3 -#define SCSI_3 0x03 -#endif - - -#define SCSI_MAX_SENSE_BYTES 255 -#define SCSI_STD_SENSE_BYTES 18 -#define SCSI_PAD_SENSE_BYTES (SCSI_MAX_SENSE_BYTES - SCSI_STD_SENSE_BYTES) - -#undef USE_SCSI_COMPLETE_SENSE -/* - * Structure definition for SCSI Sense Data - * - * NOTE: The following structure is 255 bytes in size - * iiff USE_SCSI_COMPLETE_SENSE IS defined above (i.e. w/ "#define"). - * If USE_SCSI_COMPLETE_SENSE is NOT defined above (i.e. w/ "#undef") - * then the following structure is only 19 bytes in size. - * THE CHOICE IS YOURS! - * - */ -typedef struct SCSI_Sense_Data -{ -#ifdef USE_SCSI_COMPLETE_SENSE - u8 SenseByte[SCSI_MAX_SENSE_BYTES]; -#else - u8 SenseByte[SCSI_STD_SENSE_BYTES]; -#endif - -/* - * the following structure works only for little-endian (Intel, - * LSB first (1234) byte order) systems with 4-byte ints. - * - u8 Error_Code :4, // 0x00 - Error_Class :3, - Valid :1 - ; - u8 Segment_Number // 0x01 - ; - u8 Sense_Key :4, // 0x02 - Reserved :1, - Incorrect_Length_Indicator:1, - End_Of_Media :1, - Filemark :1 - ; - u8 Information_MSB; // 0x03 - u8 Information_Byte2; // 0x04 - u8 Information_Byte1; // 0x05 - u8 Information_LSB; // 0x06 - u8 Additional_Length; // 0x07 - - u32 Command_Specific_Information; // 0x08 - 0x0b - - u8 Additional_Sense_Code; // 0x0c - u8 Additional_Sense_Code_Qualifier; // 0x0d - u8 Field_Replaceable_Unit_Code; // 0x0e - u8 Illegal_Req_Bit_Pointer :3, // 0x0f - Illegal_Req_Bit_Valid :1, - Illegal_Req_Reserved :2, - Illegal_Req_Cmd_Data :1, - Sense_Key_Specific_Valid :1 - ; - u16 Sense_Key_Specific_Data; // 0x10 - 0x11 - -#ifdef USE_SCSI_COMPLETE_SENSE - u8 Additional_Sense_Data[SCSI_PAD_SENSE_BYTES]; -#else - u8 Additional_Sense_Data[1]; -#endif - * - */ - -} SCSI_Sense_Data_t; - - -#define SD_ERRCODE_BYTE 0 -#define SD_Valid_BIT 0x80 -#define SD_Error_Code_MASK 0x7f -#define SD_Valid(sdp) \ - (int)(*((u8*)(sdp)+SD_ERRCODE_BYTE) & SD_Valid_BIT) -#define SD_Error_Code(sdp) \ - (int)(*((u8*)(sdp)+SD_ERRCODE_BYTE) & SD_Error_Code_MASK) - - -#define SD_SEGNUM_BYTE 1 -#define SD_Segment_Number(sdp) (int)(*((u8*)(sdp)+SD_SEGNUM_BYTE)) - - -#define SD_SENSEKEY_BYTE 2 -#define SD_Filemark_BIT 0x80 -#define SD_EOM_BIT 0x40 -#define SD_ILI_BIT 0x20 -#define SD_Sense_Key_MASK 0x0f -#define SD_Filemark(sdp) \ - (int)(*((u8*)(sdp)+SD_SENSEKEY_BYTE) & SD_Filemark_BIT) -#define SD_EOM(sdp) \ - (int)(*((u8*)(sdp)+SD_SENSEKEY_BYTE) & SD_EOM_BIT) -#define SD_ILI(sdp) \ - (int)(*((u8*)(sdp)+SD_SENSEKEY_BYTE) & SD_ILI_BIT) -#define SD_Sense_Key(sdp) \ - (int)(*((u8*)(sdp)+SD_SENSEKEY_BYTE) & SD_Sense_Key_MASK) - - -#define SD_INFO3_BYTE 3 -#define SD_INFO2_BYTE 4 -#define SD_INFO1_BYTE 5 -#define SD_INFO0_BYTE 6 -#define SD_Information3(sdp) (int)(*((u8*)(sdp)+SD_INFO3_BYTE)) -#define SD_Information2(sdp) (int)(*((u8*)(sdp)+SD_INFO2_BYTE)) -#define SD_Information1(sdp) (int)(*((u8*)(sdp)+SD_INFO1_BYTE)) -#define SD_Information0(sdp) (int)(*((u8*)(sdp)+SD_INFO0_BYTE)) - - -#define SD_ADDL_LEN_BYTE 7 -#define SD_Additional_Sense_Length(sdp) \ - (int)(*((u8*)(sdp)+SD_ADDL_LEN_BYTE)) -#define SD_Addl_Sense_Len SD_Additional_Sense_Length - - -#define SD_CMD_SPECIFIC3_BYTE 8 -#define SD_CMD_SPECIFIC2_BYTE 9 -#define SD_CMD_SPECIFIC1_BYTE 10 -#define SD_CMD_SPECIFIC0_BYTE 11 -#define SD_Cmd_Specific_Info3(sdp) (int)(*((u8*)(sdp)+SD_CMD_SPECIFIC3_BYTE)) -#define SD_Cmd_Specific_Info2(sdp) (int)(*((u8*)(sdp)+SD_CMD_SPECIFIC2_BYTE)) -#define SD_Cmd_Specific_Info1(sdp) (int)(*((u8*)(sdp)+SD_CMD_SPECIFIC1_BYTE)) -#define SD_Cmd_Specific_Info0(sdp) (int)(*((u8*)(sdp)+SD_CMD_SPECIFIC0_BYTE)) - - -#define SD_ADDL_SENSE_CODE_BYTE 12 -#define SD_Additional_Sense_Code(sdp) \ - (int)(*((u8*)(sdp)+SD_ADDL_SENSE_CODE_BYTE)) -#define SD_Addl_Sense_Code SD_Additional_Sense_Code -#define SD_ASC SD_Additional_Sense_Code - - -#define SD_ADDL_SENSE_CODE_QUAL_BYTE 13 -#define SD_Additional_Sense_Code_Qualifier(sdp) \ - (int)(*((u8*)(sdp)+SD_ADDL_SENSE_CODE_QUAL_BYTE)) -#define SD_Addl_Sense_Code_Qual SD_Additional_Sense_Code_Qualifier -#define SD_ASCQ SD_Additional_Sense_Code_Qualifier - - -#define SD_FIELD_REPL_UNIT_CODE_BYTE 14 -#define SD_Field_Replaceable_Unit_Code(sdp) \ - (int)(*((u8*)(sdp)+SD_FIELD_REPL_UNIT_CODE_BYTE)) -#define SD_Field_Repl_Unit_Code SD_Field_Replaceable_Unit_Code -#define SD_FRUC SD_Field_Replaceable_Unit_Code -#define SD_FRU SD_Field_Replaceable_Unit_Code - - -/* - * Sense-Key Specific offsets and macros. - */ -#define SD_SKS2_BYTE 15 -#define SD_SKS_Valid_BIT 0x80 -#define SD_SKS_Cmd_Data_BIT 0x40 -#define SD_SKS_Bit_Ptr_Valid_BIT 0x08 -#define SD_SKS_Bit_Ptr_MASK 0x07 -#define SD_SKS1_BYTE 16 -#define SD_SKS0_BYTE 17 -#define SD_Sense_Key_Specific_Valid(sdp) \ - (int)(*((u8*)(sdp)+SD_SKS2_BYTE) & SD_SKS_Valid_BIT) -#define SD_SKS_Valid SD_Sense_Key_Specific_Valid -#define SD_SKS_CDB_Error(sdp) \ - (int)(*((u8*)(sdp)+SD_SKS2_BYTE) & SD_SKS_Cmd_Data_BIT) -#define SD_Was_Illegal_Request SD_SKS_CDB_Error -#define SD_SKS_Bit_Pointer_Valid(sdp) \ - (int)(*((u8*)(sdp)+SD_SKS2_BYTE) & SD_SKS_Bit_Ptr_Valid_BIT) -#define SD_SKS_Bit_Pointer(sdp) \ - (int)(*((u8*)(sdp)+SD_SKS2_BYTE) & SD_SKS_Bit_Ptr_MASK) -#define SD_Field_Pointer(sdp) \ - (int)( ((u16)(*((u8*)(sdp)+SD_SKS1_BYTE)) << 8) \ - + *((u8*)(sdp)+SD_SKS0_BYTE) ) -#define SD_Bad_Byte SD_Field_Pointer -#define SD_Actual_Retry_Count SD_Field_Pointer -#define SD_Progress_Indication SD_Field_Pointer - -/* - * Mode Sense Write Protect Mask - */ -#define WRITE_PROTECT_MASK 0X80 - -/* - * Medium Type Codes - */ -#define OPTICAL_DEFAULT 0x00 -#define OPTICAL_READ_ONLY_MEDIUM 0x01 -#define OPTICAL_WRITE_ONCE_MEDIUM 0x02 -#define OPTICAL_READ_WRITABLE_MEDIUM 0x03 -#define OPTICAL_RO_OR_WO_MEDIUM 0x04 -#define OPTICAL_RO_OR_RW_MEDIUM 0x05 -#define OPTICAL_WO_OR_RW_MEDIUM 0x06 - - - -/* - * Structure definition for READ6, WRITE6 (6-byte CDB) - */ -typedef struct SCSI_RW6_CDB -{ - u32 OpCode :8, - LBA_HI :5, /* 5 MSBit's of the LBA */ - Lun :3, - LBA_MID :8, /* NOTE: total of 21 bits in LBA */ - LBA_LO :8 ; /* Max LBA = 0x001fffff */ - u8 BlockCount; - u8 Control; -} SCSI_RW6_t; - -#define MAX_RW6_LBA ((u32)0x001fffff) - -/* - * Structure definition for READ10, WRITE10 (10-byte CDB) - * - * NOTE: ParityCheck bit is applicable only for VERIFY and WRITE VERIFY for - * the ADP-92 DAC only. In the SCSI2 spec. this same bit is defined as a - * FUA (forced unit access) bit for READs and WRITEs. Since this driver - * does not use the FUA, this bit is defined as it is used by the ADP-92. - * Also, for READ CAPACITY, only the OpCode field is used. - */ -typedef struct SCSI_RW10_CDB -{ - u8 OpCode; - u8 Reserved1; - u32 LBA; - u8 Reserved2; - u16 BlockCount; - u8 Control; -} SCSI_RW10_t; - -#define PARITY_CHECK 0x08 /* parity check bit - byte[1], bit 3 */ - - /* - * Structure definition for data returned by READ CAPACITY cmd; - * READ CAPACITY data - */ - typedef struct READ_CAP_DATA - { - u32 MaxLBA; - u32 BlockBytes; - } SCSI_READ_CAP_DATA_t, *pSCSI_READ_CAP_DATA_t; - - -/* - * Structure definition for FORMAT UNIT CDB (6-byte CDB) - */ -typedef struct _SCSI_FORMAT_UNIT -{ - u8 OpCode; - u8 Reserved1; - u8 VendorSpecific; - u16 Interleave; - u8 Control; -} SCSI_FORMAT_UNIT_t; - -/* - * Structure definition for REQUEST SENSE (6-byte CDB) - */ -typedef struct _SCSI_REQUEST_SENSE -{ - u8 OpCode; - u8 Reserved1; - u8 Reserved2; - u8 Reserved3; - u8 AllocLength; - u8 Control; -} SCSI_REQ_SENSE_t; - -/* - * Structure definition for REPORT LUNS (12-byte CDB) - */ -typedef struct _SCSI_REPORT_LUNS -{ - u8 OpCode; - u8 Reserved1[5]; - u32 AllocationLength; - u8 Reserved2; - u8 Control; -} SCSI_REPORT_LUNS_t, *pSCSI_REPORT_LUNS_t; - - /* - * (per-level) LUN information bytes - */ -/* - * Following doesn't work on ARMCC compiler - * [apparently] because it pads every struct - * to be multiple of 4 bytes! - * So SCSI_LUN_LEVELS_t winds up being 16 - * bytes instead of 8! - * - typedef struct LUN_INFO - { - u8 AddrMethod_plus_LunOrBusNumber; - u8 LunOrTarget; - } SCSI_LUN_INFO_t, *pSCSI_LUN_INFO_t; - - typedef struct LUN_LEVELS - { - SCSI_LUN_INFO_t LUN_0; - SCSI_LUN_INFO_t LUN_1; - SCSI_LUN_INFO_t LUN_2; - SCSI_LUN_INFO_t LUN_3; - } SCSI_LUN_LEVELS_t, *pSCSI_LUN_LEVELS_t; -*/ - /* - * All 4 levels (8 bytes) of LUN information - */ - typedef struct LUN_LEVELS - { - u8 LVL1_AddrMethod_plus_LunOrBusNumber; - u8 LVL1_LunOrTarget; - u8 LVL2_AddrMethod_plus_LunOrBusNumber; - u8 LVL2_LunOrTarget; - u8 LVL3_AddrMethod_plus_LunOrBusNumber; - u8 LVL3_LunOrTarget; - u8 LVL4_AddrMethod_plus_LunOrBusNumber; - u8 LVL4_LunOrTarget; - } SCSI_LUN_LEVELS_t, *pSCSI_LUN_LEVELS_t; - - /* - * Structure definition for data returned by REPORT LUNS cmd; - * LUN reporting parameter list format - */ - typedef struct LUN_REPORT - { - u32 LunListLength; - u32 Reserved; - SCSI_LUN_LEVELS_t LunInfo[1]; - } SCSI_LUN_REPORT_t, *pSCSI_LUN_REPORT_t; - -/**************************************************************************** - * - * Externals - */ - -/**************************************************************************** - * - * Public Typedefs & Related Defines - */ - -/**************************************************************************** - * - * Macros (embedded, above) - */ - -/**************************************************************************** - * - * Public Variables - */ - -/**************************************************************************** - * - * Public Prototypes (module entry points) - */ - - -/***************************************************************************/ -#endif diff --git a/drivers/message/fusion/scsiops.c b/drivers/message/fusion/scsiops.c deleted file mode 100644 index 2143e42ab..000000000 --- a/drivers/message/fusion/scsiops.c +++ /dev/null @@ -1,309 +0,0 @@ - -static const char *ScsiOpcodeString[256] = { - "TEST UNIT READY\0\01", /* 00h */ - "REWIND\0\002" - "\001REZERO UNIT", /* 01h */ - "\0\0", /* 02h */ - "REQUEST SENSE\0\01", /* 03h */ - "FORMAT UNIT\0\03" - "\001FORMAT MEDIUM\0" - "\002FORMAT", /* 04h */ - "READ BLOCK LIMITS\0\1", /* 05h */ - "\0\0", /* 06h */ - "REASSIGN BLOCKS\0\02" - "\010INITIALIZE ELEMENT STATUS", /* 07h */ - "READ(06)\0\04" - "\001READ\0" - "\003RECEIVE\0" - "\011GET MESSAGE(06)", /* 08h */ - "\0\0", /* 09h */ - "WRITE(06)\0\05" - "\001WRITE\0" - "\002PRINT\0" - "\003SEND(6)\0" - "\011SEND MESSAGE(06)", /* 0Ah */ - "SEEK(06)\0\02" - "\003SLEW AND PRINT", /* 0Bh */ - "\0\0", /* 0Ch */ - "\0\0", /* 0Dh */ - "\0\0", /* 0Eh */ - "READ REVERSE\0\01", /* 0Fh */ - "WRITE FILEMARKS\0\02" - "\003SYNCRONIZE BUFFER", /* 10h */ - "SPACE(6)\0\01", /* 11h */ - "INQUIRY\0\01", /* 12h */ - "VERIFY\0\01", /* 13h */ - "RECOVER BUFFERED DATA\0\01", /* 14h */ - "MODE SELECT(06)\0\01", /* 15h */ - "RESERVE(06)\0\02" - "\010RESERVE ELEMENT(06)", /* 16h */ - "RELEASE(06)\0\02" - "\010RELEASE ELEMENT(06)", /* 17h */ - "COPY\0\01", /* 18h */ - "ERASE\0\01", /* 19h */ - "MODE SENSE(06)\0\01", /* 1Ah */ - "STOP START UNIT\0\04" - "\001LOAD UNLOAD\0" - "\002STOP PRINT\0" - "\006SCAN\0\002", /* 1Bh */ - "RECEIVE DIAGNOSTIC RESULTS\0\01", /* 1Ch */ - "SEND DIAGNOSTIC\0\01", /* 1Dh */ - "PREVENT ALLOW MEDIUM REMOVAL\0\01", /* 1Eh */ - "\0\0", /* 1Fh */ - "\0\0", /* 20h */ - "\0\0", /* 21h */ - "\0\0", /* 22h */ - "READ FORMAT CAPACITIES\0\01", /* 23h */ - "SET WINDOW\0\01", /* 24h */ - "READ CAPACITY\0\03" - "\006GET WINDOW\0" - "\037FREAD CARD CAPACITY", /* 25h */ - "\0\0", /* 26h */ - "\0\0", /* 27h */ - "READ(10)\0\02" - "\011GET MESSAGE(10)", /* 28h */ - "READ GENERATION\0\01", /* 29h */ - "WRITE(10)\0\03" - "\011SEND(10)\0" - "\011SEND MESSAGE(10)", /* 2Ah */ - "SEEK(10)\0\03" - "LOCATE(10)\0" - "POSITION TO ELEMENT", /* 2Bh */ - "ERASE(10)\0\01", /* 2Ch */ - "READ UPDATED BLOCK\0\01", /* 2Dh */ - "WRITE AND VERIFY(10)\0\01", /* 2Eh */ - "VERIFY(10)\0\01", /* 2Fh */ - "SEARCH DATA HIGH(10)\0\01", /* 30h */ - "SEARCH DATA EQUAL(10)\0\02" - "OBJECT POSITION", /* 31h */ - "SEARCH DATA LOW(10)\0\01", /* 32h */ - "SET LIMITS(10)\0\01", /* 33h */ - "PRE-FETCH(10)\0\03" - "READ POSITION\0" - "GET DATA BUFFER STATUS", /* 34h */ - "SYNCHRONIZE CACHE(10)\0\01", /* 35h */ - "LOCK UNLOCK CACHE(10)\0\01", /* 36h */ - "READ DEFECT DATA(10)\0\01", /* 37h */ - "MEDIUM SCAN\0\01", /* 38h */ - "COMPARE\0\01", /* 39h */ - "COPY AND VERIFY\0\01", /* 3Ah */ - "WRITE BUFFER\0\01", /* 3Bh */ - "READ BUFFER\0\01", /* 3Ch */ - "UPDATE BLOCK\0\01", /* 3Dh */ - "READ LONG\0\01", /* 3Eh */ - "WRITE LONG\0\01", /* 3Fh */ - "CHANGE DEFINITION\0\01", /* 40h */ - "WRITE SAME(10)\0\01", /* 41h */ - "READ SUB-CHANNEL\0\01", /* 42h */ - "READ TOC/PMA/ATIP\0\01", /* 43h */ - "REPORT DENSITY SUPPORT\0\01", /* 44h */ - "READ HEADER\0\01", /* 44h */ - "PLAY AUDIO(10)\0\01", /* 45h */ - "GET CONFIGURATION\0\01", /* 46h */ - "PLAY AUDIO MSF\0\01", /* 47h */ - "PLAY AUDIO TRACK INDEX\0\01", /* 48h */ - "PLAY TRACK RELATIVE(10)\0\01", /* 49h */ - "GET EVENT STATUS NOTIFICATION\0\01", /* 4Ah */ - "PAUSE/RESUME\0\01", /* 4Bh */ - "LOG SELECT\0\01", /* 4Ch */ - "LOG SENSE\0\01", /* 4Dh */ - "STOP PLAY/SCAN\0\01", /* 4Eh */ - "\0\0", /* 4Fh */ - "XDWRITE(10)\0\01", /* 50h */ - "XPWRITE(10)\0\02" - "READ DISC INFORMATION", /* 51h */ - "XDREAD(10)\0\01" - "READ TRACK INFORMATION", /* 52h */ - "RESERVE TRACK\0\01", /* 53h */ - "SEND OPC INFORMATION\0\01", /* 54h */ - "MODE SELECT(10)\0\01", /* 55h */ - "RESERVE(10)\0\02" - "RESERVE ELEMENT(10)", /* 56h */ - "RELEASE(10)\0\02" - "RELEASE ELEMENT(10)", /* 57h */ - "REPAIR TRACK\0\01", /* 58h */ - "READ MASTER CUE\0\01", /* 59h */ - "MODE SENSE(10)\0\01", /* 5Ah */ - "CLOSE TRACK/SESSION\0\01", /* 5Bh */ - "READ BUFFER CAPACITY\0\01", /* 5Ch */ - "SEND CUE SHEET\0\01", /* 5Dh */ - "PERSISTENT RESERVE IN\0\01", /* 5Eh */ - "PERSISTENT RESERVE OUT\0\01", /* 5Fh */ - "\0\0", /* 60h */ - "\0\0", /* 61h */ - "\0\0", /* 62h */ - "\0\0", /* 63h */ - "\0\0", /* 64h */ - "\0\0", /* 65h */ - "\0\0", /* 66h */ - "\0\0", /* 67h */ - "\0\0", /* 68h */ - "\0\0", /* 69h */ - "\0\0", /* 6Ah */ - "\0\0", /* 6Bh */ - "\0\0", /* 6Ch */ - "\0\0", /* 6Dh */ - "\0\0", /* 6Eh */ - "\0\0", /* 6Fh */ - "\0\0", /* 70h */ - "\0\0", /* 71h */ - "\0\0", /* 72h */ - "\0\0", /* 73h */ - "\0\0", /* 74h */ - "\0\0", /* 75h */ - "\0\0", /* 76h */ - "\0\0", /* 77h */ - "\0\0", /* 78h */ - "\0\0", /* 79h */ - "\0\0", /* 7Ah */ - "\0\0", /* 7Bh */ - "\0\0", /* 7Ch */ - "\0\0", /* 7Eh */ - "\0\0", /* 7Eh */ - "\0\0", /* 7Fh */ - "XDWRITE EXTENDED(16)\0\01", /* 80h */ - "REBUILD(16)\0\01", /* 81h */ - "REGENERATE(16)\0\01", /* 82h */ - "EXTENDED COPY\0\01", /* 83h */ - "RECEIVE COPY RESULTS\0\01", /* 84h */ - "ACCESS CONTROL IN [proposed]\0\01", /* 86h */ - "ACCESS CONTROL OUT [proposed]\0\01", /* 87h */ - "READ(16)\0\01", /* 88h */ - "DEVICE LOCKS [proposed]\0\01", /* 89h */ - "WRITE(16)\0\01", /* 8Ah */ - "\0\0", /* 8Bh */ - "READ ATTRIBUTES [proposed]\0\01", /* 8Ch */ - "WRITE ATTRIBUTES [proposed]\0\01", /* 8Dh */ - "WRITE AND VERIFY(16)\0\01", /* 8Eh */ - "VERIFY(16)\0\01", /* 8Fh */ - "PRE-FETCH(16)\0\01", /* 90h */ - "SYNCHRONIZE CACHE(16)\0\02" - "SPACE(16) [1]", /* 91h */ - "LOCK UNLOCK CACHE(16)\0\02" - "LOCATE(16) [1]", /* 92h */ - "WRITE SAME(16)\0\01", /* 93h */ - "[usage proposed by SCSI Socket Services project]\0\01", /* 94h */ - "[usage proposed by SCSI Socket Services project]\0\01", /* 95h */ - "[usage proposed by SCSI Socket Services project]\0\01", /* 96h */ - "[usage proposed by SCSI Socket Services project]\0\01", /* 97h */ - "MARGIN CONTROL [proposed]\0\01", /* 98h */ - "\0\0", /* 99h */ - "\0\0", /* 9Ah */ - "\0\0", /* 9Bh */ - "\0\0", /* 9Ch */ - "\0\0", /* 9Dh */ - "SERVICE ACTION IN [proposed]\0\01", /* 9Eh */ - "SERVICE ACTION OUT [proposed]\0\01", /* 9Fh */ - "REPORT LUNS\0\01", /* A0h */ - "BLANK\0\01", /* A1h */ - "SEND EVENT\0\01", /* A2h */ - "MAINTENANCE (IN)\0\02" - "SEND KEY", /* A3h */ - "MAINTENANCE (OUT)\0\02" - "REPORT KEY", /* A4h */ - "MOVE MEDIUM\0\02" - "PLAY AUDIO(12)", /* A5h */ - "EXCHANGE MEDIUM\0\02" - "LOAD/UNLOAD C/DVD", /* A6h */ - "MOVE MEDIUM ATTACHED\0\02" - "SET READ AHEAD\0\01", /* A7h */ - "READ(12)\0\02" - "GET MESSAGE(12)", /* A8h */ - "PLAY TRACK RELATIVE(12)\0\01", /* A9h */ - "WRITE(12)\0\02" - "SEND MESSAGE(12)", /* AAh */ - "\0\0", /* ABh */ - "ERASE(12)\0\02" - "GET PERFORMANCE", /* ACh */ - "READ DVD STRUCTURE\0\01", /* ADh */ - "WRITE AND VERIFY(12)\0\01", /* AEh */ - "VERIFY(12)\0\01", /* AFh */ - "SEARCH DATA HIGH(12)\0\01", /* B0h */ - "SEARCH DATA EQUAL(12)\0\01", /* B1h */ - "SEARCH DATA LOW(12)\0\01", /* B2h */ - "SET LIMITS(12)\0\01", /* B3h */ - "READ ELEMENT STATUS ATTACHED\0\01", /* B4h */ - "REQUEST VOLUME ELEMENT ADDRESS\0\01", /* B5h */ - "SEND VOLUME TAG\0\02" - "SET STREAMING", /* B6h */ - "READ DEFECT DATA(12)\0\01", /* B7h */ - "READ ELEMENT STATUS\0\01", /* B8h */ - "READ CD MSF\0\01", /* B9h */ - "REDUNDANCY GROUP (IN)\0\02" - "SCAN", /* BAh */ - "REDUNDANCY GROUP (OUT)\0\02" - "SET CD-ROM SPEED", /* BBh */ - "SPARE (IN)\0\02" - "PLAY CD", /* BCh */ - "SPARE (OUT)\0\02" - "MECHANISM STATUS", /* BDh */ - "VOLUME SET (IN)\0\02" - "READ CD", /* BEh */ - "VOLUME SET (OUT)\0\0\02" - "SEND DVD STRUCTURE", /* BFh */ - "\0\0", /* C0h */ - "\0\0", /* C1h */ - "\0\0", /* C2h */ - "\0\0", /* C3h */ - "\0\0", /* C4h */ - "\0\0", /* C5h */ - "\0\0", /* C6h */ - "\0\0", /* C7h */ - "\0\0", /* C8h */ - "\0\0", /* C9h */ - "\0\0", /* CAh */ - "\0\0", /* CBh */ - "\0\0", /* CCh */ - "\0\0", /* CDh */ - "\0\0", /* CEh */ - "\0\0", /* CFh */ - "\0\0", /* D0h */ - "\0\0", /* D1h */ - "\0\0", /* D2h */ - "\0\0", /* D3h */ - "\0\0", /* D4h */ - "\0\0", /* D5h */ - "\0\0", /* D6h */ - "\0\0", /* D7h */ - "\0\0", /* D8h */ - "\0\0", /* D9h */ - "\0\0", /* DAh */ - "\0\0", /* DBh */ - "\0\0", /* DCh */ - "\0\0", /* DEh */ - "\0\0", /* DEh */ - "\0\0", /* DFh */ - "\0\0", /* E0h */ - "\0\0", /* E1h */ - "\0\0", /* E2h */ - "\0\0", /* E3h */ - "\0\0", /* E4h */ - "\0\0", /* E5h */ - "\0\0", /* E6h */ - "\0\0", /* E7h */ - "\0\0", /* E8h */ - "\0\0", /* E9h */ - "\0\0", /* EAh */ - "\0\0", /* EBh */ - "\0\0", /* ECh */ - "\0\0", /* EDh */ - "\0\0", /* EEh */ - "\0\0", /* EFh */ - "\0\0", /* F0h */ - "\0\0", /* F1h */ - "\0\0", /* F2h */ - "\0\0", /* F3h */ - "\0\0", /* F4h */ - "\0\0", /* F5h */ - "\0\0", /* F6h */ - "\0\0", /* F7h */ - "\0\0", /* F8h */ - "\0\0", /* F9h */ - "\0\0", /* FAh */ - "\0\0", /* FBh */ - "\0\0", /* FEh */ - "\0\0", /* FEh */ - "\0\0", /* FEh */ - "\0\0" /* FFh */ -}; - diff --git a/drivers/message/i2o/i2o_core.c b/drivers/message/i2o/i2o_core.c deleted file mode 100644 index 66fa24b3f..000000000 --- a/drivers/message/i2o/i2o_core.c +++ /dev/null @@ -1,3978 +0,0 @@ -/* - * Core I2O structure management - * - * (C) Copyright 1999-2002 Red Hat Software - * - * Written by Alan Cox, Building Number Three Ltd - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * A lot of the I2O message side code from this is taken from the - * Red Creek RCPCI45 adapter driver by Red Creek Communications - * - * Fixes/additions: - * Philipp Rumpf - * Juha Sievänen - * Auvo Häkkinen - * Deepak Saxena - * Boji T Kannanthanam - * Alan Cox : - * Ported to Linux 2.5. - * Markus Lidel : - * Minor fixes for 2.6. - * - */ - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#ifdef CONFIG_MTRR -#include -#endif // CONFIG_MTRR - -#include "i2o_lan.h" - -//#define DRIVERDEBUG - -#ifdef DRIVERDEBUG -#define dprintk(s, args...) printk(s, ## args) -#else -#define dprintk(s, args...) -#endif - -/* OSM table */ -static struct i2o_handler *i2o_handlers[MAX_I2O_MODULES]; - -/* Controller list */ -static struct i2o_controller *i2o_controllers[MAX_I2O_CONTROLLERS]; -struct i2o_controller *i2o_controller_chain; -int i2o_num_controllers; - -/* Initiator Context for Core message */ -static int core_context; - -/* Initialization && shutdown functions */ -void i2o_sys_init(void); -static void i2o_sys_shutdown(void); -static int i2o_reset_controller(struct i2o_controller *); -static int i2o_reboot_event(struct notifier_block *, unsigned long , void *); -static int i2o_online_controller(struct i2o_controller *); -static int i2o_init_outbound_q(struct i2o_controller *); -static int i2o_post_outbound_messages(struct i2o_controller *); - -/* Reply handler */ -static void i2o_core_reply(struct i2o_handler *, struct i2o_controller *, - struct i2o_message *); - -/* Various helper functions */ -static int i2o_lct_get(struct i2o_controller *); -static int i2o_lct_notify(struct i2o_controller *); -static int i2o_hrt_get(struct i2o_controller *); - -static int i2o_build_sys_table(void); -static int i2o_systab_send(struct i2o_controller *c); - -/* I2O core event handler */ -static int i2o_core_evt(void *); -static int evt_pid; -static int evt_running; - -/* Dynamic LCT update handler */ -static int i2o_dyn_lct(void *); - -void i2o_report_controller_unit(struct i2o_controller *, struct i2o_device *); - -static void i2o_pci_dispose(struct i2o_controller *c); - -/* - * I2O System Table. Contains information about - * all the IOPs in the system. Used to inform IOPs - * about each other's existence. - * - * sys_tbl_ver is the CurrentChangeIndicator that is - * used by IOPs to track changes. - */ -static struct i2o_sys_tbl *sys_tbl; -static int sys_tbl_ind; -static int sys_tbl_len; - -/* - * This spin lock is used to keep a device from being - * added and deleted concurrently across CPUs or interrupts. - * This can occur when a user creates a device and immediatelly - * deletes it before the new_dev_notify() handler is called. - */ -static spinlock_t i2o_dev_lock = SPIN_LOCK_UNLOCKED; - -/* - * Structures and definitions for synchronous message posting. - * See i2o_post_wait() for description. - */ -struct i2o_post_wait_data -{ - int *status; /* Pointer to status block on caller stack */ - int *complete; /* Pointer to completion flag on caller stack */ - u32 id; /* Unique identifier */ - wait_queue_head_t *wq; /* Wake up for caller (NULL for dead) */ - struct i2o_post_wait_data *next; /* Chain */ - void *mem[2]; /* Memory blocks to recover on failure path */ - dma_addr_t phys[2]; /* Physical address of blocks to recover */ - u32 size[2]; /* Size of blocks to recover */ -}; - -static struct i2o_post_wait_data *post_wait_queue; -static u32 post_wait_id; // Unique ID for each post_wait -static spinlock_t post_wait_lock = SPIN_LOCK_UNLOCKED; -static void i2o_post_wait_complete(struct i2o_controller *, u32, int); - -/* OSM descriptor handler */ -static struct i2o_handler i2o_core_handler = -{ - (void *)i2o_core_reply, - NULL, - NULL, - NULL, - "I2O core layer", - 0, - I2O_CLASS_EXECUTIVE -}; - -/* - * Used when queueing a reply to be handled later - */ - -struct reply_info -{ - struct i2o_controller *iop; - u32 msg[MSG_FRAME_SIZE]; -}; -static struct reply_info evt_reply; -static struct reply_info events[I2O_EVT_Q_LEN]; -static int evt_in; -static int evt_out; -static int evt_q_len; -#define MODINC(x,y) ((x) = ((x) + 1) % (y)) - -/* - * I2O configuration spinlock. This isnt a big deal for contention - * so we have one only - */ - -static DECLARE_MUTEX(i2o_configuration_lock); - -/* - * Event spinlock. Used to keep event queue sane and from - * handling multiple events simultaneously. - */ -static spinlock_t i2o_evt_lock = SPIN_LOCK_UNLOCKED; - -/* - * Semaphore used to synchronize event handling thread with - * interrupt handler. - */ - -static DECLARE_MUTEX(evt_sem); -static DECLARE_COMPLETION(evt_dead); -static DECLARE_WAIT_QUEUE_HEAD(evt_wait); - -static struct notifier_block i2o_reboot_notifier = -{ - i2o_reboot_event, - NULL, - 0 -}; - -/* - * Config options - */ - -static int verbose; - -#if BITS_PER_LONG == 64 -/** - * i2o_context_list_add - append an ptr to the context list and return a - * matching context id. - * @ptr: pointer to add to the context list - * @c: controller to which the context list belong - * returns context id, which could be used in the transaction context - * field. - * - * Because the context field in I2O is only 32-bit large, on 64-bit the - * pointer is to large to fit in the context field. The i2o_context_list - * functiones map pointers to context fields. - */ -u32 i2o_context_list_add(void *ptr, struct i2o_controller *c) { - u32 context = 1; - struct i2o_context_list_element **entry = &c->context_list; - struct i2o_context_list_element *element; - unsigned long flags; - - spin_lock_irqsave(&c->context_list_lock, flags); - while(*entry && ((*entry)->flags & I2O_CONTEXT_LIST_USED)) { - if((*entry)->context >= context) - context = (*entry)->context + 1; - entry = &((*entry)->next); - } - - if(!*entry) { - if(unlikely(!context)) { - spin_unlock_irqrestore(&c->context_list_lock, flags); - printk(KERN_EMERG "i2o_core: context list overflow\n"); - return 0; - } - - element = kmalloc(sizeof(struct i2o_context_list_element), GFP_KERNEL); - if(!element) { - printk(KERN_EMERG "i2o_core: could not allocate memory for context list element\n"); - return 0; - } - element->context = context; - element->next = NULL; - *entry = element; - } else - element = *entry; - - element->ptr = ptr; - element->flags = I2O_CONTEXT_LIST_USED; - - spin_unlock_irqrestore(&c->context_list_lock, flags); - dprintk(KERN_DEBUG "i2o_core: add context to list %p -> %d\n", ptr, context); - return context; -} - -/** - * i2o_context_list_remove - remove a ptr from the context list and return - * the matching context id. - * @ptr: pointer to be removed from the context list - * @c: controller to which the context list belong - * returns context id, which could be used in the transaction context - * field. - */ -u32 i2o_context_list_remove(void *ptr, struct i2o_controller *c) { - struct i2o_context_list_element **entry = &c->context_list; - struct i2o_context_list_element *element; - u32 context; - unsigned long flags; - - spin_lock_irqsave(&c->context_list_lock, flags); - while(*entry && ((*entry)->ptr != ptr)) - entry = &((*entry)->next); - - if(unlikely(!*entry)) { - spin_unlock_irqrestore(&c->context_list_lock, flags); - printk(KERN_WARNING "i2o_core: could not remove nonexistent ptr %p\n", ptr); - return 0; - } - - element = *entry; - - context = element->context; - element->ptr = NULL; - element->flags |= I2O_CONTEXT_LIST_DELETED; - - spin_unlock_irqrestore(&c->context_list_lock, flags); - dprintk(KERN_DEBUG "i2o_core: markt as deleted in context list %p -> %d\n", ptr, context); - return context; -} - -/** - * i2o_context_list_get - get a ptr from the context list and remove it - * from the list. - * @context: context id to which the pointer belong - * @c: controller to which the context list belong - * returns pointer to the matching context id - */ -void *i2o_context_list_get(u32 context, struct i2o_controller *c) { - struct i2o_context_list_element **entry = &c->context_list; - struct i2o_context_list_element *element; - void *ptr; - int count = 0; - unsigned long flags; - - spin_lock_irqsave(&c->context_list_lock, flags); - while(*entry && ((*entry)->context != context)) { - entry = &((*entry)->next); - count ++; - } - - if(unlikely(!*entry)) { - spin_unlock_irqrestore(&c->context_list_lock, flags); - printk(KERN_WARNING "i2o_core: context id %d not found\n", context); - return NULL; - } - - element = *entry; - ptr = element->ptr; - if(count >= I2O_CONTEXT_LIST_MIN_LENGTH) { - *entry = (*entry)->next; - kfree(element); - } else { - element->ptr = NULL; - element->flags &= !I2O_CONTEXT_LIST_USED; - } - - spin_unlock_irqrestore(&c->context_list_lock, flags); - dprintk(KERN_DEBUG "i2o_core: get ptr from context list %d -> %p\n", context, ptr); - return ptr; -} -#endif - -/* - * I2O Core reply handler - */ -static void i2o_core_reply(struct i2o_handler *h, struct i2o_controller *c, - struct i2o_message *m) -{ - u32 *msg=(u32 *)m; - u32 status; - u32 context = msg[2]; - - if (msg[0] & MSG_FAIL) // Fail bit is set - { - u32 *preserved_msg = (u32*)(c->msg_virt + msg[7]); - - i2o_report_status(KERN_INFO, "i2o_core", msg); - i2o_dump_message(preserved_msg); - - /* If the failed request needs special treatment, - * it should be done here. */ - - /* Release the preserved msg by resubmitting it as a NOP */ - - preserved_msg[0] = cpu_to_le32(THREE_WORD_MSG_SIZE | SGL_OFFSET_0); - preserved_msg[1] = cpu_to_le32(I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0); - preserved_msg[2] = 0; - i2o_post_message(c, msg[7]); - - /* If reply to i2o_post_wait failed, return causes a timeout */ - - return; - } - -#ifdef DRIVERDEBUG - i2o_report_status(KERN_INFO, "i2o_core", msg); -#endif - - if(msg[2]&0x80000000) // Post wait message - { - if (msg[4] >> 24) - status = (msg[4] & 0xFFFF); - else - status = I2O_POST_WAIT_OK; - - i2o_post_wait_complete(c, context, status); - return; - } - - if(m->function == I2O_CMD_UTIL_EVT_REGISTER) - { - memcpy(events[evt_in].msg, msg, (msg[0]>>16)<<2); - events[evt_in].iop = c; - - spin_lock(&i2o_evt_lock); - MODINC(evt_in, I2O_EVT_Q_LEN); - if(evt_q_len == I2O_EVT_Q_LEN) - MODINC(evt_out, I2O_EVT_Q_LEN); - else - evt_q_len++; - spin_unlock(&i2o_evt_lock); - - up(&evt_sem); - wake_up_interruptible(&evt_wait); - return; - } - - if(m->function == I2O_CMD_LCT_NOTIFY) - { - up(&c->lct_sem); - return; - } - - /* - * If this happens, we want to dump the message to the syslog so - * it can be sent back to the card manufacturer by the end user - * to aid in debugging. - * - */ - printk(KERN_WARNING "%s: Unsolicited message reply sent to core!" - "Message dumped to syslog\n", - c->name); - i2o_dump_message(msg); - - return; -} - -/** - * i2o_install_handler - install a message handler - * @h: Handler structure - * - * Install an I2O handler - these handle the asynchronous messaging - * from the card once it has initialised. If the table of handlers is - * full then -ENOSPC is returned. On a success 0 is returned and the - * context field is set by the function. The structure is part of the - * system from this time onwards. It must not be freed until it has - * been uninstalled - */ - -int i2o_install_handler(struct i2o_handler *h) -{ - int i; - down(&i2o_configuration_lock); - for(i=0;icontext = i; - i2o_handlers[i]=h; - up(&i2o_configuration_lock); - return 0; - } - } - up(&i2o_configuration_lock); - return -ENOSPC; -} - -/** - * i2o_remove_handler - remove an i2o message handler - * @h: handler - * - * Remove a message handler previously installed with i2o_install_handler. - * After this function returns the handler object can be freed or re-used - */ - -int i2o_remove_handler(struct i2o_handler *h) -{ - i2o_handlers[h->context]=NULL; - return 0; -} - - -/* - * Each I2O controller has a chain of devices on it. - * Each device has a pointer to its LCT entry to be used - * for fun purposes. - */ - -/** - * i2o_install_device - attach a device to a controller - * @c: controller - * @d: device - * - * Add a new device to an i2o controller. This can be called from - * non interrupt contexts only. It adds the device and marks it as - * unclaimed. The device memory becomes part of the kernel and must - * be uninstalled before being freed or reused. Zero is returned - * on success. - */ - -int i2o_install_device(struct i2o_controller *c, struct i2o_device *d) -{ - int i; - - down(&i2o_configuration_lock); - d->controller=c; - d->owner=NULL; - d->next=c->devices; - d->prev=NULL; - if (c->devices != NULL) - c->devices->prev=d; - c->devices=d; - *d->dev_name = 0; - - for(i = 0; i < I2O_MAX_MANAGERS; i++) - d->managers[i] = NULL; - - up(&i2o_configuration_lock); - return 0; -} - -/* we need this version to call out of i2o_delete_controller */ - -int __i2o_delete_device(struct i2o_device *d) -{ - struct i2o_device **p; - int i; - - p=&(d->controller->devices); - - /* - * Hey we have a driver! - * Check to see if the driver wants us to notify it of - * device deletion. If it doesn't we assume that it - * is unsafe to delete a device with an owner and - * fail. - */ - if(d->owner) - { - if(d->owner->dev_del_notify) - { - dprintk(KERN_INFO "Device has owner, notifying\n"); - d->owner->dev_del_notify(d->controller, d); - if(d->owner) - { - printk(KERN_WARNING - "Driver \"%s\" did not release device!\n", d->owner->name); - return -EBUSY; - } - } - else - return -EBUSY; - } - - /* - * Tell any other users who are talking to this device - * that it's going away. We assume that everything works. - */ - for(i=0; i < I2O_MAX_MANAGERS; i++) - { - if(d->managers[i] && d->managers[i]->dev_del_notify) - d->managers[i]->dev_del_notify(d->controller, d); - } - - while(*p!=NULL) - { - if(*p==d) - { - /* - * Destroy - */ - *p=d->next; - kfree(d); - return 0; - } - p=&((*p)->next); - } - printk(KERN_ERR "i2o_delete_device: passed invalid device.\n"); - return -EINVAL; -} - -/** - * i2o_delete_device - remove an i2o device - * @d: device to remove - * - * This function unhooks a device from a controller. The device - * will not be unhooked if it has an owner who does not wish to free - * it, or if the owner lacks a dev_del_notify function. In that case - * -EBUSY is returned. On success 0 is returned. Other errors cause - * negative errno values to be returned - */ - -int i2o_delete_device(struct i2o_device *d) -{ - int ret; - - down(&i2o_configuration_lock); - - /* - * Seek, locate - */ - - ret = __i2o_delete_device(d); - - up(&i2o_configuration_lock); - - return ret; -} - -/** - * i2o_install_controller - attach a controller - * @c: controller - * - * Add a new controller to the i2o layer. This can be called from - * non interrupt contexts only. It adds the controller and marks it as - * unused with no devices. If the tables are full or memory allocations - * fail then a negative errno code is returned. On success zero is - * returned and the controller is bound to the system. The structure - * must not be freed or reused until being uninstalled. - */ - -int i2o_install_controller(struct i2o_controller *c) -{ - int i; - down(&i2o_configuration_lock); - for(i=0;idlct = (i2o_lct*)pci_alloc_consistent(c->pdev, 8192, &c->dlct_phys); - if(c->dlct==NULL) - { - up(&i2o_configuration_lock); - return -ENOMEM; - } - i2o_controllers[i]=c; - c->devices = NULL; - c->next=i2o_controller_chain; - i2o_controller_chain=c; - c->unit = i; - c->page_frame = NULL; - c->hrt = NULL; - c->hrt_len = 0; - c->lct = NULL; - c->status_block = NULL; - sprintf(c->name, "i2o/iop%d", i); - i2o_num_controllers++; - init_MUTEX_LOCKED(&c->lct_sem); - up(&i2o_configuration_lock); - return 0; - } - } - printk(KERN_ERR "No free i2o controller slots.\n"); - up(&i2o_configuration_lock); - return -EBUSY; -} - -/** - * i2o_delete_controller - delete a controller - * @c: controller - * - * Remove an i2o controller from the system. If the controller or its - * devices are busy then -EBUSY is returned. On a failure a negative - * errno code is returned. On success zero is returned. - */ - -int i2o_delete_controller(struct i2o_controller *c) -{ - struct i2o_controller **p; - int users; - char name[16]; - int stat; - - dprintk(KERN_INFO "Deleting controller %s\n", c->name); - - /* - * Clear event registration as this can cause weird behavior - */ - if(c->status_block->iop_state == ADAPTER_STATE_OPERATIONAL) - i2o_event_register(c, core_context, 0, 0, 0); - - down(&i2o_configuration_lock); - if((users=atomic_read(&c->users))) - { - dprintk(KERN_INFO "I2O: %d users for controller %s\n", users, - c->name); - up(&i2o_configuration_lock); - return -EBUSY; - } - while(c->devices) - { - if(__i2o_delete_device(c->devices)<0) - { - /* Shouldnt happen */ - I2O_IRQ_WRITE32(c, 0xFFFFFFFF); - c->enabled = 0; - up(&i2o_configuration_lock); - return -EBUSY; - } - } - - /* - * If this is shutdown time, the thread's already been killed - */ - if(c->lct_running) { - stat = kill_proc(c->lct_pid, SIGKILL, 1); - if(!stat) { - int count = 10 * 100; - while(c->lct_running && --count) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); - } - - if(!count) - printk(KERN_ERR - "%s: LCT thread still running!\n", - c->name); - } - } - - p=&i2o_controller_chain; - - while(*p) - { - if(*p==c) - { - /* Ask the IOP to switch to RESET state */ - i2o_reset_controller(c); - - /* Release IRQ */ - i2o_pci_dispose(c); - - *p=c->next; - up(&i2o_configuration_lock); - - if(c->page_frame) - { - pci_unmap_single(c->pdev, c->page_frame_map, MSG_POOL_SIZE, PCI_DMA_FROMDEVICE); - kfree(c->page_frame); - } - if(c->hrt) - pci_free_consistent(c->pdev, c->hrt_len, c->hrt, c->hrt_phys); - if(c->lct) - pci_free_consistent(c->pdev, c->lct->table_size << 2, c->lct, c->lct_phys); - if(c->status_block) - pci_free_consistent(c->pdev, sizeof(i2o_status_block), c->status_block, c->status_block_phys); - if(c->dlct) - pci_free_consistent(c->pdev, 8192, c->dlct, c->dlct_phys); - - i2o_controllers[c->unit]=NULL; - memcpy(name, c->name, strlen(c->name)+1); - kfree(c); - dprintk(KERN_INFO "%s: Deleted from controller chain.\n", name); - - i2o_num_controllers--; - return 0; - } - p=&((*p)->next); - } - up(&i2o_configuration_lock); - printk(KERN_ERR "i2o_delete_controller: bad pointer!\n"); - return -ENOENT; -} - -/** - * i2o_unlock_controller - unlock a controller - * @c: controller to unlock - * - * Take a lock on an i2o controller. This prevents it being deleted. - * i2o controllers are not refcounted so a deletion of an in use device - * will fail, not take affect on the last dereference. - */ - -void i2o_unlock_controller(struct i2o_controller *c) -{ - atomic_dec(&c->users); -} - -/** - * i2o_find_controller - return a locked controller - * @n: controller number - * - * Returns a pointer to the controller object. The controller is locked - * on return. NULL is returned if the controller is not found. - */ - -struct i2o_controller *i2o_find_controller(int n) -{ - struct i2o_controller *c; - - if(n<0 || n>=MAX_I2O_CONTROLLERS) - return NULL; - - down(&i2o_configuration_lock); - c=i2o_controllers[n]; - if(c!=NULL) - atomic_inc(&c->users); - up(&i2o_configuration_lock); - return c; -} - -/** - * i2o_issue_claim - claim or release a device - * @cmd: command - * @c: controller to claim for - * @tid: i2o task id - * @type: type of claim - * - * Issue I2O UTIL_CLAIM and UTIL_RELEASE messages. The message to be sent - * is set by cmd. The tid is the task id of the object to claim and the - * type is the claim type (see the i2o standard) - * - * Zero is returned on success. - */ - -static int i2o_issue_claim(u32 cmd, struct i2o_controller *c, int tid, u32 type) -{ - u32 msg[5]; - - msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0; - msg[1] = cmd << 24 | HOST_TID<<12 | tid; - msg[3] = 0; - msg[4] = type; - - return i2o_post_wait(c, msg, sizeof(msg), 60); -} - -/* - * i2o_claim_device - claim a device for use by an OSM - * @d: device to claim - * @h: handler for this device - * - * Do the leg work to assign a device to a given OSM on Linux. The - * kernel updates the internal handler data for the device and then - * performs an I2O claim for the device, attempting to claim the - * device as primary. If the attempt fails a negative errno code - * is returned. On success zero is returned. - */ - -int i2o_claim_device(struct i2o_device *d, struct i2o_handler *h) -{ - int ret = 0; - - down(&i2o_configuration_lock); - if (d->owner) { - printk(KERN_INFO "Device claim called, but dev already owned by %s!", - h->name); - ret = -EBUSY; - goto out; - } - d->owner=h; - - if(i2o_issue_claim(I2O_CMD_UTIL_CLAIM ,d->controller,d->lct_data.tid, - I2O_CLAIM_PRIMARY)) - { - d->owner = NULL; - ret = -EBUSY; - } -out: - up(&i2o_configuration_lock); - return ret; -} - -/** - * i2o_release_device - release a device that the OSM is using - * @d: device to claim - * @h: handler for this device - * - * Drop a claim by an OSM on a given I2O device. The handler is cleared - * and 0 is returned on success. - * - * AC - some devices seem to want to refuse an unclaim until they have - * finished internal processing. It makes sense since you don't want a - * new device to go reconfiguring the entire system until you are done. - * Thus we are prepared to wait briefly. - */ - -int i2o_release_device(struct i2o_device *d, struct i2o_handler *h) -{ - int err = 0; - int tries; - - down(&i2o_configuration_lock); - if (d->owner != h) { - printk(KERN_INFO "Claim release called, but not owned by %s!\n", - h->name); - up(&i2o_configuration_lock); - return -ENOENT; - } - - for(tries=0;tries<10;tries++) - { - d->owner = NULL; - - /* - * If the controller takes a nonblocking approach to - * releases we have to sleep/poll for a few times. - */ - - if((err=i2o_issue_claim(I2O_CMD_UTIL_RELEASE, d->controller, d->lct_data.tid, I2O_CLAIM_PRIMARY)) ) - { - err = -ENXIO; - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); - } - else - { - err=0; - break; - } - } - up(&i2o_configuration_lock); - return err; -} - -/** - * i2o_device_notify_on - Enable deletion notifiers - * @d: device for notification - * @h: handler to install - * - * Called by OSMs to let the core know that they want to be - * notified if the given device is deleted from the system. - */ - -int i2o_device_notify_on(struct i2o_device *d, struct i2o_handler *h) -{ - int i; - - if(d->num_managers == I2O_MAX_MANAGERS) - return -ENOSPC; - - for(i = 0; i < I2O_MAX_MANAGERS; i++) - { - if(!d->managers[i]) - { - d->managers[i] = h; - break; - } - } - - d->num_managers++; - - return 0; -} - -/** - * i2o_device_notify_off - Remove deletion notifiers - * @d: device for notification - * @h: handler to remove - * - * Called by OSMs to let the core know that they no longer - * are interested in the fate of the given device. - */ -int i2o_device_notify_off(struct i2o_device *d, struct i2o_handler *h) -{ - int i; - - for(i=0; i < I2O_MAX_MANAGERS; i++) - { - if(d->managers[i] == h) - { - d->managers[i] = NULL; - d->num_managers--; - return 0; - } - } - - return -ENOENT; -} - -/** - * i2o_event_register - register interest in an event - * @c: Controller to register interest with - * @tid: I2O task id - * @init_context: initiator context to use with this notifier - * @tr_context: transaction context to use with this notifier - * @evt_mask: mask of events - * - * Create and posts an event registration message to the task. No reply - * is waited for, or expected. Errors in posting will be reported. - */ - -int i2o_event_register(struct i2o_controller *c, u32 tid, - u32 init_context, u32 tr_context, u32 evt_mask) -{ - u32 msg[5]; // Not performance critical, so we just - // i2o_post_this it instead of building it - // in IOP memory - - msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0; - msg[1] = I2O_CMD_UTIL_EVT_REGISTER<<24 | HOST_TID<<12 | tid; - msg[2] = init_context; - msg[3] = tr_context; - msg[4] = evt_mask; - - return i2o_post_this(c, msg, sizeof(msg)); -} - -/* - * i2o_event_ack - acknowledge an event - * @c: controller - * @msg: pointer to the UTIL_EVENT_REGISTER reply we received - * - * We just take a pointer to the original UTIL_EVENT_REGISTER reply - * message and change the function code since that's what spec - * describes an EventAck message looking like. - */ - -int i2o_event_ack(struct i2o_controller *c, u32 *msg) -{ - struct i2o_message *m = (struct i2o_message *)msg; - - m->function = I2O_CMD_UTIL_EVT_ACK; - - return i2o_post_wait(c, msg, m->size * 4, 2); -} - -/* - * Core event handler. Runs as a separate thread and is woken - * up whenever there is an Executive class event. - */ -static int i2o_core_evt(void *reply_data) -{ - struct reply_info *reply = (struct reply_info *) reply_data; - u32 *msg = reply->msg; - struct i2o_controller *c = NULL; - unsigned long flags; - - daemonize("i2oevtd"); - allow_signal(SIGKILL); - - evt_running = 1; - - while(1) - { - if(down_interruptible(&evt_sem)) - { - dprintk(KERN_INFO "I2O event thread dead\n"); - printk("exiting..."); - evt_running = 0; - complete_and_exit(&evt_dead, 0); - } - - /* - * Copy the data out of the queue so that we don't have to lock - * around the whole function and just around the qlen update - */ - spin_lock_irqsave(&i2o_evt_lock, flags); - memcpy(reply, &events[evt_out], sizeof(struct reply_info)); - MODINC(evt_out, I2O_EVT_Q_LEN); - evt_q_len--; - spin_unlock_irqrestore(&i2o_evt_lock, flags); - - c = reply->iop; - dprintk(KERN_INFO "I2O IRTOS EVENT: iop%d, event %#10x\n", c->unit, msg[4]); - - /* - * We do not attempt to delete/quiesce/etc. the controller if - * some sort of error indidication occurs. We may want to do - * so in the future, but for now we just let the user deal with - * it. One reason for this is that what to do with an error - * or when to send what ærror is not really agreed on, so - * we get errors that may not be fatal but just look like they - * are...so let the user deal with it. - */ - switch(msg[4]) - { - case I2O_EVT_IND_EXEC_RESOURCE_LIMITS: - printk(KERN_ERR "%s: Out of resources\n", c->name); - break; - - case I2O_EVT_IND_EXEC_POWER_FAIL: - printk(KERN_ERR "%s: Power failure\n", c->name); - break; - - case I2O_EVT_IND_EXEC_HW_FAIL: - { - char *fail[] = - { - "Unknown Error", - "Power Lost", - "Code Violation", - "Parity Error", - "Code Execution Exception", - "Watchdog Timer Expired" - }; - - if(msg[5] <= 6) - printk(KERN_ERR "%s: Hardware Failure: %s\n", - c->name, fail[msg[5]]); - else - printk(KERN_ERR "%s: Unknown Hardware Failure\n", c->name); - - break; - } - - /* - * New device created - * - Create a new i2o_device entry - * - Inform all interested drivers about this device's existence - */ - case I2O_EVT_IND_EXEC_NEW_LCT_ENTRY: - { - struct i2o_device *d = (struct i2o_device *) - kmalloc(sizeof(struct i2o_device), GFP_KERNEL); - int i; - - if (d == NULL) { - printk(KERN_EMERG "i2oevtd: out of memory\n"); - break; - } - memcpy(&d->lct_data, &msg[5], sizeof(i2o_lct_entry)); - - d->next = NULL; - d->controller = c; - d->flags = 0; - - i2o_report_controller_unit(c, d); - i2o_install_device(c,d); - - for(i = 0; i < MAX_I2O_MODULES; i++) - { - if(i2o_handlers[i] && - i2o_handlers[i]->new_dev_notify && - (i2o_handlers[i]->class&d->lct_data.class_id)) - { - spin_lock(&i2o_dev_lock); - i2o_handlers[i]->new_dev_notify(c,d); - spin_unlock(&i2o_dev_lock); - } - } - - break; - } - - /* - * LCT entry for a device has been modified, so update it - * internally. - */ - case I2O_EVT_IND_EXEC_MODIFIED_LCT: - { - struct i2o_device *d; - i2o_lct_entry *new_lct = (i2o_lct_entry *)&msg[5]; - - for(d = c->devices; d; d = d->next) - { - if(d->lct_data.tid == new_lct->tid) - { - memcpy(&d->lct_data, new_lct, sizeof(i2o_lct_entry)); - break; - } - } - break; - } - - case I2O_EVT_IND_CONFIGURATION_FLAG: - printk(KERN_WARNING "%s requires user configuration\n", c->name); - break; - - case I2O_EVT_IND_GENERAL_WARNING: - printk(KERN_WARNING "%s: Warning notification received!" - "Check configuration for errors!\n", c->name); - break; - - case I2O_EVT_IND_EVT_MASK_MODIFIED: - /* Well I guess that was us hey .. */ - break; - - default: - printk(KERN_WARNING "%s: No handler for event (0x%08x)\n", c->name, msg[4]); - break; - } - } - - return 0; -} - -/* - * Dynamic LCT update. This compares the LCT with the currently - * installed devices to check for device deletions..this needed b/c there - * is no DELETED_LCT_ENTRY EventIndicator for the Executive class so - * we can't just have the event handler do this...annoying - * - * This is a hole in the spec that will hopefully be fixed someday. - */ -static int i2o_dyn_lct(void *foo) -{ - struct i2o_controller *c = (struct i2o_controller *)foo; - struct i2o_device *d = NULL; - struct i2o_device *d1 = NULL; - int i = 0; - int found = 0; - int entries; - void *tmp; - - daemonize("iop%d_lctd", c->unit); - allow_signal(SIGKILL); - - c->lct_running = 1; - - while(1) - { - down_interruptible(&c->lct_sem); - if(signal_pending(current)) - { - dprintk(KERN_ERR "%s: LCT thread dead\n", c->name); - c->lct_running = 0; - return 0; - } - - entries = c->dlct->table_size; - entries -= 3; - entries /= 9; - - dprintk(KERN_INFO "%s: Dynamic LCT Update\n",c->name); - dprintk(KERN_INFO "%s: Dynamic LCT contains %d entries\n", c->name, entries); - - if(!entries) - { - printk(KERN_INFO "%s: Empty LCT???\n", c->name); - continue; - } - - /* - * Loop through all the devices on the IOP looking for their - * LCT data in the LCT. We assume that TIDs are not repeated. - * as that is the only way to really tell. It's been confirmed - * by the IRTOS vendor(s?) that TIDs are not reused until they - * wrap arround(4096), and I doubt a system will up long enough - * to create/delete that many devices. - */ - for(d = c->devices; d; ) - { - found = 0; - d1 = d->next; - - for(i = 0; i < entries; i++) - { - if(d->lct_data.tid == c->dlct->lct_entry[i].tid) - { - found = 1; - break; - } - } - if(!found) - { - dprintk(KERN_INFO "i2o_core: Deleted device!\n"); - spin_lock(&i2o_dev_lock); - i2o_delete_device(d); - spin_unlock(&i2o_dev_lock); - } - d = d1; - } - - /* - * Tell LCT to renotify us next time there is a change - */ - i2o_lct_notify(c); - - /* - * Copy new LCT into public LCT - * - * Possible race if someone is reading LCT while we are copying - * over it. If this happens, we'll fix it then. but I doubt that - * the LCT will get updated often enough or will get read by - * a user often enough to worry. - */ - if(c->lct->table_size < c->dlct->table_size) - { - dma_addr_t phys; - tmp = c->lct; - c->lct = pci_alloc_consistent(c->pdev, c->dlct->table_size<<2, &phys); - if(!c->lct) - { - printk(KERN_ERR "%s: No memory for LCT!\n", c->name); - c->lct = tmp; - continue; - } - pci_free_consistent(tmp, c->lct->table_size << 2, c->lct, c->lct_phys); - c->lct_phys = phys; - } - memcpy(c->lct, c->dlct, c->dlct->table_size<<2); - } - - return 0; -} - -/** - * i2o_run_queue - process pending events on a controller - * @c: controller to process - * - * This is called by the bus specific driver layer when an interrupt - * or poll of this card interface is desired. - */ - -void i2o_run_queue(struct i2o_controller *c) -{ - struct i2o_message *m; - u32 mv; - u32 *msg; - - /* - * Old 960 steppings had a bug in the I2O unit that caused - * the queue to appear empty when it wasn't. - */ - if((mv=I2O_REPLY_READ32(c))==0xFFFFFFFF) - mv=I2O_REPLY_READ32(c); - - while(mv!=0xFFFFFFFF) - { - struct i2o_handler *i; - /* Map the message from the page frame map to kernel virtual */ - /* m=(struct i2o_message *)(mv - (unsigned long)c->page_frame_map + (unsigned long)c->page_frame); */ - m=(struct i2o_message *)bus_to_virt(mv); - msg=(u32*)m; - - /* - * Ensure this message is seen coherently but cachably by - * the processor - */ - - pci_dma_sync_single_for_cpu(c->pdev, c->page_frame_map, MSG_FRAME_SIZE, PCI_DMA_FROMDEVICE); - - /* - * Despatch it - */ - - i=i2o_handlers[m->initiator_context&(MAX_I2O_MODULES-1)]; - if(i && i->reply) - i->reply(i,c,m); - else - { - printk(KERN_WARNING "I2O: Spurious reply to handler %d\n", - m->initiator_context&(MAX_I2O_MODULES-1)); - } - i2o_flush_reply(c,mv); - mb(); - - /* That 960 bug again... */ - if((mv=I2O_REPLY_READ32(c))==0xFFFFFFFF) - mv=I2O_REPLY_READ32(c); - } -} - - -/** - * i2o_get_class_name - do i2o class name lookup - * @class: class number - * - * Return a descriptive string for an i2o class - */ - -const char *i2o_get_class_name(int class) -{ - int idx = 16; - static char *i2o_class_name[] = { - "Executive", - "Device Driver Module", - "Block Device", - "Tape Device", - "LAN Interface", - "WAN Interface", - "Fibre Channel Port", - "Fibre Channel Device", - "SCSI Device", - "ATE Port", - "ATE Device", - "Floppy Controller", - "Floppy Device", - "Secondary Bus Port", - "Peer Transport Agent", - "Peer Transport", - "Unknown" - }; - - switch(class&0xFFF) - { - case I2O_CLASS_EXECUTIVE: - idx = 0; break; - case I2O_CLASS_DDM: - idx = 1; break; - case I2O_CLASS_RANDOM_BLOCK_STORAGE: - idx = 2; break; - case I2O_CLASS_SEQUENTIAL_STORAGE: - idx = 3; break; - case I2O_CLASS_LAN: - idx = 4; break; - case I2O_CLASS_WAN: - idx = 5; break; - case I2O_CLASS_FIBRE_CHANNEL_PORT: - idx = 6; break; - case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL: - idx = 7; break; - case I2O_CLASS_SCSI_PERIPHERAL: - idx = 8; break; - case I2O_CLASS_ATE_PORT: - idx = 9; break; - case I2O_CLASS_ATE_PERIPHERAL: - idx = 10; break; - case I2O_CLASS_FLOPPY_CONTROLLER: - idx = 11; break; - case I2O_CLASS_FLOPPY_DEVICE: - idx = 12; break; - case I2O_CLASS_BUS_ADAPTER_PORT: - idx = 13; break; - case I2O_CLASS_PEER_TRANSPORT_AGENT: - idx = 14; break; - case I2O_CLASS_PEER_TRANSPORT: - idx = 15; break; - } - - return i2o_class_name[idx]; -} - - -/** - * i2o_wait_message - obtain an i2o message from the IOP - * @c: controller - * @why: explanation - * - * This function waits up to 5 seconds for a message slot to be - * available. If no message is available it prints an error message - * that is expected to be what the message will be used for (eg - * "get_status"). 0xFFFFFFFF is returned on a failure. - * - * On a success the message is returned. This is the physical page - * frame offset address from the read port. (See the i2o spec) - */ - -u32 i2o_wait_message(struct i2o_controller *c, char *why) -{ - long time=jiffies; - u32 m; - while((m=I2O_POST_READ32(c))==0xFFFFFFFF) - { - if((jiffies-time)>=5*HZ) - { - dprintk(KERN_ERR "%s: Timeout waiting for message frame to send %s.\n", - c->name, why); - return 0xFFFFFFFF; - } - schedule(); - barrier(); - } - return m; -} - -/** - * i2o_report_controller_unit - print information about a tid - * @c: controller - * @d: device - * - * Dump an information block associated with a given unit (TID). The - * tables are read and a block of text is output to printk that is - * formatted intended for the user. - */ - -void i2o_report_controller_unit(struct i2o_controller *c, struct i2o_device *d) -{ - char buf[64]; - char str[22]; - int ret; - int unit = d->lct_data.tid; - - if(verbose==0) - return; - - printk(KERN_INFO "Target ID %d.\n", unit); - if((ret=i2o_query_scalar(c, unit, 0xF100, 3, buf, 16))>=0) - { - buf[16]=0; - printk(KERN_INFO " Vendor: %s\n", buf); - } - if((ret=i2o_query_scalar(c, unit, 0xF100, 4, buf, 16))>=0) - { - buf[16]=0; - printk(KERN_INFO " Device: %s\n", buf); - } - if(i2o_query_scalar(c, unit, 0xF100, 5, buf, 16)>=0) - { - buf[16]=0; - printk(KERN_INFO " Description: %s\n", buf); - } - if((ret=i2o_query_scalar(c, unit, 0xF100, 6, buf, 8))>=0) - { - buf[8]=0; - printk(KERN_INFO " Rev: %s\n", buf); - } - - printk(KERN_INFO " Class: "); - sprintf(str, "%-21s", i2o_get_class_name(d->lct_data.class_id)); - printk("%s\n", str); - - printk(KERN_INFO " Subclass: 0x%04X\n", d->lct_data.sub_class); - printk(KERN_INFO " Flags: "); - - if(d->lct_data.device_flags&(1<<0)) - printk("C"); // ConfigDialog requested - if(d->lct_data.device_flags&(1<<1)) - printk("U"); // Multi-user capable - if(!(d->lct_data.device_flags&(1<<4))) - printk("P"); // Peer service enabled! - if(!(d->lct_data.device_flags&(1<<5))) - printk("M"); // Mgmt service enabled! - printk("\n"); - -} - - -/* - * Parse the hardware resource table. Right now we print it out - * and don't do a lot with it. We should collate these and then - * interact with the Linux resource allocation block. - * - * Lets prove we can read it first eh ? - * - * This is full of endianisms! - */ - -static int i2o_parse_hrt(struct i2o_controller *c) -{ -#ifdef DRIVERDEBUG - u32 *rows=(u32*)c->hrt; - u8 *p=(u8 *)c->hrt; - u8 *d; - int count; - int length; - int i; - int state; - - if(p[3]!=0) - { - printk(KERN_ERR "%s: HRT table for controller is too new a version.\n", - c->name); - return -1; - } - - count=p[0]|(p[1]<<8); - length = p[2]; - - printk(KERN_INFO "%s: HRT has %d entries of %d bytes each.\n", - c->name, count, length<<2); - - rows+=2; - - for(i=0;i>=12; - if(state&(1<<0)) - printk("H"); /* Hidden */ - if(state&(1<<2)) - { - printk("P"); /* Present */ - if(state&(1<<1)) - printk("C"); /* Controlled */ - } - if(state>9) - printk("*"); /* Hard */ - - printk("]:"); - - switch(p[3]&0xFFFF) - { - case 0: - /* Adapter private bus - easy */ - printk("Local bus %d: I/O at 0x%04X Mem 0x%08X", - p[2], d[1]<<8|d[0], *(u32 *)(d+4)); - break; - case 1: - /* ISA bus */ - printk("ISA %d: CSN %d I/O at 0x%04X Mem 0x%08X", - p[2], d[2], d[1]<<8|d[0], *(u32 *)(d+4)); - break; - - case 2: /* EISA bus */ - printk("EISA %d: Slot %d I/O at 0x%04X Mem 0x%08X", - p[2], d[3], d[1]<<8|d[0], *(u32 *)(d+4)); - break; - - case 3: /* MCA bus */ - printk("MCA %d: Slot %d I/O at 0x%04X Mem 0x%08X", - p[2], d[3], d[1]<<8|d[0], *(u32 *)(d+4)); - break; - - case 4: /* PCI bus */ - printk("PCI %d: Bus %d Device %d Function %d", - p[2], d[2], d[1], d[0]); - break; - - case 0x80: /* Other */ - default: - printk("Unsupported bus type."); - break; - } - printk("\n"); - rows+=length; - } -#endif - return 0; -} - -/* - * The logical configuration table tells us what we can talk to - * on the board. Most of the stuff isn't interesting to us. - */ - -static int i2o_parse_lct(struct i2o_controller *c) -{ - int i; - int max; - int tid; - struct i2o_device *d; - i2o_lct *lct = c->lct; - - if (lct == NULL) { - printk(KERN_ERR "%s: LCT is empty???\n", c->name); - return -1; - } - - max = lct->table_size; - max -= 3; - max /= 9; - - printk(KERN_INFO "%s: LCT has %d entries.\n", c->name, max); - - if(lct->iop_flags&(1<<0)) - printk(KERN_WARNING "%s: Configuration dialog desired.\n", c->name); - - for(i=0;icontroller = c; - d->next = NULL; - - memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry)); - - d->flags = 0; - tid = d->lct_data.tid; - - i2o_report_controller_unit(c, d); - - i2o_install_device(c, d); - } - return 0; -} - - -/** - * i2o_quiesce_controller - quiesce controller - * @c: controller - * - * Quiesce an IOP. Causes IOP to make external operation quiescent - * (i2o 'READY' state). Internal operation of the IOP continues normally. - */ - -int i2o_quiesce_controller(struct i2o_controller *c) -{ - u32 msg[4]; - int ret; - - i2o_status_get(c); - - /* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */ - - if ((c->status_block->iop_state != ADAPTER_STATE_READY) && - (c->status_block->iop_state != ADAPTER_STATE_OPERATIONAL)) - { - return 0; - } - - msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0; - msg[1] = I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID; - msg[3] = 0; - - /* Long timeout needed for quiesce if lots of devices */ - - if ((ret = i2o_post_wait(c, msg, sizeof(msg), 240))) - printk(KERN_INFO "%s: Unable to quiesce (status=%#x).\n", - c->name, -ret); - else - dprintk(KERN_INFO "%s: Quiesced.\n", c->name); - - i2o_status_get(c); // Entered READY state - return ret; -} - -/** - * i2o_enable_controller - move controller from ready to operational - * @c: controller - * - * Enable IOP. This allows the IOP to resume external operations and - * reverses the effect of a quiesce. In the event of an error a negative - * errno code is returned. - */ - -int i2o_enable_controller(struct i2o_controller *c) -{ - u32 msg[4]; - int ret; - - i2o_status_get(c); - - /* Enable only allowed on READY state */ - if(c->status_block->iop_state != ADAPTER_STATE_READY) - return -EINVAL; - - msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0; - msg[1]=I2O_CMD_SYS_ENABLE<<24|HOST_TID<<12|ADAPTER_TID; - - /* How long of a timeout do we need? */ - - if ((ret = i2o_post_wait(c, msg, sizeof(msg), 240))) - printk(KERN_ERR "%s: Could not enable (status=%#x).\n", - c->name, -ret); - else - dprintk(KERN_INFO "%s: Enabled.\n", c->name); - - i2o_status_get(c); // entered OPERATIONAL state - - return ret; -} - -/** - * i2o_clear_controller - clear a controller - * @c: controller - * - * Clear an IOP to HOLD state, ie. terminate external operations, clear all - * input queues and prepare for a system restart. IOP's internal operation - * continues normally and the outbound queue is alive. - * The IOP is not expected to rebuild its LCT. - */ - -int i2o_clear_controller(struct i2o_controller *c) -{ - struct i2o_controller *iop; - u32 msg[4]; - int ret; - - /* Quiesce all IOPs first */ - - for (iop = i2o_controller_chain; iop; iop = iop->next) - i2o_quiesce_controller(iop); - - msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0; - msg[1]=I2O_CMD_ADAPTER_CLEAR<<24|HOST_TID<<12|ADAPTER_TID; - msg[3]=0; - - if ((ret=i2o_post_wait(c, msg, sizeof(msg), 30))) - printk(KERN_INFO "%s: Unable to clear (status=%#x).\n", - c->name, -ret); - else - dprintk(KERN_INFO "%s: Cleared.\n",c->name); - - i2o_status_get(c); - - /* Enable other IOPs */ - - for (iop = i2o_controller_chain; iop; iop = iop->next) - if (iop != c) - i2o_enable_controller(iop); - - return ret; -} - - -/** - * i2o_reset_controller - reset an IOP - * @c: controller to reset - * - * Reset the IOP into INIT state and wait until IOP gets into RESET state. - * Terminate all external operations, clear IOP's inbound and outbound - * queues, terminate all DDMs, and reload the IOP's operating environment - * and all local DDMs. The IOP rebuilds its LCT. - */ - -static int i2o_reset_controller(struct i2o_controller *c) -{ - struct i2o_controller *iop; - u32 m; - u8 *status; - dma_addr_t status_phys; - u32 *msg; - long time; - - /* Quiesce all IOPs first */ - - for (iop = i2o_controller_chain; iop; iop = iop->next) - { - if(!iop->dpt) - i2o_quiesce_controller(iop); - } - - m=i2o_wait_message(c, "AdapterReset"); - if(m==0xFFFFFFFF) - return -ETIMEDOUT; - msg=(u32 *)(c->msg_virt+m); - - status = pci_alloc_consistent(c->pdev, 4, &status_phys); - if(status == NULL) { - 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; - msg[2]=core_context; - msg[3]=0; - msg[4]=0; - msg[5]=0; - msg[6]=status_phys; - msg[7]=0; /* 64bit host FIXME */ - - i2o_post_message(c,m); - - /* Wait for a reply */ - time=jiffies; - while(*status==0) - { - if((jiffies-time)>=20*HZ) - { - printk(KERN_ERR "IOP reset timeout.\n"); - /* The controller still may respond and overwrite - * status_phys, LEAK it to prevent memory corruption. - */ - return -ETIMEDOUT; - } - schedule(); - barrier(); - } - - if (*status==I2O_CMD_IN_PROGRESS) - { - /* - * Once the reset is sent, the IOP goes into the INIT state - * which is indeterminate. We need to wait until the IOP - * has rebooted before we can let the system talk to - * it. We read the inbound Free_List until a message is - * available. If we can't read one in the given ammount of - * time, we assume the IOP could not reboot properly. - */ - - dprintk(KERN_INFO "%s: Reset in progress, waiting for reboot...\n", - c->name); - - time = jiffies; - m = I2O_POST_READ32(c); - while(m == 0XFFFFFFFF) - { - if((jiffies-time) >= 30*HZ) - { - printk(KERN_ERR "%s: Timeout waiting for IOP reset.\n", - c->name); - /* The controller still may respond and - * overwrite status_phys, LEAK it to prevent - * memory corruption. - */ - return -ETIMEDOUT; - } - schedule(); - barrier(); - m = I2O_POST_READ32(c); - } - i2o_flush_reply(c,m); - } - - /* If IopReset was rejected or didn't perform reset, try IopClear */ - - i2o_status_get(c); - if (status[0] == I2O_CMD_REJECTED || - c->status_block->iop_state != ADAPTER_STATE_RESET) - { - printk(KERN_WARNING "%s: Reset rejected, trying to clear\n",c->name); - i2o_clear_controller(c); - } - else - dprintk(KERN_INFO "%s: Reset completed.\n", c->name); - - /* Enable other IOPs */ - - for (iop = i2o_controller_chain; iop; iop = iop->next) - if (iop != c) - i2o_enable_controller(iop); - - pci_free_consistent(c->pdev, 4, status, status_phys); - return 0; -} - - -/** - * i2o_status_get - get the status block for the IOP - * @c: controller - * - * Issue a status query on the controller. This updates the - * attached status_block. If the controller fails to reply or an - * error occurs then a negative errno code is returned. On success - * zero is returned and the status_blok is updated. - */ - -int i2o_status_get(struct i2o_controller *c) -{ - long time; - u32 m; - u32 *msg; - u8 *status_block; - - if (c->status_block == NULL) - { - c->status_block = (i2o_status_block *) - pci_alloc_consistent(c->pdev, sizeof(i2o_status_block), &c->status_block_phys); - if (c->status_block == NULL) - { - printk(KERN_CRIT "%s: Get Status Block failed; Out of memory.\n", - c->name); - return -ENOMEM; - } - } - - status_block = (u8*)c->status_block; - memset(c->status_block,0,sizeof(i2o_status_block)); - - m=i2o_wait_message(c, "StatusGet"); - if(m==0xFFFFFFFF) - return -ETIMEDOUT; - msg=(u32 *)(c->msg_virt+m); - - msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0; - msg[1]=I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID; - msg[2]=core_context; - msg[3]=0; - msg[4]=0; - msg[5]=0; - msg[6]=c->status_block_phys; - msg[7]=0; /* 64bit host FIXME */ - msg[8]=sizeof(i2o_status_block); /* always 88 bytes */ - - i2o_post_message(c,m); - - /* Wait for a reply */ - - time=jiffies; - while(status_block[87]!=0xFF) - { - if((jiffies-time)>=5*HZ) - { - printk(KERN_ERR "%s: Get status timeout.\n",c->name); - return -ETIMEDOUT; - } - yield(); - barrier(); - } - -#ifdef DRIVERDEBUG - printk(KERN_INFO "%s: State = ", c->name); - switch (c->status_block->iop_state) { - case 0x01: - printk("INIT\n"); - break; - case 0x02: - printk("RESET\n"); - break; - case 0x04: - printk("HOLD\n"); - break; - case 0x05: - printk("READY\n"); - break; - case 0x08: - printk("OPERATIONAL\n"); - break; - case 0x10: - printk("FAILED\n"); - break; - case 0x11: - printk("FAULTED\n"); - break; - default: - printk("%x (unknown !!)\n",c->status_block->iop_state); -} -#endif - - return 0; -} - -/* - * Get the Hardware Resource Table for the device. - * The HRT contains information about possible hidden devices - * but is mostly useless to us - */ -int i2o_hrt_get(struct i2o_controller *c) -{ - u32 msg[6]; - int ret, size = sizeof(i2o_hrt); - int loops = 3; /* we only try 3 times to get the HRT, this should be - more then enough. Worst case should be 2 times.*/ - - /* First read just the header to figure out the real size */ - - do { - /* first we allocate the memory for the HRT */ - if (c->hrt == NULL) { - c->hrt=pci_alloc_consistent(c->pdev, size, &c->hrt_phys); - if (c->hrt == NULL) { - printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", c->name); - return -ENOMEM; - } - c->hrt_len = size; - } - - msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4; - msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID; - msg[3]= 0; - msg[4]= (0xD0000000 | c->hrt_len); /* Simple transaction */ - msg[5]= c->hrt_phys; /* Dump it here */ - - ret = i2o_post_wait_mem(c, msg, sizeof(msg), 20, c->hrt, NULL, c->hrt_phys, 0, c->hrt_len, 0); - - if(ret == -ETIMEDOUT) - { - /* The HRT block we used is in limbo somewhere. When the iop wakes up - we will recover it */ - c->hrt = NULL; - c->hrt_len = 0; - return ret; - } - - if(ret<0) - { - printk(KERN_ERR "%s: Unable to get HRT (status=%#x)\n", - c->name, -ret); - return ret; - } - - if (c->hrt->num_entries * c->hrt->entry_len << 2 > c->hrt_len) { - size = c->hrt->num_entries * c->hrt->entry_len << 2; - pci_free_consistent(c->pdev, c->hrt_len, c->hrt, c->hrt_phys); - c->hrt_len = 0; - c->hrt = NULL; - } - loops --; - } while (c->hrt == NULL && loops > 0); - - if(c->hrt == NULL) - { - printk(KERN_ERR "%s: Unable to get HRT after three tries, giving up\n", c->name); - return -1; - } - - i2o_parse_hrt(c); // just for debugging - - return 0; -} - -/* - * Send the I2O System Table to the specified IOP - * - * The system table contains information about all the IOPs in the - * system. It is build and then sent to each IOP so that IOPs can - * establish connections between each other. - * - */ -static int i2o_systab_send(struct i2o_controller *iop) -{ - u32 msg[12]; - dma_addr_t sys_tbl_phys; - int ret; - struct resource *root; - u32 *privbuf = kmalloc(16, GFP_KERNEL); - if(privbuf == NULL) - return -ENOMEM; - - - if(iop->status_block->current_mem_size < iop->status_block->desired_mem_size) - { - struct resource *res = &iop->mem_resource; - res->name = iop->pdev->bus->name; - res->flags = IORESOURCE_MEM; - res->start = 0; - res->end = 0; - printk("%s: requires private memory resources.\n", iop->name); - root = pci_find_parent_resource(iop->pdev, res); - if(root==NULL) - printk("Can't find parent resource!\n"); - if(root && allocate_resource(root, res, - iop->status_block->desired_mem_size, - iop->status_block->desired_mem_size, - iop->status_block->desired_mem_size, - 1<<20, /* Unspecified, so use 1Mb and play safe */ - NULL, - NULL)>=0) - { - iop->mem_alloc = 1; - iop->status_block->current_mem_size = 1 + res->end - res->start; - iop->status_block->current_mem_base = res->start; - printk(KERN_INFO "%s: allocated %ld bytes of PCI memory at 0x%08lX.\n", - iop->name, 1+res->end-res->start, res->start); - } - } - if(iop->status_block->current_io_size < iop->status_block->desired_io_size) - { - struct resource *res = &iop->io_resource; - res->name = iop->pdev->bus->name; - res->flags = IORESOURCE_IO; - res->start = 0; - res->end = 0; - printk("%s: requires private memory resources.\n", iop->name); - root = pci_find_parent_resource(iop->pdev, res); - if(root==NULL) - printk("Can't find parent resource!\n"); - if(root && allocate_resource(root, res, - iop->status_block->desired_io_size, - iop->status_block->desired_io_size, - iop->status_block->desired_io_size, - 1<<20, /* Unspecified, so use 1Mb and play safe */ - NULL, - NULL)>=0) - { - iop->io_alloc = 1; - iop->status_block->current_io_size = 1 + res->end - res->start; - iop->status_block->current_mem_base = res->start; - printk(KERN_INFO "%s: allocated %ld bytes of PCI I/O at 0x%08lX.\n", - iop->name, 1+res->end-res->start, res->start); - } - } - else - { - privbuf[0] = iop->status_block->current_mem_base; - privbuf[1] = iop->status_block->current_mem_size; - privbuf[2] = iop->status_block->current_io_base; - privbuf[3] = iop->status_block->current_io_size; - } - - msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6; - msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID; - msg[3] = 0; - msg[4] = (0<<16) | ((iop->unit+2) ); /* Host 0 IOP ID (unit + 2) */ - msg[5] = 0; /* Segment 0 */ - - /* - * Provide three SGL-elements: - * System table (SysTab), Private memory space declaration and - * Private i/o space declaration - * - * Nasty one here. We can't use pci_alloc_consistent to send the - * same table to everyone. We have to go remap it for them all - */ - - sys_tbl_phys = pci_map_single(iop->pdev, sys_tbl, sys_tbl_len, PCI_DMA_TODEVICE); - msg[6] = 0x54000000 | sys_tbl_phys; - - msg[7] = sys_tbl_phys; - msg[8] = 0x54000000 | privbuf[1]; - msg[9] = privbuf[0]; - msg[10] = 0xD4000000 | privbuf[3]; - msg[11] = privbuf[2]; - - ret=i2o_post_wait(iop, msg, sizeof(msg), 120); - - pci_unmap_single(iop->pdev, sys_tbl_phys, sys_tbl_len, PCI_DMA_TODEVICE); - - if(ret==-ETIMEDOUT) - { - printk(KERN_ERR "%s: SysTab setup timed out.\n", iop->name); - } - else if(ret<0) - { - printk(KERN_ERR "%s: Unable to set SysTab (status=%#x).\n", - iop->name, -ret); - } - else - { - dprintk(KERN_INFO "%s: SysTab set.\n", iop->name); - } - i2o_status_get(iop); // Entered READY state - - kfree(privbuf); - return ret; - - } - -/* - * Initialize I2O subsystem. - */ -void __init i2o_sys_init(void) -{ - struct i2o_controller *iop, *niop = NULL; - - printk(KERN_INFO "Activating I2O controllers...\n"); - printk(KERN_INFO "This may take a few minutes if there are many devices\n"); - - /* In INIT state, Activate IOPs */ - for (iop = i2o_controller_chain; iop; iop = niop) { - dprintk(KERN_INFO "Calling i2o_activate_controller for %s...\n", - iop->name); - niop = iop->next; - if (i2o_activate_controller(iop) < 0) - i2o_delete_controller(iop); - } - - /* Active IOPs in HOLD state */ - -rebuild_sys_tab: - if (i2o_controller_chain == NULL) - return; - - /* - * If build_sys_table fails, we kill everything and bail - * as we can't init the IOPs w/o a system table - */ - dprintk(KERN_INFO "i2o_core: Calling i2o_build_sys_table...\n"); - if (i2o_build_sys_table() < 0) { - i2o_sys_shutdown(); - return; - } - - /* If IOP don't get online, we need to rebuild the System table */ - for (iop = i2o_controller_chain; iop; iop = niop) { - niop = iop->next; - dprintk(KERN_INFO "Calling i2o_online_controller for %s...\n", iop->name); - if (i2o_online_controller(iop) < 0) { - i2o_delete_controller(iop); - goto rebuild_sys_tab; - } - } - - /* Active IOPs now in OPERATIONAL state */ - - /* - * Register for status updates from all IOPs - */ - for(iop = i2o_controller_chain; iop; iop=iop->next) { - - /* Create a kernel thread to deal with dynamic LCT updates */ - iop->lct_pid = kernel_thread(i2o_dyn_lct, iop, CLONE_SIGHAND); - - /* Update change ind on DLCT */ - iop->dlct->change_ind = iop->lct->change_ind; - - /* Start dynamic LCT updates */ - i2o_lct_notify(iop); - - /* Register for all events from IRTOS */ - i2o_event_register(iop, core_context, 0, 0, 0xFFFFFFFF); - } -} - -/** - * i2o_sys_shutdown - shutdown I2O system - * - * Bring down each i2o controller and then return. Each controller - * is taken through an orderly shutdown - */ - -static void i2o_sys_shutdown(void) -{ - struct i2o_controller *iop, *niop; - - /* Delete all IOPs from the controller chain */ - /* that will reset all IOPs too */ - - for (iop = i2o_controller_chain; iop; iop = niop) { - niop = iop->next; - i2o_delete_controller(iop); - } -} - -/** - * i2o_activate_controller - bring controller up to HOLD - * @iop: controller - * - * This function brings an I2O controller into HOLD state. The adapter - * is reset if necessary and then the queues and resource table - * are read. -1 is returned on a failure, 0 on success. - * - */ - -int i2o_activate_controller(struct i2o_controller *iop) -{ - /* In INIT state, Wait Inbound Q to initialize (in i2o_status_get) */ - /* In READY state, Get status */ - - if (i2o_status_get(iop) < 0) { - printk(KERN_INFO "Unable to obtain status of %s, " - "attempting a reset.\n", iop->name); - if (i2o_reset_controller(iop) < 0) - return -1; - } - - if(iop->status_block->iop_state == ADAPTER_STATE_FAULTED) { - printk(KERN_CRIT "%s: hardware fault\n", iop->name); - return -1; - } - - if (iop->status_block->i2o_version > I2OVER15) { - printk(KERN_ERR "%s: Not running vrs. 1.5. of the I2O Specification.\n", - iop->name); - return -1; - } - - if (iop->status_block->iop_state == ADAPTER_STATE_READY || - iop->status_block->iop_state == ADAPTER_STATE_OPERATIONAL || - iop->status_block->iop_state == ADAPTER_STATE_HOLD || - iop->status_block->iop_state == ADAPTER_STATE_FAILED) - { - dprintk(KERN_INFO "%s: Already running, trying to reset...\n", - iop->name); - if (i2o_reset_controller(iop) < 0) - return -1; - } - - if (i2o_init_outbound_q(iop) < 0) - return -1; - - if (i2o_post_outbound_messages(iop)) - return -1; - - /* In HOLD state */ - - if (i2o_hrt_get(iop) < 0) - return -1; - - return 0; -} - - -/** - * i2o_init_outbound_queue - setup the outbound queue - * @c: controller - * - * Clear and (re)initialize IOP's outbound queue. Returns 0 on - * success or a negative errno code on a failure. - */ - -int i2o_init_outbound_q(struct i2o_controller *c) -{ - u8 *status; - dma_addr_t status_phys; - u32 m; - u32 *msg; - u32 time; - - dprintk(KERN_INFO "%s: Initializing Outbound Queue...\n", c->name); - m=i2o_wait_message(c, "OutboundInit"); - if(m==0xFFFFFFFF) - return -ETIMEDOUT; - msg=(u32 *)(c->msg_virt+m); - - status = pci_alloc_consistent(c->pdev, 4, &status_phys); - if (status==NULL) { - printk(KERN_ERR "%s: Outbound Queue initialization failed - no free memory.\n", - c->name); - return -ENOMEM; - } - memset(status, 0, 4); - - msg[0]= EIGHT_WORD_MSG_SIZE| TRL_OFFSET_6; - msg[1]= I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID; - msg[2]= core_context; - msg[3]= 0x0106; /* Transaction context */ - msg[4]= 4096; /* Host page frame size */ - /* Frame size is in words. 256 bytes a frame for now */ - msg[5]= MSG_FRAME_SIZE<<16|0x80; /* Outbound msg frame size in words and Initcode */ - msg[6]= 0xD0000004; /* Simple SG LE, EOB */ - msg[7]= status_phys; - - i2o_post_message(c,m); - - barrier(); - time=jiffies; - while(status[0] < I2O_CMD_REJECTED) - { - if((jiffies-time)>=30*HZ) - { - if(status[0]==0x00) - printk(KERN_ERR "%s: Ignored queue initialize request.\n", - c->name); - else - printk(KERN_ERR "%s: Outbound queue initialize timeout.\n", - c->name); - pci_free_consistent(c->pdev, 4, status, status_phys); - return -ETIMEDOUT; - } - yield(); - barrier(); - } - - if(status[0] != I2O_CMD_COMPLETED) - { - printk(KERN_ERR "%s: IOP outbound initialise failed.\n", c->name); - pci_free_consistent(c->pdev, 4, status, status_phys); - return -ETIMEDOUT; - } - pci_free_consistent(c->pdev, 4, status, status_phys); - return 0; -} - -/** - * i2o_post_outbound_messages - fill message queue - * @c: controller - * - * Allocate a message frame and load the messages into the IOP. The - * function returns zero on success or a negative errno code on - * failure. - */ - -int i2o_post_outbound_messages(struct i2o_controller *c) -{ - int i; - u32 m; - /* Alloc space for IOP's outbound queue message frames */ - - c->page_frame = kmalloc(MSG_POOL_SIZE, GFP_KERNEL); - if(c->page_frame==NULL) { - printk(KERN_ERR "%s: Outbound Q initialize failed; out of memory.\n", - c->name); - return -ENOMEM; - } - - c->page_frame_map = pci_map_single(c->pdev, c->page_frame, MSG_POOL_SIZE, PCI_DMA_FROMDEVICE); - - if(c->page_frame_map == 0) - { - kfree(c->page_frame); - printk(KERN_ERR "%s: Unable to map outbound queue.\n", c->name); - return -ENOMEM; - } - - m = c->page_frame_map; - - /* Post frames */ - - for(i=0; i< NMBR_MSG_FRAMES; i++) { - I2O_REPLY_WRITE32(c,m); - mb(); - m += (MSG_FRAME_SIZE << 2); - } - - return 0; -} - -/* - * Get the IOP's Logical Configuration Table - */ -int i2o_lct_get(struct i2o_controller *c) -{ - u32 msg[8]; - int ret, size = c->status_block->expected_lct_size; - - do { - if (c->lct == NULL) { - c->lct = pci_alloc_consistent(c->pdev, size, &c->lct_phys); - if(c->lct == NULL) { - printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n", - c->name); - return -ENOMEM; - } - } - memset(c->lct, 0, size); - - msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6; - msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID; - /* msg[2] filled in i2o_post_wait */ - msg[3] = 0; - msg[4] = 0xFFFFFFFF; /* All devices */ - msg[5] = 0x00000000; /* Report now */ - msg[6] = 0xD0000000|size; - msg[7] = c->lct_phys; - - ret=i2o_post_wait_mem(c, msg, sizeof(msg), 120, c->lct, NULL, c->lct_phys, 0, size, 0); - - if(ret == -ETIMEDOUT) - { - c->lct = NULL; - return ret; - } - - if(ret<0) - { - printk(KERN_ERR "%s: LCT Get failed (status=%#x.\n", - c->name, -ret); - return ret; - } - - if (c->lct->table_size << 2 > size) { - int new_size = c->lct->table_size << 2; - pci_free_consistent(c->pdev, size, c->lct, c->lct_phys); - size = new_size; - c->lct = NULL; - } - } while (c->lct == NULL); - - if ((ret=i2o_parse_lct(c)) < 0) - return ret; - - return 0; -} - -/* - * Like above, but used for async notification. The main - * difference is that we keep track of the CurrentChangeIndiicator - * so that we only get updates when it actually changes. - * - */ -int i2o_lct_notify(struct i2o_controller *c) -{ - u32 msg[8]; - - msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6; - msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID; - msg[2] = core_context; - msg[3] = 0xDEADBEEF; - msg[4] = 0xFFFFFFFF; /* All devices */ - msg[5] = c->dlct->change_ind+1; /* Next change */ - msg[6] = 0xD0000000|8192; - msg[7] = c->dlct_phys; - - return i2o_post_this(c, msg, sizeof(msg)); -} - -/* - * Bring a controller online into OPERATIONAL state. - */ - -int i2o_online_controller(struct i2o_controller *iop) -{ - u32 v; - - if (i2o_systab_send(iop) < 0) - return -1; - - /* In READY state */ - - dprintk(KERN_INFO "%s: Attempting to enable...\n", iop->name); - if (i2o_enable_controller(iop) < 0) - return -1; - - /* In OPERATIONAL state */ - - dprintk(KERN_INFO "%s: Attempting to get/parse lct...\n", iop->name); - if (i2o_lct_get(iop) < 0) - return -1; - - /* Check battery status */ - - iop->battery = 0; - if(i2o_query_scalar(iop, ADAPTER_TID, 0x0000, 4, &v, 4)>=0) - { - if(v&16) - iop->battery = 1; - } - - return 0; -} - -/* - * Build system table - * - * The system table contains information about all the IOPs in the - * system (duh) and is used by the Executives on the IOPs to establish - * peer2peer connections. We're not supporting peer2peer at the moment, - * but this will be needed down the road for things like lan2lan forwarding. - */ -static int i2o_build_sys_table(void) -{ - struct i2o_controller *iop = NULL; - struct i2o_controller *niop = NULL; - int count = 0; - - sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs - (i2o_num_controllers) * - sizeof(struct i2o_sys_tbl_entry); - - if(sys_tbl) - kfree(sys_tbl); - - sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL); - if(!sys_tbl) { - printk(KERN_CRIT "SysTab Set failed. Out of memory.\n"); - return -ENOMEM; - } - memset((void*)sys_tbl, 0, sys_tbl_len); - - sys_tbl->num_entries = i2o_num_controllers; - sys_tbl->version = I2OVERSION; /* TODO: Version 2.0 */ - sys_tbl->change_ind = sys_tbl_ind++; - - for(iop = i2o_controller_chain; iop; iop = niop) - { - niop = iop->next; - - /* - * Get updated IOP state so we have the latest information - * - * We should delete the controller at this point if it - * doesn't respond since if it's not on the system table - * it is techninically not part of the I2O subsyßtem... - */ - if(i2o_status_get(iop)) { - printk(KERN_ERR "%s: Deleting b/c could not get status while" - "attempting to build system table\n", iop->name); - i2o_delete_controller(iop); - sys_tbl->num_entries--; - continue; // try the next one - } - - sys_tbl->iops[count].org_id = iop->status_block->org_id; - sys_tbl->iops[count].iop_id = iop->unit + 2; - sys_tbl->iops[count].seg_num = 0; - sys_tbl->iops[count].i2o_version = - iop->status_block->i2o_version; - sys_tbl->iops[count].iop_state = - iop->status_block->iop_state; - sys_tbl->iops[count].msg_type = - iop->status_block->msg_type; - sys_tbl->iops[count].frame_size = - iop->status_block->inbound_frame_size; - sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ?? - sys_tbl->iops[count].iop_capabilities = - iop->status_block->iop_capabilities; - sys_tbl->iops[count].inbound_low = (u32)iop->post_port; - sys_tbl->iops[count].inbound_high = 0; // FIXME: 64-bit support - - count++; - } - -#ifdef DRIVERDEBUG -{ - u32 *table; - table = (u32*)sys_tbl; - for(count = 0; count < (sys_tbl_len >>2); count++) - printk(KERN_INFO "sys_tbl[%d] = %0#10x\n", count, table[count]); -} -#endif - - return 0; -} - - -/* - * Run time support routines - */ - -/* - * Generic "post and forget" helpers. This is less efficient - we do - * a memcpy for example that isnt strictly needed, but for most uses - * this is simply not worth optimising - */ - -int i2o_post_this(struct i2o_controller *c, u32 *data, int len) -{ - u32 m; - u32 *msg; - unsigned long t=jiffies; - - do - { - mb(); - m = I2O_POST_READ32(c); - } - while(m==0xFFFFFFFF && (jiffies-t)name); - return -ETIMEDOUT; - } - msg = (u32 *)(c->msg_virt + m); - memcpy_toio(msg, data, len); - i2o_post_message(c,m); - return 0; -} - -/** - * i2o_post_wait_mem - I2O query/reply with DMA buffers - * @c: controller - * @msg: message to send - * @len: length of message - * @timeout: time in seconds to wait - * @mem1: attached memory buffer 1 - * @mem2: attached memory buffer 2 - * @phys1: physical address of buffer 1 - * @phys2: physical address of buffer 2 - * @size1: size of buffer 1 - * @size2: size of buffer 2 - * - * This core API allows an OSM to post a message and then be told whether - * or not the system received a successful reply. - * - * If the message times out then the value '-ETIMEDOUT' is returned. This - * is a special case. In this situation the message may (should) complete - * at an indefinite time in the future. When it completes it will use the - * memory buffers attached to the request. If -ETIMEDOUT is returned then - * the memory buffers must not be freed. Instead the event completion will - * free them for you. In all other cases the buffers are your problem. - * - * Pass NULL for unneeded buffers. - */ - -int i2o_post_wait_mem(struct i2o_controller *c, u32 *msg, int len, int timeout, void *mem1, void *mem2, dma_addr_t phys1, dma_addr_t phys2, int size1, int size2) -{ - DECLARE_WAIT_QUEUE_HEAD(wq_i2o_post); - DECLARE_WAITQUEUE(wait, current); - int complete = 0; - int status; - unsigned long flags = 0; - struct i2o_post_wait_data *wait_data = - kmalloc(sizeof(struct i2o_post_wait_data), GFP_KERNEL); - - if(!wait_data) - return -ENOMEM; - - /* - * Create a new notification object - */ - wait_data->status = &status; - wait_data->complete = &complete; - wait_data->mem[0] = mem1; - wait_data->mem[1] = mem2; - wait_data->phys[0] = phys1; - wait_data->phys[1] = phys2; - wait_data->size[0] = size1; - wait_data->size[1] = size2; - - /* - * Queue the event with its unique id - */ - spin_lock_irqsave(&post_wait_lock, flags); - - wait_data->next = post_wait_queue; - post_wait_queue = wait_data; - wait_data->id = (++post_wait_id) & 0x7fff; - wait_data->wq = &wq_i2o_post; - - spin_unlock_irqrestore(&post_wait_lock, flags); - - /* - * Fill in the message id - */ - - msg[2] = 0x80000000|(u32)core_context|((u32)wait_data->id<<16); - - /* - * Post the message to the controller. At some point later it - * will return. If we time out before it returns then - * complete will be zero. From the point post_this returns - * the wait_data may have been deleted. - */ - - add_wait_queue(&wq_i2o_post, &wait); - set_current_state(TASK_INTERRUPTIBLE); - if ((status = i2o_post_this(c, msg, len))==0) { - schedule_timeout(HZ * timeout); - } - else - { - remove_wait_queue(&wq_i2o_post, &wait); - return -EIO; - } - remove_wait_queue(&wq_i2o_post, &wait); - - if(signal_pending(current)) - status = -EINTR; - - spin_lock_irqsave(&post_wait_lock, flags); - barrier(); /* Be sure we see complete as it is locked */ - if(!complete) - { - /* - * Mark the entry dead. We cannot remove it. This is important. - * When it does terminate (which it must do if the controller hasnt - * died..) then it will otherwise scribble on stuff. - * !complete lets us safely check if the entry is still - * allocated and thus we can write into it - */ - wait_data->wq = NULL; - status = -ETIMEDOUT; - } - else - { - /* Debugging check - remove me soon */ - if(status == -ETIMEDOUT) - { - printk("TIMEDOUT BUG!\n"); - status = -EIO; - } - } - /* And the wait_data is not leaked either! */ - spin_unlock_irqrestore(&post_wait_lock, flags); - return status; -} - -/** - * i2o_post_wait - I2O query/reply - * @c: controller - * @msg: message to send - * @len: length of message - * @timeout: time in seconds to wait - * - * This core API allows an OSM to post a message and then be told whether - * or not the system received a successful reply. - */ - -int i2o_post_wait(struct i2o_controller *c, u32 *msg, int len, int timeout) -{ - return i2o_post_wait_mem(c, msg, len, timeout, NULL, NULL, 0, 0, 0, 0); -} - -/* - * i2o_post_wait is completed and we want to wake up the - * sleeping proccess. Called by core's reply handler. - */ - -static void i2o_post_wait_complete(struct i2o_controller *c, u32 context, int status) -{ - struct i2o_post_wait_data **p1, *q; - unsigned long flags; - - /* - * We need to search through the post_wait - * queue to see if the given message is still - * outstanding. If not, it means that the IOP - * took longer to respond to the message than we - * had allowed and timer has already expired. - * Not much we can do about that except log - * it for debug purposes, increase timeout, and recompile - * - * Lock needed to keep anyone from moving queue pointers - * around while we're looking through them. - */ - - spin_lock_irqsave(&post_wait_lock, flags); - - for(p1 = &post_wait_queue; *p1!=NULL; p1 = &((*p1)->next)) - { - q = (*p1); - if(q->id == ((context >> 16) & 0x7fff)) { - /* - * Delete it - */ - - *p1 = q->next; - - /* - * Live or dead ? - */ - - if(q->wq) - { - /* Live entry - wakeup and set status */ - *q->status = status; - *q->complete = 1; - wake_up(q->wq); - } - else - { - /* - * Free resources. Caller is dead - */ - - if(q->mem[0]) - pci_free_consistent(c->pdev, q->size[0], q->mem[0], q->phys[0]); - if(q->mem[1]) - pci_free_consistent(c->pdev, q->size[1], q->mem[1], q->phys[1]); - - printk(KERN_WARNING "i2o_post_wait event completed after timeout.\n"); - } - kfree(q); - spin_unlock(&post_wait_lock); - return; - } - } - spin_unlock(&post_wait_lock); - - printk(KERN_DEBUG "i2o_post_wait: Bogus reply!\n"); -} - -/* Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET - * - * This function can be used for all UtilParamsGet/Set operations. - * The OperationList is given in oplist-buffer, - * and results are returned in reslist-buffer. - * Note that the minimum sized reslist is 8 bytes and contains - * ResultCount, ErrorInfoSize, BlockStatus and BlockSize. - */ - -int i2o_issue_params(int cmd, struct i2o_controller *iop, int tid, - void *oplist, int oplen, void *reslist, int reslen) -{ - u32 msg[9]; - u32 *res32 = (u32*)reslist; - u32 *restmp = (u32*)reslist; - int len = 0; - int i = 0; - int wait_status; - u32 *opmem, *resmem; - dma_addr_t opmem_phys, resmem_phys; - - /* Get DMAable memory */ - opmem = pci_alloc_consistent(iop->pdev, oplen, &opmem_phys); - if(opmem == NULL) - return -ENOMEM; - memcpy(opmem, oplist, oplen); - - resmem = pci_alloc_consistent(iop->pdev, reslen, &resmem_phys); - if(resmem == NULL) - { - pci_free_consistent(iop->pdev, oplen, opmem, opmem_phys); - return -ENOMEM; - } - - msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5; - msg[1] = cmd << 24 | HOST_TID << 12 | tid; - msg[3] = 0; - msg[4] = 0; - msg[5] = 0x54000000 | oplen; /* OperationList */ - msg[6] = opmem_phys; - msg[7] = 0xD0000000 | reslen; /* ResultList */ - msg[8] = resmem_phys; - - wait_status = i2o_post_wait_mem(iop, msg, sizeof(msg), 10, opmem, resmem, opmem_phys, resmem_phys, oplen, reslen); - - /* - * This only looks like a memory leak - don't "fix" it. - */ - if(wait_status == -ETIMEDOUT) - return wait_status; - - memcpy(reslist, resmem, reslen); - pci_free_consistent(iop->pdev, reslen, resmem, resmem_phys); - pci_free_consistent(iop->pdev, oplen, opmem, opmem_phys); - - /* Query failed */ - if(wait_status != 0) - return wait_status; - /* - * Calculate number of bytes of Result LIST - * We need to loop through each Result BLOCK and grab the length - */ - restmp = res32 + 1; - len = 1; - for(i = 0; i < (res32[0]&0X0000FFFF); i++) - { - if(restmp[0]&0x00FF0000) /* BlockStatus != SUCCESS */ - { - printk(KERN_WARNING "%s - Error:\n ErrorInfoSize = 0x%02x, " - "BlockStatus = 0x%02x, BlockSize = 0x%04x\n", - (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET" - : "PARAMS_GET", - res32[1]>>24, (res32[1]>>16)&0xFF, res32[1]&0xFFFF); - - /* - * If this is the only request,than we return an error - */ - if((res32[0]&0x0000FFFF) == 1) - { - return -((res32[1] >> 16) & 0xFF); /* -BlockStatus */ - } - } - len += restmp[0] & 0x0000FFFF; /* Length of res BLOCK */ - restmp += restmp[0] & 0x0000FFFF; /* Skip to next BLOCK */ - } - return (len << 2); /* bytes used by result list */ -} - -/* - * Query one scalar group value or a whole scalar group. - */ -int i2o_query_scalar(struct i2o_controller *iop, int tid, - int group, int field, void *buf, int buflen) -{ - u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field }; - u8 resblk[8+buflen]; /* 8 bytes for header */ - int size; - - if (field == -1) /* whole group */ - opblk[4] = -1; - - size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, iop, tid, - opblk, sizeof(opblk), resblk, sizeof(resblk)); - - memcpy(buf, resblk+8, buflen); /* cut off header */ - - if(size>buflen) - return buflen; - return size; -} - -/* - * Set a scalar group value or a whole group. - */ -int i2o_set_scalar(struct i2o_controller *iop, int tid, - int group, int field, void *buf, int buflen) -{ - u16 *opblk; - u8 resblk[8+buflen]; /* 8 bytes for header */ - int size; - - opblk = kmalloc(buflen+64, GFP_KERNEL); - if (opblk == NULL) - { - printk(KERN_ERR "i2o: no memory for operation buffer.\n"); - return -ENOMEM; - } - - opblk[0] = 1; /* operation count */ - opblk[1] = 0; /* pad */ - opblk[2] = I2O_PARAMS_FIELD_SET; - opblk[3] = group; - - if(field == -1) { /* whole group */ - opblk[4] = -1; - memcpy(opblk+5, buf, buflen); - } - else /* single field */ - { - opblk[4] = 1; - opblk[5] = field; - memcpy(opblk+6, buf, buflen); - } - - size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, - opblk, 12+buflen, resblk, sizeof(resblk)); - - kfree(opblk); - if(size>buflen) - return buflen; - return size; -} - -/* - * if oper == I2O_PARAMS_TABLE_GET, get from all rows - * if fieldcount == -1 return all fields - * ibuf and ibuflen are unused (use NULL, 0) - * else return specific fields - * ibuf contains fieldindexes - * - * if oper == I2O_PARAMS_LIST_GET, get from specific rows - * if fieldcount == -1 return all fields - * ibuf contains rowcount, keyvalues - * else return specific fields - * fieldcount is # of fieldindexes - * ibuf contains fieldindexes, rowcount, keyvalues - * - * You could also use directly function i2o_issue_params(). - */ -int i2o_query_table(int oper, struct i2o_controller *iop, int tid, int group, - int fieldcount, void *ibuf, int ibuflen, - void *resblk, int reslen) -{ - u16 *opblk; - int size; - - opblk = kmalloc(10 + ibuflen, GFP_KERNEL); - if (opblk == NULL) - { - printk(KERN_ERR "i2o: no memory for query buffer.\n"); - return -ENOMEM; - } - - opblk[0] = 1; /* operation count */ - opblk[1] = 0; /* pad */ - opblk[2] = oper; - opblk[3] = group; - opblk[4] = fieldcount; - memcpy(opblk+5, ibuf, ibuflen); /* other params */ - - size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET,iop, tid, - opblk, 10+ibuflen, resblk, reslen); - - kfree(opblk); - if(size>reslen) - return reslen; - return size; -} - -/* - * Clear table group, i.e. delete all rows. - */ -int i2o_clear_table(struct i2o_controller *iop, int tid, int group) -{ - u16 opblk[] = { 1, 0, I2O_PARAMS_TABLE_CLEAR, group }; - u8 resblk[32]; /* min 8 bytes for result header */ - - return i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, - opblk, sizeof(opblk), resblk, sizeof(resblk)); -} - -/* - * Add a new row into a table group. - * - * if fieldcount==-1 then we add whole rows - * buf contains rowcount, keyvalues - * else just specific fields are given, rest use defaults - * buf contains fieldindexes, rowcount, keyvalues - */ -int i2o_row_add_table(struct i2o_controller *iop, int tid, - int group, int fieldcount, void *buf, int buflen) -{ - u16 *opblk; - u8 resblk[32]; /* min 8 bytes for header */ - int size; - - opblk = kmalloc(buflen+64, GFP_KERNEL); - if (opblk == NULL) - { - printk(KERN_ERR "i2o: no memory for operation buffer.\n"); - return -ENOMEM; - } - - opblk[0] = 1; /* operation count */ - opblk[1] = 0; /* pad */ - opblk[2] = I2O_PARAMS_ROW_ADD; - opblk[3] = group; - opblk[4] = fieldcount; - memcpy(opblk+5, buf, buflen); - - size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, - opblk, 10+buflen, resblk, sizeof(resblk)); - - kfree(opblk); - if(size>buflen) - return buflen; - return size; -} - - -/* - * Used for error reporting/debugging purposes. - * Following fail status are common to all classes. - * The preserved message must be handled in the reply handler. - */ -void i2o_report_fail_status(u8 req_status, u32* msg) -{ - static char *FAIL_STATUS[] = { - "0x80", /* not used */ - "SERVICE_SUSPENDED", /* 0x81 */ - "SERVICE_TERMINATED", /* 0x82 */ - "CONGESTION", - "FAILURE", - "STATE_ERROR", - "TIME_OUT", - "ROUTING_FAILURE", - "INVALID_VERSION", - "INVALID_OFFSET", - "INVALID_MSG_FLAGS", - "FRAME_TOO_SMALL", - "FRAME_TOO_LARGE", - "INVALID_TARGET_ID", - "INVALID_INITIATOR_ID", - "INVALID_INITIATOR_CONTEX", /* 0x8F */ - "UNKNOWN_FAILURE" /* 0xFF */ - }; - - if (req_status == I2O_FSC_TRANSPORT_UNKNOWN_FAILURE) - printk("TRANSPORT_UNKNOWN_FAILURE (%0#2x)\n.", req_status); - else - printk("TRANSPORT_%s.\n", FAIL_STATUS[req_status & 0x0F]); - - /* Dump some details */ - - printk(KERN_ERR " InitiatorId = %d, TargetId = %d\n", - (msg[1] >> 12) & 0xFFF, msg[1] & 0xFFF); - printk(KERN_ERR " LowestVersion = 0x%02X, HighestVersion = 0x%02X\n", - (msg[4] >> 8) & 0xFF, msg[4] & 0xFF); - printk(KERN_ERR " FailingHostUnit = 0x%04X, FailingIOP = 0x%03X\n", - msg[5] >> 16, msg[5] & 0xFFF); - - printk(KERN_ERR " Severity: 0x%02X ", (msg[4] >> 16) & 0xFF); - if (msg[4] & (1<<16)) - printk("(FormatError), " - "this msg can never be delivered/processed.\n"); - if (msg[4] & (1<<17)) - printk("(PathError), " - "this msg can no longer be delivered/processed.\n"); - if (msg[4] & (1<<18)) - printk("(PathState), " - "the system state does not allow delivery.\n"); - if (msg[4] & (1<<19)) - printk("(Congestion), resources temporarily not available;" - "do not retry immediately.\n"); -} - -/* - * Used for error reporting/debugging purposes. - * Following reply status are common to all classes. - */ -void i2o_report_common_status(u8 req_status) -{ - static char *REPLY_STATUS[] = { - "SUCCESS", - "ABORT_DIRTY", - "ABORT_NO_DATA_TRANSFER", - "ABORT_PARTIAL_TRANSFER", - "ERROR_DIRTY", - "ERROR_NO_DATA_TRANSFER", - "ERROR_PARTIAL_TRANSFER", - "PROCESS_ABORT_DIRTY", - "PROCESS_ABORT_NO_DATA_TRANSFER", - "PROCESS_ABORT_PARTIAL_TRANSFER", - "TRANSACTION_ERROR", - "PROGRESS_REPORT" - }; - - if (req_status >= ARRAY_SIZE(REPLY_STATUS)) - printk("RequestStatus = %0#2x", req_status); - else - printk("%s", REPLY_STATUS[req_status]); -} - -/* - * Used for error reporting/debugging purposes. - * Following detailed status are valid for executive class, - * utility class, DDM class and for transaction error replies. - */ -static void i2o_report_common_dsc(u16 detailed_status) -{ - static char *COMMON_DSC[] = { - "SUCCESS", - "0x01", // not used - "BAD_KEY", - "TCL_ERROR", - "REPLY_BUFFER_FULL", - "NO_SUCH_PAGE", - "INSUFFICIENT_RESOURCE_SOFT", - "INSUFFICIENT_RESOURCE_HARD", - "0x08", // not used - "CHAIN_BUFFER_TOO_LARGE", - "UNSUPPORTED_FUNCTION", - "DEVICE_LOCKED", - "DEVICE_RESET", - "INAPPROPRIATE_FUNCTION", - "INVALID_INITIATOR_ADDRESS", - "INVALID_MESSAGE_FLAGS", - "INVALID_OFFSET", - "INVALID_PARAMETER", - "INVALID_REQUEST", - "INVALID_TARGET_ADDRESS", - "MESSAGE_TOO_LARGE", - "MESSAGE_TOO_SMALL", - "MISSING_PARAMETER", - "TIMEOUT", - "UNKNOWN_ERROR", - "UNKNOWN_FUNCTION", - "UNSUPPORTED_VERSION", - "DEVICE_BUSY", - "DEVICE_NOT_AVAILABLE" - }; - - if (detailed_status > I2O_DSC_DEVICE_NOT_AVAILABLE) - printk(" / DetailedStatus = %0#4x.\n", detailed_status); - else - printk(" / %s.\n", COMMON_DSC[detailed_status]); -} - -/* - * Used for error reporting/debugging purposes - */ -static void i2o_report_lan_dsc(u16 detailed_status) -{ - static char *LAN_DSC[] = { // Lan detailed status code strings - "SUCCESS", - "DEVICE_FAILURE", - "DESTINATION_NOT_FOUND", - "TRANSMIT_ERROR", - "TRANSMIT_ABORTED", - "RECEIVE_ERROR", - "RECEIVE_ABORTED", - "DMA_ERROR", - "BAD_PACKET_DETECTED", - "OUT_OF_MEMORY", - "BUCKET_OVERRUN", - "IOP_INTERNAL_ERROR", - "CANCELED", - "INVALID_TRANSACTION_CONTEXT", - "DEST_ADDRESS_DETECTED", - "DEST_ADDRESS_OMITTED", - "PARTIAL_PACKET_RETURNED", - "TEMP_SUSPENDED_STATE", // last Lan detailed status code - "INVALID_REQUEST" // general detailed status code - }; - - if (detailed_status > I2O_DSC_INVALID_REQUEST) - printk(" / %0#4x.\n", detailed_status); - else - printk(" / %s.\n", LAN_DSC[detailed_status]); -} - -/* - * Used for error reporting/debugging purposes - */ -static void i2o_report_util_cmd(u8 cmd) -{ - switch (cmd) { - case I2O_CMD_UTIL_NOP: - printk("UTIL_NOP, "); - break; - case I2O_CMD_UTIL_ABORT: - printk("UTIL_ABORT, "); - break; - case I2O_CMD_UTIL_CLAIM: - printk("UTIL_CLAIM, "); - break; - case I2O_CMD_UTIL_RELEASE: - printk("UTIL_CLAIM_RELEASE, "); - break; - case I2O_CMD_UTIL_CONFIG_DIALOG: - printk("UTIL_CONFIG_DIALOG, "); - break; - case I2O_CMD_UTIL_DEVICE_RESERVE: - printk("UTIL_DEVICE_RESERVE, "); - break; - case I2O_CMD_UTIL_DEVICE_RELEASE: - printk("UTIL_DEVICE_RELEASE, "); - break; - case I2O_CMD_UTIL_EVT_ACK: - printk("UTIL_EVENT_ACKNOWLEDGE, "); - break; - case I2O_CMD_UTIL_EVT_REGISTER: - printk("UTIL_EVENT_REGISTER, "); - break; - case I2O_CMD_UTIL_LOCK: - printk("UTIL_LOCK, "); - break; - case I2O_CMD_UTIL_LOCK_RELEASE: - printk("UTIL_LOCK_RELEASE, "); - break; - case I2O_CMD_UTIL_PARAMS_GET: - printk("UTIL_PARAMS_GET, "); - break; - case I2O_CMD_UTIL_PARAMS_SET: - printk("UTIL_PARAMS_SET, "); - break; - case I2O_CMD_UTIL_REPLY_FAULT_NOTIFY: - printk("UTIL_REPLY_FAULT_NOTIFY, "); - break; - default: - printk("Cmd = %0#2x, ",cmd); - } -} - -/* - * Used for error reporting/debugging purposes - */ -static void i2o_report_exec_cmd(u8 cmd) -{ - switch (cmd) { - case I2O_CMD_ADAPTER_ASSIGN: - printk("EXEC_ADAPTER_ASSIGN, "); - break; - case I2O_CMD_ADAPTER_READ: - printk("EXEC_ADAPTER_READ, "); - break; - case I2O_CMD_ADAPTER_RELEASE: - printk("EXEC_ADAPTER_RELEASE, "); - break; - case I2O_CMD_BIOS_INFO_SET: - printk("EXEC_BIOS_INFO_SET, "); - break; - case I2O_CMD_BOOT_DEVICE_SET: - printk("EXEC_BOOT_DEVICE_SET, "); - break; - case I2O_CMD_CONFIG_VALIDATE: - printk("EXEC_CONFIG_VALIDATE, "); - break; - case I2O_CMD_CONN_SETUP: - printk("EXEC_CONN_SETUP, "); - break; - case I2O_CMD_DDM_DESTROY: - printk("EXEC_DDM_DESTROY, "); - break; - case I2O_CMD_DDM_ENABLE: - printk("EXEC_DDM_ENABLE, "); - break; - case I2O_CMD_DDM_QUIESCE: - printk("EXEC_DDM_QUIESCE, "); - break; - case I2O_CMD_DDM_RESET: - printk("EXEC_DDM_RESET, "); - break; - case I2O_CMD_DDM_SUSPEND: - printk("EXEC_DDM_SUSPEND, "); - break; - case I2O_CMD_DEVICE_ASSIGN: - printk("EXEC_DEVICE_ASSIGN, "); - break; - case I2O_CMD_DEVICE_RELEASE: - printk("EXEC_DEVICE_RELEASE, "); - break; - case I2O_CMD_HRT_GET: - printk("EXEC_HRT_GET, "); - break; - case I2O_CMD_ADAPTER_CLEAR: - printk("EXEC_IOP_CLEAR, "); - break; - case I2O_CMD_ADAPTER_CONNECT: - printk("EXEC_IOP_CONNECT, "); - break; - case I2O_CMD_ADAPTER_RESET: - printk("EXEC_IOP_RESET, "); - break; - case I2O_CMD_LCT_NOTIFY: - printk("EXEC_LCT_NOTIFY, "); - break; - case I2O_CMD_OUTBOUND_INIT: - printk("EXEC_OUTBOUND_INIT, "); - break; - case I2O_CMD_PATH_ENABLE: - printk("EXEC_PATH_ENABLE, "); - break; - case I2O_CMD_PATH_QUIESCE: - printk("EXEC_PATH_QUIESCE, "); - break; - case I2O_CMD_PATH_RESET: - printk("EXEC_PATH_RESET, "); - break; - case I2O_CMD_STATIC_MF_CREATE: - printk("EXEC_STATIC_MF_CREATE, "); - break; - case I2O_CMD_STATIC_MF_RELEASE: - printk("EXEC_STATIC_MF_RELEASE, "); - break; - case I2O_CMD_STATUS_GET: - printk("EXEC_STATUS_GET, "); - break; - case I2O_CMD_SW_DOWNLOAD: - printk("EXEC_SW_DOWNLOAD, "); - break; - case I2O_CMD_SW_UPLOAD: - printk("EXEC_SW_UPLOAD, "); - break; - case I2O_CMD_SW_REMOVE: - printk("EXEC_SW_REMOVE, "); - break; - case I2O_CMD_SYS_ENABLE: - printk("EXEC_SYS_ENABLE, "); - break; - case I2O_CMD_SYS_MODIFY: - printk("EXEC_SYS_MODIFY, "); - break; - case I2O_CMD_SYS_QUIESCE: - printk("EXEC_SYS_QUIESCE, "); - break; - case I2O_CMD_SYS_TAB_SET: - printk("EXEC_SYS_TAB_SET, "); - break; - default: - printk("Cmd = %#02x, ",cmd); - } -} - -/* - * Used for error reporting/debugging purposes - */ -static void i2o_report_lan_cmd(u8 cmd) -{ - switch (cmd) { - case LAN_PACKET_SEND: - printk("LAN_PACKET_SEND, "); - break; - case LAN_SDU_SEND: - printk("LAN_SDU_SEND, "); - break; - case LAN_RECEIVE_POST: - printk("LAN_RECEIVE_POST, "); - break; - case LAN_RESET: - printk("LAN_RESET, "); - break; - case LAN_SUSPEND: - printk("LAN_SUSPEND, "); - break; - default: - printk("Cmd = %0#2x, ",cmd); - } -} - -/* - * Used for error reporting/debugging purposes. - * Report Cmd name, Request status, Detailed Status. - */ -void i2o_report_status(const char *severity, const char *str, u32 *msg) -{ - u8 cmd = (msg[1]>>24)&0xFF; - u8 req_status = (msg[4]>>24)&0xFF; - u16 detailed_status = msg[4]&0xFFFF; - struct i2o_handler *h = i2o_handlers[msg[2] & (MAX_I2O_MODULES-1)]; - - if (cmd == I2O_CMD_UTIL_EVT_REGISTER) - return; // No status in this reply - - printk("%s%s: ", severity, str); - - if (cmd < 0x1F) // Utility cmd - i2o_report_util_cmd(cmd); - - else if (cmd >= 0xA0 && cmd <= 0xEF) // Executive cmd - i2o_report_exec_cmd(cmd); - - else if (h->class == I2O_CLASS_LAN && cmd >= 0x30 && cmd <= 0x3F) - i2o_report_lan_cmd(cmd); // LAN cmd - else - printk("Cmd = %0#2x, ", cmd); // Other cmds - - if (msg[0] & MSG_FAIL) { - i2o_report_fail_status(req_status, msg); - return; - } - - i2o_report_common_status(req_status); - - if (cmd < 0x1F || (cmd >= 0xA0 && cmd <= 0xEF)) - i2o_report_common_dsc(detailed_status); - else if (h->class == I2O_CLASS_LAN && cmd >= 0x30 && cmd <= 0x3F) - i2o_report_lan_dsc(detailed_status); - else - printk(" / DetailedStatus = %0#4x.\n", detailed_status); -} - -/* Used to dump a message to syslog during debugging */ -void i2o_dump_message(u32 *msg) -{ -#ifdef DRIVERDEBUG - int i; - printk(KERN_INFO "Dumping I2O message size %d @ %p\n", - msg[0]>>16&0xffff, msg); - for(i = 0; i < ((msg[0]>>16)&0xffff); i++) - printk(KERN_INFO " msg[%d] = %0#10x\n", i, msg[i]); -#endif -} - -/* - * I2O reboot/shutdown notification. - * - * - Call each OSM's reboot notifier (if one exists) - * - Quiesce each IOP in the system - * - * Each IOP has to be quiesced before we can ensure that the system - * can be properly shutdown as a transaction that has already been - * acknowledged still needs to be placed in permanent store on the IOP. - * The SysQuiesce causes the IOP to force all HDMs to complete their - * transactions before returning, so only at that point is it safe - * - */ -static int i2o_reboot_event(struct notifier_block *n, unsigned long code, void -*p) -{ - int i = 0; - struct i2o_controller *c = NULL; - - if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF) - return NOTIFY_DONE; - - printk(KERN_INFO "Shutting down I2O system.\n"); - printk(KERN_INFO - " This could take a few minutes if there are many devices attached\n"); - - for(i = 0; i < MAX_I2O_MODULES; i++) - { - if(i2o_handlers[i] && i2o_handlers[i]->reboot_notify) - i2o_handlers[i]->reboot_notify(); - } - - for(c = i2o_controller_chain; c; c = c->next) - { - if(i2o_quiesce_controller(c)) - { - printk(KERN_WARNING "i2o: Could not quiesce %s.\n" - "Verify setup on next system power up.\n", - c->name); - } - } - - printk(KERN_INFO "I2O system down.\n"); - return NOTIFY_DONE; -} - - - - -/** - * i2o_pci_dispose - Free bus specific resources - * @c: I2O controller - * - * Disable interrupts and then free interrupt, I/O and mtrr resources - * used by this controller. Called by the I2O core on unload. - */ - -static void i2o_pci_dispose(struct i2o_controller *c) -{ - I2O_IRQ_WRITE32(c,0xFFFFFFFF); - if(c->irq > 0) - free_irq(c->irq, c); - iounmap(c->base_virt); - if(c->raptor) - iounmap(c->msg_virt); - -#ifdef CONFIG_MTRR - if(c->mtrr_reg0 > 0) - mtrr_del(c->mtrr_reg0, 0, 0); - if(c->mtrr_reg1 > 0) - mtrr_del(c->mtrr_reg1, 0, 0); -#endif -} - -/** - * i2o_pci_interrupt - Bus specific interrupt handler - * @irq: interrupt line - * @dev_id: cookie - * - * Handle an interrupt from a PCI based I2O controller. This turns out - * to be rather simple. We keep the controller pointer in the cookie. - */ - -static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r) -{ - struct i2o_controller *c = dev_id; - i2o_run_queue(c); - return IRQ_HANDLED; -} - -/** - * i2o_pci_install - Install a PCI i2o controller - * @dev: PCI device of the I2O controller - * - * Install a PCI (or in theory AGP) i2o controller. Devices are - * initialized, configured and registered with the i2o core subsystem. Be - * very careful with ordering. There may be pending interrupts. - * - * To Do: Add support for polled controllers - */ - -int __init i2o_pci_install(struct pci_dev *dev) -{ - struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller), - GFP_KERNEL); - void *bar0_virt; - void *bar1_virt; - unsigned long bar0_phys = 0; - unsigned long bar1_phys = 0; - unsigned long bar0_size = 0; - unsigned long bar1_size = 0; - - int i; - - if(c==NULL) - { - printk(KERN_ERR "i2o: Insufficient memory to add controller.\n"); - return -ENOMEM; - } - memset(c, 0, sizeof(*c)); - - c->irq = -1; - c->dpt = 0; - c->raptor = 0; - c->short_req = 0; - c->pdev = dev; - -#if BITS_PER_LONG == 64 - c->context_list_lock = SPIN_LOCK_UNLOCKED; -#endif - - /* - * Cards that fall apart if you hit them with large I/O - * loads... - */ - - if(dev->vendor == PCI_VENDOR_ID_NCR && dev->device == 0x0630) - { - c->short_req = 1; - printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n"); - } - - if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) - { - c->promise = 1; - printk(KERN_INFO "I2O: Promise workarounds activated.\n"); - } - - /* - * Cards that go bananas if you quiesce them before you reset - * them - */ - - if(dev->vendor == PCI_VENDOR_ID_DPT) { - c->dpt=1; - if(dev->device == 0xA511) - c->raptor=1; - } - - for(i=0; i<6; i++) - { - /* Skip I/O spaces */ - if(!(pci_resource_flags(dev, i) & IORESOURCE_IO)) - { - if(!bar0_phys) - { - bar0_phys = pci_resource_start(dev, i); - bar0_size = pci_resource_len(dev, i); - if(!c->raptor) - break; - } - else - { - bar1_phys = pci_resource_start(dev, i); - bar1_size = pci_resource_len(dev, i); - break; - } - } - } - - if(i==6) - { - printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n"); - kfree(c); - return -EINVAL; - } - - - /* Map the I2O controller */ - if(!c->raptor) - printk(KERN_INFO "i2o: PCI I2O controller at %08lX size=%ld\n", bar0_phys, bar0_size); - else - printk(KERN_INFO "i2o: PCI I2O controller\n BAR0 at 0x%08lX size=%ld\n BAR1 at 0x%08lX size=%ld\n", bar0_phys, bar0_size, bar1_phys, bar1_size); - - bar0_virt = ioremap(bar0_phys, bar0_size); - if(bar0_virt==0) - { - printk(KERN_ERR "i2o: Unable to map controller.\n"); - kfree(c); - return -EINVAL; - } - - if(c->raptor) - { - bar1_virt = ioremap(bar1_phys, bar1_size); - if(bar1_virt==0) - { - printk(KERN_ERR "i2o: Unable to map controller.\n"); - kfree(c); - iounmap(bar0_virt); - return -EINVAL; - } - } else { - bar1_virt = bar0_virt; - bar1_phys = bar0_phys; - bar1_size = bar0_size; - } - - c->irq_mask = bar0_virt+0x34; - c->post_port = bar0_virt+0x40; - c->reply_port = bar0_virt+0x44; - - c->base_phys = bar0_phys; - c->base_virt = bar0_virt; - c->msg_phys = bar1_phys; - c->msg_virt = bar1_virt; - - /* - * Enable Write Combining MTRR for IOP's memory region - */ -#ifdef CONFIG_MTRR - c->mtrr_reg0 = mtrr_add(c->base_phys, bar0_size, MTRR_TYPE_WRCOMB, 1); - /* - * If it is an INTEL i960 I/O processor then set the first 64K to - * Uncacheable since the region contains the Messaging unit which - * shouldn't be cached. - */ - c->mtrr_reg1 = -1; - if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT) - { - printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n"); - c->mtrr_reg1 = mtrr_add(c->base_phys, 65536, MTRR_TYPE_UNCACHABLE, 1); - if(c->mtrr_reg1< 0) - { - printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n"); - mtrr_del(c->mtrr_reg0, c->msg_phys, bar1_size); - c->mtrr_reg0 = -1; - } - } - if(c->raptor) - c->mtrr_reg1 = mtrr_add(c->msg_phys, bar1_size, MTRR_TYPE_WRCOMB, 1); - -#endif - - I2O_IRQ_WRITE32(c,0xFFFFFFFF); - - i = i2o_install_controller(c); - - if(i<0) - { - printk(KERN_ERR "i2o: Unable to install controller.\n"); - kfree(c); - iounmap(bar0_virt); - if(c->raptor) - iounmap(bar1_virt); - return i; - } - - c->irq = dev->irq; - if(c->irq) - { - i=request_irq(dev->irq, i2o_pci_interrupt, SA_SHIRQ, - c->name, c); - if(i<0) - { - printk(KERN_ERR "%s: unable to allocate interrupt %d.\n", - c->name, dev->irq); - c->irq = -1; - i2o_delete_controller(c); - iounmap(bar0_virt); - if(c->raptor) - iounmap(bar1_virt); - return -EBUSY; - } - } - - printk(KERN_INFO "%s: Installed at IRQ%d\n", c->name, dev->irq); - I2O_IRQ_WRITE32(c,0x0); - c->enabled = 1; - return 0; -} - -/** - * i2o_pci_scan - Scan the pci bus for controllers - * - * Scan the PCI devices on the system looking for any device which is a - * memory of the Intelligent, I2O class. We attempt to set up each such device - * and register it with the core. - * - * Returns the number of controllers registered - * - * Note; Do not change this to a hot plug interface. I2O 1.5 itself - * does not support hot plugging. - */ - -int __init i2o_pci_scan(void) -{ - struct pci_dev *dev = NULL; - int count=0; - - printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) - { - if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O && - (dev->vendor!=PCI_VENDOR_ID_DPT || dev->device!=0xA511)) - continue; - - if((dev->class>>8)==PCI_CLASS_INTELLIGENT_I2O && - (dev->class&0xFF)>1) - { - printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n"); - continue; - } - if (pci_enable_device(dev)) - continue; - printk(KERN_INFO "i2o: I2O controller on bus %d at %d.\n", - dev->bus->number, dev->devfn); - if(pci_set_dma_mask(dev, 0xffffffff)) - { - printk(KERN_WARNING "I2O controller on bus %d at %d : No suitable DMA available\n", dev->bus->number, dev->devfn); - continue; - } - pci_set_master(dev); - if(i2o_pci_install(dev)==0) - count++; - } - if(count) - printk(KERN_INFO "i2o: %d I2O controller%s found and installed.\n", count, - count==1?"":"s"); - return count?count:-ENODEV; -} - -static int i2o_core_init(void) -{ - printk(KERN_INFO "I2O Core - (C) Copyright 1999 Red Hat Software\n"); - if (i2o_install_handler(&i2o_core_handler) < 0) - { - printk(KERN_ERR "i2o_core: Unable to install core handler.\nI2O stack not loaded!"); - return 0; - } - - core_context = i2o_core_handler.context; - - /* - * Initialize event handling thread - */ - - init_MUTEX_LOCKED(&evt_sem); - evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND); - if(evt_pid < 0) - { - printk(KERN_ERR "I2O: Could not create event handler kernel thread\n"); - i2o_remove_handler(&i2o_core_handler); - return 0; - } - else - printk(KERN_INFO "I2O: Event thread created as pid %d\n", evt_pid); - - i2o_pci_scan(); - if(i2o_num_controllers) - i2o_sys_init(); - - register_reboot_notifier(&i2o_reboot_notifier); - - return 0; -} - -static void i2o_core_exit(void) -{ - int stat; - - unregister_reboot_notifier(&i2o_reboot_notifier); - - if(i2o_num_controllers) - i2o_sys_shutdown(); - - /* - * If this is shutdown time, the thread has already been killed - */ - if(evt_running) { - printk("Terminating i2o threads..."); - stat = kill_proc(evt_pid, SIGKILL, 1); - if(!stat) { - printk("waiting...\n"); - wait_for_completion(&evt_dead); - } - printk("done.\n"); - } - i2o_remove_handler(&i2o_core_handler); -} - -module_init(i2o_core_init); -module_exit(i2o_core_exit); - -MODULE_PARM(verbose, "i"); -MODULE_PARM_DESC(verbose, "Verbose diagnostics"); - -MODULE_AUTHOR("Red Hat Software"); -MODULE_DESCRIPTION("I2O Core"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(i2o_controller_chain); -EXPORT_SYMBOL(i2o_num_controllers); -EXPORT_SYMBOL(i2o_find_controller); -EXPORT_SYMBOL(i2o_unlock_controller); -EXPORT_SYMBOL(i2o_status_get); -EXPORT_SYMBOL(i2o_install_handler); -EXPORT_SYMBOL(i2o_remove_handler); -EXPORT_SYMBOL(i2o_install_controller); -EXPORT_SYMBOL(i2o_delete_controller); -EXPORT_SYMBOL(i2o_run_queue); -EXPORT_SYMBOL(i2o_claim_device); -EXPORT_SYMBOL(i2o_release_device); -EXPORT_SYMBOL(i2o_device_notify_on); -EXPORT_SYMBOL(i2o_device_notify_off); -EXPORT_SYMBOL(i2o_post_this); -EXPORT_SYMBOL(i2o_post_wait); -EXPORT_SYMBOL(i2o_post_wait_mem); -EXPORT_SYMBOL(i2o_query_scalar); -EXPORT_SYMBOL(i2o_set_scalar); -EXPORT_SYMBOL(i2o_query_table); -EXPORT_SYMBOL(i2o_clear_table); -EXPORT_SYMBOL(i2o_row_add_table); -EXPORT_SYMBOL(i2o_issue_params); -EXPORT_SYMBOL(i2o_event_register); -EXPORT_SYMBOL(i2o_event_ack); -EXPORT_SYMBOL(i2o_report_status); -EXPORT_SYMBOL(i2o_dump_message); -EXPORT_SYMBOL(i2o_get_class_name); -EXPORT_SYMBOL(i2o_context_list_add); -EXPORT_SYMBOL(i2o_context_list_get); -EXPORT_SYMBOL(i2o_context_list_remove); diff --git a/drivers/mtd/maps/chestnut.c b/drivers/mtd/maps/chestnut.c deleted file mode 100644 index 1cb5f1527..000000000 --- a/drivers/mtd/maps/chestnut.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * drivers/mtd/maps/chestnut.c - * - * $Id: chestnut.c,v 1.1 2005/01/05 16:59:50 dwmw2 Exp $ - * - * Flash map driver for IBM Chestnut (750FXGX Eval) - * - * Chose not to enable 8 bit flash as it contains the firmware and board - * info. Thus only the 32bit flash is supported. - * - * Author: - * - * 2004 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct map_info chestnut32_map = { - .name = "User FS", - .size = CHESTNUT_32BIT_SIZE, - .bankwidth = 4, - .phys = CHESTNUT_32BIT_BASE, -}; - -static struct mtd_partition chestnut32_partitions[] = { - { - .name = "User FS", - .offset = 0, - .size = CHESTNUT_32BIT_SIZE, - } -}; - -static struct mtd_info *flash32; - -int __init init_chestnut(void) -{ - /* 32-bit FLASH */ - - chestnut32_map.virt = ioremap(chestnut32_map.phys, chestnut32_map.size); - - if (!chestnut32_map.virt) { - printk(KERN_NOTICE "Failed to ioremap 32-bit flash\n"); - return -EIO; - } - - simple_map_init(&chestnut32_map); - - flash32 = do_map_probe("cfi_probe", &chestnut32_map); - if (flash32) { - flash32->owner = THIS_MODULE; - add_mtd_partitions(flash32, chestnut32_partitions, - ARRAY_SIZE(chestnut32_partitions)); - } else { - printk(KERN_NOTICE "map probe failed for 32-bit flash\n"); - return -ENXIO; - } - - return 0; -} - -static void __exit -cleanup_chestnut(void) -{ - if (flash32) { - del_mtd_partitions(flash32); - map_destroy(flash32); - } - - if (chestnut32_map.virt) { - iounmap((void *)chestnut32_map.virt); - chestnut32_map.virt = 0; - } -} - -module_init(init_chestnut); -module_exit(cleanup_chestnut); - -MODULE_DESCRIPTION("MTD map and partitions for IBM Chestnut (750fxgx Eval)"); -MODULE_AUTHOR(""); -MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/dc390.h b/drivers/scsi/dc390.h deleted file mode 100644 index eeaf46a69..000000000 --- a/drivers/scsi/dc390.h +++ /dev/null @@ -1,32 +0,0 @@ -/*********************************************************************** - * FILE NAME : DC390.H * - * BY : C.L. Huang * - * Description: Device Driver for Tekram DC-390(T) PCI SCSI * - * Bus Master Host Adapter * - ***********************************************************************/ -/* $Id: dc390.h,v 2.43.2.22 2000/12/20 00:39:36 garloff Exp $ */ - -/* - * DC390/AMD 53C974 driver, header file - */ - -#ifndef DC390_H -#define DC390_H - -#include - -#define DC390_BANNER "Tekram DC390/AM53C974" -#define DC390_VERSION "2.1d 2004-05-27" - -/* We don't have eh_abort_handler, eh_device_reset_handler, - * eh_bus_reset_handler, eh_host_reset_handler yet! - * So long: Use old exception handling :-( */ -#define OLD_EH - -#if LINUX_VERSION_CODE < KERNEL_VERSION (2,1,70) || defined (OLD_EH) -# define NEW_EH -#else -# define NEW_EH use_new_eh_code: 1, -# define USE_NEW_EH -#endif -#endif /* DC390_H */ diff --git a/drivers/usb/host/ohci-omap.h b/drivers/usb/host/ohci-omap.h deleted file mode 100644 index 58ae2b400..000000000 --- a/drivers/usb/host/ohci-omap.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * linux/drivers/usb/host/ohci-omap.h - * - * OMAP OHCI USB controller specific defines - */ - -/* OMAP USB OHCI common defines */ -#define OMAP_OHCI_NAME "omap-ohci" -#define OMAP_OHCI_BASE 0xfffba000 -#define OMAP_OHCI_SIZE 4096 - -#define HMC_CLEAR (0x3f << 1) -#define APLL_NDPLL_SWITCH 0x0001 -#define DPLL_PLL_ENABLE 0x0010 -#define DPLL_LOCK 0x0001 -#define SOFT_REQ_REG_REQ 0x0001 -#define USB_MCLK_EN 0x0010 -#define USB_HOST_HHC_UHOST_EN 0x00000200 -#define SOFT_USB_OTG_REQ (1 << 8) -#define SOFT_USB_REQ (1 << 3) -#define STATUS_REQ_REG 0xfffe0840 -#define USB_HOST_DPLL_REQ (1 << 8) -#define SOFT_DPLL_REQ (1 << 0) - -/* OMAP-1510 USB OHCI defines */ -#define OMAP1510_LB_MEMSIZE 32 /* Should be same as SDRAM size */ -#define OMAP1510_LB_CLOCK_DIV 0xfffec10c -#define OMAP1510_LB_MMU_CTL 0xfffec208 -#define OMAP1510_LB_MMU_LCK 0xfffec224 -#define OMAP1510_LB_MMU_LD_TLB 0xfffec228 -#define OMAP1510_LB_MMU_CAM_H 0xfffec22c -#define OMAP1510_LB_MMU_CAM_L 0xfffec230 -#define OMAP1510_LB_MMU_RAM_H 0xfffec234 -#define OMAP1510_LB_MMU_RAM_L 0xfffec238 - -/* OMAP-1610 USB OHCI defines */ -#define USB_TRANSCEIVER_CTRL 0xfffe1064 -#define OTG_REV 0xfffb0400 - -#define OTG_SYSCON_1 0xfffb0404 -#define OTG_IDLE_EN (1 << 15) -#define DEV_IDLE_EN (1 << 13) - -#define OTG_SYSCON_2 0xfffb0408 -#define OTG_CTRL 0xfffb040c -#define OTG_IRQ_EN 0xfffb0410 -#define OTG_IRQ_SRC 0xfffb0414 - -#define OTG_EN (1 << 31) -#define USBX_SYNCHRO (1 << 30) -#define SRP_VBUS (1 << 12) -#define OTG_PADEN (1 << 10) -#define HMC_PADEN (1 << 9) -#define UHOST_EN (1 << 8) - -/* Hardware specific defines */ -#define OMAP1510_FPGA_HOST_CTRL 0xe800020c diff --git a/drivers/usb/media/pwc-ctrl.c b/drivers/usb/media/pwc-ctrl.c deleted file mode 100644 index d8a7b90d3..000000000 --- a/drivers/usb/media/pwc-ctrl.c +++ /dev/null @@ -1,1644 +0,0 @@ -/* Driver for Philips webcam - Functions that send various control messages to the webcam, including - video modes. - (C) 1999-2003 Nemosoft Unv. (webcam@smcc.demon.nl) - - 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 -*/ - -/* - Changes - 2001/08/03 Alvarado Added methods for changing white balance and - red/green gains - */ - -/* Control functions for the cam; brightness, contrast, video mode, etc. */ - -#ifdef __KERNEL__ -#include -#endif -#include -#include - -#include "pwc.h" -#include "pwc-ioctl.h" -#include "pwc-uncompress.h" - -/* Request types: video */ -#define SET_LUM_CTL 0x01 -#define GET_LUM_CTL 0x02 -#define SET_CHROM_CTL 0x03 -#define GET_CHROM_CTL 0x04 -#define SET_STATUS_CTL 0x05 -#define GET_STATUS_CTL 0x06 -#define SET_EP_STREAM_CTL 0x07 -#define GET_EP_STREAM_CTL 0x08 -#define SET_MPT_CTL 0x0D -#define GET_MPT_CTL 0x0E - -/* Selectors for the Luminance controls [GS]ET_LUM_CTL */ -#define AGC_MODE_FORMATTER 0x2000 -#define PRESET_AGC_FORMATTER 0x2100 -#define SHUTTER_MODE_FORMATTER 0x2200 -#define PRESET_SHUTTER_FORMATTER 0x2300 -#define PRESET_CONTOUR_FORMATTER 0x2400 -#define AUTO_CONTOUR_FORMATTER 0x2500 -#define BACK_LIGHT_COMPENSATION_FORMATTER 0x2600 -#define CONTRAST_FORMATTER 0x2700 -#define DYNAMIC_NOISE_CONTROL_FORMATTER 0x2800 -#define FLICKERLESS_MODE_FORMATTER 0x2900 -#define AE_CONTROL_SPEED 0x2A00 -#define BRIGHTNESS_FORMATTER 0x2B00 -#define GAMMA_FORMATTER 0x2C00 - -/* Selectors for the Chrominance controls [GS]ET_CHROM_CTL */ -#define WB_MODE_FORMATTER 0x1000 -#define AWB_CONTROL_SPEED_FORMATTER 0x1100 -#define AWB_CONTROL_DELAY_FORMATTER 0x1200 -#define PRESET_MANUAL_RED_GAIN_FORMATTER 0x1300 -#define PRESET_MANUAL_BLUE_GAIN_FORMATTER 0x1400 -#define COLOUR_MODE_FORMATTER 0x1500 -#define SATURATION_MODE_FORMATTER1 0x1600 -#define SATURATION_MODE_FORMATTER2 0x1700 - -/* Selectors for the Status controls [GS]ET_STATUS_CTL */ -#define SAVE_USER_DEFAULTS_FORMATTER 0x0200 -#define RESTORE_USER_DEFAULTS_FORMATTER 0x0300 -#define RESTORE_FACTORY_DEFAULTS_FORMATTER 0x0400 -#define READ_AGC_FORMATTER 0x0500 -#define READ_SHUTTER_FORMATTER 0x0600 -#define READ_RED_GAIN_FORMATTER 0x0700 -#define READ_BLUE_GAIN_FORMATTER 0x0800 -#define SENSOR_TYPE_FORMATTER1 0x0C00 -#define READ_RAW_Y_MEAN_FORMATTER 0x3100 -#define SET_POWER_SAVE_MODE_FORMATTER 0x3200 -#define MIRROR_IMAGE_FORMATTER 0x3300 -#define LED_FORMATTER 0x3400 -#define SENSOR_TYPE_FORMATTER2 0x3700 - -/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */ -#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100 - -/* Formatters for the motorized pan & tilt [GS]ET_MPT_CTL */ -#define PT_RELATIVE_CONTROL_FORMATTER 0x01 -#define PT_RESET_CONTROL_FORMATTER 0x02 -#define PT_STATUS_FORMATTER 0x03 - -static char *size2name[PSZ_MAX] = -{ - "subQCIF", - "QSIF", - "QCIF", - "SIF", - "CIF", - "VGA", -}; - -/********/ - -/* Entries for the Nala (645/646) camera; the Nala doesn't have compression - preferences, so you either get compressed or non-compressed streams. - - An alternate value of 0 means this mode is not available at all. - */ - -struct Nala_table_entry { - char alternate; /* USB alternate setting */ - int compressed; /* Compressed yes/no */ - - unsigned char mode[3]; /* precomputed mode table */ -}; - -static struct Nala_table_entry Nala_table[PSZ_MAX][8] = -{ -#include "pwc_nala.h" -}; - -/* This tables contains entries for the 675/680/690 (Timon) camera, with - 4 different qualities (no compression, low, medium, high). - It lists the bandwidth requirements for said mode by its alternate interface - number. An alternate of 0 means that the mode is unavailable. - - There are 6 * 4 * 4 entries: - 6 different resolutions subqcif, qsif, qcif, sif, cif, vga - 6 framerates: 5, 10, 15, 20, 25, 30 - 4 compression modi: none, low, medium, high - - When an uncompressed mode is not available, the next available compressed mode - will be chosen (unless the decompressor is absent). Sometimes there are only - 1 or 2 compressed modes available; in that case entries are duplicated. -*/ -struct Timon_table_entry -{ - char alternate; /* USB alternate interface */ - unsigned short packetsize; /* Normal packet size */ - unsigned short bandlength; /* Bandlength when decompressing */ - unsigned char mode[13]; /* precomputed mode settings for cam */ -}; - -static struct Timon_table_entry Timon_table[PSZ_MAX][6][4] = -{ -#include "pwc_timon.h" -}; - -/* Entries for the Kiara (730/740/750) camera */ - -struct Kiara_table_entry -{ - char alternate; /* USB alternate interface */ - unsigned short packetsize; /* Normal packet size */ - unsigned short bandlength; /* Bandlength when decompressing */ - unsigned char mode[12]; /* precomputed mode settings for cam */ -}; - -static struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] = -{ -#include "pwc_kiara.h" -}; - - -/****************************************************************************/ - - -#define SendControlMsg(request, value, buflen) \ - usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), \ - request, \ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \ - value, \ - pdev->vcinterface, \ - &buf, buflen, HZ / 2) - -#define RecvControlMsg(request, value, buflen) \ - usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), \ - request, \ - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \ - value, \ - pdev->vcinterface, \ - &buf, buflen, HZ / 2) - - -#if PWC_DEBUG -void pwc_hexdump(void *p, int len) -{ - int i; - unsigned char *s; - char buf[100], *d; - - s = (unsigned char *)p; - d = buf; - *d = '\0'; - Debug("Doing hexdump @ %p, %d bytes.\n", p, len); - for (i = 0; i < len; i++) { - d += sprintf(d, "%02X ", *s++); - if ((i & 0xF) == 0xF) { - Debug("%s\n", buf); - d = buf; - *d = '\0'; - } - } - if ((i & 0xF) != 0) - Debug("%s\n", buf); -} -#endif - -static inline int send_video_command(struct usb_device *udev, int index, void *buf, int buflen) -{ - return usb_control_msg(udev, - usb_sndctrlpipe(udev, 0), - SET_EP_STREAM_CTL, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - VIDEO_OUTPUT_CONTROL_FORMATTER, - index, - buf, buflen, HZ); -} - - - -static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) -{ - unsigned char buf[3]; - int ret, fps; - struct Nala_table_entry *pEntry; - int frames2frames[31] = - { /* closest match of framerate */ - 0, 0, 0, 0, 4, /* 0-4 */ - 5, 5, 7, 7, 10, /* 5-9 */ - 10, 10, 12, 12, 15, /* 10-14 */ - 15, 15, 15, 20, 20, /* 15-19 */ - 20, 20, 20, 24, 24, /* 20-24 */ - 24, 24, 24, 24, 24, /* 25-29 */ - 24 /* 30 */ - }; - int frames2table[31] = - { 0, 0, 0, 0, 0, /* 0-4 */ - 1, 1, 1, 2, 2, /* 5-9 */ - 3, 3, 4, 4, 4, /* 10-14 */ - 5, 5, 5, 5, 5, /* 15-19 */ - 6, 6, 6, 6, 7, /* 20-24 */ - 7, 7, 7, 7, 7, /* 25-29 */ - 7 /* 30 */ - }; - - if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25) - return -EINVAL; - frames = frames2frames[frames]; - fps = frames2table[frames]; - pEntry = &Nala_table[size][fps]; - if (pEntry->alternate == 0) - return -EINVAL; - - if (pEntry->compressed && pdev->decompressor == NULL) - return -ENOENT; /* Not supported. */ - - memcpy(buf, pEntry->mode, 3); - ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3); - if (ret < 0) { - Debug("Failed to send video command... %d\n", ret); - return ret; - } - if (pEntry->compressed && pdev->decompressor != 0 && pdev->vpalette != VIDEO_PALETTE_RAW) - pdev->decompressor->init(pdev->type, pdev->release, buf, pdev->decompress_data); - - pdev->cmd_len = 3; - memcpy(pdev->cmd_buf, buf, 3); - - /* Set various parameters */ - pdev->vframes = frames; - pdev->vsize = size; - pdev->valternate = pEntry->alternate; - pdev->image = pwc_image_sizes[size]; - pdev->frame_size = (pdev->image.x * pdev->image.y * 3) / 2; - if (pEntry->compressed) { - if (pdev->release < 5) { /* 4 fold compression */ - pdev->vbandlength = 528; - pdev->frame_size /= 4; - } - else { - pdev->vbandlength = 704; - pdev->frame_size /= 3; - } - } - else - pdev->vbandlength = 0; - return 0; -} - - -static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) -{ - unsigned char buf[13]; - struct Timon_table_entry *pChoose; - int ret, fps; - - if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3) - return -EINVAL; - if (size == PSZ_VGA && frames > 15) - return -EINVAL; - fps = (frames / 5) - 1; - - /* Find a supported framerate with progressively higher compression ratios - if the preferred ratio is not available. - */ - pChoose = NULL; - if (pdev->decompressor == NULL) { -#if PWC_DEBUG - Debug("Trying to find uncompressed mode.\n"); -#endif - pChoose = &Timon_table[size][fps][0]; - } - else { - while (compression <= 3) { - pChoose = &Timon_table[size][fps][compression]; - if (pChoose->alternate != 0) - break; - compression++; - } - } - if (pChoose == NULL || pChoose->alternate == 0) - return -ENOENT; /* Not supported. */ - - memcpy(buf, pChoose->mode, 13); - if (snapshot) - buf[0] |= 0x80; - ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 13); - if (ret < 0) - return ret; - - if (pChoose->bandlength > 0 && pdev->decompressor != 0 && pdev->vpalette != VIDEO_PALETTE_RAW) - pdev->decompressor->init(pdev->type, pdev->release, buf, pdev->decompress_data); - - pdev->cmd_len = 13; - memcpy(pdev->cmd_buf, buf, 13); - - /* Set various parameters */ - pdev->vframes = frames; - pdev->vsize = size; - pdev->vsnapshot = snapshot; - pdev->valternate = pChoose->alternate; - pdev->image = pwc_image_sizes[size]; - pdev->vbandlength = pChoose->bandlength; - if (pChoose->bandlength > 0) - pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4; - else - pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8; - return 0; -} - - -static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) -{ - struct Kiara_table_entry *pChoose = NULL; - int fps, ret; - unsigned char buf[12]; - struct Kiara_table_entry RawEntry = {6, 773, 1272, {0xAD, 0xF4, 0x10, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}}; - - if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3) - return -EINVAL; - if (size == PSZ_VGA && frames > 15) - return -EINVAL; - fps = (frames / 5) - 1; - - /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ - if (size == PSZ_VGA && frames == 5 && snapshot) - { - /* Only available in case the raw palette is selected or - we have the decompressor available. This mode is - only available in compressed form - */ - if (pdev->vpalette == VIDEO_PALETTE_RAW || pdev->decompressor != NULL) - { - Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette); - pChoose = &RawEntry; - } - else - { - Info("VGA/5 BAYER mode _must_ have a decompressor available, or use RAW palette.\n"); - } - } - else - { - /* Find a supported framerate with progressively higher compression ratios - if the preferred ratio is not available. - Skip this step when using RAW modes. - */ - if (pdev->decompressor == NULL && pdev->vpalette != VIDEO_PALETTE_RAW) { -#if PWC_DEBUG - Debug("Trying to find uncompressed mode.\n"); -#endif - pChoose = &Kiara_table[size][fps][0]; - } - else { - while (compression <= 3) { - pChoose = &Kiara_table[size][fps][compression]; - if (pChoose->alternate != 0) - break; - compression++; - } - } - } - if (pChoose == NULL || pChoose->alternate == 0) - return -ENOENT; /* Not supported. */ - - /* usb_control_msg won't take staticly allocated arrays as argument?? */ - memcpy(buf, pChoose->mode, 12); - if (snapshot) - buf[0] |= 0x80; - - /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */ - ret = send_video_command(pdev->udev, 4 /* pdev->vendpoint */, buf, 12); - if (ret < 0) - return ret; - - if (pChoose->bandlength > 0 && pdev->decompressor != 0 && pdev->vpalette != VIDEO_PALETTE_RAW) - pdev->decompressor->init(pdev->type, pdev->release, buf, pdev->decompress_data); - - pdev->cmd_len = 12; - memcpy(pdev->cmd_buf, buf, 12); - /* All set and go */ - pdev->vframes = frames; - pdev->vsize = size; - pdev->vsnapshot = snapshot; - pdev->valternate = pChoose->alternate; - pdev->image = pwc_image_sizes[size]; - pdev->vbandlength = pChoose->bandlength; - if (pdev->vbandlength > 0) - pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4; - else - pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8; - return 0; -} - - - -/** - @pdev: device structure - @width: viewport width - @height: viewport height - @frame: framerate, in fps - @compression: preferred compression ratio - @snapshot: snapshot mode or streaming - */ -int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot) -{ - int ret, size; - - Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); - size = pwc_decode_size(pdev, width, height); - if (size < 0) { - Debug("Could not find suitable size.\n"); - return -ERANGE; - } - Debug("decode_size = %d.\n", size); - - ret = -EINVAL; - switch(pdev->type) { - case 645: - case 646: - ret = set_video_mode_Nala(pdev, size, frames); - break; - - case 675: - case 680: - case 690: - ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot); - break; - - case 720: - case 730: - case 740: - case 750: - ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot); - break; - } - if (ret < 0) { - if (ret == -ENOENT) - Info("Video mode %s@%d fps is only supported with the decompressor module (pwcx).\n", size2name[size], frames); - else { - Err("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); - } - return ret; - } - pdev->view.x = width; - pdev->view.y = height; - pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size; - pwc_set_image_buffer_size(pdev); - Trace(TRACE_SIZE, "Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y); - return 0; -} - - -void pwc_set_image_buffer_size(struct pwc_device *pdev) -{ - int i, factor = 0, filler = 0; - - /* for PALETTE_YUV420P */ - switch(pdev->vpalette) - { - case VIDEO_PALETTE_YUV420P: - factor = 6; - filler = 128; - break; - case VIDEO_PALETTE_RAW: - factor = 6; /* can be uncompressed YUV420P */ - filler = 0; - break; - } - - /* Set sizes in bytes */ - pdev->image.size = pdev->image.x * pdev->image.y * factor / 4; - pdev->view.size = pdev->view.x * pdev->view.y * factor / 4; - - /* Align offset, or you'll get some very weird results in - YUV420 mode... x must be multiple of 4 (to get the Y's in - place), and y even (or you'll mixup U & V). This is less of a - problem for YUV420P. - */ - pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC; - pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE; - - /* Fill buffers with gray or black */ - for (i = 0; i < MAX_IMAGES; i++) { - if (pdev->image_ptr[i] != NULL) - memset(pdev->image_ptr[i], filler, pdev->view.size); - } -} - - - -/* BRIGHTNESS */ - -int pwc_get_brightness(struct pwc_device *pdev) -{ - char buf; - int ret; - - ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); - if (ret < 0) - return ret; - return buf << 9; -} - -int pwc_set_brightness(struct pwc_device *pdev, int value) -{ - char buf; - - if (value < 0) - value = 0; - if (value > 0xffff) - value = 0xffff; - buf = (value >> 9) & 0x7f; - return SendControlMsg(SET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); -} - -/* CONTRAST */ - -int pwc_get_contrast(struct pwc_device *pdev) -{ - char buf; - int ret; - - ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1); - if (ret < 0) - return ret; - return buf << 10; -} - -int pwc_set_contrast(struct pwc_device *pdev, int value) -{ - char buf; - - if (value < 0) - value = 0; - if (value > 0xffff) - value = 0xffff; - buf = (value >> 10) & 0x3f; - return SendControlMsg(SET_LUM_CTL, CONTRAST_FORMATTER, 1); -} - -/* GAMMA */ - -int pwc_get_gamma(struct pwc_device *pdev) -{ - char buf; - int ret; - - ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1); - if (ret < 0) - return ret; - return buf << 11; -} - -int pwc_set_gamma(struct pwc_device *pdev, int value) -{ - char buf; - - if (value < 0) - value = 0; - if (value > 0xffff) - value = 0xffff; - buf = (value >> 11) & 0x1f; - return SendControlMsg(SET_LUM_CTL, GAMMA_FORMATTER, 1); -} - - -/* SATURATION */ - -int pwc_get_saturation(struct pwc_device *pdev) -{ - char buf; - int ret; - - if (pdev->type < 675) - return -1; - ret = RecvControlMsg(GET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); - if (ret < 0) - return ret; - return 32768 + buf * 327; -} - -int pwc_set_saturation(struct pwc_device *pdev, int value) -{ - char buf; - - if (pdev->type < 675) - return -EINVAL; - if (value < 0) - value = 0; - if (value > 0xffff) - value = 0xffff; - /* saturation ranges from -100 to +100 */ - buf = (value - 32768) / 327; - return SendControlMsg(SET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); -} - -/* AGC */ - -static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value) -{ - char buf; - int ret; - - if (mode) - buf = 0x0; /* auto */ - else - buf = 0xff; /* fixed */ - - ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1); - - if (!mode && ret >= 0) { - if (value < 0) - value = 0; - if (value > 0xffff) - value = 0xffff; - buf = (value >> 10) & 0x3F; - ret = SendControlMsg(SET_LUM_CTL, PRESET_AGC_FORMATTER, 1); - } - if (ret < 0) - return ret; - return 0; -} - -static inline int pwc_get_agc(struct pwc_device *pdev, int *value) -{ - unsigned char buf; - int ret; - - ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1); - if (ret < 0) - return ret; - - if (buf != 0) { /* fixed */ - ret = RecvControlMsg(GET_LUM_CTL, PRESET_AGC_FORMATTER, 1); - if (ret < 0) - return ret; - if (buf > 0x3F) - buf = 0x3F; - *value = (buf << 10); - } - else { /* auto */ - ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1); - if (ret < 0) - return ret; - /* Gah... this value ranges from 0x00 ... 0x9F */ - if (buf > 0x9F) - buf = 0x9F; - *value = -(48 + buf * 409); - } - - return 0; -} - -static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) -{ - char buf[2]; - int speed, ret; - - - if (mode) - buf[0] = 0x0; /* auto */ - else - buf[0] = 0xff; /* fixed */ - - ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1); - - if (!mode && ret >= 0) { - if (value < 0) - value = 0; - if (value > 0xffff) - value = 0xffff; - switch(pdev->type) { - case 675: - case 680: - case 690: - /* speed ranges from 0x0 to 0x290 (656) */ - speed = (value / 100); - buf[1] = speed >> 8; - buf[0] = speed & 0xff; - break; - case 720: - case 730: - case 740: - case 750: - /* speed seems to range from 0x0 to 0xff */ - buf[1] = 0; - buf[0] = value >> 8; - break; - } - - ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2); - } - return ret; -} - - -/* POWER */ - -int pwc_camera_power(struct pwc_device *pdev, int power) -{ - char buf; - - if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6)) - return 0; /* Not supported by Nala or Timon < release 6 */ - - if (power) - buf = 0x00; /* active */ - else - buf = 0xFF; /* power save */ - return SendControlMsg(SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 1); -} - - - -/* private calls */ - -static inline int pwc_restore_user(struct pwc_device *pdev) -{ - char buf; /* dummy */ - return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0); -} - -static inline int pwc_save_user(struct pwc_device *pdev) -{ - char buf; /* dummy */ - return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0); -} - -static inline int pwc_restore_factory(struct pwc_device *pdev) -{ - char buf; /* dummy */ - return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0); -} - - /* ************************************************* */ - /* Patch by Alvarado: (not in the original version */ - - /* - * the camera recognizes modes from 0 to 4: - * - * 00: indoor (incandescant lighting) - * 01: outdoor (sunlight) - * 02: fluorescent lighting - * 03: manual - * 04: auto - */ -static inline int pwc_set_awb(struct pwc_device *pdev, int mode) -{ - char buf; - int ret; - - if (mode < 0) - mode = 0; - - if (mode > 4) - mode = 4; - - buf = mode & 0x07; /* just the lowest three bits */ - - ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1); - - if (ret < 0) - return ret; - return 0; -} - -static inline int pwc_get_awb(struct pwc_device *pdev) -{ - unsigned char buf; - int ret; - - ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1); - - if (ret < 0) - return ret; - return buf; -} - -static inline int pwc_set_red_gain(struct pwc_device *pdev, int value) -{ - unsigned char buf; - - if (value < 0) - value = 0; - if (value > 0xffff) - value = 0xffff; - /* only the msb is considered */ - buf = value >> 8; - return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); -} - -static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value) -{ - unsigned char buf; - int ret; - - ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); - if (ret < 0) - return ret; - *value = buf << 8; - return 0; -} - - -static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value) -{ - unsigned char buf; - - if (value < 0) - value = 0; - if (value > 0xffff) - value = 0xffff; - /* only the msb is considered */ - buf = value >> 8; - return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); -} - -static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value) -{ - unsigned char buf; - int ret; - - ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); - if (ret < 0) - return ret; - *value = buf << 8; - return 0; -} - - -/* The following two functions are different, since they only read the - internal red/blue gains, which may be different from the manual - gains set or read above. - */ -static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value) -{ - unsigned char buf; - int ret; - - ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1); - if (ret < 0) - return ret; - *value = buf << 8; - return 0; -} - -static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value) -{ - unsigned char buf; - int ret; - - ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1); - if (ret < 0) - return ret; - *value = buf << 8; - return 0; -} - - -static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed) -{ - unsigned char buf; - - /* useful range is 0x01..0x20 */ - buf = speed / 0x7f0; - return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); -} - -static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value) -{ - unsigned char buf; - int ret; - - ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); - if (ret < 0) - return ret; - *value = buf * 0x7f0; - return 0; -} - - -static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay) -{ - unsigned char buf; - - /* useful range is 0x01..0x3F */ - buf = (delay >> 10); - return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); -} - -static inline int pwc_get_wb_delay(struct pwc_device *pdev, int *value) -{ - unsigned char buf; - int ret; - - ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); - if (ret < 0) - return ret; - *value = buf << 10; - return 0; -} - - -int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) -{ - unsigned char buf[2]; - - if (pdev->type < 730) - return 0; - on_value /= 100; - off_value /= 100; - if (on_value < 0) - on_value = 0; - if (on_value > 0xff) - on_value = 0xff; - if (off_value < 0) - off_value = 0; - if (off_value > 0xff) - off_value = 0xff; - - buf[0] = on_value; - buf[1] = off_value; - - return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2); -} - -int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value) -{ - unsigned char buf[2]; - int ret; - - if (pdev->type < 730) { - *on_value = -1; - *off_value = -1; - return 0; - } - - ret = RecvControlMsg(GET_STATUS_CTL, LED_FORMATTER, 2); - if (ret < 0) - return ret; - *on_value = buf[0] * 100; - *off_value = buf[1] * 100; - return 0; -} - -static inline int pwc_set_contour(struct pwc_device *pdev, int contour) -{ - unsigned char buf; - int ret; - - if (contour < 0) - buf = 0xff; /* auto contour on */ - else - buf = 0x0; /* auto contour off */ - ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1); - if (ret < 0) - return ret; - - if (contour < 0) - return 0; - if (contour > 0xffff) - contour = 0xffff; - - buf = (contour >> 10); /* contour preset is [0..3f] */ - ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1); - if (ret < 0) - return ret; - return 0; -} - -static inline int pwc_get_contour(struct pwc_device *pdev, int *contour) -{ - unsigned char buf; - int ret; - - ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1); - if (ret < 0) - return ret; - - if (buf == 0) { - /* auto mode off, query current preset value */ - ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1); - if (ret < 0) - return ret; - *contour = buf << 10; - } - else - *contour = -1; - return 0; -} - - -static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight) -{ - unsigned char buf; - - if (backlight) - buf = 0xff; - else - buf = 0x0; - return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); -} - -static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight) -{ - int ret; - unsigned char buf; - - ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); - if (ret < 0) - return ret; - *backlight = buf; - return 0; -} - - -static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker) -{ - unsigned char buf; - - if (flicker) - buf = 0xff; - else - buf = 0x0; - return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); -} - -static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker) -{ - int ret; - unsigned char buf; - - ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); - if (ret < 0) - return ret; - *flicker = buf; - return 0; -} - - -static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise) -{ - unsigned char buf; - - if (noise < 0) - noise = 0; - if (noise > 3) - noise = 3; - buf = noise; - return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); -} - -static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) -{ - int ret; - unsigned char buf; - - ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); - if (ret < 0) - return ret; - *noise = buf; - return 0; -} - -int pwc_mpt_reset(struct pwc_device *pdev, int flags) -{ - unsigned char buf; - - buf = flags & 0x03; // only lower two bits are currently used - return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1); -} - -static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) -{ - unsigned char buf[4]; - - /* set new relative angle; angles are expressed in degrees * 100, - but cam as .5 degree resolution, hence devide by 200. Also - the angle must be multiplied by 64 before it's send to - the cam (??) - */ - pan = 64 * pan / 100; - tilt = -64 * tilt / 100; /* positive tilt is down, which is not what the user would expect */ - buf[0] = pan & 0xFF; - buf[1] = (pan >> 8) & 0xFF; - buf[2] = tilt & 0xFF; - buf[3] = (tilt >> 8) & 0xFF; - return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4); -} - -static inline int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status) -{ - int ret; - unsigned char buf[5]; - - ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5); - if (ret < 0) - return ret; - status->status = buf[0] & 0x7; // 3 bits are used for reporting - status->time_pan = (buf[1] << 8) + buf[2]; - status->time_tilt = (buf[3] << 8) + buf[4]; - return 0; -} - - -int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) -{ - unsigned char buf; - int ret = -1, request; - - if (pdev->type < 675) - request = SENSOR_TYPE_FORMATTER1; - else if (pdev->type < 730) - return -1; /* The Vesta series doesn't have this call */ - else - request = SENSOR_TYPE_FORMATTER2; - - ret = RecvControlMsg(GET_STATUS_CTL, request, 1); - if (ret < 0) - return ret; - if (pdev->type < 675) - *sensor = buf | 0x100; - else - *sensor = buf; - return 0; -} - - - /* End of Add-Ons */ - /* ************************************************* */ - -/* Linux 2.5.something and 2.6 pass direct pointers to arguments of - ioctl() calls. With 2.4, you have to do tedious copy_from_user() - and copy_to_user() calls. With these macros we circumvent this, - and let me maintain only one source file. The functionality is - exactly the same otherwise. - */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - -/* define local variable for arg */ -#define ARG_DEF(ARG_type, ARG_name)\ - ARG_type *ARG_name = arg; -/* copy arg to local variable */ -#define ARG_IN(ARG_name) /* nothing */ -/* argument itself (referenced) */ -#define ARGR(ARG_name) (*ARG_name) -/* argument address */ -#define ARGA(ARG_name) ARG_name -/* copy local variable to arg */ -#define ARG_OUT(ARG_name) /* nothing */ - -#else - -#define ARG_DEF(ARG_type, ARG_name)\ - ARG_type ARG_name; -#define ARG_IN(ARG_name)\ - if (copy_from_user(&ARG_name, arg, sizeof(ARG_name))) {\ - ret = -EFAULT;\ - break;\ - } -#define ARGR(ARG_name) ARG_name -#define ARGA(ARG_name) &ARG_name -#define ARG_OUT(ARG_name)\ - if (copy_to_user(arg, &ARG_name, sizeof(ARG_name))) {\ - ret = -EFAULT;\ - break;\ - } - -#endif - -int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) -{ - int ret = 0; - - switch(cmd) { - case VIDIOCPWCRUSER: - { - if (pwc_restore_user(pdev)) - ret = -EINVAL; - break; - } - - case VIDIOCPWCSUSER: - { - if (pwc_save_user(pdev)) - ret = -EINVAL; - break; - } - - case VIDIOCPWCFACTORY: - { - if (pwc_restore_factory(pdev)) - ret = -EINVAL; - break; - } - - case VIDIOCPWCSCQUAL: - { - ARG_DEF(int, qual) - - ARG_IN(qual) - if (ARGR(qual) < 0 || ARGR(qual) > 3) - ret = -EINVAL; - else - ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); - if (ret >= 0) - pdev->vcompression = ARGR(qual); - break; - } - - case VIDIOCPWCGCQUAL: - { - ARG_DEF(int, qual) - - ARGR(qual) = pdev->vcompression; - ARG_OUT(qual) - break; - } - - case VIDIOCPWCPROBE: - { - ARG_DEF(struct pwc_probe, probe) - - strcpy(ARGR(probe).name, pdev->vdev->name); - ARGR(probe).type = pdev->type; - ARG_OUT(probe) - break; - } - - case VIDIOCPWCGSERIAL: - { - ARG_DEF(struct pwc_serial, serial) - - strcpy(ARGR(serial).serial, pdev->serial); - ARG_OUT(serial) - break; - } - - case VIDIOCPWCSAGC: - { - ARG_DEF(int, agc) - - ARG_IN(agc) - if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc))) - ret = -EINVAL; - break; - } - - case VIDIOCPWCGAGC: - { - ARG_DEF(int, agc) - - if (pwc_get_agc(pdev, ARGA(agc))) - ret = -EINVAL; - ARG_OUT(agc) - break; - } - - case VIDIOCPWCSSHUTTER: - { - ARG_DEF(int, shutter_speed) - - ARG_IN(shutter_speed) - ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed)); - break; - } - - case VIDIOCPWCSAWB: - { - ARG_DEF(struct pwc_whitebalance, wb) - - ARG_IN(wb) - ret = pwc_set_awb(pdev, ARGR(wb).mode); - if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) { - pwc_set_red_gain(pdev, ARGR(wb).manual_red); - pwc_set_blue_gain(pdev, ARGR(wb).manual_blue); - } - break; - } - - case VIDIOCPWCGAWB: - { - ARG_DEF(struct pwc_whitebalance, wb) - - memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance)); - ARGR(wb).mode = pwc_get_awb(pdev); - if (ARGR(wb).mode < 0) - ret = -EINVAL; - else { - if (ARGR(wb).mode == PWC_WB_MANUAL) { - ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red); - if (ret < 0) - break; - ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue); - if (ret < 0) - break; - } - if (ARGR(wb).mode == PWC_WB_AUTO) { - ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red); - if (ret < 0) - break; - ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue); - if (ret < 0) - break; - } - } - ARG_OUT(wb) - break; - } - - case VIDIOCPWCSAWBSPEED: - { - ARG_DEF(struct pwc_wb_speed, wbs) - - if (ARGR(wbs).control_speed > 0) { - ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed); - } - if (ARGR(wbs).control_delay > 0) { - ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay); - } - break; - } - - case VIDIOCPWCGAWBSPEED: - { - ARG_DEF(struct pwc_wb_speed, wbs) - - ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed); - if (ret < 0) - break; - ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay); - if (ret < 0) - break; - ARG_OUT(wbs) - break; - } - - case VIDIOCPWCSLED: - { - ARG_DEF(struct pwc_leds, leds) - - ARG_IN(leds) - ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off); - break; - } - - - case VIDIOCPWCGLED: - { - ARG_DEF(struct pwc_leds, leds) - - ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off); - ARG_OUT(leds) - break; - } - - case VIDIOCPWCSCONTOUR: - { - ARG_DEF(int, contour) - - ARG_IN(contour) - ret = pwc_set_contour(pdev, ARGR(contour)); - break; - } - - case VIDIOCPWCGCONTOUR: - { - ARG_DEF(int, contour) - - ret = pwc_get_contour(pdev, ARGA(contour)); - ARG_OUT(contour) - break; - } - - case VIDIOCPWCSBACKLIGHT: - { - ARG_DEF(int, backlight) - - ARG_IN(backlight) - ret = pwc_set_backlight(pdev, ARGR(backlight)); - break; - } - - case VIDIOCPWCGBACKLIGHT: - { - ARG_DEF(int, backlight) - - ret = pwc_get_backlight(pdev, ARGA(backlight)); - ARG_OUT(backlight) - break; - } - - case VIDIOCPWCSFLICKER: - { - ARG_DEF(int, flicker) - - ARG_IN(flicker) - ret = pwc_set_flicker(pdev, ARGR(flicker)); - break; - } - - case VIDIOCPWCGFLICKER: - { - ARG_DEF(int, flicker) - - ret = pwc_get_flicker(pdev, ARGA(flicker)); - ARG_OUT(flicker) - break; - } - - case VIDIOCPWCSDYNNOISE: - { - ARG_DEF(int, dynnoise) - - ARG_IN(dynnoise) - ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise)); - break; - } - - case VIDIOCPWCGDYNNOISE: - { - ARG_DEF(int, dynnoise) - - ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise)); - ARG_OUT(dynnoise); - break; - } - - case VIDIOCPWCGREALSIZE: - { - ARG_DEF(struct pwc_imagesize, size) - - ARGR(size).width = pdev->image.x; - ARGR(size).height = pdev->image.y; - ARG_OUT(size) - break; - } - - case VIDIOCPWCMPTRESET: - { - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - ARG_DEF(int, flags) - - ARG_IN(flags) - ret = pwc_mpt_reset(pdev, ARGR(flags)); - if (ret >= 0) - { - pdev->pan_angle = 0; - pdev->tilt_angle = 0; - } - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTGRANGE: - { - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - ARG_DEF(struct pwc_mpt_range, range) - - ARGR(range) = pdev->angle_range; - ARG_OUT(range) - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTSANGLE: - { - int new_pan, new_tilt; - - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - ARG_DEF(struct pwc_mpt_angles, angles) - - ARG_IN(angles) - /* The camera can only set relative angles, so - do some calculations when getting an absolute angle . - */ - if (ARGR(angles).absolute) - { - new_pan = ARGR(angles).pan; - new_tilt = ARGR(angles).tilt; - } - else - { - new_pan = pdev->pan_angle + ARGR(angles).pan; - new_tilt = pdev->tilt_angle + ARGR(angles).tilt; - } - /* check absolute ranges */ - if (new_pan < pdev->angle_range.pan_min || - new_pan > pdev->angle_range.pan_max || - new_tilt < pdev->angle_range.tilt_min || - new_tilt > pdev->angle_range.tilt_max) - { - ret = -ERANGE; - } - else - { - /* go to relative range, check again */ - new_pan -= pdev->pan_angle; - new_tilt -= pdev->tilt_angle; - /* angles are specified in degrees * 100, thus the limit = 36000 */ - if (new_pan < -36000 || new_pan > 36000 || new_tilt < -36000 || new_tilt > 36000) - ret = -ERANGE; - } - if (ret == 0) /* no errors so far */ - { - ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt); - if (ret >= 0) - { - pdev->pan_angle += new_pan; - pdev->tilt_angle += new_tilt; - } - if (ret == -EPIPE) /* stall -> out of range */ - ret = -ERANGE; - } - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTGANGLE: - { - - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - ARG_DEF(struct pwc_mpt_angles, angles) - - ARGR(angles).absolute = 1; - ARGR(angles).pan = pdev->pan_angle; - ARGR(angles).tilt = pdev->tilt_angle; - ARG_OUT(angles) - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTSTATUS: - { - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - ARG_DEF(struct pwc_mpt_status, status) - - ret = pwc_mpt_get_status(pdev, ARGA(status)); - ARG_OUT(status) - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCGVIDCMD: - { - ARG_DEF(struct pwc_video_command, cmd); - - ARGR(cmd).type = pdev->type; - ARGR(cmd).release = pdev->release; - ARGR(cmd).command_len = pdev->cmd_len; - memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len); - ARGR(cmd).bandlength = pdev->vbandlength; - ARGR(cmd).frame_size = pdev->frame_size; - ARG_OUT(cmd) - break; - } - - default: - ret = -ENOIOCTLCMD; - break; - } - - if (ret > 0) - return 0; - return ret; -} - - - diff --git a/drivers/usb/media/pwc-if.c b/drivers/usb/media/pwc-if.c deleted file mode 100644 index f3a70b2d0..000000000 --- a/drivers/usb/media/pwc-if.c +++ /dev/null @@ -1,2193 +0,0 @@ -/* Linux driver for Philips webcam - USB and Video4Linux interface part. - (C) 1999-2004 Nemosoft Unv. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -/* - This code forms the interface between the USB layers and the Philips - specific stuff. Some adanved stuff of the driver falls under an - NDA, signed between me and Philips B.V., Eindhoven, the Netherlands, and - is thus not distributed in source form. The binary pwcx.o module - contains the code that falls under the NDA. - - In case you're wondering: 'pwc' stands for "Philips WebCam", but - I really didn't want to type 'philips_web_cam' every time (I'm lazy as - any Linux kernel hacker, but I don't like uncomprehensible abbreviations - without explanation). - - Oh yes, convention: to disctinguish between all the various pointers to - device-structures, I use these names for the pointer variables: - udev: struct usb_device * - vdev: struct video_device * - pdev: struct pwc_devive * -*/ - -/* Contributors: - - Alvarado: adding whitebalance code - - Alistar Moire: QuickCam 3000 Pro device/product ID - - Tony Hoyle: Creative Labs Webcam 5 device/product ID - - Mark Burazin: solving hang in VIDIOCSYNC when camera gets unplugged - - Jk Fang: Sotec Afina Eye ID - - Xavier Roche: QuickCam Pro 4000 ID - - Jens Knudsen: QuickCam Zoom ID - - J. Debert: QuickCam for Notebooks ID -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pwc.h" -#include "pwc-ioctl.h" -#include "pwc-uncompress.h" - -/* Function prototypes and driver templates */ - -/* hotplug device table support */ -static struct usb_device_id pwc_device_table [] = { - { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */ - { USB_DEVICE(0x0471, 0x0303) }, - { USB_DEVICE(0x0471, 0x0304) }, - { USB_DEVICE(0x0471, 0x0307) }, - { USB_DEVICE(0x0471, 0x0308) }, - { USB_DEVICE(0x0471, 0x030C) }, - { USB_DEVICE(0x0471, 0x0310) }, - { USB_DEVICE(0x0471, 0x0311) }, - { USB_DEVICE(0x0471, 0x0312) }, - { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */ - { USB_DEVICE(0x069A, 0x0001) }, /* Askey */ - { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */ - { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */ - { USB_DEVICE(0x046D, 0x08B2) }, /* Logitech QuickCam Pro 4000 */ - { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */ - { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */ - { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */ - { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */ - { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */ - { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */ - { USB_DEVICE(0x055D, 0x9000) }, /* Samsung */ - { USB_DEVICE(0x055D, 0x9001) }, - { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */ - { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */ - { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */ - { USB_DEVICE(0x06BE, 0x8116) }, /* new Afina Eye */ - { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */ - { USB_DEVICE(0x0d81, 0x1900) }, - { } -}; -MODULE_DEVICE_TABLE(usb, pwc_device_table); - -static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id); -static void usb_pwc_disconnect(struct usb_interface *intf); - -static struct usb_driver pwc_driver = { - .owner = THIS_MODULE, - .name = "Philips webcam", /* name */ - .id_table = pwc_device_table, - .probe = usb_pwc_probe, /* probe() */ - .disconnect = usb_pwc_disconnect, /* disconnect() */ -}; - -#define MAX_DEV_HINTS 20 -#define MAX_ISOC_ERRORS 20 - -static int default_size = PSZ_QCIF; -static int default_fps = 10; -static int default_fbufs = 3; /* Default number of frame buffers */ -static int default_mbufs = 2; /* Default number of mmap() buffers */ - int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX; -static int power_save = 0; -static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */ - int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */ -static struct { - int type; - char serial_number[30]; - int device_node; - struct pwc_device *pdev; -} device_hint[MAX_DEV_HINTS]; - -/***/ - -static int pwc_video_open(struct inode *inode, struct file *file); -static int pwc_video_close(struct inode *inode, struct file *file); -static ssize_t pwc_video_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos); -static unsigned int pwc_video_poll(struct file *file, poll_table *wait); -static int pwc_video_ioctl(struct inode *inode, struct file *file, - unsigned int ioctlnr, unsigned long arg); -static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); - -static struct file_operations pwc_fops = { - .owner = THIS_MODULE, - .open = pwc_video_open, - .release = pwc_video_close, - .read = pwc_video_read, - .poll = pwc_video_poll, - .mmap = pwc_video_mmap, - .ioctl = pwc_video_ioctl, - .llseek = no_llseek, -}; -static struct video_device pwc_template = { - .owner = THIS_MODULE, - .name = "Philips Webcam", /* Filled in later */ - .type = VID_TYPE_CAPTURE, - .hardware = VID_HARDWARE_PWC, - .release = video_device_release, - .fops = &pwc_fops, - .minor = -1, -}; - -/***************************************************************************/ - -/* Okay, this is some magic that I worked out and the reasoning behind it... - - The biggest problem with any USB device is of course: "what to do - when the user unplugs the device while it is in use by an application?" - We have several options: - 1) Curse them with the 7 plagues when they do (requires divine intervention) - 2) Tell them not to (won't work: they'll do it anyway) - 3) Oops the kernel (this will have a negative effect on a user's uptime) - 4) Do something sensible. - - Of course, we go for option 4. - - It happens that this device will be linked to two times, once from - usb_device and once from the video_device in their respective 'private' - pointers. This is done when the device is probed() and all initialization - succeeded. The pwc_device struct links back to both structures. - - When a device is unplugged while in use it will be removed from the - list of known USB devices; I also de-register it as a V4L device, but - unfortunately I can't free the memory since the struct is still in use - by the file descriptor. This free-ing is then deferend until the first - opportunity. Crude, but it works. - - A small 'advantage' is that if a user unplugs the cam and plugs it back - in, it should get assigned the same video device minor, but unfortunately - it's non-trivial to re-link the cam back to the video device... (that - would surely be magic! :)) -*/ - -/***************************************************************************/ -/* Private functions */ - -/* Here we want the physical address of the memory. - * This is used when initializing the contents of the area. - */ -static inline unsigned long kvirt_to_pa(unsigned long adr) -{ - unsigned long kva, ret; - - kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); - kva |= adr & (PAGE_SIZE-1); /* restore the offset */ - ret = __pa(kva); - return ret; -} - -static void * rvmalloc(unsigned long size) -{ - void * mem; - unsigned long adr; - - size=PAGE_ALIGN(size); - mem=vmalloc_32(size); - if (mem) - { - memset(mem, 0, size); /* Clear the ram out, no junk to the user */ - adr=(unsigned long) mem; - while (size > 0) - { - SetPageReserved(vmalloc_to_page((void *)adr)); - adr+=PAGE_SIZE; - size-=PAGE_SIZE; - } - } - return mem; -} - -static void rvfree(void * mem, unsigned long size) -{ - unsigned long adr; - - if (mem) - { - adr=(unsigned long) mem; - while ((long) size > 0) - { - ClearPageReserved(vmalloc_to_page((void *)adr)); - adr+=PAGE_SIZE; - size-=PAGE_SIZE; - } - vfree(mem); - } -} - - - - -static int pwc_allocate_buffers(struct pwc_device *pdev) -{ - int i; - void *kbuf; - - Trace(TRACE_MEMORY, ">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev); - - if (pdev == NULL) - return -ENXIO; - -#ifdef PWC_MAGIC - if (pdev->magic != PWC_MAGIC) { - Err("allocate_buffers(): magic failed.\n"); - return -ENXIO; - } -#endif - /* Allocate Isochronuous pipe buffers */ - for (i = 0; i < MAX_ISO_BUFS; i++) { - if (pdev->sbuf[i].data == NULL) { - kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL); - if (kbuf == NULL) { - Err("Failed to allocate iso buffer %d.\n", i); - return -ENOMEM; - } - Trace(TRACE_MEMORY, "Allocated iso buffer at %p.\n", kbuf); - pdev->sbuf[i].data = kbuf; - memset(kbuf, 0, ISO_BUFFER_SIZE); - } - } - - /* Allocate frame buffer structure */ - if (pdev->fbuf == NULL) { - kbuf = kmalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL); - if (kbuf == NULL) { - Err("Failed to allocate frame buffer structure.\n"); - return -ENOMEM; - } - Trace(TRACE_MEMORY, "Allocated frame buffer structure at %p.\n", kbuf); - pdev->fbuf = kbuf; - memset(kbuf, 0, default_fbufs * sizeof(struct pwc_frame_buf)); - } - /* create frame buffers, and make circular ring */ - for (i = 0; i < default_fbufs; i++) { - if (pdev->fbuf[i].data == NULL) { - kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ - if (kbuf == NULL) { - Err("Failed to allocate frame buffer %d.\n", i); - return -ENOMEM; - } - Trace(TRACE_MEMORY, "Allocated frame buffer %d at %p.\n", i, kbuf); - pdev->fbuf[i].data = kbuf; - memset(kbuf, 128, PWC_FRAME_SIZE); - } - } - - /* Allocate decompressor table space */ - kbuf = NULL; - if (pdev->decompressor != NULL) { - kbuf = kmalloc(pdev->decompressor->table_size, GFP_KERNEL); - if (kbuf == NULL) { - Err("Failed to allocate decompress table.\n"); - return -ENOMEM; - } - Trace(TRACE_MEMORY, "Allocated decompress table %p.\n", kbuf); - } - pdev->decompress_data = kbuf; - - /* Allocate image buffer; double buffer for mmap() */ - kbuf = rvmalloc(default_mbufs * pdev->len_per_image); - if (kbuf == NULL) { - Err("Failed to allocate image buffer(s).\n"); - return -ENOMEM; - } - Trace(TRACE_MEMORY, "Allocated image buffer at %p.\n", kbuf); - pdev->image_data = kbuf; - for (i = 0; i < default_mbufs; i++) - pdev->image_ptr[i] = kbuf + i * pdev->len_per_image; - for (; i < MAX_IMAGES; i++) - pdev->image_ptr[i] = NULL; - - kbuf = NULL; - - Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n"); - return 0; -} - -static void pwc_free_buffers(struct pwc_device *pdev) -{ - int i; - - Trace(TRACE_MEMORY, "Entering free_buffers(%p).\n", pdev); - - if (pdev == NULL) - return; -#ifdef PWC_MAGIC - if (pdev->magic != PWC_MAGIC) { - Err("free_buffers(): magic failed.\n"); - return; - } -#endif - - /* Release Iso-pipe buffers */ - for (i = 0; i < MAX_ISO_BUFS; i++) - if (pdev->sbuf[i].data != NULL) { - Trace(TRACE_MEMORY, "Freeing ISO buffer at %p.\n", pdev->sbuf[i].data); - kfree(pdev->sbuf[i].data); - pdev->sbuf[i].data = NULL; - } - - /* The same for frame buffers */ - if (pdev->fbuf != NULL) { - for (i = 0; i < default_fbufs; i++) { - if (pdev->fbuf[i].data != NULL) { - Trace(TRACE_MEMORY, "Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data); - vfree(pdev->fbuf[i].data); - pdev->fbuf[i].data = NULL; - } - } - kfree(pdev->fbuf); - pdev->fbuf = NULL; - } - - /* Intermediate decompression buffer & tables */ - if (pdev->decompress_data != NULL) { - Trace(TRACE_MEMORY, "Freeing decompression buffer at %p.\n", pdev->decompress_data); - kfree(pdev->decompress_data); - pdev->decompress_data = NULL; - } - pdev->decompressor = NULL; - - /* Release image buffers */ - if (pdev->image_data != NULL) { - Trace(TRACE_MEMORY, "Freeing image buffer at %p.\n", pdev->image_data); - rvfree(pdev->image_data, default_mbufs * pdev->len_per_image); - } - pdev->image_data = NULL; - - Trace(TRACE_MEMORY, "Leaving free_buffers().\n"); -} - -/* The frame & image buffer mess. - - Yes, this is a mess. Well, it used to be simple, but alas... In this - module, 3 buffers schemes are used to get the data from the USB bus to - the user program. The first scheme involves the ISO buffers (called thus - since they transport ISO data from the USB controller), and not really - interesting. Suffices to say the data from this buffer is quickly - gathered in an interrupt handler (pwc_isoc_handler) and placed into the - frame buffer. - - The frame buffer is the second scheme, and is the central element here. - It collects the data from a single frame from the camera (hence, the - name). Frames are delimited by the USB camera with a short USB packet, - so that's easy to detect. The frame buffers form a list that is filled - by the camera+USB controller and drained by the user process through - either read() or mmap(). - - The image buffer is the third scheme, in which frames are decompressed - and converted into planar format. For mmap() there is more than - one image buffer available. - - The frame buffers provide the image buffering. In case the user process - is a bit slow, this introduces lag and some undesired side-effects. - The problem arises when the frame buffer is full. I used to drop the last - frame, which makes the data in the queue stale very quickly. But dropping - the frame at the head of the queue proved to be a litte bit more difficult. - I tried a circular linked scheme, but this introduced more problems than - it solved. - - Because filling and draining are completely asynchronous processes, this - requires some fiddling with pointers and mutexes. - - Eventually, I came up with a system with 2 lists: an 'empty' frame list - and a 'full' frame list: - * Initially, all frame buffers but one are on the 'empty' list; the one - remaining buffer is our initial fill frame. - * If a frame is needed for filling, we try to take it from the 'empty' - list, unless that list is empty, in which case we take the buffer at - the head of the 'full' list. - * When our fill buffer has been filled, it is appended to the 'full' - list. - * If a frame is needed by read() or mmap(), it is taken from the head of - the 'full' list, handled, and then appended to the 'empty' list. If no - buffer is present on the 'full' list, we wait. - The advantage is that the buffer that is currently being decompressed/ - converted, is on neither list, and thus not in our way (any other scheme - I tried had the problem of old data lingering in the queue). - - Whatever strategy you choose, it always remains a tradeoff: with more - frame buffers the chances of a missed frame are reduced. On the other - hand, on slower machines it introduces lag because the queue will - always be full. - */ - -/** - \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first. - */ -static inline int pwc_next_fill_frame(struct pwc_device *pdev) -{ - int ret; - unsigned long flags; - - ret = 0; - spin_lock_irqsave(&pdev->ptrlock, flags); - if (pdev->fill_frame != NULL) { - /* append to 'full' list */ - if (pdev->full_frames == NULL) { - pdev->full_frames = pdev->fill_frame; - pdev->full_frames_tail = pdev->full_frames; - } - else { - pdev->full_frames_tail->next = pdev->fill_frame; - pdev->full_frames_tail = pdev->fill_frame; - } - } - if (pdev->empty_frames != NULL) { - /* We have empty frames available. That's easy */ - pdev->fill_frame = pdev->empty_frames; - pdev->empty_frames = pdev->empty_frames->next; - } - else { - /* Hmm. Take it from the full list */ -#if PWC_DEBUG - /* sanity check */ - if (pdev->full_frames == NULL) { - Err("Neither empty or full frames available!\n"); - spin_unlock_irqrestore(&pdev->ptrlock, flags); - return -EINVAL; - } -#endif - pdev->fill_frame = pdev->full_frames; - pdev->full_frames = pdev->full_frames->next; - ret = 1; - } - pdev->fill_frame->next = NULL; -#if PWC_DEBUG - Trace(TRACE_SEQUENCE, "Assigning sequence number %d.\n", pdev->sequence); - pdev->fill_frame->sequence = pdev->sequence++; -#endif - spin_unlock_irqrestore(&pdev->ptrlock, flags); - return ret; -} - - -/** - \brief Reset all buffers, pointers and lists, except for the image_used[] buffer. - - If the image_used[] buffer is cleared too, mmap()/VIDIOCSYNC will run into trouble. - */ -static void pwc_reset_buffers(struct pwc_device *pdev) -{ - int i; - unsigned long flags; - - spin_lock_irqsave(&pdev->ptrlock, flags); - pdev->full_frames = NULL; - pdev->full_frames_tail = NULL; - for (i = 0; i < default_fbufs; i++) { - pdev->fbuf[i].filled = 0; - if (i > 0) - pdev->fbuf[i].next = &pdev->fbuf[i - 1]; - else - pdev->fbuf->next = NULL; - } - pdev->empty_frames = &pdev->fbuf[default_fbufs - 1]; - pdev->empty_frames_tail = pdev->fbuf; - pdev->read_frame = NULL; - pdev->fill_frame = pdev->empty_frames; - pdev->empty_frames = pdev->empty_frames->next; - - pdev->image_read_pos = 0; - pdev->fill_image = 0; - spin_unlock_irqrestore(&pdev->ptrlock, flags); -} - - -/** - \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers. - */ -static int pwc_handle_frame(struct pwc_device *pdev) -{ - int ret = 0; - unsigned long flags; - - spin_lock_irqsave(&pdev->ptrlock, flags); - /* First grab our read_frame; this is removed from all lists, so - we can release the lock after this without problems */ - if (pdev->read_frame != NULL) { - /* This can't theoretically happen */ - Err("Huh? Read frame still in use?\n"); - } - else { - if (pdev->full_frames == NULL) { - Err("Woops. No frames ready.\n"); - } - else { - pdev->read_frame = pdev->full_frames; - pdev->full_frames = pdev->full_frames->next; - pdev->read_frame->next = NULL; - } - - if (pdev->read_frame != NULL) { -#if PWC_DEBUG - Trace(TRACE_SEQUENCE, "Decompressing frame %d\n", pdev->read_frame->sequence); -#endif - /* Decompression is a lenghty process, so it's outside of the lock. - This gives the isoc_handler the opportunity to fill more frames - in the mean time. - */ - spin_unlock_irqrestore(&pdev->ptrlock, flags); - ret = pwc_decompress(pdev); - spin_lock_irqsave(&pdev->ptrlock, flags); - - /* We're done with read_buffer, tack it to the end of the empty buffer list */ - if (pdev->empty_frames == NULL) { - pdev->empty_frames = pdev->read_frame; - pdev->empty_frames_tail = pdev->empty_frames; - } - else { - pdev->empty_frames_tail->next = pdev->read_frame; - pdev->empty_frames_tail = pdev->read_frame; - } - pdev->read_frame = NULL; - } - } - spin_unlock_irqrestore(&pdev->ptrlock, flags); - return ret; -} - -/** - \brief Advance pointers of image buffer (after each user request) -*/ -static inline void pwc_next_image(struct pwc_device *pdev) -{ - pdev->image_used[pdev->fill_image] = 0; - pdev->fill_image = (pdev->fill_image + 1) % default_mbufs; -} - - -/* This gets called for the Isochronous pipe (video). This is done in - * interrupt time, so it has to be fast, not crash, and not stall. Neat. - */ -static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) -{ - struct pwc_device *pdev; - int i, fst, flen; - int awake; - struct pwc_frame_buf *fbuf; - unsigned char *fillptr = NULL; - unsigned char *iso_buf = NULL; - - awake = 0; - pdev = (struct pwc_device *)urb->context; - if (pdev == NULL) { - Err("isoc_handler() called with NULL device?!\n"); - return; - } -#ifdef PWC_MAGIC - if (pdev->magic != PWC_MAGIC) { - Err("isoc_handler() called with bad magic!\n"); - return; - } -#endif - if (urb->status == -ENOENT || urb->status == -ECONNRESET) { - Trace(TRACE_OPEN, "pwc_isoc_handler(): URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); - return; - } - if (urb->status != -EINPROGRESS && urb->status != 0) { - const char *errmsg; - - errmsg = "Unknown"; - switch(urb->status) { - case -ENOSR: errmsg = "Buffer error (overrun)"; break; - case -EPIPE: errmsg = "Stalled (device not responding)"; break; - case -EOVERFLOW: errmsg = "Babble (bad cable?)"; break; - case -EPROTO: errmsg = "Bit-stuff error (bad cable?)"; break; - case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break; - case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break; - } - Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg); - /* Give up after a number of contiguous errors on the USB bus. - Appearantly something is wrong so we simulate an unplug event. - */ - if (++pdev->visoc_errors > MAX_ISOC_ERRORS) - { - Info("Too many ISOC errors, bailing out.\n"); - pdev->error_status = EIO; - awake = 1; - wake_up_interruptible(&pdev->frameq); - } - goto handler_end; // ugly, but practical - } - - fbuf = pdev->fill_frame; - if (fbuf == NULL) { - Err("pwc_isoc_handler without valid fill frame.\n"); - awake = 1; - goto handler_end; - } - else { - fillptr = fbuf->data + fbuf->filled; - } - - /* Reset ISOC error counter. We did get here, after all. */ - pdev->visoc_errors = 0; - - /* vsync: 0 = don't copy data - 1 = sync-hunt - 2 = synched - */ - /* Compact data */ - for (i = 0; i < urb->number_of_packets; i++) { - fst = urb->iso_frame_desc[i].status; - flen = urb->iso_frame_desc[i].actual_length; - iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset; - if (fst == 0) { - if (flen > 0) { /* if valid data... */ - if (pdev->vsync > 0) { /* ...and we are not sync-hunting... */ - pdev->vsync = 2; - - /* ...copy data to frame buffer, if possible */ - if (flen + fbuf->filled > pdev->frame_total_size) { - Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size); - pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */ - pdev->vframes_error++; - } - else { - memmove(fillptr, iso_buf, flen); - fillptr += flen; - } - } - fbuf->filled += flen; - } /* ..flen > 0 */ - - if (flen < pdev->vlast_packet_size) { - /* Shorter packet... We probably have the end of an image-frame; - wake up read() process and let select()/poll() do something. - Decompression is done in user time over there. - */ - if (pdev->vsync == 2) { - /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus - frames on the USB wire after an exposure change. This conditition is - however detected in the cam and a bit is set in the header. - */ - if (pdev->type == 730) { - unsigned char *ptr = (unsigned char *)fbuf->data; - - if (ptr[1] == 1 && ptr[0] & 0x10) { -#if PWC_DEBUG - Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence); -#endif - pdev->drop_frames += 2; - pdev->vframes_error++; - } - if ((ptr[0] ^ pdev->vmirror) & 0x01) { - if (ptr[0] & 0x01) - Info("Snapshot button pressed.\n"); - else - Info("Snapshot button released.\n"); - } - if ((ptr[0] ^ pdev->vmirror) & 0x02) { - if (ptr[0] & 0x02) - Info("Image is mirrored.\n"); - else - Info("Image is normal.\n"); - } - pdev->vmirror = ptr[0] & 0x03; - /* Sometimes the trailer of the 730 is still sent as a 4 byte packet - after a short frame; this condition is filtered out specifically. A 4 byte - frame doesn't make sense anyway. - So we get either this sequence: - drop_bit set -> 4 byte frame -> short frame -> good frame - Or this one: - drop_bit set -> short frame -> good frame - So we drop either 3 or 2 frames in all! - */ - if (fbuf->filled == 4) - pdev->drop_frames++; - } - - /* In case we were instructed to drop the frame, do so silently. - The buffer pointers are not updated either (but the counters are reset below). - */ - if (pdev->drop_frames > 0) - pdev->drop_frames--; - else { - /* Check for underflow first */ - if (fbuf->filled < pdev->frame_total_size) { - Trace(TRACE_FLOW, "Frame buffer underflow (%d bytes); discarded.\n", fbuf->filled); - pdev->vframes_error++; - } - else { - /* Send only once per EOF */ - awake = 1; /* delay wake_ups */ - - /* Find our next frame to fill. This will always succeed, since we - * nick a frame from either empty or full list, but if we had to - * take it from the full list, it means a frame got dropped. - */ - if (pwc_next_fill_frame(pdev)) { - pdev->vframes_dumped++; - if ((pdev->vframe_count > FRAME_LOWMARK) && (pwc_trace & TRACE_FLOW)) { - if (pdev->vframes_dumped < 20) - Trace(TRACE_FLOW, "Dumping frame %d.\n", pdev->vframe_count); - if (pdev->vframes_dumped == 20) - Trace(TRACE_FLOW, "Dumping frame %d (last message).\n", pdev->vframe_count); - } - } - fbuf = pdev->fill_frame; - } - } /* !drop_frames */ - pdev->vframe_count++; - } - fbuf->filled = 0; - fillptr = fbuf->data; - pdev->vsync = 1; - } /* .. flen < last_packet_size */ - pdev->vlast_packet_size = flen; - } /* ..status == 0 */ -#if PWC_DEBUG - /* This is normally not interesting to the user, unless you are really debugging something */ - else { - static int iso_error = 0; - iso_error++; - if (iso_error < 20) - Trace(TRACE_FLOW, "Iso frame %d of USB has error %d\n", i, fst); - } -#endif - } - -handler_end: - if (awake) - wake_up_interruptible(&pdev->frameq); - - urb->dev = pdev->udev; - i = usb_submit_urb(urb, GFP_ATOMIC); - if (i != 0) - Err("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); -} - - -static int pwc_isoc_init(struct pwc_device *pdev) -{ - struct usb_device *udev; - struct urb *urb; - int i, j, ret; - - struct usb_interface *intf; - struct usb_host_interface *idesc = NULL; - - if (pdev == NULL) - return -EFAULT; - if (pdev->iso_init) - return 0; - pdev->vsync = 0; - udev = pdev->udev; - - /* Get the current alternate interface, adjust packet size */ - if (!udev->actconfig) - return -EFAULT; - intf = usb_ifnum_to_if(udev, 0); - if (intf) - idesc = usb_altnum_to_altsetting(intf, pdev->valternate); - if (!idesc) - return -EFAULT; - - /* Search video endpoint */ - pdev->vmax_packet_size = -1; - for (i = 0; i < idesc->desc.bNumEndpoints; i++) - if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) { - pdev->vmax_packet_size = idesc->endpoint[i].desc.wMaxPacketSize; - break; - } - - if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) { - Err("Failed to find packet size for video endpoint in current alternate setting.\n"); - return -ENFILE; /* Odd error, that should be noticable */ - } - - /* Set alternate interface */ - ret = 0; - Trace(TRACE_OPEN, "Setting alternate interface %d\n", pdev->valternate); - ret = usb_set_interface(pdev->udev, 0, pdev->valternate); - if (ret < 0) - return ret; - - for (i = 0; i < MAX_ISO_BUFS; i++) { - urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); - if (urb == NULL) { - Err("Failed to allocate urb %d\n", i); - ret = -ENOMEM; - break; - } - pdev->sbuf[i].urb = urb; - Trace(TRACE_MEMORY, "Allocated URB at 0x%p\n", urb); - } - if (ret) { - /* De-allocate in reverse order */ - while (i >= 0) { - if (pdev->sbuf[i].urb != NULL) - usb_free_urb(pdev->sbuf[i].urb); - pdev->sbuf[i].urb = NULL; - i--; - } - return ret; - } - - /* init URB structure */ - for (i = 0; i < MAX_ISO_BUFS; i++) { - urb = pdev->sbuf[i].urb; - - urb->interval = 1; // devik - urb->dev = udev; - urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint); - urb->transfer_flags = URB_ISO_ASAP; - urb->transfer_buffer = pdev->sbuf[i].data; - urb->transfer_buffer_length = ISO_BUFFER_SIZE; - urb->complete = pwc_isoc_handler; - urb->context = pdev; - urb->start_frame = 0; - urb->number_of_packets = ISO_FRAMES_PER_DESC; - for (j = 0; j < ISO_FRAMES_PER_DESC; j++) { - urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE; - urb->iso_frame_desc[j].length = pdev->vmax_packet_size; - } - } - - /* link */ - for (i = 0; i < MAX_ISO_BUFS; i++) { - ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); - if (ret) - Err("isoc_init() submit_urb %d failed with error %d\n", i, ret); - else - Trace(TRACE_MEMORY, "URB 0x%p submitted.\n", pdev->sbuf[i].urb); - } - - /* All is done... */ - pdev->iso_init = 1; - Trace(TRACE_OPEN, "<< pwc_isoc_init()\n"); - return 0; -} - -static void pwc_isoc_cleanup(struct pwc_device *pdev) -{ - int i; - - Trace(TRACE_OPEN, ">> pwc_isoc_cleanup()\n"); - if (pdev == NULL) - return; - - /* Unlinking ISOC buffers one by one */ - for (i = 0; i < MAX_ISO_BUFS; i++) { - struct urb *urb; - - urb = pdev->sbuf[i].urb; - if (urb != 0) { - if (pdev->iso_init) { - Trace(TRACE_MEMORY, "Unlinking URB %p\n", urb); - usb_unlink_urb(urb); - } - Trace(TRACE_MEMORY, "Freeing URB\n"); - usb_free_urb(urb); - pdev->sbuf[i].urb = NULL; - } - } - - /* Stop camera, but only if we are sure the camera is still there (unplug - is signalled by EPIPE) - */ - if (pdev->error_status && pdev->error_status != EPIPE) { - Trace(TRACE_OPEN, "Setting alternate interface 0.\n"); - usb_set_interface(pdev->udev, 0, 0); - } - - pdev->iso_init = 0; - Trace(TRACE_OPEN, "<< pwc_isoc_cleanup()\n"); -} - -int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot) -{ - int ret, start; - - /* Stop isoc stuff */ - pwc_isoc_cleanup(pdev); - /* Reset parameters */ - pwc_reset_buffers(pdev); - /* Try to set video mode... */ - start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot); - if (ret) { - Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n"); - /* That failed... restore old mode (we know that worked) */ - start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); - if (start) { - Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n"); - } - } - if (start == 0) - { - if (pwc_isoc_init(pdev) < 0) - { - Info("Failed to restart ISOC transfers in pwc_try_video_mode.\n"); - ret = -EAGAIN; /* let's try again, who knows if it works a second time */ - } - } - pdev->drop_frames++; /* try to avoid garbage during switch */ - return ret; /* Return original error code */ -} - - -/***************************************************************************/ -/* Video4Linux functions */ - -static int pwc_video_open(struct inode *inode, struct file *file) -{ - int i; - struct video_device *vdev = video_devdata(file); - struct pwc_device *pdev; - - Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev); - - pdev = (struct pwc_device *)vdev->priv; - if (pdev == NULL) - BUG(); - if (pdev->vopen) - return -EBUSY; - - down(&pdev->modlock); - if (!pdev->usb_init) { - Trace(TRACE_OPEN, "Doing first time initialization.\n"); - pdev->usb_init = 1; - - if (pwc_trace & TRACE_OPEN) - { - /* Query sensor type */ - const char *sensor_type = NULL; - int ret; - - ret = pwc_get_cmos_sensor(pdev, &i); - if (ret >= 0) - { - switch(i) { - case 0x00: sensor_type = "Hyundai CMOS sensor"; break; - case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break; - case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break; - case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break; - case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break; - case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break; - case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break; - case 0x40: sensor_type = "UPA 1021 sensor"; break; - case 0x100: sensor_type = "VGA sensor"; break; - case 0x101: sensor_type = "PAL MR sensor"; break; - default: sensor_type = "unknown type of sensor"; break; - } - } - if (sensor_type != NULL) - Info("This %s camera is equipped with a %s (%d).\n", pdev->vdev->name, sensor_type, i); - } - } - - /* Turn on camera */ - if (power_save) { - i = pwc_camera_power(pdev, 1); - if (i < 0) - Info("Failed to restore power to the camera! (%d)\n", i); - } - /* Set LED on/off time */ - if (pwc_set_leds(pdev, led_on, led_off) < 0) - Info("Failed to set LED on/off time.\n"); - - /* Find our decompressor, if any */ - pdev->decompressor = pwc_find_decompressor(pdev->type); -#if PWC_DEBUG - Debug("Found decompressor for %d at 0x%p\n", pdev->type, pdev->decompressor); -#endif - pwc_construct(pdev); /* set min/max sizes correct */ - - /* So far, so good. Allocate memory. */ - i = pwc_allocate_buffers(pdev); - if (i < 0) { - Trace(TRACE_OPEN, "Failed to allocate buffer memory.\n"); - up(&pdev->modlock); - return i; - } - - /* Reset buffers & parameters */ - pwc_reset_buffers(pdev); - for (i = 0; i < default_mbufs; i++) - pdev->image_used[i] = 0; - pdev->vframe_count = 0; - pdev->vframes_dumped = 0; - pdev->vframes_error = 0; - pdev->visoc_errors = 0; - pdev->error_status = 0; -#if PWC_DEBUG - pdev->sequence = 0; -#endif - pwc_construct(pdev); /* set min/max sizes correct */ - - /* Set some defaults */ - pdev->vsnapshot = 0; - - /* Start iso pipe for video; first try the last used video size - (or the default one); if that fails try QCIF/10 or QSIF/10; - it that fails too, give up. - */ - i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0); - if (i) { - Trace(TRACE_OPEN, "First attempt at set_video_mode failed.\n"); - if (pdev->type == 730 || pdev->type == 740 || pdev->type == 750) - i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QSIF].x, pwc_image_sizes[PSZ_QSIF].y, 10, pdev->vcompression, 0); - else - i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QCIF].x, pwc_image_sizes[PSZ_QCIF].y, 10, pdev->vcompression, 0); - } - if (i) { - Trace(TRACE_OPEN, "Second attempt at set_video_mode failed.\n"); - up(&pdev->modlock); - return i; - } - - i = pwc_isoc_init(pdev); - if (i) { - Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i); - up(&pdev->modlock); - return i; - } - - pdev->vopen++; - file->private_data = vdev; - /* lock decompressor; this has a small race condition, since we - could in theory unload pwcx.o between pwc_find_decompressor() - above and this call. I doubt it's ever going to be a problem. - */ - if (pdev->decompressor != NULL) - pdev->decompressor->lock(); - up(&pdev->modlock); - Trace(TRACE_OPEN, "<< video_open() returns 0.\n"); - return 0; -} - -/* Note that all cleanup is done in the reverse order as in _open */ -static int pwc_video_close(struct inode *inode, struct file *file) -{ - struct video_device *vdev = file->private_data; - struct pwc_device *pdev; - int i; - - Trace(TRACE_OPEN, ">> video_close called(vdev = 0x%p).\n", vdev); - - pdev = (struct pwc_device *)vdev->priv; - if (pdev->vopen == 0) - Info("video_close() called on closed device?\n"); - - /* Dump statistics, but only if a reasonable amount of frames were - processed (to prevent endless log-entries in case of snap-shot - programs) - */ - if (pdev->vframe_count > 20) - Info("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error); - - if (pdev->decompressor != NULL) { - pdev->decompressor->exit(); - pdev->decompressor->unlock(); - pdev->decompressor = NULL; - } - - pwc_isoc_cleanup(pdev); - pwc_free_buffers(pdev); - - /* Turn off LEDS and power down camera, but only when not unplugged */ - if (pdev->error_status != EPIPE) { - /* Turn LEDs off */ - if (pwc_set_leds(pdev, 0, 0) < 0) - Info("Failed to set LED on/off time.\n"); - if (power_save) { - i = pwc_camera_power(pdev, 0); - if (i < 0) - Err("Failed to power down camera (%d)\n", i); - } - } - pdev->vopen = 0; - Trace(TRACE_OPEN, "<< video_close()\n"); - return 0; -} - -/* - * FIXME: what about two parallel reads ???? - * ANSWER: Not supported. You can't open the device more than once, - despite what the V4L1 interface says. First, I don't see - the need, second there's no mechanism of alerting the - 2nd/3rd/... process of events like changing image size. - And I don't see the point of blocking that for the - 2nd/3rd/... process. - In multi-threaded environments reading parallel from any - device is tricky anyhow. - */ - -static ssize_t pwc_video_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - struct video_device *vdev = file->private_data; - struct pwc_device *pdev; - int noblock = file->f_flags & O_NONBLOCK; - DECLARE_WAITQUEUE(wait, current); - int bytes_to_read; - - Trace(TRACE_READ, "video_read(0x%p, %p, %zd) called.\n", vdev, buf, count); - if (vdev == NULL) - return -EFAULT; - pdev = vdev->priv; - if (pdev == NULL) - return -EFAULT; - if (pdev->error_status) - return -pdev->error_status; /* Something happened, report what. */ - - /* In case we're doing partial reads, we don't have to wait for a frame */ - if (pdev->image_read_pos == 0) { - /* Do wait queueing according to the (doc)book */ - add_wait_queue(&pdev->frameq, &wait); - while (pdev->full_frames == NULL) { - /* Check for unplugged/etc. here */ - if (pdev->error_status) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -pdev->error_status ; - } - if (noblock) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -EWOULDBLOCK; - } - if (signal_pending(current)) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -ERESTARTSYS; - } - schedule(); - set_current_state(TASK_INTERRUPTIBLE); - } - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - - /* Decompress and release frame */ - if (pwc_handle_frame(pdev)) - return -EFAULT; - } - - Trace(TRACE_READ, "Copying data to user space.\n"); - if (pdev->vpalette == VIDEO_PALETTE_RAW) - bytes_to_read = pdev->frame_size; - else - bytes_to_read = pdev->view.size; - - /* copy bytes to user space; we allow for partial reads */ - if (count + pdev->image_read_pos > bytes_to_read) - count = bytes_to_read - pdev->image_read_pos; - if (copy_to_user(buf, pdev->image_ptr[pdev->fill_image] + pdev->image_read_pos, count)) - return -EFAULT; - pdev->image_read_pos += count; - if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */ - pdev->image_read_pos = 0; - pwc_next_image(pdev); - } - return count; -} - -static unsigned int pwc_video_poll(struct file *file, poll_table *wait) -{ - struct video_device *vdev = file->private_data; - struct pwc_device *pdev; - - if (vdev == NULL) - return -EFAULT; - pdev = vdev->priv; - if (pdev == NULL) - return -EFAULT; - - poll_wait(file, &pdev->frameq, wait); - if (pdev->error_status) - return POLLERR; - if (pdev->full_frames != NULL) /* we have frames waiting */ - return (POLLIN | POLLRDNORM); - - return 0; -} - -static int pwc_video_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct video_device *vdev = file->private_data; - struct pwc_device *pdev; - DECLARE_WAITQUEUE(wait, current); - - if (vdev == NULL) - return -EFAULT; - pdev = vdev->priv; - if (pdev == NULL) - return -EFAULT; - - switch (cmd) { - /* Query cabapilities */ - case VIDIOCGCAP: - { - struct video_capability *caps = arg; - - strcpy(caps->name, vdev->name); - caps->type = VID_TYPE_CAPTURE; - caps->channels = 1; - caps->audios = 1; - caps->minwidth = pdev->view_min.x; - caps->minheight = pdev->view_min.y; - caps->maxwidth = pdev->view_max.x; - caps->maxheight = pdev->view_max.y; - break; - } - - /* Channel functions (simulate 1 channel) */ - case VIDIOCGCHAN: - { - struct video_channel *v = arg; - - if (v->channel != 0) - return -EINVAL; - v->flags = 0; - v->tuners = 0; - v->type = VIDEO_TYPE_CAMERA; - strcpy(v->name, "Webcam"); - return 0; - } - - case VIDIOCSCHAN: - { - /* The spec says the argument is an integer, but - the bttv driver uses a video_channel arg, which - makes sense becasue it also has the norm flag. - */ - struct video_channel *v = arg; - if (v->channel != 0) - return -EINVAL; - return 0; - } - - - /* Picture functions; contrast etc. */ - case VIDIOCGPICT: - { - struct video_picture *p = arg; - int val; - - val = pwc_get_brightness(pdev); - if (val >= 0) - p->brightness = val; - else - p->brightness = 0xffff; - val = pwc_get_contrast(pdev); - if (val >= 0) - p->contrast = val; - else - p->contrast = 0xffff; - /* Gamma, Whiteness, what's the difference? :) */ - val = pwc_get_gamma(pdev); - if (val >= 0) - p->whiteness = val; - else - p->whiteness = 0xffff; - val = pwc_get_saturation(pdev); - if (val >= 0) - p->colour = val; - else - p->colour = 0xffff; - p->depth = 24; - p->palette = pdev->vpalette; - p->hue = 0xFFFF; /* N/A */ - break; - } - - case VIDIOCSPICT: - { - struct video_picture *p = arg; - /* - * FIXME: Suppose we are mid read - ANSWER: No problem: the firmware of the camera - can handle brightness/contrast/etc - changes at _any_ time, and the palette - is used exactly once in the uncompress - routine. - */ - pwc_set_brightness(pdev, p->brightness); - pwc_set_contrast(pdev, p->contrast); - pwc_set_gamma(pdev, p->whiteness); - pwc_set_saturation(pdev, p->colour); - if (p->palette && p->palette != pdev->vpalette) { - switch (p->palette) { - case VIDEO_PALETTE_YUV420P: - case VIDEO_PALETTE_RAW: - pdev->vpalette = p->palette; - return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); - break; - default: - return -EINVAL; - break; - } - } - break; - } - - /* Window/size parameters */ - case VIDIOCGWIN: - { - struct video_window *vw = arg; - - vw->x = 0; - vw->y = 0; - vw->width = pdev->view.x; - vw->height = pdev->view.y; - vw->chromakey = 0; - vw->flags = (pdev->vframes << PWC_FPS_SHIFT) | - (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0); - break; - } - - case VIDIOCSWIN: - { - struct video_window *vw = arg; - int fps, snapshot, ret; - - fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT; - snapshot = vw->flags & PWC_FPS_SNAPSHOT; - if (fps == 0) - fps = pdev->vframes; - if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot) - return 0; - ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot); - if (ret) - return ret; - break; - } - - /* We don't have overlay support (yet) */ - case VIDIOCGFBUF: - { - struct video_buffer *vb = arg; - - memset(vb,0,sizeof(*vb)); - break; - } - - /* mmap() functions */ - case VIDIOCGMBUF: - { - /* Tell the user program how much memory is needed for a mmap() */ - struct video_mbuf *vm = arg; - int i; - - memset(vm, 0, sizeof(*vm)); - vm->size = default_mbufs * pdev->len_per_image; - vm->frames = default_mbufs; /* double buffering should be enough for most applications */ - for (i = 0; i < default_mbufs; i++) - vm->offsets[i] = i * pdev->len_per_image; - break; - } - - case VIDIOCMCAPTURE: - { - /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */ - struct video_mmap *vm = arg; - - Trace(TRACE_READ, "VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format); - if (vm->frame < 0 || vm->frame >= default_mbufs) - return -EINVAL; - - /* xawtv is nasty. It probes the available palettes - by setting a very small image size and trying - various palettes... The driver doesn't support - such small images, so I'm working around it. - */ - if (vm->format) - { - switch (vm->format) - { - case VIDEO_PALETTE_YUV420P: - case VIDEO_PALETTE_RAW: - break; - default: - return -EINVAL; - break; - } - } - - if ((vm->width != pdev->view.x || vm->height != pdev->view.y) && - (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) { - int ret; - - Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n"); - ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot); - if (ret) - return ret; - } /* ... size mismatch */ - - /* FIXME: should we lock here? */ - if (pdev->image_used[vm->frame]) - return -EBUSY; /* buffer wasn't available. Bummer */ - pdev->image_used[vm->frame] = 1; - - /* Okay, we're done here. In the SYNC call we wait until a - frame comes available, then expand image into the given - buffer. - In contrast to the CPiA cam the Philips cams deliver a - constant stream, almost like a grabber card. Also, - we have separate buffers for the rawdata and the image, - meaning we can nearly always expand into the requested buffer. - */ - Trace(TRACE_READ, "VIDIOCMCAPTURE done.\n"); - break; - } - - case VIDIOCSYNC: - { - /* The doc says: "Whenever a buffer is used it should - call VIDIOCSYNC to free this frame up and continue." - - The only odd thing about this whole procedure is - that MCAPTURE flags the buffer as "in use", and - SYNC immediately unmarks it, while it isn't - after SYNC that you know that the buffer actually - got filled! So you better not start a CAPTURE in - the same frame immediately (use double buffering). - This is not a problem for this cam, since it has - extra intermediate buffers, but a hardware - grabber card will then overwrite the buffer - you're working on. - */ - int *mbuf = arg; - int ret; - - Trace(TRACE_READ, "VIDIOCSYNC called (%d).\n", *mbuf); - - /* bounds check */ - if (*mbuf < 0 || *mbuf >= default_mbufs) - return -EINVAL; - /* check if this buffer was requested anyway */ - if (pdev->image_used[*mbuf] == 0) - return -EINVAL; - - /* Add ourselves to the frame wait-queue. - - FIXME: needs auditing for safety. - QUESTION: In what respect? I think that using the - frameq is safe now. - */ - add_wait_queue(&pdev->frameq, &wait); - while (pdev->full_frames == NULL) { - if (pdev->error_status) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -pdev->error_status; - } - - if (signal_pending(current)) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -ERESTARTSYS; - } - schedule(); - set_current_state(TASK_INTERRUPTIBLE); - } - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - - /* The frame is ready. Expand in the image buffer - requested by the user. I don't care if you - mmap() 5 buffers and request data in this order: - buffer 4 2 3 0 1 2 3 0 4 3 1 . . . - Grabber hardware may not be so forgiving. - */ - Trace(TRACE_READ, "VIDIOCSYNC: frame ready.\n"); - pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */ - /* Decompress, etc */ - ret = pwc_handle_frame(pdev); - pdev->image_used[*mbuf] = 0; - if (ret) - return -EFAULT; - break; - } - - case VIDIOCGAUDIO: - { - struct video_audio *v = arg; - - strcpy(v->name, "Microphone"); - v->audio = -1; /* unknown audio minor */ - v->flags = 0; - v->mode = VIDEO_SOUND_MONO; - v->volume = 0; - v->bass = 0; - v->treble = 0; - v->balance = 0x8000; - v->step = 1; - break; - } - - case VIDIOCSAUDIO: - { - /* Dummy: nothing can be set */ - break; - } - - case VIDIOCGUNIT: - { - struct video_unit *vu = arg; - - vu->video = pdev->vdev->minor & 0x3F; - vu->audio = -1; /* not known yet */ - vu->vbi = -1; - vu->radio = -1; - vu->teletext = -1; - break; - } - default: - return pwc_ioctl(pdev, cmd, arg); - } /* ..switch */ - return 0; -} - -static int pwc_video_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl); -} - - -static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct video_device *vdev = file->private_data; - struct pwc_device *pdev; - unsigned long start = vma->vm_start; - unsigned long size = vma->vm_end-vma->vm_start; - unsigned long page, pos; - - Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size); - pdev = vdev->priv; - - pos = (unsigned long)pdev->image_data; - while (size > 0) { - page = kvirt_to_pa(pos); - if (remap_page_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) - return -EAGAIN; - - start += PAGE_SIZE; - pos += PAGE_SIZE; - if (size > PAGE_SIZE) - size -= PAGE_SIZE; - else - size = 0; - } - - return 0; -} - -/***************************************************************************/ -/* USB functions */ - -/* This function gets called when a new device is plugged in or the usb core - * is loaded. - */ - -static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct pwc_device *pdev = NULL; - int vendor_id, product_id, type_id; - int i, hint; - int features = 0; - int video_nr = -1; /* default: use next available device */ - char serial_number[30], *name; - - /* Check if we can handle this device */ - Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", - udev->descriptor.idVendor, udev->descriptor.idProduct, - intf->altsetting->desc.bInterfaceNumber); - - /* the interfaces are probed one by one. We are only interested in the - video interface (0) now. - Interface 1 is the Audio Control, and interface 2 Audio itself. - */ - if (intf->altsetting->desc.bInterfaceNumber > 0) - return -ENODEV; - - vendor_id = udev->descriptor.idVendor; - product_id = udev->descriptor.idProduct; - - if (vendor_id == 0x0471) { - switch (product_id) { - case 0x0302: - Info("Philips PCA645VC USB webcam detected.\n"); - name = "Philips 645 webcam"; - type_id = 645; - break; - case 0x0303: - Info("Philips PCA646VC USB webcam detected.\n"); - name = "Philips 646 webcam"; - type_id = 646; - break; - case 0x0304: - Info("Askey VC010 type 2 USB webcam detected.\n"); - name = "Askey VC010 webcam"; - type_id = 646; - break; - case 0x0307: - Info("Philips PCVC675K (Vesta) USB webcam detected.\n"); - name = "Philips 675 webcam"; - type_id = 675; - break; - case 0x0308: - Info("Philips PCVC680K (Vesta Pro) USB webcam detected.\n"); - name = "Philips 680 webcam"; - type_id = 680; - break; - case 0x030C: - Info("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n"); - name = "Philips 690 webcam"; - type_id = 690; - break; - case 0x0310: - Info("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n"); - name = "Philips 730 webcam"; - type_id = 730; - break; - case 0x0311: - Info("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n"); - name = "Philips 740 webcam"; - type_id = 740; - break; - case 0x0312: - Info("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n"); - name = "Philips 750 webcam"; - type_id = 750; - break; - case 0x0313: - Info("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n"); - name = "Philips 720K/40 webcam"; - type_id = 720; - break; - default: - return -ENODEV; - break; - } - } - else if (vendor_id == 0x069A) { - switch(product_id) { - case 0x0001: - Info("Askey VC010 type 1 USB webcam detected.\n"); - name = "Askey VC010 webcam"; - type_id = 645; - break; - default: - return -ENODEV; - break; - } - } - else if (vendor_id == 0x046d) { - switch(product_id) { - case 0x08b0: - Info("Logitech QuickCam Pro 3000 USB webcam detected.\n"); - name = "Logitech QuickCam Pro 3000"; - type_id = 740; /* CCD sensor */ - break; - case 0x08b1: - Info("Logitech QuickCam Notebook Pro USB webcam detected.\n"); - name = "Logitech QuickCam Notebook Pro"; - type_id = 740; /* CCD sensor */ - break; - case 0x08b2: - Info("Logitech QuickCam 4000 Pro USB webcam detected.\n"); - name = "Logitech QuickCam Pro 4000"; - type_id = 740; /* CCD sensor */ - break; - case 0x08b3: - Info("Logitech QuickCam Zoom USB webcam detected.\n"); - name = "Logitech QuickCam Zoom"; - type_id = 740; /* CCD sensor */ - break; - case 0x08B4: - Info("Logitech QuickCam Zoom (new model) USB webcam detected.\n"); - name = "Logitech QuickCam Zoom"; - type_id = 740; /* CCD sensor */ - break; - case 0x08b5: - Info("Logitech QuickCam Orbit/Sphere USB webcam detected.\n"); - name = "Logitech QuickCam Orbit"; - type_id = 740; /* CCD sensor */ - features |= FEATURE_MOTOR_PANTILT; - break; - case 0x08b6: - case 0x08b7: - case 0x08b8: - Info("Logitech QuickCam detected (reserved ID).\n"); - name = "Logitech QuickCam (res.)"; - type_id = 730; /* Assuming CMOS */ - break; - default: - return -ENODEV; - break; - } - } - else if (vendor_id == 0x055d) { - /* I don't know the difference between the C10 and the C30; - I suppose the difference is the sensor, but both cameras - work equally well with a type_id of 675 - */ - switch(product_id) { - case 0x9000: - Info("Samsung MPC-C10 USB webcam detected.\n"); - name = "Samsung MPC-C10"; - type_id = 675; - break; - case 0x9001: - Info("Samsung MPC-C30 USB webcam detected.\n"); - name = "Samsung MPC-C30"; - type_id = 675; - break; - default: - return -ENODEV; - break; - } - } - else if (vendor_id == 0x041e) { - switch(product_id) { - case 0x400c: - Info("Creative Labs Webcam 5 detected.\n"); - name = "Creative Labs Webcam 5"; - type_id = 730; - break; - case 0x4011: - Info("Creative Labs Webcam Pro Ex detected.\n"); - name = "Creative Labs Webcam Pro Ex"; - type_id = 740; - break; - default: - return -ENODEV; - break; - } - } - else if (vendor_id == 0x04cc) { - switch(product_id) { - case 0x8116: - Info("Sotec Afina Eye USB webcam detected.\n"); - name = "Sotec Afina Eye"; - type_id = 730; - break; - default: - return -ENODEV; - break; - } - } - else if (vendor_id == 0x06be) { - switch(product_id) { - case 0x8116: - /* Basicly the same as the Sotec Afina Eye */ - Info("AME CU-001 USB webcam detected.\n"); - name = "AME CU-001"; - type_id = 730; - break; - default: - return -ENODEV; - break; - } - } - else if (vendor_id == 0x06be) { - switch(product_id) { - case 0x8116: - /* This is essentially the same cam as the Sotec Afina Eye */ - Info("AME Co. Afina Eye USB webcam detected.\n"); - name = "AME Co. Afina Eye"; - type_id = 750; - break; - default: - return -ENODEV; - break; - } - - } - else if (vendor_id == 0x0d81) { - switch(product_id) { - case 0x1900: - Info("Visionite VCS-UC300 USB webcam detected.\n"); - name = "Visionite VCS-UC300"; - type_id = 740; /* CCD sensor */ - break; - case 0x1910: - Info("Visionite VCS-UM100 USB webcam detected.\n"); - name = "Visionite VCS-UM100"; - type_id = 730; /* CMOS sensor */ - break; - default: - return -ENODEV; - break; - } - } - else - return -ENODEV; /* Not any of the know types; but the list keeps growing. */ - - memset(serial_number, 0, 30); - usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29); - Trace(TRACE_PROBE, "Device serial number is %s\n", serial_number); - - if (udev->descriptor.bNumConfigurations > 1) - Info("Warning: more than 1 configuration available.\n"); - - /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */ - pdev = kmalloc(sizeof(struct pwc_device), GFP_KERNEL); - if (pdev == NULL) { - Err("Oops, could not allocate memory for pwc_device.\n"); - return -ENOMEM; - } - memset(pdev, 0, sizeof(struct pwc_device)); - pdev->type = type_id; - pdev->vsize = default_size; - pdev->vframes = default_fps; - strcpy(pdev->serial, serial_number); - pdev->features = features; - if (vendor_id == 0x046D && product_id == 0x08B5) - { - /* Logitech QuickCam Orbit - The ranges have been determined experimentally; they may differ from cam to cam. - Also, the exact ranges left-right and up-down are different for my cam - */ - pdev->angle_range.pan_min = -7000; - pdev->angle_range.pan_max = 7000; - pdev->angle_range.tilt_min = -3000; - pdev->angle_range.tilt_max = 2500; - } - - init_MUTEX(&pdev->modlock); - pdev->ptrlock = SPIN_LOCK_UNLOCKED; - - pdev->udev = udev; - init_waitqueue_head(&pdev->frameq); - pdev->vcompression = pwc_preferred_compression; - - /* Allocate video_device structure */ - pdev->vdev = video_device_alloc(); - if (pdev->vdev == 0) - { - Err("Err, cannot allocate video_device struture. Failing probe."); - kfree(pdev); - return -ENOMEM; - } - memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); - strcpy(pdev->vdev->name, name); - pdev->vdev->owner = THIS_MODULE; - video_set_drvdata(pdev->vdev, pdev); - - pdev->release = udev->descriptor.bcdDevice; - Trace(TRACE_PROBE, "Release: %04x\n", pdev->release); - - /* Now search device_hint[] table for a match, so we can hint a node number. */ - for (hint = 0; hint < MAX_DEV_HINTS; hint++) { - if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) && - (device_hint[hint].pdev == NULL)) { - /* so far, so good... try serial number */ - if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) { - /* match! */ - video_nr = device_hint[hint].device_node; - Trace(TRACE_PROBE, "Found hint, will try to register as /dev/video%d\n", video_nr); - break; - } - } - } - - pdev->vdev->release = video_device_release; - i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); - if (i < 0) { - Err("Failed to register as video device (%d).\n", i); - video_device_release(pdev->vdev); /* Drip... drip... drip... */ - kfree(pdev); /* Oops, no memory leaks please */ - return -EIO; - } - else { - Info("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F); - } - - /* occupy slot */ - if (hint < MAX_DEV_HINTS) - device_hint[hint].pdev = pdev; - - Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev); - usb_set_intfdata (intf, pdev); - return 0; -} - -/* The user janked out the cable... */ -static void usb_pwc_disconnect(struct usb_interface *intf) -{ - struct pwc_device *pdev; - int hint; - - lock_kernel(); - pdev = usb_get_intfdata (intf); - usb_set_intfdata (intf, NULL); - if (pdev == NULL) { - Err("pwc_disconnect() Called without private pointer.\n"); - goto disconnect_out; - } - if (pdev->udev == NULL) { - Err("pwc_disconnect() already called for %p\n", pdev); - goto disconnect_out; - } - if (pdev->udev != interface_to_usbdev(intf)) { - Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n"); - goto disconnect_out; - } -#ifdef PWC_MAGIC - if (pdev->magic != PWC_MAGIC) { - Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n"); - goto disconnect_out; - } -#endif - - /* We got unplugged; this is signalled by an EPIPE error code */ - if (pdev->vopen) { - Info("Disconnected while webcam is in use!\n"); - pdev->error_status = EPIPE; - } - - /* Alert waiting processes */ - wake_up_interruptible(&pdev->frameq); - /* Wait until device is closed */ - while (pdev->vopen) - schedule(); - /* Device is now closed, so we can safely unregister it */ - Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n"); - video_unregister_device(pdev->vdev); - - /* Free memory (don't set pdev to 0 just yet) */ - kfree(pdev); - -disconnect_out: - /* search device_hint[] table if we occupy a slot, by any chance */ - for (hint = 0; hint < MAX_DEV_HINTS; hint++) - if (device_hint[hint].pdev == pdev) - device_hint[hint].pdev = NULL; - - unlock_kernel(); -} - - -/* *grunt* We have to do atoi ourselves :-( */ -static int pwc_atoi(const char *s) -{ - int k = 0; - - k = 0; - while (*s != '\0' && *s >= '0' && *s <= '9') { - k = 10 * k + (*s - '0'); - s++; - } - return k; -} - - -/* - * Initialization code & module stuff - */ - -static char *size = NULL; -static int fps = 0; -static int fbufs = 0; -static int mbufs = 0; -static int trace = -1; -static int compression = -1; -static int leds[2] = { -1, -1 }; -static char *dev_hint[MAX_DEV_HINTS] = { }; - -MODULE_PARM(size, "s"); -MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga"); -MODULE_PARM(fps, "i"); -MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); -MODULE_PARM(fbufs, "i"); -MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve"); -MODULE_PARM(mbufs, "i"); -MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers"); -MODULE_PARM(trace, "i"); -MODULE_PARM_DESC(trace, "For debugging purposes"); -MODULE_PARM(power_save, "i"); -MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off"); -MODULE_PARM(compression, "i"); -MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); -MODULE_PARM(leds, "2i"); -MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); -MODULE_PARM(dev_hint, "0-20s"); -MODULE_PARM_DESC(dev_hint, "Device node hints"); - -MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); -MODULE_AUTHOR("Nemosoft Unv. "); -MODULE_LICENSE("GPL"); - -static int __init usb_pwc_init(void) -{ - int i, sz; - char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" }; - - Info("Philips webcam module version " PWC_VERSION " loaded.\n"); - Info("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n"); - Info("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n"); - Info("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); - - if (fps) { - if (fps < 4 || fps > 30) { - Err("Framerate out of bounds (4-30).\n"); - return -EINVAL; - } - default_fps = fps; - Info("Default framerate set to %d.\n", default_fps); - } - - if (size) { - /* string; try matching with array */ - for (sz = 0; sz < PSZ_MAX; sz++) { - if (!strcmp(sizenames[sz], size)) { /* Found! */ - default_size = sz; - break; - } - } - if (sz == PSZ_MAX) { - Err("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n"); - return -EINVAL; - } - Info("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y); - } - if (mbufs) { - if (mbufs < 1 || mbufs > MAX_IMAGES) { - Err("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES); - return -EINVAL; - } - default_mbufs = mbufs; - Info("Number of image buffers set to %d.\n", default_mbufs); - } - if (fbufs) { - if (fbufs < 2 || fbufs > MAX_FRAMES) { - Err("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES); - return -EINVAL; - } - default_fbufs = fbufs; - Info("Number of frame buffers set to %d.\n", default_fbufs); - } - if (trace >= 0) { - Info("Trace options: 0x%04x\n", trace); - pwc_trace = trace; - } - if (compression >= 0) { - if (compression > 3) { - Err("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n"); - return -EINVAL; - } - pwc_preferred_compression = compression; - Info("Preferred compression set to %d.\n", pwc_preferred_compression); - } - if (power_save) - Info("Enabling power save on open/close.\n"); - if (leds[0] >= 0) - led_on = leds[0]; - if (leds[1] >= 0) - led_off = leds[1]; - - /* Big device node whoopla. Basicly, it allows you to assign a - device node (/dev/videoX) to a camera, based on its type - & serial number. The format is [type[.serialnumber]:]node. - - Any camera that isn't matched by these rules gets the next - available free device node. - */ - for (i = 0; i < MAX_DEV_HINTS; i++) { - char *s, *colon, *dot; - - /* This loop also initializes the array */ - device_hint[i].pdev = NULL; - s = dev_hint[i]; - if (s != NULL && *s != '\0') { - device_hint[i].type = -1; /* wildcard */ - strcpy(device_hint[i].serial_number, "*"); - - /* parse string: chop at ':' & '/' */ - colon = dot = s; - while (*colon != '\0' && *colon != ':') - colon++; - while (*dot != '\0' && *dot != '.') - dot++; - /* Few sanity checks */ - if (*dot != '\0' && dot > colon) { - Err("Malformed camera hint: the colon must be after the dot.\n"); - return -EINVAL; - } - - if (*colon == '\0') { - /* No colon */ - if (*dot != '\0') { - Err("Malformed camera hint: no colon + device node given.\n"); - return -EINVAL; - } - else { - /* No type or serial number specified, just a number. */ - device_hint[i].device_node = pwc_atoi(s); - } - } - else { - /* There's a colon, so we have at least a type and a device node */ - device_hint[i].type = pwc_atoi(s); - device_hint[i].device_node = pwc_atoi(colon + 1); - if (*dot != '\0') { - /* There's a serial number as well */ - int k; - - dot++; - k = 0; - while (*dot != ':' && k < 29) { - device_hint[i].serial_number[k++] = *dot; - dot++; - } - device_hint[i].serial_number[k] = '\0'; - } - } -#if PWC_DEBUG - Debug("device_hint[%d]:\n", i); - Debug(" type : %d\n", device_hint[i].type); - Debug(" serial# : %s\n", device_hint[i].serial_number); - Debug(" node : %d\n", device_hint[i].device_node); -#endif - } - else - device_hint[i].type = 0; /* not filled */ - } /* ..for MAX_DEV_HINTS */ - - Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver); - return usb_register(&pwc_driver); -} - -static void __exit usb_pwc_exit(void) -{ - Trace(TRACE_MODULE, "Deregistering driver.\n"); - usb_deregister(&pwc_driver); - Info("Philips webcam module removed.\n"); -} - -module_init(usb_pwc_init); -module_exit(usb_pwc_exit); - diff --git a/drivers/usb/media/pwc-ioctl.h b/drivers/usb/media/pwc-ioctl.h deleted file mode 100644 index 2535a3c38..000000000 --- a/drivers/usb/media/pwc-ioctl.h +++ /dev/null @@ -1,279 +0,0 @@ -#ifndef PWC_IOCTL_H -#define PWC_IOCTL_H - -/* (C) 2001-2004 Nemosoft Unv. webcam@smcc.demon.nl - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* This is pwc-ioctl.h belonging to PWC 8.12.1 - It contains structures and defines to communicate from user space - directly to the driver. - */ - -/* - Changes - 2001/08/03 Alvarado Added ioctl constants to access methods for - changing white balance and red/blue gains - 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE - 2003/12/13 Nemosft Unv. Some modifications to make interfacing to - PWCX easier - */ - -/* These are private ioctl() commands, specific for the Philips webcams. - They contain functions not found in other webcams, and settings not - specified in the Video4Linux API. - - The #define names are built up like follows: - VIDIOC VIDeo IOCtl prefix - PWC Philps WebCam - G optional: Get - S optional: Set - ... the function - */ - - - /* Enumeration of image sizes */ -#define PSZ_SQCIF 0x00 -#define PSZ_QSIF 0x01 -#define PSZ_QCIF 0x02 -#define PSZ_SIF 0x03 -#define PSZ_CIF 0x04 -#define PSZ_VGA 0x05 -#define PSZ_MAX 6 - - -/* The frame rate is encoded in the video_window.flags parameter using - the upper 16 bits, since some flags are defined nowadays. The following - defines provide a mask and shift to filter out this value. - - In 'Snapshot' mode the camera freezes its automatic exposure and colour - balance controls. - */ -#define PWC_FPS_SHIFT 16 -#define PWC_FPS_MASK 0x00FF0000 -#define PWC_FPS_FRMASK 0x003F0000 -#define PWC_FPS_SNAPSHOT 0x00400000 - - -/* structure for transfering x & y coordinates */ -struct pwc_coord -{ - int x, y; /* guess what */ - int size; /* size, or offset */ -}; - - -/* Used with VIDIOCPWCPROBE */ -struct pwc_probe -{ - char name[32]; - int type; -}; - -struct pwc_serial -{ - char serial[30]; /* String with serial number. Contains terminating 0 */ -}; - -/* pwc_whitebalance.mode values */ -#define PWC_WB_INDOOR 0 -#define PWC_WB_OUTDOOR 1 -#define PWC_WB_FL 2 -#define PWC_WB_MANUAL 3 -#define PWC_WB_AUTO 4 - -/* Used with VIDIOCPWC[SG]AWB (Auto White Balance). - Set mode to one of the PWC_WB_* values above. - *red and *blue are the respective gains of these colour components inside - the camera; range 0..65535 - When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read; - otherwise undefined. - 'read_red' and 'read_blue' are read-only. -*/ -struct pwc_whitebalance -{ - int mode; - int manual_red, manual_blue; /* R/W */ - int read_red, read_blue; /* R/O */ -}; - -/* - 'control_speed' and 'control_delay' are used in automatic whitebalance mode, - and tell the camera how fast it should react to changes in lighting, and - with how much delay. Valid values are 0..65535. -*/ -struct pwc_wb_speed -{ - int control_speed; - int control_delay; - -}; - -/* Used with VIDIOCPWC[SG]LED */ -struct pwc_leds -{ - int led_on; /* Led on-time; range = 0..25000 */ - int led_off; /* Led off-time; range = 0..25000 */ -}; - -/* Image size (used with GREALSIZE) */ -struct pwc_imagesize -{ - int width; - int height; -}; - -/* Defines and structures for Motorized Pan & Tilt */ -#define PWC_MPT_PAN 0x01 -#define PWC_MPT_TILT 0x02 -#define PWC_MPT_TIMEOUT 0x04 /* for status */ - -/* Set angles; when absolute != 0, the angle is absolute and the - driver calculates the relative offset for you. This can only - be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns - absolute angles. - */ -struct pwc_mpt_angles -{ - int absolute; /* write-only */ - int pan; /* degrees * 100 */ - int tilt; /* degress * 100 */ -}; - -/* Range of angles of the camera, both horizontally and vertically. - */ -struct pwc_mpt_range -{ - int pan_min, pan_max; /* degrees * 100 */ - int tilt_min, tilt_max; -}; - -struct pwc_mpt_status -{ - int status; - int time_pan; - int time_tilt; -}; - - -/* This is used for out-of-kernel decompression. With it, you can get - all the necessary information to initialize and use the decompressor - routines in standalone applications. - */ -struct pwc_video_command -{ - int type; /* camera type (645, 675, 730, etc.) */ - int release; /* release number */ - - int size; /* one of PSZ_* */ - int alternate; - int command_len; /* length of USB video command */ - unsigned char command_buf[13]; /* Actual USB video command */ - int bandlength; /* >0 = compressed */ - int frame_size; /* Size of one (un)compressed frame */ -}; - -/* Flags for PWCX subroutines. Not all modules honour all flags. */ -#define PWCX_FLAG_PLANAR 0x0001 -#define PWCX_FLAG_BAYER 0x0008 - - -/* IOCTL definitions */ - - /* Restore user settings */ -#define VIDIOCPWCRUSER _IO('v', 192) - /* Save user settings */ -#define VIDIOCPWCSUSER _IO('v', 193) - /* Restore factory settings */ -#define VIDIOCPWCFACTORY _IO('v', 194) - - /* You can manipulate the compression factor. A compression preference of 0 - means use uncompressed modes when available; 1 is low compression, 2 is - medium and 3 is high compression preferred. Of course, the higher the - compression, the lower the bandwidth used but more chance of artefacts - in the image. The driver automatically chooses a higher compression when - the preferred mode is not available. - */ - /* Set preferred compression quality (0 = uncompressed, 3 = highest compression) */ -#define VIDIOCPWCSCQUAL _IOW('v', 195, int) - /* Get preferred compression quality */ -#define VIDIOCPWCGCQUAL _IOR('v', 195, int) - - -/* Retrieve serial number of camera */ -#define VIDIOCPWCGSERIAL _IOR('v', 198, struct pwc_serial) - - /* This is a probe function; since so many devices are supported, it - becomes difficult to include all the names in programs that want to - check for the enhanced Philips stuff. So in stead, try this PROBE; - it returns a structure with the original name, and the corresponding - Philips type. - To use, fill the structure with zeroes, call PROBE and if that succeeds, - compare the name with that returned from VIDIOCGCAP; they should be the - same. If so, you can be assured it is a Philips (OEM) cam and the type - is valid. - */ -#define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe) - - /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */ -#define VIDIOCPWCSAGC _IOW('v', 200, int) - /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */ -#define VIDIOCPWCGAGC _IOR('v', 200, int) - /* Set shutter speed; int < 0 = auto; >= 0 = fixed, range 0..65535 */ -#define VIDIOCPWCSSHUTTER _IOW('v', 201, int) - - /* Color compensation (Auto White Balance) */ -#define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance) -#define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance) - - /* Auto WB speed */ -#define VIDIOCPWCSAWBSPEED _IOW('v', 203, struct pwc_wb_speed) -#define VIDIOCPWCGAWBSPEED _IOR('v', 203, struct pwc_wb_speed) - - /* LEDs on/off/blink; int range 0..65535 */ -#define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds) -#define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds) - - /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */ -#define VIDIOCPWCSCONTOUR _IOW('v', 206, int) -#define VIDIOCPWCGCONTOUR _IOR('v', 206, int) - - /* Backlight compensation; 0 = off, otherwise on */ -#define VIDIOCPWCSBACKLIGHT _IOW('v', 207, int) -#define VIDIOCPWCGBACKLIGHT _IOR('v', 207, int) - - /* Flickerless mode; = 0 off, otherwise on */ -#define VIDIOCPWCSFLICKER _IOW('v', 208, int) -#define VIDIOCPWCGFLICKER _IOR('v', 208, int) - - /* Dynamic noise reduction; 0 off, 3 = high noise reduction */ -#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int) -#define VIDIOCPWCGDYNNOISE _IOR('v', 209, int) - - /* Real image size as used by the camera; tells you whether or not there's a gray border around the image */ -#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize) - - /* Motorized pan & tilt functions */ -#define VIDIOCPWCMPTRESET _IOW('v', 211, int) -#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range) -#define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles) -#define VIDIOCPWCMPTGANGLE _IOR('v', 212, struct pwc_mpt_angles) -#define VIDIOCPWCMPTSTATUS _IOR('v', 213, struct pwc_mpt_status) - - /* Get the USB set-video command; needed for initializing libpwcx */ -#define VIDIOCPWCGVIDCMD _IOR('v', 215, struct pwc_video_command) - -#endif diff --git a/drivers/usb/media/pwc-misc.c b/drivers/usb/media/pwc-misc.c deleted file mode 100644 index 09f629da3..000000000 --- a/drivers/usb/media/pwc-misc.c +++ /dev/null @@ -1,146 +0,0 @@ -/* Linux driver for Philips webcam - Various miscellaneous functions and tables. - (C) 1999-2003 Nemosoft Unv. (webcam@smcc.demon.nl) - - 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 "pwc.h" - -struct pwc_coord pwc_image_sizes[PSZ_MAX] = -{ - { 128, 96, 0 }, - { 160, 120, 0 }, - { 176, 144, 0 }, - { 320, 240, 0 }, - { 352, 288, 0 }, - { 640, 480, 0 }, -}; - -/* x,y -> PSZ_ */ -int pwc_decode_size(struct pwc_device *pdev, int width, int height) -{ - int i, find; - - /* Make sure we don't go beyond our max size. - NB: we have different limits for RAW and normal modes. In case - you don't have the decompressor loaded or use RAW mode, - the maximum viewable size is smaller. - */ - if (pdev->vpalette == VIDEO_PALETTE_RAW) - { - if (width > pdev->abs_max.x || height > pdev->abs_max.y) - { - Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n"); - return -1; - } - } - else - { - if (width > pdev->view_max.x || height > pdev->view_max.y) - { - Debug("VIDEO_PALETTE_ not RAW: going beyond view_max.\n"); - return -1; - } - } - - /* Find the largest size supported by the camera that fits into the - requested size. - */ - find = -1; - for (i = 0; i < PSZ_MAX; i++) { - if (pdev->image_mask & (1 << i)) { - if (pwc_image_sizes[i].x <= width && pwc_image_sizes[i].y <= height) - find = i; - } - } - return find; -} - -/* initialize variables depending on type and decompressor*/ -void pwc_construct(struct pwc_device *pdev) -{ - switch(pdev->type) { - case 645: - case 646: - pdev->view_min.x = 128; - pdev->view_min.y = 96; - pdev->view_max.x = 352; - pdev->view_max.y = 288; - pdev->abs_max.x = 352; - pdev->abs_max.y = 288; - pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF; - pdev->vcinterface = 2; - pdev->vendpoint = 4; - pdev->frame_header_size = 0; - pdev->frame_trailer_size = 0; - break; - case 675: - case 680: - case 690: - pdev->view_min.x = 128; - pdev->view_min.y = 96; - /* Anthill bug #38: PWC always reports max size, even without PWCX */ - if (pdev->decompressor != NULL) { - pdev->view_max.x = 640; - pdev->view_max.y = 480; - } - else { - pdev->view_max.x = 352; - pdev->view_max.y = 288; - } - pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA; - pdev->abs_max.x = 640; - pdev->abs_max.y = 480; - pdev->vcinterface = 3; - pdev->vendpoint = 4; - pdev->frame_header_size = 0; - pdev->frame_trailer_size = 0; - break; - case 720: - case 730: - case 740: - case 750: - pdev->view_min.x = 160; - pdev->view_min.y = 120; - /* Anthill bug #38: PWC always reports max size, even without PWCX */ - if (pdev->decompressor != NULL) { - pdev->view_max.x = 640; - pdev->view_max.y = 480; - } - else { - /* We use CIF, not SIF since some tools really need CIF. So we cheat a bit. */ - pdev->view_max.x = 352; - pdev->view_max.y = 288; - } - pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA; - pdev->abs_max.x = 640; - pdev->abs_max.y = 480; - pdev->vcinterface = 3; - pdev->vendpoint = 5; - pdev->frame_header_size = TOUCAM_HEADER_SIZE; - pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE; - break; - } - pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */ - pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; - pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; - /* length of image, in YUV format; always allocate enough memory. */ - pdev->len_per_image = (pdev->abs_max.x * pdev->abs_max.y * 3) / 2; -} - - diff --git a/drivers/usb/media/pwc-uncompress.c b/drivers/usb/media/pwc-uncompress.c deleted file mode 100644 index 269cd227f..000000000 --- a/drivers/usb/media/pwc-uncompress.c +++ /dev/null @@ -1,180 +0,0 @@ -/* Linux driver for Philips webcam - Decompression frontend. - (C) 1999-2003 Nemosoft Unv. (webcam@smcc.demon.nl) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -/* - This is where the decompression routines register and unregister - themselves. It also has a decompressor wrapper function. -*/ - -#include -#include -// #include - -#include "pwc.h" -#include "pwc-uncompress.h" - - -/* This contains a list of all registered decompressors */ -static LIST_HEAD(pwc_decompressor_list); - -/* Should the pwc_decompress structure ever change, we increase the - version number so that we don't get nasty surprises, or can - dynamically adjust our structure. - */ -const int pwc_decompressor_version = PWC_MAJOR; - -/* Add decompressor to list, ignoring duplicates */ -void pwc_register_decompressor(struct pwc_decompressor *pwcd) -{ - if (pwc_find_decompressor(pwcd->type) == NULL) { - Trace(TRACE_PWCX, "Adding decompressor for model %d.\n", pwcd->type); - list_add_tail(&pwcd->pwcd_list, &pwc_decompressor_list); - } -} - -/* Remove decompressor from list */ -void pwc_unregister_decompressor(int type) -{ - struct pwc_decompressor *find; - - find = pwc_find_decompressor(type); - if (find != NULL) { - Trace(TRACE_PWCX, "Removing decompressor for model %d.\n", type); - list_del(&find->pwcd_list); - } -} - -/* Find decompressor in list */ -struct pwc_decompressor *pwc_find_decompressor(int type) -{ - struct list_head *tmp; - struct pwc_decompressor *pwcd; - - list_for_each(tmp, &pwc_decompressor_list) { - pwcd = list_entry(tmp, struct pwc_decompressor, pwcd_list); - if (pwcd->type == type) - return pwcd; - } - return NULL; -} - - - -int pwc_decompress(struct pwc_device *pdev) -{ - struct pwc_frame_buf *fbuf; - int n, line, col, stride; - void *yuv, *image; - u16 *src; - u16 *dsty, *dstu, *dstv; - - if (pdev == NULL) - return -EFAULT; -#if defined(__KERNEL__) && defined(PWC_MAGIC) - if (pdev->magic != PWC_MAGIC) { - Err("pwc_decompress(): magic failed.\n"); - return -EFAULT; - } -#endif - - fbuf = pdev->read_frame; - if (fbuf == NULL) - return -EFAULT; - image = pdev->image_ptr[pdev->fill_image]; - if (!image) - return -EFAULT; - - yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ - - /* Raw format; that's easy... */ - if (pdev->vpalette == VIDEO_PALETTE_RAW) - { - memcpy(image, yuv, pdev->frame_size); - return 0; - } - - if (pdev->vbandlength == 0) { - /* Uncompressed mode. We copy the data into the output buffer, - using the viewport size (which may be larger than the image - size). Unfortunately we have to do a bit of byte stuffing - to get the desired output format/size. - */ - /* - * We do some byte shuffling here to go from the - * native format to YUV420P. - */ - src = (u16 *)yuv; - n = pdev->view.x * pdev->view.y; - - /* offset in Y plane */ - stride = pdev->view.x * pdev->offset.y + pdev->offset.x; - dsty = (u16 *)(image + stride); - - /* offsets in U/V planes */ - stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2; - dstu = (u16 *)(image + n + stride); - dstv = (u16 *)(image + n + n / 4 + stride); - - /* increment after each line */ - stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */ - - for (line = 0; line < pdev->image.y; line++) { - for (col = 0; col < pdev->image.x; col += 4) { - *dsty++ = *src++; - *dsty++ = *src++; - if (line & 1) - *dstv++ = *src++; - else - *dstu++ = *src++; - } - dsty += stride; - if (line & 1) - dstv += (stride >> 1); - else - dstu += (stride >> 1); - } - } - else { - /* Compressed; the decompressor routines will write the data - in planar format immediately. - */ - int flags; - - flags = PWCX_FLAG_PLANAR; - if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) - flags |= PWCX_FLAG_BAYER; - - if (pdev->decompressor) - pdev->decompressor->decompress( - &pdev->image, &pdev->view, &pdev->offset, - yuv, image, - flags, - pdev->decompress_data, pdev->vbandlength); - else - return -ENXIO; /* No such device or address: missing decompressor */ - } - return 0; -} - -/* Make sure these functions are available for the decompressor plugin - both when this code is compiled into the kernel or as as module. - */ - -EXPORT_SYMBOL_NOVERS(pwc_decompressor_version); -EXPORT_SYMBOL(pwc_register_decompressor); -EXPORT_SYMBOL(pwc_unregister_decompressor); diff --git a/drivers/usb/media/pwc-uncompress.h b/drivers/usb/media/pwc-uncompress.h deleted file mode 100644 index c3db3de8a..000000000 --- a/drivers/usb/media/pwc-uncompress.h +++ /dev/null @@ -1,84 +0,0 @@ -/* (C) 1999-2003 Nemosoft Unv. (webcam@smcc.demon.nl) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* This file is the bridge between the kernel module and the plugin; it - describes the structures and datatypes used in both modules. Any - significant change should be reflected by increasing the - pwc_decompressor_version major number. - */ -#ifndef PWC_UNCOMPRESS_H -#define PWC_UNCOMPRESS_H - -#include -#include -#include - -#include "pwc-ioctl.h" - -/* from pwc-dec.h */ -#define PWCX_FLAG_PLANAR 0x0001 -/* */ - - -#ifdef __cplusplus -extern "C" { -#endif - -/* The decompressor structure. - Every type of decompressor registers itself with the main module. - When a device is opened, it looks up the correct compressor, and - uses that when a compressed video mode is requested. - */ -struct pwc_decompressor -{ - int type; /* type of camera (645, 680, etc) */ - int table_size; /* memory needed */ - - void (* init)(int type, int release, void *buffer, void *table); /* Initialization routine; should be called after each set_video_mode */ - void (* exit)(void); /* Cleanup routine */ - void (* decompress)(struct pwc_coord *image, struct pwc_coord *view, - struct pwc_coord *offset, - void *src, void *dst, int flags, - void *table, int bandlength); - void (* lock)(void); /* make sure module cannot be unloaded */ - void (* unlock)(void); /* release lock on module */ - - struct list_head pwcd_list; -}; - - -/* Our structure version number. Is set to the version number major */ -extern const int pwc_decompressor_version; - -/* Adds decompressor to list, based on its 'type' field (which matches the 'type' field in pwc_device; ignores any double requests */ -extern void pwc_register_decompressor(struct pwc_decompressor *pwcd); -/* Removes decompressor, based on the type number */ -extern void pwc_unregister_decompressor(int type); -/* Returns pointer to decompressor struct, or NULL if it doesn't exist */ -extern struct pwc_decompressor *pwc_find_decompressor(int type); - -#ifdef CONFIG_USB_PWCX -/* If the decompressor is compiled in, we must call these manually */ -extern int usb_pwcx_init(void); -extern void usb_pwcx_exit(void); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/drivers/usb/media/pwc.h b/drivers/usb/media/pwc.h deleted file mode 100644 index 68143f435..000000000 --- a/drivers/usb/media/pwc.h +++ /dev/null @@ -1,271 +0,0 @@ -/* (C) 1999-2003 Nemosoft Unv. (webcam@smcc.demon.nl) - - 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 PWC_H -#define PWC_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pwc-uncompress.h" -#include "pwc-ioctl.h" - -/* Defines and structures for the Philips webcam */ -/* Used for checking memory corruption/pointer validation */ -#define PWC_MAGIC 0x89DC10ABUL -#undef PWC_MAGIC - -/* Turn some debugging options on/off */ -#define PWC_DEBUG 0 - -/* Trace certain actions in the driver */ -#define TRACE_MODULE 0x0001 -#define TRACE_PROBE 0x0002 -#define TRACE_OPEN 0x0004 -#define TRACE_READ 0x0008 -#define TRACE_MEMORY 0x0010 -#define TRACE_FLOW 0x0020 -#define TRACE_SIZE 0x0040 -#define TRACE_PWCX 0x0080 -#define TRACE_SEQUENCE 0x1000 - -#define Trace(R, A...) if (pwc_trace & R) printk(KERN_DEBUG PWC_NAME " " A) -#define Debug(A...) printk(KERN_DEBUG PWC_NAME " " A) -#define Info(A...) printk(KERN_INFO PWC_NAME " " A) -#define Err(A...) printk(KERN_ERR PWC_NAME " " A) - - -/* Defines for ToUCam cameras */ -#define TOUCAM_HEADER_SIZE 8 -#define TOUCAM_TRAILER_SIZE 4 - -#define FEATURE_MOTOR_PANTILT 0x0001 - -/* Version block */ -#define PWC_MAJOR 9 -#define PWC_MINOR 0 -#define PWC_VERSION "9.0.1" -#define PWC_NAME "pwc" - -/* Turn certain features on/off */ -#define PWC_INT_PIPE 0 - -/* Ignore errors in the first N frames, to allow for startup delays */ -#define FRAME_LOWMARK 5 - -/* Size and number of buffers for the ISO pipe. */ -#define MAX_ISO_BUFS 2 -#define ISO_FRAMES_PER_DESC 10 -#define ISO_MAX_FRAME_SIZE 960 -#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE) - -/* Frame buffers: contains compressed or uncompressed video data. */ -#define MAX_FRAMES 5 -/* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */ -#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE) - -/* Absolute maximum number of buffers available for mmap() */ -#define MAX_IMAGES 10 - -/* The following structures were based on cpia.h. Why reinvent the wheel? :-) */ -struct pwc_iso_buf -{ - void *data; - int length; - int read; - struct urb *urb; -}; - -/* intermediate buffers with raw data from the USB cam */ -struct pwc_frame_buf -{ - void *data; - volatile int filled; /* number of bytes filled */ - struct pwc_frame_buf *next; /* list */ -#if PWC_DEBUG - int sequence; /* Sequence number */ -#endif -}; - -struct pwc_device -{ - struct video_device *vdev; -#ifdef PWC_MAGIC - int magic; -#endif - /* Pointer to our usb_device */ - struct usb_device *udev; - - int type; /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */ - int release; /* release number */ - int features; /* feature bits */ - char serial[30]; /* serial number (string) */ - int error_status; /* set when something goes wrong with the cam (unplugged, USB errors) */ - int usb_init; /* set when the cam has been initialized over USB */ - - /*** Video data ***/ - int vopen; /* flag */ - int vendpoint; /* video isoc endpoint */ - int vcinterface; /* video control interface */ - int valternate; /* alternate interface needed */ - int vframes, vsize; /* frames-per-second & size (see PSZ_*) */ - int vpalette; /* palette: 420P, RAW or RGBBAYER */ - int vframe_count; /* received frames */ - int vframes_dumped; /* counter for dumped frames */ - int vframes_error; /* frames received in error */ - int vmax_packet_size; /* USB maxpacket size */ - int vlast_packet_size; /* for frame synchronisation */ - int visoc_errors; /* number of contiguous ISOC errors */ - int vcompression; /* desired compression factor */ - int vbandlength; /* compressed band length; 0 is uncompressed */ - char vsnapshot; /* snapshot mode */ - char vsync; /* used by isoc handler */ - char vmirror; /* for ToUCaM series */ - - int cmd_len; - unsigned char cmd_buf[13]; - - /* The image acquisition requires 3 to 4 steps: - 1. data is gathered in short packets from the USB controller - 2. data is synchronized and packed into a frame buffer - 3a. in case data is compressed, decompress it directly into image buffer - 3b. in case data is uncompressed, copy into image buffer with viewport - 4. data is transferred to the user process - - Note that MAX_ISO_BUFS != MAX_FRAMES != MAX_IMAGES.... - We have in effect a back-to-back-double-buffer system. - */ - /* 1: isoc */ - struct pwc_iso_buf sbuf[MAX_ISO_BUFS]; - char iso_init; - - /* 2: frame */ - struct pwc_frame_buf *fbuf; /* all frames */ - struct pwc_frame_buf *empty_frames, *empty_frames_tail; /* all empty frames */ - struct pwc_frame_buf *full_frames, *full_frames_tail; /* all filled frames */ - struct pwc_frame_buf *fill_frame; /* frame currently being filled */ - struct pwc_frame_buf *read_frame; /* frame currently read by user process */ - int frame_header_size, frame_trailer_size; - int frame_size; - int frame_total_size; /* including header & trailer */ - int drop_frames; -#if PWC_DEBUG - int sequence; /* Debugging aid */ -#endif - - /* 3: decompression */ - struct pwc_decompressor *decompressor; /* function block with decompression routines */ - void *decompress_data; /* private data for decompression engine */ - - /* 4: image */ - /* We have an 'image' and a 'view', where 'image' is the fixed-size image - as delivered by the camera, and 'view' is the size requested by the - program. The camera image is centered in this viewport, laced with - a gray or black border. view_min <= image <= view <= view_max; - */ - int image_mask; /* bitmask of supported sizes */ - struct pwc_coord view_min, view_max; /* minimum and maximum viewable sizes */ - struct pwc_coord abs_max; /* maximum supported size with compression */ - struct pwc_coord image, view; /* image and viewport size */ - struct pwc_coord offset; /* offset within the viewport */ - - void *image_data; /* total buffer, which is subdivided into ... */ - void *image_ptr[MAX_IMAGES]; /* ...several images... */ - int fill_image; /* ...which are rotated. */ - int len_per_image; /* length per image */ - int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */ - int image_used[MAX_IMAGES]; /* For MCAPTURE and SYNC */ - - struct semaphore modlock; /* to prevent races in video_open(), etc */ - spinlock_t ptrlock; /* for manipulating the buffer pointers */ - - /*** motorized pan/tilt feature */ - struct pwc_mpt_range angle_range; - int pan_angle; /* in degrees * 100 */ - int tilt_angle; /* absolute angle; 0,0 is home position */ - - /*** Misc. data ***/ - wait_queue_head_t frameq; /* When waiting for a frame to finish... */ -#if PWC_INT_PIPE - void *usb_int_handler; /* for the interrupt endpoint */ -#endif -}; - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Global variables */ -extern int pwc_trace; -extern int pwc_preferred_compression; - -/** functions in pwc-if.c */ -int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot); - -/** Functions in pwc-misc.c */ -/* sizes in pixels */ -extern struct pwc_coord pwc_image_sizes[PSZ_MAX]; - -int pwc_decode_size(struct pwc_device *pdev, int width, int height); -void pwc_construct(struct pwc_device *pdev); - -/** Functions in pwc-ctrl.c */ -/* Request a certain video mode. Returns < 0 if not possible */ -extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot); -/* Calculate the number of bytes per image (not frame) */ -extern void pwc_set_image_buffer_size(struct pwc_device *pdev); - -/* Various controls; should be obvious. Value 0..65535, or < 0 on error */ -extern int pwc_get_brightness(struct pwc_device *pdev); -extern int pwc_set_brightness(struct pwc_device *pdev, int value); -extern int pwc_get_contrast(struct pwc_device *pdev); -extern int pwc_set_contrast(struct pwc_device *pdev, int value); -extern int pwc_get_gamma(struct pwc_device *pdev); -extern int pwc_set_gamma(struct pwc_device *pdev, int value); -extern int pwc_get_saturation(struct pwc_device *pdev); -extern int pwc_set_saturation(struct pwc_device *pdev, int value); -extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); -extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value); -extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); - -/* Power down or up the camera; not supported by all models */ -extern int pwc_camera_power(struct pwc_device *pdev, int power); - -/* Private ioctl()s; see pwc-ioctl.h */ -extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); - - -/** pwc-uncompress.c */ -/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ -extern int pwc_decompress(struct pwc_device *pdev); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/drivers/usb/media/pwc_kiara.h b/drivers/usb/media/pwc_kiara.h deleted file mode 100644 index 0b13422ba..000000000 --- a/drivers/usb/media/pwc_kiara.h +++ /dev/null @@ -1,270 +0,0 @@ - /* SQCIF */ - { - /* 5 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 10 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 15 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 20 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 25 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 30 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - }, - /* QSIF */ - { - /* 5 fps */ - { - {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, - {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, - {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, - {1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}}, - }, - /* 10 fps */ - { - {2, 291, 0, {0x1C, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0x01, 0x80}}, - {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}}, - {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}}, - {1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}}, - }, - /* 15 fps */ - { - {3, 437, 0, {0x1B, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x01, 0x80}}, - {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}}, - {2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}}, - {1, 192, 420, {0x13, 0xF4, 0x30, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x18, 0xC0, 0x00, 0x80}}, - }, - /* 20 fps */ - { - {4, 589, 0, {0x1A, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4D, 0x02, 0x80}}, - {3, 448, 730, {0x12, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xC0, 0x01, 0x80}}, - {2, 292, 476, {0x12, 0xF4, 0x30, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0x01, 0x80}}, - {1, 192, 312, {0x12, 0xF4, 0x50, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0x00, 0x80}}, - }, - /* 25 fps */ - { - {5, 703, 0, {0x19, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x02, 0x80}}, - {3, 447, 610, {0x11, 0xF4, 0x30, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x28, 0xBF, 0x01, 0x80}}, - {2, 292, 398, {0x11, 0xF4, 0x50, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x28, 0x24, 0x01, 0x80}}, - {1, 193, 262, {0x11, 0xF4, 0x50, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x28, 0xC1, 0x00, 0x80}}, - }, - /* 30 fps */ - { - {8, 874, 0, {0x18, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x6A, 0x03, 0x80}}, - {5, 704, 730, {0x10, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x28, 0xC0, 0x02, 0x80}}, - {3, 448, 492, {0x10, 0xF4, 0x30, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x28, 0xC0, 0x01, 0x80}}, - {2, 292, 320, {0x10, 0xF4, 0x50, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x28, 0x24, 0x01, 0x80}}, - }, - }, - /* QCIF */ - { - /* 5 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 10 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 15 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 20 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 25 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 30 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - }, - /* SIF */ - { - /* 5 fps */ - { - {4, 582, 0, {0x0D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x02, 0x80}}, - {3, 387, 1276, {0x05, 0xF4, 0x30, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x01, 0x80}}, - {2, 291, 960, {0x05, 0xF4, 0x30, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0x01, 0x80}}, - {1, 191, 630, {0x05, 0xF4, 0x50, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x18, 0xBF, 0x00, 0x80}}, - }, - /* 10 fps */ - { - {0, }, - {6, 775, 1278, {0x04, 0xF4, 0x30, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x03, 0x80}}, - {3, 447, 736, {0x04, 0xF4, 0x30, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x28, 0xBF, 0x01, 0x80}}, - {2, 292, 480, {0x04, 0xF4, 0x70, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x28, 0x24, 0x01, 0x80}}, - }, - /* 15 fps */ - { - {0, }, - {9, 955, 1050, {0x03, 0xF4, 0x30, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x03, 0x80}}, - {4, 592, 650, {0x03, 0xF4, 0x30, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x50, 0x02, 0x80}}, - {3, 448, 492, {0x03, 0xF4, 0x50, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x38, 0xC0, 0x01, 0x80}}, - }, - /* 20 fps */ - { - {0, }, - {9, 958, 782, {0x02, 0xF4, 0x30, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x03, 0x80}}, - {5, 703, 574, {0x02, 0xF4, 0x50, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x02, 0x80}}, - {3, 446, 364, {0x02, 0xF4, 0x90, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x38, 0xBE, 0x01, 0x80}}, - }, - /* 25 fps */ - { - {0, }, - {9, 958, 654, {0x01, 0xF4, 0x30, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x03, 0x80}}, - {6, 776, 530, {0x01, 0xF4, 0x50, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x03, 0x80}}, - {4, 592, 404, {0x01, 0xF4, 0x70, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x48, 0x50, 0x02, 0x80}}, - }, - /* 30 fps */ - { - {0, }, - {9, 957, 526, {0x00, 0xF4, 0x50, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x03, 0x80}}, - {6, 775, 426, {0x00, 0xF4, 0x70, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x03, 0x80}}, - {4, 590, 324, {0x00, 0x7A, 0x88, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x50, 0x4E, 0x02, 0x80}}, - }, - }, - /* CIF */ - { - /* 5 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 10 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 15 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 20 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 25 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 30 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - }, - /* VGA */ - { - /* 5 fps */ - { - {0, }, - {6, 773, 1272, {0x25, 0xF4, 0x30, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}}, - {4, 592, 976, {0x25, 0xF4, 0x50, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x02, 0x80}}, - {3, 448, 738, {0x25, 0xF4, 0x90, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x01, 0x80}}, - }, - /* 10 fps */ - { - {0, }, - {9, 956, 788, {0x24, 0xF4, 0x70, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x03, 0x80}}, - {6, 776, 640, {0x24, 0xF4, 0xB0, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x03, 0x80}}, - {4, 592, 488, {0x24, 0x7A, 0xE8, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x02, 0x80}}, - }, - /* 15 fps */ - { - {0, }, - {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}}, - {9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}}, - {8, 895, 492, {0x23, 0x7A, 0xE8, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x03, 0x80}}, - }, - /* 20 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 25 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 30 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - }, diff --git a/drivers/usb/media/pwc_nala.h b/drivers/usb/media/pwc_nala.h deleted file mode 100644 index e6c5cb69d..000000000 --- a/drivers/usb/media/pwc_nala.h +++ /dev/null @@ -1,66 +0,0 @@ - /* SQCIF */ - { - {0, 0, {0x04, 0x01, 0x03}}, - {8, 0, {0x05, 0x01, 0x03}}, - {7, 0, {0x08, 0x01, 0x03}}, - {7, 0, {0x0A, 0x01, 0x03}}, - {6, 0, {0x0C, 0x01, 0x03}}, - {5, 0, {0x0F, 0x01, 0x03}}, - {4, 0, {0x14, 0x01, 0x03}}, - {3, 0, {0x18, 0x01, 0x03}}, - }, - /* QSIF */ - { - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - }, - /* QCIF */ - { - {0, 0, {0x04, 0x01, 0x02}}, - {8, 0, {0x05, 0x01, 0x02}}, - {7, 0, {0x08, 0x01, 0x02}}, - {6, 0, {0x0A, 0x01, 0x02}}, - {5, 0, {0x0C, 0x01, 0x02}}, - {4, 0, {0x0F, 0x01, 0x02}}, - {1, 0, {0x14, 0x01, 0x02}}, - {1, 0, {0x18, 0x01, 0x02}}, - }, - /* SIF */ - { - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - }, - /* CIF */ - { - {4, 0, {0x04, 0x01, 0x01}}, - {7, 1, {0x05, 0x03, 0x01}}, - {6, 1, {0x08, 0x03, 0x01}}, - {4, 1, {0x0A, 0x03, 0x01}}, - {3, 1, {0x0C, 0x03, 0x01}}, - {2, 1, {0x0F, 0x03, 0x01}}, - {0}, - {0}, - }, - /* VGA */ - { - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - }, diff --git a/drivers/usb/media/pwc_timon.h b/drivers/usb/media/pwc_timon.h deleted file mode 100644 index 0cc20b807..000000000 --- a/drivers/usb/media/pwc_timon.h +++ /dev/null @@ -1,270 +0,0 @@ - /* SQCIF */ - { - /* 5 fps */ - { - {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, - {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, - {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, - {1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}}, - }, - /* 10 fps */ - { - {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, - {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, - {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, - {2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}}, - }, - /* 15 fps */ - { - {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, - {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, - {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, - {3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}}, - }, - /* 20 fps */ - { - {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, - {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, - {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, - {4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}}, - }, - /* 25 fps */ - { - {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, - {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, - {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, - {5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}}, - }, - /* 30 fps */ - { - {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, - {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, - {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, - {7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}}, - }, - }, - /* QSIF */ - { - /* 5 fps */ - { - {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, - {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, - {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, - {1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}}, - }, - /* 10 fps */ - { - {2, 291, 0, {0x2C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0xA1, 0xC0, 0x02}}, - {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, - {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, - {1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, - }, - /* 15 fps */ - { - {3, 437, 0, {0x2B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x6D, 0xC0, 0x02}}, - {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, - {2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, - {1, 191, 420, {0x2B, 0xF4, 0x0D, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x08, 0xBF, 0xF4, 0xC0, 0x02}}, - }, - /* 20 fps */ - { - {4, 588, 0, {0x2A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4C, 0x52, 0xC0, 0x02}}, - {3, 447, 730, {0x2A, 0xF4, 0x05, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, - {2, 292, 476, {0x2A, 0xF4, 0x0D, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0xA1, 0xC0, 0x02}}, - {1, 192, 312, {0x2A, 0xF4, 0x1D, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}}, - }, - /* 25 fps */ - { - {5, 703, 0, {0x29, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x42, 0xC0, 0x02}}, - {3, 447, 610, {0x29, 0xF4, 0x05, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, - {2, 292, 398, {0x29, 0xF4, 0x0D, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}}, - {1, 192, 262, {0x29, 0xF4, 0x25, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}}, - }, - /* 30 fps */ - { - {8, 873, 0, {0x28, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x69, 0x37, 0xC0, 0x02}}, - {5, 704, 774, {0x28, 0xF4, 0x05, 0x18, 0x21, 0x17, 0x59, 0x0F, 0x18, 0xC0, 0x42, 0xC0, 0x02}}, - {3, 448, 492, {0x28, 0xF4, 0x05, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x18, 0xC0, 0x69, 0xC0, 0x02}}, - {2, 291, 320, {0x28, 0xF4, 0x1D, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}}, - }, - }, - /* QCIF */ - { - /* 5 fps */ - { - {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, - {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, - {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, - {1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}}, - }, - /* 10 fps */ - { - {3, 385, 0, {0x0C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x81, 0x79, 0xC0, 0x02}}, - {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, - {2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}}, - {1, 194, 532, {0x0C, 0xF4, 0x05, 0x10, 0x9A, 0x0F, 0xBE, 0x1B, 0x08, 0xC2, 0xF0, 0xC0, 0x02}}, - }, - /* 15 fps */ - { - {4, 577, 0, {0x0B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x41, 0x52, 0xC0, 0x02}}, - {3, 447, 818, {0x0B, 0xF4, 0x05, 0x19, 0x89, 0x18, 0xAD, 0x0F, 0x10, 0xBF, 0x69, 0xC0, 0x02}}, - {2, 292, 534, {0x0B, 0xF4, 0x05, 0x10, 0xA3, 0x0F, 0xC7, 0x19, 0x10, 0x24, 0xA1, 0xC0, 0x02}}, - {1, 195, 356, {0x0B, 0xF4, 0x15, 0x0B, 0x11, 0x0A, 0x35, 0x1E, 0x10, 0xC3, 0xF0, 0xC0, 0x02}}, - }, - /* 20 fps */ - { - {6, 776, 0, {0x0A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x3F, 0xC0, 0x02}}, - {4, 591, 804, {0x0A, 0xF4, 0x05, 0x19, 0x1E, 0x18, 0x42, 0x0F, 0x18, 0x4F, 0x4E, 0xC0, 0x02}}, - {3, 447, 608, {0x0A, 0xF4, 0x05, 0x12, 0xFD, 0x12, 0x21, 0x15, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, - {2, 291, 396, {0x0A, 0xF4, 0x15, 0x0C, 0x5E, 0x0B, 0x82, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}}, - }, - /* 25 fps */ - { - {9, 928, 0, {0x09, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA0, 0x33, 0xC0, 0x02}}, - {5, 703, 800, {0x09, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x10, 0x18, 0xBF, 0x42, 0xC0, 0x02}}, - {3, 447, 508, {0x09, 0xF4, 0x0D, 0x0F, 0xD2, 0x0E, 0xF6, 0x1B, 0x18, 0xBF, 0x69, 0xC0, 0x02}}, - {2, 292, 332, {0x09, 0xF4, 0x1D, 0x0A, 0x5A, 0x09, 0x7E, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}}, - }, - /* 30 fps */ - { - {0, }, - {9, 956, 876, {0x08, 0xF4, 0x05, 0x1B, 0x58, 0x1A, 0x7C, 0x0E, 0x20, 0xBC, 0x33, 0x10, 0x02}}, - {4, 592, 542, {0x08, 0xF4, 0x05, 0x10, 0xE4, 0x10, 0x08, 0x17, 0x20, 0x50, 0x4E, 0x10, 0x02}}, - {2, 291, 266, {0x08, 0xF4, 0x25, 0x08, 0x48, 0x07, 0x6C, 0x1E, 0x20, 0x23, 0xA1, 0x10, 0x02}}, - }, - }, - /* SIF */ - { - /* 5 fps */ - { - {4, 582, 0, {0x35, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x52, 0x60, 0x02}}, - {3, 387, 1276, {0x35, 0xF4, 0x05, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x79, 0x60, 0x02}}, - {2, 291, 960, {0x35, 0xF4, 0x0D, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0xA1, 0x60, 0x02}}, - {1, 191, 630, {0x35, 0xF4, 0x1D, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x08, 0xBF, 0xF4, 0x60, 0x02}}, - }, - /* 10 fps */ - { - {0, }, - {6, 775, 1278, {0x34, 0xF4, 0x05, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x3F, 0x10, 0x02}}, - {3, 447, 736, {0x34, 0xF4, 0x15, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x18, 0xBF, 0x69, 0x10, 0x02}}, - {2, 291, 480, {0x34, 0xF4, 0x2D, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x18, 0x23, 0xA1, 0x10, 0x02}}, - }, - /* 15 fps */ - { - {0, }, - {9, 955, 1050, {0x33, 0xF4, 0x05, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x33, 0x10, 0x02}}, - {4, 591, 650, {0x33, 0xF4, 0x15, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x4F, 0x4E, 0x10, 0x02}}, - {3, 448, 492, {0x33, 0xF4, 0x25, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x28, 0xC0, 0x69, 0x10, 0x02}}, - }, - /* 20 fps */ - { - {0, }, - {9, 958, 782, {0x32, 0xF4, 0x0D, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x33, 0xD0, 0x02}}, - {5, 703, 574, {0x32, 0xF4, 0x1D, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x42, 0xD0, 0x02}}, - {3, 446, 364, {0x32, 0xF4, 0x3D, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x30, 0xBE, 0x69, 0xD0, 0x02}}, - }, - /* 25 fps */ - { - {0, }, - {9, 958, 654, {0x31, 0xF4, 0x15, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x33, 0x90, 0x02}}, - {6, 776, 530, {0x31, 0xF4, 0x25, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x3F, 0x90, 0x02}}, - {4, 592, 404, {0x31, 0xF4, 0x35, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x38, 0x50, 0x4E, 0x90, 0x02}}, - }, - /* 30 fps */ - { - {0, }, - {9, 957, 526, {0x30, 0xF4, 0x25, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x33, 0x60, 0x02}}, - {6, 775, 426, {0x30, 0xF4, 0x35, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x3F, 0x60, 0x02}}, - {4, 590, 324, {0x30, 0x7A, 0x4B, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x40, 0x4E, 0x52, 0x60, 0x02}}, - }, - }, - /* CIF */ - { - /* 5 fps */ - { - {6, 771, 0, {0x15, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x3F, 0x80, 0x02}}, - {4, 465, 1278, {0x15, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x03, 0x18, 0xD1, 0x65, 0x80, 0x02}}, - {2, 291, 800, {0x15, 0xF4, 0x15, 0x18, 0xF4, 0x17, 0x3C, 0x05, 0x18, 0x23, 0xA1, 0x80, 0x02}}, - {1, 193, 528, {0x15, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x18, 0xC1, 0xF4, 0x80, 0x02}}, - }, - /* 10 fps */ - { - {0, }, - {9, 932, 1278, {0x14, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x04, 0x30, 0xA4, 0x33, 0x10, 0x02}}, - {4, 591, 812, {0x14, 0xF4, 0x15, 0x19, 0x56, 0x17, 0x9E, 0x06, 0x28, 0x4F, 0x4E, 0x10, 0x02}}, - {2, 291, 400, {0x14, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x28, 0x23, 0xA1, 0x10, 0x02}}, - }, - /* 15 fps */ - { - {0, }, - {9, 956, 876, {0x13, 0xF4, 0x0D, 0x1B, 0x58, 0x19, 0xA0, 0x05, 0x38, 0xBC, 0x33, 0x60, 0x02}}, - {5, 703, 644, {0x13, 0xF4, 0x1D, 0x14, 0x1C, 0x12, 0x64, 0x08, 0x38, 0xBF, 0x42, 0x60, 0x02}}, - {3, 448, 410, {0x13, 0xF4, 0x3D, 0x0C, 0xC4, 0x0B, 0x0C, 0x0E, 0x38, 0xC0, 0x69, 0x60, 0x02}}, - }, - /* 20 fps */ - { - {0, }, - {9, 956, 650, {0x12, 0xF4, 0x1D, 0x14, 0x4A, 0x12, 0x92, 0x09, 0x48, 0xBC, 0x33, 0x10, 0x03}}, - {6, 776, 528, {0x12, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x40, 0x08, 0x3F, 0x10, 0x03}}, - {4, 591, 402, {0x12, 0xF4, 0x3D, 0x0C, 0x8F, 0x0A, 0xD7, 0x0E, 0x40, 0x4F, 0x4E, 0x10, 0x03}}, - }, - /* 25 fps */ - { - {0, }, - {9, 956, 544, {0x11, 0xF4, 0x25, 0x10, 0xF4, 0x0F, 0x3C, 0x0A, 0x48, 0xBC, 0x33, 0xC0, 0x02}}, - {7, 840, 478, {0x11, 0xF4, 0x2D, 0x0E, 0xEB, 0x0D, 0x33, 0x0B, 0x48, 0x48, 0x3B, 0xC0, 0x02}}, - {5, 703, 400, {0x11, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x48, 0xBF, 0x42, 0xC0, 0x02}}, - }, - /* 30 fps */ - { - {0, }, - {9, 956, 438, {0x10, 0xF4, 0x35, 0x0D, 0xAC, 0x0B, 0xF4, 0x0D, 0x50, 0xBC, 0x33, 0x10, 0x02}}, - {7, 838, 384, {0x10, 0xF4, 0x45, 0x0B, 0xFD, 0x0A, 0x45, 0x0F, 0x50, 0x46, 0x3B, 0x10, 0x02}}, - {6, 773, 354, {0x10, 0x7A, 0x4B, 0x0B, 0x0C, 0x09, 0x80, 0x10, 0x50, 0x05, 0x3F, 0x10, 0x02}}, - }, - }, - /* VGA */ - { - /* 5 fps */ - { - {0, }, - {6, 773, 1272, {0x1D, 0xF4, 0x15, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x3F, 0x10, 0x02}}, - {4, 592, 976, {0x1D, 0xF4, 0x25, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x4E, 0x10, 0x02}}, - {3, 448, 738, {0x1D, 0xF4, 0x3D, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x69, 0x10, 0x02}}, - }, - /* 10 fps */ - { - {0, }, - {9, 956, 788, {0x1C, 0xF4, 0x35, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x33, 0x10, 0x02}}, - {6, 776, 640, {0x1C, 0x7A, 0x53, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x3F, 0x10, 0x02}}, - {4, 592, 488, {0x1C, 0x7A, 0x6B, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x4E, 0x10, 0x02}}, - }, - /* 15 fps */ - { - {0, }, - {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}}, - {9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}}, - {8, 895, 492, {0x1B, 0x7A, 0x6B, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x37, 0x80, 0x02}}, - }, - /* 20 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 25 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - /* 30 fps */ - { - {0, }, - {0, }, - {0, }, - {0, }, - }, - }, -- 2.47.0