Release 4.11 drivers/scsi/dpt_i2o.c
/***************************************************************************
dpti.c - description
-------------------
begin : Thu Sep 7 2000
copyright : (C) 2000 by Adaptec
July 30, 2001 First version being submitted
for inclusion in the kernel. V2.4
See Documentation/scsi/dpti.txt for history, notes, license info
and credits
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/***************************************************************************
* Sat Dec 20 2003 Go Taniguchi <go@turbolinux.co.jp>
- Support 2.6 kernel and DMA-mapping
- ioctl fix for raid tools
- use schedule_timeout in long long loop
**************************************************************************/
/*#define DEBUG 1 */
/*#define UARTDELAY 1 */
#include <linux/module.h>
MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
////////////////////////////////////////////////////////////////
#include <linux/ioctl.h> /* For SCSI-Passthrough */
#include <linux/uaccess.h>
#include <linux/stat.h>
#include <linux/slab.h> /* for kmalloc() */
#include <linux/pci.h> /* for PCI support */
#include <linux/proc_fs.h>
#include <linux/blkdev.h>
#include <linux/delay.h> /* for udelay */
#include <linux/interrupt.h>
#include <linux/kernel.h> /* for printk */
#include <linux/sched.h>
#include <linux/reboot.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/mutex.h>
#include <asm/processor.h> /* for boot_cpu_data */
#include <asm/pgtable.h>
#include <asm/io.h> /* for virt_to_bus, etc. */
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include "dpt/dptsig.h"
#include "dpti.h"
/*============================================================================
* Create a binary signature - this is read by dptsig
* Needed for our management apps
*============================================================================
*/
static DEFINE_MUTEX(adpt_mutex);
static dpt_sig_S DPTI_sig = {
{'d', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION,
#ifdef __i386__
PROC_INTEL, PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
#elif defined(__ia64__)
PROC_INTEL, PROC_IA64,
#elif defined(__sparc__)
PROC_ULTRASPARC, PROC_ULTRASPARC,
#elif defined(__alpha__)
PROC_ALPHA, PROC_ALPHA,
#else
(-1),(-1),
#endif
FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
DPT_MONTH, DPT_DAY, DPT_YEAR, "Adaptec Linux I2O RAID Driver"
};
/*============================================================================
* Globals
*============================================================================
*/
static DEFINE_MUTEX(adpt_configuration_lock);
static struct i2o_sys_tbl *sys_tbl;
static dma_addr_t sys_tbl_pa;
static int sys_tbl_ind;
static int sys_tbl_len;
static adpt_hba* hba_chain = NULL;
static int hba_count = 0;
static struct class *adpt_sysfs_class;
static long adpt_unlocked_ioctl(struct file *, unsigned int, unsigned long);
#ifdef CONFIG_COMPAT
static long compat_adpt_ioctl(struct file *, unsigned int, unsigned long);
#endif
static const struct file_operations adpt_fops = {
.unlocked_ioctl = adpt_unlocked_ioctl,
.open = adpt_open,
.release = adpt_close,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_adpt_ioctl,
#endif
.llseek = noop_llseek,
};
/* Structures and definitions for synchronous message posting.
* See adpt_i2o_post_wait() for description
* */
struct adpt_i2o_post_wait_data
{
int status;
u32 id;
adpt_wait_queue_head_t *wq;
struct adpt_i2o_post_wait_data *next;
};
static struct adpt_i2o_post_wait_data *adpt_post_wait_queue = NULL;
static u32 adpt_post_wait_id = 0;
static DEFINE_SPINLOCK(adpt_post_wait_lock);
/*============================================================================
* Functions
*============================================================================
*/
static inline int dpt_dma64(adpt_hba *pHba)
{
return (sizeof(dma_addr_t) > 4 && (pHba)->dma64);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Miquel van Smoorenburg | 27 | 100.00% | 1 | 100.00% |
Total | 27 | 100.00% | 1 | 100.00% |
static inline u32 dma_high(dma_addr_t addr)
{
return upper_32_bits(addr);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Miquel van Smoorenburg | 16 | 100.00% | 1 | 100.00% |
Total | 16 | 100.00% | 1 | 100.00% |
static inline u32 dma_low(dma_addr_t addr)
{
return (u32)addr;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Miquel van Smoorenburg | 16 | 100.00% | 1 | 100.00% |
Total | 16 | 100.00% | 1 | 100.00% |
static u8 adpt_read_blink_led(adpt_hba* host)
{
if (host->FwDebugBLEDflag_P) {
if( readb(host->FwDebugBLEDflag_P) == 0xbc ){
return readb(host->FwDebugBLEDvalue_P);
}
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 42 | 100.00% | 1 | 100.00% |
Total | 42 | 100.00% | 1 | 100.00% |
/*============================================================================
* Scsi host template interface functions
*============================================================================
*/
#ifdef MODULE
static struct pci_device_id dptids[] = {
{ PCI_DPT_VENDOR_ID, PCI_DPT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
{ PCI_DPT_VENDOR_ID, PCI_DPT_RAPTOR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
{ 0, }
};
#endif
MODULE_DEVICE_TABLE(pci,dptids);
static int adpt_detect(struct scsi_host_template* sht)
{
struct pci_dev *pDev = NULL;
adpt_hba *pHba;
adpt_hba *next;
PINFO("Detecting Adaptec I2O RAID controllers...\n");
/* search for all Adatpec I2O RAID cards */
while ((pDev = pci_get_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
if(pDev->device == PCI_DPT_DEVICE_ID ||
pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
if(adpt_install_hba(sht, pDev) ){
PERROR("Could not Init an I2O RAID device\n");
PERROR("Will not try to detect others.\n");
return hba_count-1;
}
pci_dev_get(pDev);
}
}
/* In INIT state, Activate IOPs */
for (pHba = hba_chain; pHba; pHba = next) {
next = pHba->next;
// Activate does get status , init outbound, and get hrt
if (adpt_i2o_activate_hba(pHba) < 0) {
adpt_i2o_delete_hba(pHba);
}
}
/* Active IOPs in HOLD state */
rebuild_sys_tab:
if (hba_chain == NULL)
return 0;
/*
* If build_sys_table fails, we kill everything and bail
* as we can't init the IOPs w/o a system table
*/
if (adpt_i2o_build_sys_table() < 0) {
adpt_i2o_sys_shutdown();
return 0;
}
PDEBUG("HBA's in HOLD state\n");
/* If IOP don't get online, we need to rebuild the System table */
for (pHba = hba_chain; pHba; pHba = pHba->next) {
if (adpt_i2o_online_hba(pHba) < 0) {
adpt_i2o_delete_hba(pHba);
goto rebuild_sys_tab;
}
}
/* Active IOPs now in OPERATIONAL state */
PDEBUG("HBA's in OPERATIONAL state\n");
printk("dpti: If you have a lot of devices this could take a few minutes.\n");
for (pHba = hba_chain; pHba; pHba = next) {
next = pHba->next;
printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
if (adpt_i2o_lct_get(pHba) < 0){
adpt_i2o_delete_hba(pHba);
continue;
}
if (adpt_i2o_parse_lct(pHba) < 0){
adpt_i2o_delete_hba(pHba);
continue;
}
adpt_inquiry(pHba);
}
adpt_sysfs_class = class_create(THIS_MODULE, "dpt_i2o");
if (IS_ERR(adpt_sysfs_class)) {
printk(KERN_WARNING"dpti: unable to create dpt_i2o class\n");
adpt_sysfs_class = NULL;
}
for (pHba = hba_chain; pHba; pHba = next) {
next = pHba->next;
if (adpt_scsi_host_alloc(pHba, sht) < 0){
adpt_i2o_delete_hba(pHba);
continue;
}
pHba->initialized = TRUE;
pHba->state &= ~DPTI_STATE_RESET;
if (adpt_sysfs_class) {
struct device *dev = device_create(adpt_sysfs_class,
NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), NULL,
"dpti%d", pHba->unit);
if (IS_ERR(dev)) {
printk(KERN_WARNING"dpti%d: unable to "
"create device in dpt_i2o class\n",
pHba->unit);
}
}
}
// Register our control device node
// nodes will need to be created in /dev to access this
// the nodes can not be created from within the driver
if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
adpt_i2o_sys_shutdown();
return 0;
}
return hba_count;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 325 | 72.87% | 1 | 12.50% |
Miquel van Smoorenburg | 81 | 18.16% | 2 | 25.00% |
Dan Carpenter | 22 | 4.93% | 1 | 12.50% |
Andrew Morton | 9 | 2.02% | 1 | 12.50% |
Alan Cox | 6 | 1.35% | 1 | 12.50% |
Greg Kroah-Hartman | 3 | 0.67% | 2 | 25.00% |
Total | 446 | 100.00% | 8 | 100.00% |
/*
* scsi_unregister will be called AFTER we return.
*/
static int adpt_release(struct Scsi_Host *host)
{
adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
// adpt_i2o_quiesce_hba(pHba);
adpt_i2o_delete_hba(pHba);
scsi_unregister(host);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 19 | 47.50% | 2 | 50.00% |
Linus Torvalds | 19 | 47.50% | 1 | 25.00% |
Matthew Wilcox | 2 | 5.00% | 1 | 25.00% |
Total | 40 | 100.00% | 4 | 100.00% |
static void adpt_inquiry(adpt_hba* pHba)
{
u32 msg[17];
u32 *mptr;
u32 *lenptr;
int direction;
int scsidir;
u32 len;
u32 reqlen;
u8* buf;
dma_addr_t addr;
u8 scb[16];
s32 rcode;
memset(msg, 0, sizeof(msg));
buf = dma_alloc_coherent(&pHba->pDev->dev, 80, &addr, GFP_KERNEL);
if(!buf){
printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
return;
}
memset((void*)buf, 0, 36);
len = 36;
direction = 0x00000000;
scsidir =0x40000000; // DATA IN (iop<--dev)
if (dpt_dma64(pHba))
reqlen = 17; // SINGLE SGE, 64 bit
else
reqlen = 14; // SINGLE SGE, 32 bit
/* Stick the headers on */
msg[0] = reqlen<<16 | SGL_OFFSET_12;
msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID);
msg[2] = 0;
msg[3] = 0;
// Adaptec/DPT Private stuff
msg[4] = I2O_CMD_SCSI_EXEC|DPT_ORGANIZATION_ID<<16;
msg[5] = ADAPTER_TID | 1<<16 /* Interpret*/;
/* Direction, disconnect ok | sense data | simple queue , CDBLen */
// I2O_SCB_FLAG_ENABLE_DISCONNECT |
// I2O_SCB_FLAG_SIMPLE_QUEUE_TAG |
// I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
msg[6] = scsidir|0x20a00000| 6 /* cmd len*/;
mptr=msg+7;
memset(scb, 0, sizeof(scb));
// Write SCSI command into the message - always 16 byte block
scb[0] = INQUIRY;
scb[1] = 0;
scb[2] = 0;
scb[3] = 0;
scb[4] = 36;
scb[5] = 0;
// Don't care about the rest of scb
memcpy(mptr, scb, sizeof(scb));
mptr+=4;
lenptr=mptr++; /* Remember me - fill in when we know */
/* Now fill in the SGList and command */
*lenptr = len;
if (dpt_dma64(pHba)) {
*mptr++ = (0x7C<<24)+(2<<16)+0x02; /* Enable 64 bit */
*mptr++ = 1 << PAGE_SHIFT;
*mptr++ = 0xD0000000|direction|len;
*mptr++ = dma_low(addr);
*mptr++ = dma_high(addr);
} else {
*mptr++ = 0xD0000000|direction|len;
*mptr++ = addr;
}
// Send it on it's way
rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120);
if (rcode != 0) {
sprintf(pHba->detail, "Adaptec I2O RAID");
printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
if (rcode != -ETIME && rcode != -EINTR)
dma_free_coherent(&pHba->pDev->dev, 80, buf, addr);
} else {
memset(pHba->detail, 0, sizeof(pHba->detail));
memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
memcpy(&(pHba->detail[16]), " Model: ", 8);
memcpy(&(pHba->detail[24]), (u8*) &buf[16], 16);
memcpy(&(pHba->detail[40]), " FW: ", 4);
memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
pHba->detail[48] = '\0'; /* precautionary */
dma_free_coherent(&pHba->pDev->dev, 80, buf, addr);
}
adpt_i2o_status_get(pHba);
return ;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 504 | 80.90% | 1 | 25.00% |
Miquel van Smoorenburg | 102 | 16.37% | 2 | 50.00% |
Andrew Morton | 17 | 2.73% | 1 | 25.00% |
Total | 623 | 100.00% | 4 | 100.00% |
static int adpt_slave_configure(struct scsi_device * device)
{
struct Scsi_Host *host = device->host;
adpt_hba* pHba;
pHba = (adpt_hba *) host->hostdata[0];
if (host->can_queue && device->tagged_supported) {
scsi_change_queue_depth(device,
host->can_queue - 1);
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 41 | 65.08% | 1 | 20.00% |
Doug Ledford | 19 | 30.16% | 2 | 40.00% |
Christoph Hellwig | 3 | 4.76% | 2 | 40.00% |
Total | 63 | 100.00% | 5 | 100.00% |
static int adpt_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
{
adpt_hba* pHba = NULL;
struct adpt_device* pDev = NULL; /* dpt per device information */
cmd->scsi_done = done;
/*
* SCSI REQUEST_SENSE commands will be executed automatically by the
* Host Adapter for any errors, so they should not be executed
* explicitly unless the Sense Data is zero indicating that no error
* occurred.
*/
if ((cmd->cmnd[0] == REQUEST_SENSE) && (cmd->sense_buffer[0] != 0)) {
cmd->result = (DID_OK << 16);
cmd->scsi_done(cmd);
return 0;
}
pHba = (adpt_hba*)cmd->device->host->hostdata[0];
if (!pHba) {
return FAILED;
}
rmb();
if ((pHba->state) & DPTI_STATE_RESET)
return SCSI_MLQUEUE_HOST_BUSY;
// TODO if the cmd->device if offline then I may need to issue a bus rescan
// followed by a get_lct to see if the device is there anymore
if((pDev = (struct adpt_device*) (cmd->device->hostdata)) == NULL) {
/*
* First command request for this device. Set up a pointer
* to the device structure. This should be a TEST_UNIT_READY
* command from scan_scsis_single.
*/
if ((pDev = adpt_find_device(pHba, (u32)cmd->device->channel, (u32)cmd->device->id, cmd->device->lun)) == NULL) {
// TODO: if any luns are at this bus, scsi id then fake a TEST_UNIT_READY and INQUIRY response
// with type 7F (for all luns less than the max for this bus,id) so the lun scan will continue.
cmd->result = (DID_NO_CONNECT << 16);
cmd->scsi_done(cmd);
return 0;
}
cmd->device->hostdata = pDev;
}
pDev->pScsi_dev = cmd->device;
/*
* If we are being called from when the device is being reset,
* delay processing of the command until later.
*/
if (pDev->state & DPTI_DEV_RESET ) {
return FAILED;
}
return adpt_scsi_to_i2o(pHba, cmd, pDev);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 244 | 94.21% | 1 | 16.67% |
Luben Tuikov | 9 | 3.47% | 2 | 33.33% |
Christoph Hellwig | 4 | 1.54% | 1 | 16.67% |
Jeff Garzik | 1 | 0.39% | 1 | 16.67% |
Hannes Reinecke | 1 | 0.39% | 1 | 16.67% |
Total | 259 | 100.00% | 6 | 100.00% |
static DEF_SCSI_QCMD(adpt_queue)
static int adpt_bios_param(struct scsi_device *sdev, struct block_device *dev,
sector_t capacity, int geom[])
{
int heads=-1;
int sectors=-1;
int cylinders=-1;
// *** First lets set the default geometry ****
// If the capacity is less than ox2000
if (capacity < 0x2000 ) { // floppy
heads = 18;
sectors = 2;
}
// else if between 0x2000 and 0x20000
else if (capacity < 0x20000) {
heads = 64;
sectors = 32;
}
// else if between 0x20000 and 0x40000
else if (capacity < 0x40000) {
heads = 65;
sectors = 63;
}
// else if between 0x4000 and 0x80000
else if (capacity < 0x80000) {
heads = 128;
sectors = 63;
}
// else if greater than 0x80000
else {
heads = 255;
sectors = 63;
}
cylinders = sector_div(capacity, heads * sectors);
// Special case if CDROM
if(sdev->type == 5) { // CDROM
heads = 252;
sectors = 63;
cylinders = 1111;
}
geom[0] = heads;
geom[1] = sectors;
geom[2] = cylinders;
PDEBUG("adpt_bios_param: exit\n");
return 0;
}
static
const char *adpt_info(struct Scsi_Host *host)
{
adpt_hba* pHba;
pHba = (adpt_hba *) host->hostdata[0];
return (char *) (pHba->detail);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 40 | 97.56% | 1 | 50.00% |
Jeff Garzik | 1 | 2.44% | 1 | 50.00% |
Total | 41 | 100.00% | 2 | 100.00% |
static int adpt_show_info(struct seq_file *m, struct Scsi_Host *host)
{
struct adpt_device* d;
int id;
int chan;
adpt_hba* pHba;
int unit;
// Find HBA (host bus adapter) we are looking for
mutex_lock(&adpt_configuration_lock);
for (pHba = hba_chain; pHba; pHba = pHba->next) {
if (pHba->host == host) {
break; /* found adapter */
}
}
mutex_unlock(&adpt_configuration_lock);
if (pHba == NULL) {
return 0;
}
host = pHba->host;
seq_printf(m, "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION);
seq_printf(m, "%s\n", pHba->detail);
seq_printf(m, "SCSI Host=scsi%d Control Node=/dev/%s irq=%d\n",
pHba->host->host_no, pHba->name, host->irq);
seq_printf(m, "\tpost fifo size = %d\n\treply fifo size = %d\n\tsg table size = %d\n\n",
host->can_queue, (int) pHba->reply_fifo_size , host->sg_tablesize);
seq_puts(m, "Devices:\n");
for(chan = 0; chan < MAX_CHANNEL; chan++) {
for(id = 0; id < MAX_ID; id++) {
d = pHba->channel[chan].device[id];
while(d) {
seq_printf(m,"\t%-24.24s", d->pScsi_dev->vendor);
seq_printf(m," Rev: %-8.8s\n", d->pScsi_dev->rev);
unit = d->pI2o_dev->lct_data.tid;
seq_printf(m, "\tTID=%d, (Channel=%d, Target=%d, Lun=%llu) (%s)\n\n",
unit, (int)d->scsi_channel, (int)d->scsi_id, d->scsi_lun,
scsi_device_online(d->pScsi_dev)? "online":"offline");
d = d->next_lun;
}
}
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 264 | 89.49% | 1 | 14.29% |
Al Viro | 22 | 7.46% | 1 | 14.29% |
James Bottomley | 3 | 1.02% | 1 | 14.29% |
Christoph Hellwig | 2 | 0.68% | 1 | 14.29% |
Arjan van de Ven | 2 | 0.68% | 1 | 14.29% |
Hannes Reinecke | 1 | 0.34% | 1 | 14.29% |
Rasmus Villemoes | 1 | 0.34% | 1 | 14.29% |
Total | 295 | 100.00% | 7 | 100.00% |
/*
* Turn a struct scsi_cmnd * into a unique 32 bit 'context'.
*/
static u32 adpt_cmd_to_context(struct scsi_cmnd *cmd)
{
return (u32)cmd->serial_number;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Miquel van Smoorenburg | 11 | 57.89% | 1 | 33.33% |
Linus Torvalds | 6 | 31.58% | 1 | 33.33% |
Christoph Hellwig | 2 | 10.53% | 1 | 33.33% |
Total | 19 | 100.00% | 3 | 100.00% |
/*
* Go from a u32 'context' to a struct scsi_cmnd * .
* This could probably be made more efficient.
*/
static struct scsi_cmnd *
adpt_cmd_from_context(adpt_hba * pHba, u32 context)
{
struct scsi_cmnd * cmd;
struct scsi_device * d;
if (context == 0)
return NULL;
spin_unlock(pHba->host->host_lock);
shost_for_each_device(d, pHba->host) {
unsigned long flags;
spin_lock_irqsave(&d->list_lock, flags);
list_for_each_entry(cmd, &d->cmd_list, list) {
if (((u32)cmd->serial_number == context)) {
spin_unlock_irqrestore(&d->list_lock, flags);
scsi_device_put(d);
spin_lock(pHba->host->host_lock);
return cmd;
}
}
spin_unlock_irqrestore(&d->list_lock, flags);
}
spin_lock(pHba->host->host_lock);
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Miquel van Smoorenburg | 89 | 64.03% | 1 | 33.33% |
Linus Torvalds | 49 | 35.25% | 1 | 33.33% |
Luben Tuikov | 1 | 0.72% | 1 | 33.33% |
Total | 139 | 100.00% | 3 | 100.00% |
/*
* Turn a pointer to ioctl reply data into an u32 'context'
*/
static u32 adpt_ioctl_to_context(adpt_hba * pHba, void *reply)
{
#if BITS_PER_LONG == 32
return (u32)(unsigned long)reply;
#else
ulong flags = 0;
u32 nr, i;
spin_lock_irqsave(pHba->host->host_lock, flags);
nr = ARRAY_SIZE(pHba->ioctl_reply_context);
for (i = 0; i < nr; i++) {
if (pHba->ioctl_reply_context[i] == NULL) {
pHba->ioctl_reply_context[i] = reply;
break;
}
}
spin_unlock_irqrestore(pHba->host->host_lock, flags);
if (i >= nr) {
printk(KERN_WARNING"%s: Too many outstanding "
"ioctl commands\n", pHba->name);
return (u32)-1;
}
return i;
#endif
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Miquel van Smoorenburg | 138 | 97.87% | 1 | 50.00% |
Linus Torvalds | 3 | 2.13% | 1 | 50.00% |
Total | 141 | 100.00% | 2 | 100.00% |
/*
* Go from an u32 'context' to a pointer to ioctl reply data.
*/
static void *adpt_ioctl_from_context(adpt_hba *pHba, u32 context)
{
#if BITS_PER_LONG == 32
return (void *)(unsigned long)context;
#else
void *p = pHba->ioctl_reply_context[context];
pHba->ioctl_reply_context[context] = NULL;
return p;
#endif
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Miquel van Smoorenburg | 51 | 89.47% | 1 | 50.00% |
Linus Torvalds | 6 | 10.53% | 1 | 50.00% |
Total | 57 | 100.00% | 2 | 100.00% |
/*===========================================================================
* Error Handling routines
*===========================================================================
*/
static int adpt_abort(struct scsi_cmnd * cmd)
{
adpt_hba* pHba = NULL; /* host bus adapter structure */
struct adpt_device* dptdevice; /* dpt per device information */
u32 msg[5];
int rcode;
if(cmd->serial_number == 0){
return FAILED;
}
pHba = (adpt_hba*) cmd->device->host->hostdata[0];
printk(KERN_INFO"%s: Trying to Abort\n",pHba->name);
if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) {
printk(KERN_ERR "%s: Unable to abort: No device in cmnd\n",pHba->name);
return FAILED;
}
memset(msg, 0, sizeof(msg));
msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid;
msg[2] = 0;
msg[3]= 0;
msg[4] = adpt_cmd_to_context(cmd);
if (pHba->host)
spin_lock_irq(pHba->host->host_lock);
rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER);
if (pHba->host)
spin_unlock_irq(pHba->host->host_lock);
if (rcode != 0) {
if(rcode == -EOPNOTSUPP ){
printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
return FAILED;
}
printk(KERN_INFO"%s: Abort failed.\n",pHba->name);
return FAILED;
}
printk(KERN_INFO"%s: Abort complete.\n",pHba->name);
return SUCCESS;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 230 | 84.56% | 1 | 16.67% |
Mark Salyzyn | 32 | 11.76% | 1 | 16.67% |
Christoph Hellwig | 5 | 1.84% | 2 | 33.33% |
Miquel van Smoorenburg | 3 | 1.10% | 1 | 16.67% |
Luben Tuikov | 2 | 0.74% | 1 | 16.67% |
Total | 272 | 100.00% | 6 | 100.00% |
#define I2O_DEVICE_RESET 0x27
// This is the same for BLK and SCSI devices
// NOTE this is wrong in the i2o.h definitions
// This is not currently supported by our adapter but we issue it anyway
static int adpt_device_reset(struct scsi_cmnd* cmd)
{
adpt_hba* pHba;
u32 msg[4];
u32 rcode;
int old_state;
struct adpt_device* d = cmd->device->hos