/*
* I2O Configuration Interface Driver
*
* (C) Copyright 1999-2002 Red Hat
*
* Written by Alan Cox, Building Number Three Ltd
*
* Fixes/additions:
* Deepak Saxena (04/20/1999):
* Added basic ioctl() support
* Deepak Saxena (06/07/1999):
* Added software download ioctl (still testing)
* Auvo H�kkinen (09/10/1999):
* Changes to i2o_cfg_reply(), ioctl_parms()
* Added ioct_validate()
* Taneli V�h�kangas (09/30/1999):
* Fixed ioctl_swdl()
* Taneli V�h�kangas (10/04/1999):
* Changed ioctl_swdl(), implemented ioctl_swul() and ioctl_swdel()
* Deepak Saxena (11/18/1999):
* Added event managmenet support
* Alan Cox <alan@redhat.com>:
* 2.4 rewrite ported to 2.5
* Markus Lidel <Markus.Lidel@shadowconnect.com>:
* Added pass-thru support for Adaptec's raidutils
*
* 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.
*/
#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/miscdevice.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
#include <linux/ioctl32.h>
#include <linux/compat.h>
#include <linux/syscalls.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#define OSM_NAME "config-osm"
#define OSM_VERSION "$Rev$"
#define OSM_DESCRIPTION "I2O Configuration OSM"
extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd,
unsigned long arg);
static spinlock_t i2o_config_lock;
#define MODINC(x,y) ((x) = ((x) + 1) % (y))
struct sg_simple_element {
u32 flag_count;
u32 addr_bus;
};
struct i2o_cfg_info {
struct file *fp;
struct fasync_struct *fasync;
struct i2o_evt_info event_q[I2O_EVT_Q_LEN];
u16 q_in; // Queue head index
u16 q_out; // Queue tail index
u16 q_len; // Queue length
u16 q_lost; // Number of lost events
ulong q_id; // Event queue ID...used as tx_context
struct i2o_cfg_info *next;
};
static struct i2o_cfg_info *open_files = NULL;
static ulong i2o_cfg_info_id = 0;
/*
* Each of these describes an i2o message handler. They are
* multiplexed by the i2o_core code
*/
static struct i2o_driver i2o_config_driver = {
.name = OSM_NAME
};
static int i2o_cfg_getiops(unsigned long arg)
{
struct i2o_controller *c;
u8 __user *user_iop_table = (void __user *)arg;
u8 tmp[MAX_I2O_CONTROLLERS];
int ret = 0;
memset(tmp, 0, MAX_I2O_CONTROLLERS);
list_for_each_entry(c, &i2o_controllers, list)
tmp[c->unit] = 1;
if (copy_to_user(user_iop_table, tmp, MAX_I2O_CONTROLLERS))
ret = -EFAULT;
return ret;
};
static int i2o_cfg_gethrt(unsigned long arg)
{
struct i2o_controller *c;
struct i2o_cmd_hrtlct __user *cmd = (struct i2o_cmd_hrtlct __user *)arg;
struct i2o_cmd_hrtlct kcmd;
i2o_hrt *hrt;
int len;
u32 reslen;
int ret = 0;
if (copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_hrtlct)))
return -EFAULT;
if (get_user(reslen, kcmd.reslen) < 0)
return -EFAULT;
if (kcmd.resbuf == NULL)
return -EFAULT;
c = i2o_find_iop(kcmd.iop);
i