+++ /dev/null
-/*
- * linux/drivers/char/busmouse.c
- *
- * Copyright (C) 1995 - 1998 Russell King <linux@arm.linux.org.uk>
- * Protocol taken from original busmouse.c
- * read() waiting taken from psaux.c
- *
- * Medium-level interface for quadrature or bus mice.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/miscdevice.h>
-#include <linux/random.h>
-#include <linux/init.h>
-#include <linux/smp_lock.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-
-#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");
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- i2c-sensor.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl> and
- Mark D. Studebaker <mdsxyz123@yahoo.com>
-
- 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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/sysctl.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <asm/uaccess.h>
-
-
-/* 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 <frodol@dds.nl>");
-MODULE_DESCRIPTION("i2c-sensor driver");
-MODULE_LICENSE("GPL");
+++ /dev/null
-/*
- * 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;
-}
-
+++ /dev/null
-#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
+++ /dev/null
-#!/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
+++ /dev/null
-/*
- * 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 <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <asm/io.h>
-
-#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);
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
+++ /dev/null
-#ifndef ISENSE_H_INCLUDED
-#define ISENSE_H_INCLUDED
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#ifdef __KERNEL__
-#include <linux/types.h> /* needed for u8, etc. */
-#include <linux/string.h> /* needed for strcat */
-#include <linux/kernel.h> /* 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
-
+++ /dev/null
-/*
- * 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 <linux/types.h>
-#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
+++ /dev/null
-
-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 */
-};
-
+++ /dev/null
-/*
- * 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 <Juha.Sievanen@cs.Helsinki.FI>
- * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
- * Deepak Saxena <deepak@plexity.net>
- * Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
- * Alan Cox <alan@redhat.com>:
- * Ported to Linux 2.5.
- * Markus Lidel <Markus.Lidel@shadowconnect.com>:
- * Minor fixes for 2.6.
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-
-#include <linux/i2o.h>
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-
-#include <linux/bitops.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <asm/semaphore.h>
-#include <linux/completion.h>
-#include <linux/workqueue.h>
-
-#include <asm/io.h>
-#include <linux/reboot.h>
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#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;i<MAX_I2O_MODULES;i++)
- {
- if(i2o_handlers[i]==NULL)
- {
- h->context = 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;i<MAX_I2O_CONTROLLERS;i++)
- {
- if(i2o_controllers[i]==NULL)
- {
- c->dlct = (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<count;i++)
- {
- printk(KERN_INFO "Adapter %08X: ", rows[0]);
- p=(u8 *)(rows+1);
- d=(u8 *)(rows+2);
- state=p[1]<<8|p[0];
-
- printk("TID %04X:[", state&0xFFF);
- state>>=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;i<max;i++)
- {
- d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
- if(d==NULL)
- {
- printk(KERN_CRIT "i2o_core: Out of memory for I2O device data.\n");
- return -ENOMEM;
- }
-
- d->controller = 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)<HZ);
-
- if(m==0xFFFFFFFF)
- {
- printk(KERN_ERR "%s: Timeout waiting for message frame!\n",
- c->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);
+++ /dev/null
-/*
- * 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: <source@mvista.com>
- *
- * 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 <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <platforms/chestnut.h>
-
-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("<source@mvista.com>");
-MODULE_LICENSE("GPL");
+++ /dev/null
-/***********************************************************************
- * 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 <linux/version.h>
-
-#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 */
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/* 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 <asm/uaccess.h>
-#endif
-#include <asm/errno.h>
-#include <linux/version.h>
-
-#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;
-}
-
-
-
+++ /dev/null
-/* 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 <linux/errno.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <asm/io.h>
-
-#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. <webcam@smcc.demon.nl>");
-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);
-
+++ /dev/null
-#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
+++ /dev/null
-/* 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 <linux/slab.h>
-
-#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;
-}
-
-
+++ /dev/null
-/* 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 <asm/current.h>
-#include <asm/types.h>
-// #include <linux/sched.h>
-
-#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);
+++ /dev/null
-/* (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 <linux/config.h>
-#include <linux/linkage.h>
-#include <linux/list.h>
-
-#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
+++ /dev/null
-/* (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 <linux/version.h>
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/spinlock.h>
-#include <linux/videodev.h>
-#include <linux/wait.h>
-#include <linux/smp_lock.h>
-#include <asm/semaphore.h>
-#include <asm/errno.h>
-
-#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
+++ /dev/null
- /* 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, },
- },
- },
+++ /dev/null
- /* 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},
- },
+++ /dev/null
- /* 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, },
- },
- },