Commit dac1ab6d authored by James Bottomley's avatar James Bottomley

Merge by hand

pci_ids.h (removal of on ID next to addition of another)
scsi_transport_iscsi.c: change of attribute_container_unregister
to transport_container_unregister.
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parents 4df73de0 bd210e30
......@@ -1397,9 +1397,6 @@ running once the system is up.
sym53c416= [HW,SCSI]
See header of drivers/scsi/sym53c416.c.
sym53c8xx= [HW,SCSI]
See Documentation/scsi/ncr53c8xx.txt.
t128= [HW,SCSI]
See header of drivers/scsi/t128.c.
......
......@@ -2,7 +2,7 @@ This file contains brief information about the SCSI tape driver.
The driver is currently maintained by Kai Mäkisara (email
Kai.Makisara@kolumbus.fi)
Last modified: Wed Feb 25 14:09:08 2004 by makisara
Last modified: Sun Feb 20 22:28:27 2005 by kai.makisara
BASICS
......@@ -85,6 +85,9 @@ writing and the last operation has been a write. Two filemarks can be
optionally written. In both cases end of data is signified by
returning zero bytes for two consecutive reads.
If the rewind, offline, or seek is done and previous tape operation was write,
a filemark is written before moving tape.
The compile options are defined in the file linux/drivers/scsi/st_options.h.
4. If the open option O_NONBLOCK is used, open succeeds even if the
......
......@@ -440,7 +440,7 @@ lilo: linux root=/dev/sda2 sym53c8xx.cmd_per_lun=4 sym53c8xx.sync=10 sym53c8xx.d
The following command will install the driver module with the same
options as above.
modprobe sym53c8xx cmd_per_lun=4 sync=10 debug=0x200"
modprobe sym53c8xx cmd_per_lun=4 sync=10 debug=0x200
10.2 Available arguments
......
......@@ -145,6 +145,20 @@ void transport_setup_device(struct device *dev)
}
EXPORT_SYMBOL_GPL(transport_setup_device);
static int transport_add_class_device(struct attribute_container *cont,
struct device *dev,
struct class_device *classdev)
{
int error = attribute_container_add_class_device(classdev);
struct transport_container *tcont =
attribute_container_to_transport_container(cont);
if (!error && tcont->statistics)
error = sysfs_create_group(&classdev->kobj, tcont->statistics);
return error;
}
/**
* transport_add_device - declare a new dev for transport class association
......@@ -159,8 +173,7 @@ EXPORT_SYMBOL_GPL(transport_setup_device);
void transport_add_device(struct device *dev)
{
attribute_container_device_trigger(dev,
attribute_container_add_class_device_adapter);
attribute_container_device_trigger(dev, transport_add_class_device);
}
EXPORT_SYMBOL_GPL(transport_add_device);
......@@ -197,13 +210,18 @@ static int transport_remove_classdev(struct attribute_container *cont,
struct device *dev,
struct class_device *classdev)
{
struct transport_container *tcont =
attribute_container_to_transport_container(cont);
struct transport_class *tclass = class_to_transport_class(cont->class);
if (tclass->remove)
tclass->remove(dev);
if (tclass->remove != anon_transport_dummy_function)
if (tclass->remove != anon_transport_dummy_function) {
if (tcont->statistics)
sysfs_remove_group(&classdev->kobj, tcont->statistics);
attribute_container_class_device_del(classdev);
}
return 0;
}
......
......@@ -83,8 +83,8 @@
#define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR
#endif
#define MPT_LINUX_VERSION_COMMON "3.01.18"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.18"
#define MPT_LINUX_VERSION_COMMON "3.01.19"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.19"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
......@@ -420,7 +420,6 @@ do { \
typedef struct _MPT_IOCTL {
struct _MPT_ADAPTER *ioc;
struct timer_list timer; /* timer function for this adapter */
u8 ReplyFrame[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */
u8 sense[MPT_SENSE_BUFFER_ALLOC];
int wait_done; /* wake-up value for this ioc */
......@@ -428,8 +427,6 @@ typedef struct _MPT_IOCTL {
u8 status; /* current command status */
u8 reset; /* 1 if bus reset allowed */
u8 target; /* target for reset */
void *tmPtr;
struct timer_list TMtimer; /* timer function for this adapter */
struct semaphore sem_ioc;
} MPT_IOCTL;
......@@ -882,11 +879,9 @@ typedef struct _MPT_SCSI_HOST {
int port;
u32 pad0;
struct scsi_cmnd **ScsiLookup;
u32 qtag_tick;
VirtDevice **Targets;
MPT_LOCAL_REPLY *pLocal; /* used for internal commands */
struct timer_list timer;
struct timer_list TMtimer; /* Timer for TM commands ONLY */
/* Pool of memory for holding SCpnts before doing
* OS callbacks. freeQ is the free pool.
*/
......@@ -896,7 +891,6 @@ typedef struct _MPT_SCSI_HOST {
u8 pad1;
u8 tmState;
u8 rsvd[2];
MPT_FRAME_HDR *tmPtr; /* Ptr to TM request*/
MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */
struct scsi_cmnd *abortSCpnt;
MPT_LOCAL_REPLY localReply; /* internal cmd reply struct */
......
This diff is collapsed.
This diff is collapsed.
......@@ -1098,7 +1098,6 @@
0180 Snipe chipset SCSI controller
1014 0241 iSeries 2757 DASD IOA
1014 0264 Quad Channel PCI-X U320 SCSI RAID Adapter (2780)
1014 02BD Quad Channel PCI-X U320 DDR SCSI RAID Adapter (570F)
0188 EADS-X PCI-X to PCI-X Bridge
01a7 PCI-X to PCI-X Bridge
01bd ServeRAID Controller
......@@ -1123,7 +1122,9 @@
0268 Gigabit Ethernet-SX Adapter (PCI-X)
0269 10/100/1000 Base-TX Ethernet Adapter (PCI-X)
028C Citrine chipset SCSI controller
1014 02BE Dual Channel PCI-X U320 DDR SCSI RAID Adapter (571B)
1014 028D Dual Channel PCI-X DDR SAS RAID Adapter (572E)
1014 02BE Dual Channel PCI-X DDR U320 SCSI RAID Adapter (571B)
1014 02C0 Dual Channel PCI-X DDR U320 SCSI Adapter (571A)
0302 X-Architecture Bridge [Summit]
0314 ZISC 036 Neural accelerator card
ffff MPIC-2 interrupt controller
......@@ -9528,6 +9529,8 @@
9005 0294 ESD SO-DIMM PCI-X SATA ZCR (Prowler)
0286 AAC-RAID (Rocket)
9005 028c ASR-2230S + ASR-2230SLP PCI-X (Lancer)
0503 Scamp chipset SCSI controller
1014 02BF Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571E)
8000 ASC-29320A U320
800f AIC-7901 U320
8010 ASC-39320 U320
......
......@@ -825,6 +825,7 @@ process_extended_message(struct Scsi_Host *host,
switch(hostdata->msgin[2]) {
case A_SDTR_MSG:
if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
struct scsi_target *starget = SCp->device->sdev_target;
__u8 period = hostdata->msgin[3];
__u8 offset = hostdata->msgin[4];
......@@ -832,22 +833,15 @@ process_extended_message(struct Scsi_Host *host,
offset = 0;
period = 0;
}
spi_offset(starget) = offset;
spi_period(starget) = period;
if(NCR_700_is_flag_set(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION)) {
if(spi_offset(SCp->device->sdev_target) != 0)
printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n",
host->host_no, pun, lun,
offset, period*4);
else
printk(KERN_INFO "scsi%d: (%d:%d) Asynchronous\n",
host->host_no, pun, lun);
spi_display_xfer_agreement(starget);
NCR_700_clear_flag(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION);
}
spi_offset(SCp->device->sdev_target) = offset;
spi_period(SCp->device->sdev_target) = period;
NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
......
......@@ -619,7 +619,7 @@ config SCSI_EATA_MAX_TAGS
config SCSI_EATA_PIO
tristate "EATA-PIO (old DPT PM2001, PM2012A) support"
depends on (ISA || EISA || PCI) && SCSI
depends on (ISA || EISA || PCI) && SCSI && BROKEN
---help---
This driver supports all EATA-PIO protocol compliant SCSI Host
Adapters like the DPT PM2001 and the PM2012A. EATA-DMA compliant
......@@ -1257,7 +1257,7 @@ config SCSI_QLOGIC_FAS
config SCSI_QLOGIC_ISP
tristate "Qlogic ISP SCSI support (old driver)"
depends on PCI && SCSI
depends on PCI && SCSI && BROKEN
---help---
This driver works for all QLogic PCI SCSI host adapters (IQ-PCI,
IQ-PCI-10, IQ_PCI-D) except for the PCI-basic card. (This latter
......
......@@ -533,7 +533,7 @@ static int should_disconnect(unsigned char cmd)
static void NCR5380_set_timer(struct NCR5380_hostdata *hostdata, unsigned long timeout)
{
hostdata->time_expires = jiffies + timeout;
schedule_delayed_work(&hostdata->coroutine, hostdata->time_expires);
schedule_delayed_work(&hostdata->coroutine, timeout);
}
......@@ -671,16 +671,8 @@ static void __init NCR5380_print_options(struct Scsi_Host *instance)
static void NCR5380_print_status(struct Scsi_Host *instance)
{
static char pr_bfr[512];
char *start;
int len;
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_dprint_phase(NDEBUG_ANY, instance);
len = NCR5380_proc_info(instance, pr_bfr, &start, 0, sizeof(pr_bfr), 0);
pr_bfr[len] = 0;
printk("\n%s\n", pr_bfr);
}
/******************************************/
......@@ -2689,11 +2681,6 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
NCR5380_print_status(instance);
printk(KERN_WARNING "scsi%d : aborting command\n", instance->host_no);
print_Scsi_Cmnd(cmd);
NCR5380_print_status(instance);
NCR5380_setup(instance);
dprintk(NDEBUG_ABORT, ("scsi%d : abort called\n", instance->host_no));
......
......@@ -106,7 +106,7 @@
#include "53c700.h"
#include "NCR_D700.h"
char *NCR_D700; /* command line from insmod */
static char *NCR_D700; /* command line from insmod */
MODULE_AUTHOR("James Bottomley");
MODULE_DESCRIPTION("NCR Dual700 SCSI Driver");
......@@ -352,7 +352,7 @@ NCR_D700_remove(struct device *dev)
static short NCR_D700_id_table[] = { NCR_D700_MCA_ID, 0 };
struct mca_driver NCR_D700_driver = {
static struct mca_driver NCR_D700_driver = {
.id_table = NCR_D700_id_table,
.driver = {
.name = "NCR_D700",
......
......@@ -45,6 +45,7 @@
#include <linux/syscalls.h>
#include <linux/ioctl32.h>
#include <linux/delay.h>
#include <linux/smp_lock.h>
#include <asm/semaphore.h>
#include <scsi/scsi.h>
......@@ -191,28 +192,6 @@ static struct aac_driver_ident aac_drivers[] = {
{ aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 } /* Adaptec Rocket Catch All */
};
#ifdef CONFIG_COMPAT
/*
* Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version
*/
static int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg, struct file *file)
{
struct fib_ioctl __user *f;
f = compat_alloc_user_space(sizeof(*f));
if (!access_ok(VERIFY_WRITE, f, sizeof(*f)))
return -EFAULT;
clear_user(f, sizeof(*f));
if (copy_in_user(f, (void __user *)arg, sizeof(struct fib_ioctl) - sizeof(u32)))
return -EFAULT;
return sys_ioctl(fd, cmd, (unsigned long)f);
}
#endif
/**
* aac_queuecommand - queue a SCSI command
* @cmd: SCSI command to queue
......@@ -494,9 +473,65 @@ static int aac_cfg_ioctl(struct inode *inode, struct file *file,
return aac_do_ioctl(file->private_data, cmd, (void __user *)arg);
}
#ifdef CONFIG_COMPAT
static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long arg)
{
long ret;
lock_kernel();
switch (cmd) {
case FSACTL_MINIPORT_REV_CHECK:
case FSACTL_SENDFIB:
case FSACTL_OPEN_GET_ADAPTER_FIB:
case FSACTL_CLOSE_GET_ADAPTER_FIB:
case FSACTL_SEND_RAW_SRB:
case FSACTL_GET_PCI_INFO:
case FSACTL_QUERY_DISK:
case FSACTL_DELETE_DISK:
case FSACTL_FORCE_DELETE_DISK:
case FSACTL_GET_CONTAINERS:
ret = aac_do_ioctl(dev, cmd, (void __user *)arg);
break;
case FSACTL_GET_NEXT_ADAPTER_FIB: {
struct fib_ioctl __user *f;
f = compat_alloc_user_space(sizeof(*f));
ret = 0;
if (clear_user(f, sizeof(*f) != sizeof(*f)))
ret = -EFAULT;
if (copy_in_user(f, (void __user *)arg, sizeof(struct fib_ioctl) - sizeof(u32)))
ret = -EFAULT;
if (!ret)
ret = aac_do_ioctl(dev, cmd, (void __user *)arg);
break;
}
default:
ret = -ENOIOCTLCMD;
break;
}
unlock_kernel();
return ret;
}
static int aac_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
{
struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;
return aac_compat_do_ioctl(dev, cmd, (unsigned long)arg);
}
static long aac_compat_cfg_ioctl(struct file *file, unsigned cmd, unsigned long arg)
{
return aac_compat_do_ioctl((struct aac_dev *)file->private_data, cmd, arg);
}
#endif
static struct file_operations aac_cfg_fops = {
.owner = THIS_MODULE,
.ioctl = aac_cfg_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = aac_compat_cfg_ioctl,
#endif
.open = aac_cfg_open,
};
......@@ -506,6 +541,9 @@ static struct scsi_host_template aac_driver_template = {
.proc_name = "aacraid",
.info = aac_info,
.ioctl = aac_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = aac_compat_ioctl,
#endif
.queuecommand = aac_queuecommand,
.bios_param = aac_biosparm,
.slave_configure = aac_slave_configure,
......@@ -699,39 +737,11 @@ static int __init aac_init(void)
printk(KERN_WARNING
"aacraid: unable to register \"aac\" device.\n");
}
#ifdef CONFIG_COMPAT
register_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK, NULL);
register_ioctl32_conversion(FSACTL_SENDFIB, NULL);
register_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB, NULL);
register_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB,
aac_get_next_adapter_fib_ioctl);
register_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB, NULL);
register_ioctl32_conversion(FSACTL_SEND_RAW_SRB, NULL);
register_ioctl32_conversion(FSACTL_GET_PCI_INFO, NULL);
register_ioctl32_conversion(FSACTL_QUERY_DISK, NULL);
register_ioctl32_conversion(FSACTL_DELETE_DISK, NULL);
register_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK, NULL);
register_ioctl32_conversion(FSACTL_GET_CONTAINERS, NULL);
#endif
return 0;
}
static void __exit aac_exit(void)
{
#ifdef CONFIG_COMPAT
unregister_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK);
unregister_ioctl32_conversion(FSACTL_SENDFIB);
unregister_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB);
unregister_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB);
unregister_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB);
unregister_ioctl32_conversion(FSACTL_SEND_RAW_SRB);
unregister_ioctl32_conversion(FSACTL_GET_PCI_INFO);
unregister_ioctl32_conversion(FSACTL_QUERY_DISK);
unregister_ioctl32_conversion(FSACTL_DELETE_DISK);
unregister_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK);
unregister_ioctl32_conversion(FSACTL_GET_CONTAINERS);
#endif
unregister_chrdev(aac_cfg_major, "aac");
pci_unregister_driver(&aac_pci_driver);
}
......
......@@ -182,7 +182,7 @@
* cross a page boundy.
*/
#define SEGMENTX_LEN (sizeof(struct SGentry)*DC395x_MAX_SG_LISTENTRY)
#define VIRTX_LEN (sizeof(void *) * DC395x_MAX_SG_LISTENTRY)
struct SGentry {
u32 address; /* bus! address */
......@@ -234,6 +234,7 @@ struct ScsiReqBlk {
u8 sg_count; /* No of HW sg entries for this request */
u8 sg_index; /* Index of HW sg entry for this request */
u32 total_xfer_length; /* Total number of bytes remaining to be transfered */
void **virt_map;
unsigned char *virt_addr; /* Virtual address of current transfer position */
/*
......@@ -1020,14 +1021,14 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
reqlen, cmd->request_buffer, cmd->use_sg,
srb->sg_count);
srb->virt_addr = page_address(sl->page);
for (i = 0; i < srb->sg_count; i++) {
u32 busaddr = (u32)sg_dma_address(&sl[i]);
u32 seglen = (u32)sl[i].length;
sgp[i].address = busaddr;
u32 seglen = (u32)sg_dma_len(sl + i);
sgp[i].address = (u32)sg_dma_address(sl + i);
sgp[i].length = seglen;
srb->total_xfer_length += seglen;
srb->virt_map[i] = kmap(sl[i].page);
}
srb->virt_addr = srb->virt_map[0];
sgp += srb->sg_count - 1;
/*
......@@ -1964,6 +1965,7 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
int segment = cmd->use_sg;
u32 xferred = srb->total_xfer_length - left; /* bytes transfered */
struct SGentry *psge = srb->segment_x + srb->sg_index;
void **virt = srb->virt_map;
dprintkdbg(DBG_0,
"sg_update_list: Transfered %i of %i bytes, %i remain\n",
......@@ -2003,16 +2005,16 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
/* We have to walk the scatterlist to find it */
sg = (struct scatterlist *)cmd->request_buffer;
idx = 0;
while (segment--) {
unsigned long mask =
~((unsigned long)sg->length - 1) & PAGE_MASK;
if ((sg_dma_address(sg) & mask) == (psge->address & mask)) {
srb->virt_addr = (page_address(sg->page)
+ psge->address -
(psge->address & PAGE_MASK));
srb->virt_addr = virt[idx] + (psge->address & ~PAGE_MASK);
return;
}
++sg;
++idx;
}
dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n");
......@@ -2138,7 +2140,7 @@ static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
DC395x_read32(acb, TRM_S1040_DMA_CXCNT));
}
/*
* calculate all the residue data that not yet tranfered
* calculate all the residue data that not yet transfered
* SCSI transfer counter + left in SCSI FIFO data
*
* .....TRM_S1040_SCSI_COUNTER (24bits)
......@@ -3256,6 +3258,7 @@ static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
struct scsi_cmnd *cmd = srb->cmd;
enum dma_data_direction dir = cmd->sc_data_direction;
if (cmd->use_sg && dir != PCI_DMA_NONE) {
int i;
/* unmap DC395x SG list */
dprintkdbg(DBG_SG, "pci_unmap_srb: list=%08x(%05x)\n",
srb->sg_bus_addr, SEGMENTX_LEN);
......@@ -3265,6 +3268,8 @@ static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
dprintkdbg(DBG_SG, "pci_unmap_srb: segs=%i buffer=%p\n",
cmd->use_sg, cmd->request_buffer);
/* unmap the sg segments */
for (i = 0; i < srb->sg_count; i++)
kunmap(virt_to_page(srb->virt_map[i]));
pci_unmap_sg(acb->dev,
(struct scatterlist *)cmd->request_buffer,
cmd->use_sg, dir);
......@@ -3311,7 +3316,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
if (cmd->use_sg) {
struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset);
ptr = (struct ScsiInqData *)(srb->virt_map[0] + sg->offset);
} else {
ptr = (struct ScsiInqData *)(cmd->request_buffer);
}
......@@ -4246,8 +4251,9 @@ static void adapter_sg_tables_free(struct AdapterCtlBlk *acb)
const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
if (acb->srb_array[i].segment_x)
kfree(acb->srb_array[i].segment_x);
kfree(acb->srb_array[i].segment_x);
vfree(acb->srb_array[0].virt_map);
}
......@@ -4263,9 +4269,12 @@ static int __devinit adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
int srb_idx = 0;
unsigned i = 0;
struct SGentry *ptr;
void **virt_array;
for (i = 0; i < DC395x_MAX_SRB_CNT; i++)
for (i = 0; i < DC395x_MAX_SRB_CNT; i++) {
acb->srb_array[i].segment_x = NULL;
acb->srb_array[i].virt_map = NULL;
}
dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages);
while (pages--) {
......@@ -4286,6 +4295,19 @@ static int __devinit adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
ptr + (i * DC395x_MAX_SG_LISTENTRY);
else
dprintkl(KERN_DEBUG, "No space for tmsrb SG table reserved?!\n");
virt_array = vmalloc((DC395x_MAX_SRB_CNT + 1) * DC395x_MAX_SG_LISTENTRY * sizeof(void*));
if (!virt_array) {
adapter_sg_tables_free(acb);
return 1;
}
for (i = 0; i < DC395x_MAX_SRB_CNT + 1; i++) {
acb->srb_array[i].virt_map = virt_array;
virt_array += DC395x_MAX_SG_LISTENTRY;
}
return 0;
}
......
......@@ -216,6 +216,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
spin_lock_init(&shost->default_lock);
scsi_assign_lock(shost, &shost->default_lock);
INIT_LIST_HEAD(&shost->__devices);
INIT_LIST_HEAD(&shost->__targets);
INIT_LIST_HEAD(&shost->eh_cmd_q);
INIT_LIST_HEAD(&shost->starved_list);
init_waitqueue_head(&shost->host_wait);
......
This diff is collapsed.
This diff is collapsed.
......@@ -16,6 +16,7 @@
*/
#include "megaraid_mm.h"
#include <linux/smp_lock.h>
// Entry points for char node driver
......@@ -43,8 +44,7 @@ static void mraid_mm_free_adp_resources(mraid_mmadp_t *);
static void mraid_mm_teardown_dma_pools(mraid_mmadp_t *);
#ifdef CONFIG_COMPAT
static int mraid_mm_compat_ioctl(unsigned int, unsigned int, unsigned long,
struct file *);
static long mraid_mm_compat_ioctl(struct file *, unsigned int, unsigned long);
#endif
MODULE_AUTHOR("LSI Logic Corporation");
......@@ -71,6 +71,9 @@ static wait_queue_head_t wait_q;
static struct file_operations lsi_fops = {
.open = mraid_mm_open,
.ioctl = mraid_mm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = mraid_mm_compat_ioctl,
#endif
.owner = THIS_MODULE,
};
......@@ -1215,8 +1218,6 @@ mraid_mm_init(void)
INIT_LIST_HEAD(&adapters_list_g);
register_ioctl32_conversion(MEGAIOCCMD, mraid_mm_compat_ioctl);
return 0;
}
......@@ -1225,13 +1226,15 @@ mraid_mm_init(void)
* mraid_mm_compat_ioctl : 32bit to 64bit ioctl conversion routine
*/
#ifdef CONFIG_COMPAT
static int
mraid_mm_compat_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg, struct file *filep)
static long
mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd,
unsigned long arg)
{
struct inode *inode = filep->f_dentry->d_inode;
return mraid_mm_ioctl(inode, filep, cmd, arg);
int err;
lock_kernel();
err = mraid_mm_ioctl(NULL, filep, cmd, arg);
unlock_kernel();
return err;
}
#endif
......@@ -1244,7 +1247,6 @@ mraid_mm_exit(void)
con_log(CL_DLEVEL1 , ("exiting common mod\n"));
unregister_chrdev(majorno, "megadev");
unregister_ioctl32_conversion(MEGAIOCCMD);
}
module_init(mraid_mm_init);
......
......@@ -5127,6 +5127,22 @@ static int osst_ioctl(struct inode * inode,struct file * file,
return retval;
}
#ifdef CONFIG_COMPAT
static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg)
{
struct osst_tape *STp = file->private_data;
struct scsi_device *sdev = STp->device;
int ret = -ENOIOCTLCMD;
if (sdev->host->hostt->compat_ioctl) {
ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
}
return ret;
}
#endif
/* Memory handling routines */
......@@ -5462,6 +5478,9 @@ static struct file_operations osst_fops = {
.read = osst_read,
.write = osst_write,
.ioctl = osst_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = osst_compat_ioctl,
#endif
.open = os_scsi_tape_open,
.flush = os_scsi_tape_flush,
.release = os_scsi_tape_close,
......
......@@ -20,6 +20,9 @@
#define QLA1280_VERSION "3.25"
/*****************************************************************************
Revision History:
Rev 3.25.1, February 10, 2005 Christoph Hellwig
- use pci_map_single to map non-S/G requests
- remove qla1280_proc_info
Rev 3.25, September 28, 2004, Christoph Hellwig
- add support for ISP1020/1040
- don't include "scsi.h" anymore for 2.6.x
......@@ -670,8 +673,6 @@ static struct qla_boards ql1280_board_tbl[] = {
};
static int qla1280_verbose = 1;
static int qla1280_buffer_size;
static char *qla1280_buffer;
#if DEBUG_QLA1280
static int ql_debug_level = 1;
......@@ -694,97 +695,6 @@ static int ql_debug_level = 1;
#define LEAVE_INTR(x) dprintk(4, "qla1280 : Leaving %s()\n", x);
/*************************************************************************
* qla1280_proc_info
*
* Description:
* Return information to handle /proc support for the driver.
*
* buffer - ptrs to a page buffer
*
* Returns:
*************************************************************************/
#define PROC_BUF &qla1280_buffer[len]
static int qla1280_proc_info(struct Scsi_Host *host, char *buffer,
char **start, off_t offset, int length, int inout)
{
struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
struct qla_boards *bdp = &ql1280_board_tbl[ha->devnum];
int size = 0;
int len = 0;
if (inout)
return -ENOSYS;
/*
* if our old buffer is the right size use it otherwise
* allocate a new one.
*/
if (qla1280_buffer_size != PAGE_SIZE) {
/* deallocate this buffer and get a new one */
if (qla1280_buffer != NULL) {
free_page((unsigned long)qla1280_buffer);
qla1280_buffer_size = 0;
}
qla1280_buffer = (char *)get_zeroed_page(GFP_KERNEL);
}
if (qla1280_buffer == NULL) {
size = sprintf(buffer, "qla1280 - kmalloc error at line %d\n",
__LINE__);
return size;
}
/* save the size of our buffer */
qla1280_buffer_size = PAGE_SIZE;
/* 3.20 clear the buffer we use for proc display */
memset(qla1280_buffer, 0, PAGE_SIZE);
/* start building the print buffer */
size = sprintf(PROC_BUF,
"QLogic PCI to SCSI Adapter for ISP 1280/12160:\n"
" Firmware version: %2d.%02d.%02d, Driver version %s\n",
bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
QLA1280_VERSION);
len += size;
size = sprintf(PROC_BUF, "SCSI Host Adapter Information: %s\n",
bdp->name);
len += size;
size = sprintf(PROC_BUF, "Request Queue count= 0x%x, Response "
"Queue count= 0x%x\n",
REQUEST_ENTRY_CNT, RESPONSE_ENTRY_CNT);
len += size;
size = sprintf(PROC_BUF, "Number of pending commands = 0x%lx\n",
ha->actthreads);
len += size;
size = sprintf(PROC_BUF, "Number of free request entries = %d\n",
ha->req_q_cnt);
len += size;
size = sprintf(PROC_BUF, "\n"); /* 1 */
len += size;
if (len >= qla1280_buffer_size) {
printk(KERN_WARNING
"qla1280: Overflow buffer in qla1280_proc.c\n");
}
if (offset > len - 1) {
free_page((unsigned long) qla1280_buffer);
qla1280_buffer = NULL;
qla1280_buffer_size = length = 0;
*start = NULL;
} else {
*start = &qla1280_buffer[offset]; /* Start of wanted data */
if (len - offset < length) {
length = len - offset;
}
}
return length;
}
static int qla1280_read_nvram(struct scsi_qla_host *ha)
{
uint16_t *wptr;
......@@ -1334,22 +1244,6 @@ qla1280_biosparam_old(Disk * disk, kdev_t dev, int geom[])
{
return qla1280_biosparam(disk->device, NULL, disk->capacity, geom);
}
static int
qla1280_proc_info_old(char *buffer, char **start, off_t offset, int length,
int hostno, int inout)
{
struct Scsi_Host *host;
for (host = scsi_hostlist; host; host = host->next) {
if (host->host_no == hostno) {
return qla1280_proc_info(host, buffer, start,
offset, length, inout);
}
}
return -ESRCH;
}
#endif
/**************************************************************************
......@@ -1571,16 +1465,12 @@ qla1280_done(struct scsi_qla_host *ha)
/* Release memory used for this I/O */
if (cmd->use_sg) {
dprintk(3, "S/G unmap_sg cmd=%p\n", cmd);
pci_unmap_sg(ha->pdev, cmd->request_buffer,
cmd->use_sg, cmd->sc_data_direction);
cmd->use_sg, cmd->sc_data_direction);
} else if (cmd->request_bufflen) {
/*dprintk(1, "No S/G unmap_single cmd=%x saved_dma_handle=%lx\n",
cmd, sp->saved_dma_handle); */
pci_unmap_page(ha->pdev, sp->saved_dma_handle,
cmd->request_bufflen, cmd->sc_data_direction);
pci_unmap_single(ha->pdev, sp->saved_dma_handle,
cmd->request_bufflen,
cmd->sc_data_direction);
}
/* Call the mid-level driver interrupt handler */
......@@ -3354,14 +3244,11 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
REQUEST_ENTRY_SIZE);
}
} else { /* No scatter gather data transfer */
struct page *page = virt_to_page(cmd->request_buffer);
unsigned long off = (unsigned long)cmd->request_buffer & ~PAGE_MASK;
dma_handle = pci_map_page(ha->pdev, page, off,
cmd->request_bufflen,
cmd->sc_data_direction);
dma_handle = pci_map_single(ha->pdev,
cmd->request_buffer,
cmd->request_bufflen,
cmd->sc_data_direction);
/* save dma_handle for pci_unmap_page */
sp->saved_dma_handle = dma_handle;
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
if (ha->flags.use_pci_vchannel)
......@@ -3636,11 +3523,10 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
REQUEST_ENTRY_SIZE);
}
} else { /* No S/G data transfer */
struct page *page = virt_to_page(cmd->request_buffer);
unsigned long off = (unsigned long)cmd->request_buffer & ~PAGE_MASK;
dma_handle = pci_map_page(ha->pdev, page, off,
cmd->request_bufflen,
cmd->sc_data_direction);
dma_handle = pci_map_single(ha->pdev,
cmd->request_buffer,
cmd->request_bufflen,
cmd->sc_data_direction);
sp->saved_dma_handle = dma_handle;
*dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle));
......@@ -4668,7 +4554,6 @@ static struct scsi_host_template qla1280_driver_template = {
.eh_bus_reset_handler = qla1280_eh_bus_reset,
.eh_host_reset_handler = qla1280_eh_adapter_reset,
.bios_param = qla1280_biosparam,
.proc_info = qla1280_proc_info,
.can_queue = 0xfffff,
.this_id = -1,
.sg_tablesize = SG_ALL,
......@@ -4688,7 +4573,6 @@ static Scsi_Host_Template qla1280_driver_template = {
.eh_bus_reset_handler = qla1280_eh_bus_reset,
.eh_host_reset_handler = qla1280_eh_adapter_reset,
.bios_param = qla1280_biosparam_old,
.proc_info = qla1280_proc_info_old,
.can_queue = 0xfffff,
.this_id = -1,
.sg_tablesize = SG_ALL,
......
......@@ -87,12 +87,6 @@
#define CDB_SIZE(cmd) (((((cmd)->cmnd[0] >> 5) & 7) < 6) ? \
COMMAND_SIZE((cmd)->cmnd[0]) : (cmd)->cmd_len)
/*
* Data declarations.
*/
unsigned long scsi_pid;
static unsigned long serial_number;
/*
* Note - the initial logging level can be set here to log events at boot time.
* After the system is up, you may enable logging via the /proc interface.
......@@ -510,6 +504,21 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
}
#endif
/*
* Assign a serial number and pid to the request for error recovery
* and debugging purposes. Protected by the Host_Lock of host.
*/
static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
{
cmd->serial_number = host->cmd_serial_number++;
if (cmd->serial_number == 0)
cmd->serial_number = host->cmd_serial_number++;
cmd->pid = host->cmd_pid++;
if (cmd->pid == 0)
cmd->pid = host->cmd_pid++;
}
/*
* Function: scsi_dispatch_command
*
......@@ -532,6 +541,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
* returns an immediate error upwards, and signals
* that the device is no longer present */
cmd->result = DID_NO_CONNECT << 16;
atomic_inc(&cmd->device->iorequest_cnt);
scsi_done(cmd);
/* return 0 (because the command has been processed) */
goto out;
......@@ -556,13 +566,6 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
goto out;
}
/* Assign a unique nonzero serial_number. */
/* XXX(hch): this is racy */
if (++serial_number == 0)
serial_number = 1;
cmd->serial_number = serial_number;
cmd->pid = scsi_pid++;
/*
* If SCSI-2 or lower, store the LUN value in cmnd.
*/
......@@ -593,6 +596,10 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
host->resetting = 0;
}
/*
* AK: unlikely race here: for some reason the timer could
* expire before the serial number is set up below.
*/
scsi_add_timer(cmd, cmd->timeout_per_command, scsi_times_out);
scsi_log_send(cmd);
......@@ -605,6 +612,8 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
cmd->state = SCSI_STATE_QUEUED;
cmd->owner = SCSI_OWNER_LOWLEVEL;
atomic_inc(&cmd->device->iorequest_cnt);
/*
* Before we queue this command, check if the command
* length exceeds what the host adapter can handle.
......@@ -619,6 +628,8 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
}
spin_lock_irqsave(host->host_lock, flags);
scsi_cmd_get_serial(host, cmd);
if (unlikely(test_bit(SHOST_CANCEL, &host->shost_state))) {
cmd->result = (DID_NO_CONNECT << 16);
scsi_done(cmd);
......@@ -627,6 +638,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
}
spin_unlock_irqrestore(host->host_lock, flags);
if (rtn) {
atomic_inc(&cmd->device->iodone_cnt);
scsi_queue_insert(cmd,
(rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
rtn : SCSI_MLQUEUE_HOST_BUSY);
......@@ -758,6 +770,10 @@ void __scsi_done(struct scsi_cmnd *cmd)
cmd->state = SCSI_STATE_BHQUEUE;
cmd->owner = SCSI_OWNER_BH_HANDLER;
atomic_inc(&cmd->device->iodone_cnt);
if (cmd->result)
atomic_inc(&cmd->device->ioerr_cnt);
/*
* Next, enqueue the command into the done queue.
* It is a per-CPU queue, so we just disable local interrupts
......@@ -920,12 +936,9 @@ EXPORT_SYMBOL(scsi_finish_command);
* the right thing depending on whether or not the device is
* currently active and whether or not it even has the
* command blocks built yet.
*
* XXX(hch): What exactly is device_request_lock trying to protect?
*/
void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags)
{
static DEFINE_SPINLOCK(device_request_lock);
unsigned long flags;
/*
......@@ -934,8 +947,7 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags)
if (tags <= 0)
return;
spin_lock_irqsave(&device_request_lock, flags);
spin_lock(sdev->request_queue->queue_lock);
spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
/* Check to see if the queue is managed by the block layer
* if it is, and we fail to adjust the depth, exit */
......@@ -964,8 +976,7 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags)
break;
}
out:
spin_unlock(sdev->request_queue->queue_lock);
spin_unlock_irqrestore(&device_request_lock, flags);
spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
}
EXPORT_SYMBOL(scsi_adjust_queue_depth);
......@@ -1104,6 +1115,60 @@ void starget_for_each_device(struct scsi_target *starget, void * data,
}
EXPORT_SYMBOL(starget_for_each_device);
/**
* __scsi_device_lookup_by_target - find a device given the target (UNLOCKED)
* @starget: SCSI target pointer
* @lun: SCSI Logical Unit Number
*
* Looks up the scsi_device with the specified @lun for a give
* @starget. The returned scsi_device does not have an additional
* reference. You must hold the host's host_lock over this call and
* any access to the returned scsi_device.
*
* Note: The only reason why drivers would want to use this is because
* they're need to access the device list in irq context. Otherwise you
* really want to use scsi_device_lookup_by_target instead.
**/
struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *starget,
uint lun)
{
struct scsi_device *sdev;
list_for_each_entry(sdev, &starget->devices, same_target_siblings) {
if (sdev->lun ==lun)
return sdev;
}
return NULL;
}
EXPORT_SYMBOL(__scsi_device_lookup_by_target);
/**
* scsi_device_lookup_by_target - find a device given the target
* @starget: SCSI target pointer
* @lun: SCSI Logical Unit Number
*
* Looks up the scsi_device with the specified @channel, @id, @lun for a
* give host. The returned scsi_device has an additional reference that
* needs to be release with scsi_host_put once you're done with it.
**/
struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *starget,
uint lun)
{
struct scsi_device *sdev;
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
sdev = __scsi_device_lookup_by_target(starget, lun);
if (sdev && scsi_device_get(sdev))
sdev = NULL;
spin_unlock_irqrestore(shost->host_lock, flags);
return sdev;
}
EXPORT_SYMBOL(scsi_device_lookup_by_target);
/**
* scsi_device_lookup - find a device given the host (UNLOCKED)
* @shost: SCSI host pointer
......
......@@ -63,6 +63,7 @@ static struct {
{"MAXTOR", "XT-4170S", "B5A", BLIST_NOLUN}, /* locks up */
{"MAXTOR", "XT-8760S", "B7B", BLIST_NOLUN}, /* locks up */
{"MEDIAVIS", "RENO CD-ROMX2A", "2.03", BLIST_NOLUN}, /* responds to all lun */
{"MICROTEK", "ScanMakerIII", "2.30", BLIST_NOLUN}, /* responds to all lun */
{"NEC", "CD-ROM DRIVE:841", "1.0", BLIST_NOLUN},/* locks up */
{"PHILIPS", "PCA80SC", "V4-2", BLIST_NOLUN}, /* responds to all lun */
{"RODIME", "RO3000S", "2.33", BLIST_NOLUN}, /* locks up */
......@@ -159,6 +160,7 @@ static struct {
{"HP", "C3323-300", "4269", BLIST_NOTQ},
{"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN},
{"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
{"IBM", "2105", NULL, BLIST_RETRY_HWERROR},
{"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
{"IOMEGA", "Io20S *F", NULL, BLIST_KEY},
{"INSITE", "Floptical F*8I", NULL, BLIST_KEY},
......@@ -192,6 +194,7 @@ static struct {
{"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36},
{"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN},
{"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */
{"ST650211", "CF", NULL, BLIST_RETRY_HWERROR},
{"SUN", "T300", "*", BLIST_SPARSELUN},
{"SUN", "T4", "*", BLIST_SPARSELUN},
{"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN},
......@@ -201,6 +204,7 @@ static struct {
{"WangDAT", "Model 2600", "01.7", BLIST_SELECT_NO_ATN},
{"WangDAT", "Model 3200", "02.2", BLIST_SELECT_NO_ATN},
{"WangDAT", "Model 1300", "02.4", BLIST_SELECT_NO_ATN},
{"WDC WD25", "00JB-00FUA0", NULL, BLIST_NOREPORTLUN},
{"XYRATEX", "RS", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
{"Zzyzx", "RocketStor 500S", NULL, BLIST_SPARSELUN},
{"Zzyzx", "RocketStor 2000", NULL, BLIST_SPARSELUN},
......
......@@ -31,6 +31,7 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsi_request.h>
#include <scsi/scsi_devinfo.h>
#include "scsi_priv.h"
#include "scsi_logging.h"
......@@ -350,10 +351,18 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
case MEDIUM_ERROR:
return NEEDS_RETRY;
case HARDWARE_ERROR:
if (scsi_get_device_flags(scmd->device,
scmd->device->vendor,
scmd->device->model)
& BLIST_RETRY_HWERROR)
return NEEDS_RETRY;
else
return SUCCESS;
case ILLEGAL_REQUEST:
case BLANK_CHECK:
case DATA_PROTECT:
case HARDWARE_ERROR:
default:
return SUCCESS;
}
......
......@@ -365,10 +365,11 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
{
struct Scsi_Host *shost = current_sdev->host;
struct scsi_device *sdev, *tmp;
struct scsi_target *starget = scsi_target(current_sdev);
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
scsi_target(current_sdev)->starget_sdev_user = NULL;
starget->starget_sdev_user = NULL;
spin_unlock_irqrestore(shost->host_lock, flags);
/*
......@@ -380,10 +381,12 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
blk_run_queue(current_sdev->request_queue);
spin_lock_irqsave(shost->host_lock, flags);
if (scsi_target(current_sdev)->starget_sdev_user)
if (starget->starget_sdev_user)
goto out;
list_for_each_entry_safe(sdev, tmp, &current_sdev->same_target_siblings,
list_for_each_entry_safe(sdev, tmp, &starget->devices,
same_target_siblings) {
if (sdev == current_sdev)
continue;
if (scsi_device_get(sdev))
continue;
......
This diff is collapsed.
......@@ -154,33 +154,25 @@ void scsi_device_dev_release(struct device *dev)
{
struct scsi_device *sdev;
struct device *parent;
struct scsi_target *starget;
unsigned long flags;
int delete;
parent = dev->parent;
sdev = to_scsi_device(dev);
starget = to_scsi_target(parent);
spin_lock_irqsave(sdev->host->host_lock, flags);
/* If we're the last LUN on the target, destroy the target */
delete = list_empty(&sdev->same_target_siblings);
starget->reap_ref++;
list_del(&sdev->siblings);
list_del(&sdev->same_target_siblings);
list_del(&sdev->starved_entry);
spin_unlock_irqrestore(sdev->host->host_lock, flags);
if (delete) {
struct scsi_target *starget = to_scsi_target(parent);
if (!starget->create) {
transport_remove_device(&starget->dev);
device_del(parent);
}
transport_destroy_device(&starget->dev);
put_device(parent);
}
if (sdev->request_queue)
scsi_free_queue(sdev->request_queue);
scsi_target_reap(scsi_target(sdev));
kfree(sdev->inquiry);
kfree(sdev);
......@@ -408,6 +400,28 @@ show_queue_type_field(struct device *dev, char *buf)
static DEVICE_ATTR(queue_type, S_IRUGO, show_queue_type_field, NULL);
static ssize_t
show_iostat_counterbits(struct device *dev, char *buf)
{
return snprintf(buf, 20, "%d\n", (int)sizeof(atomic_t) * 8);
}
static DEVICE_ATTR(iocounterbits, S_IRUGO, show_iostat_counterbits, NULL);
#define show_sdev_iostat(field) \
static ssize_t \
show_iostat_##field(struct device *dev, char *buf) \
{ \
struct scsi_device *sdev = to_scsi_device(dev); \
unsigned long long count = atomic_read(&sdev->field); \
return snprintf(buf, 20, "0x%llx\n", count); \
} \
static DEVICE_ATTR(field, S_IRUGO, show_iostat_##field, NULL)
show_sdev_iostat(iorequest_cnt);
show_sdev_iostat(iodone_cnt);
show_sdev_iostat(ioerr_cnt);
/* Default template for device attributes. May NOT be modified */
static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
......@@ -423,6 +437,10 @@ static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
&dev_attr_delete,
&dev_attr_state,
&dev_attr_timeout,
&dev_attr_iocounterbits,
&dev_attr_iorequest_cnt,
&dev_attr_iodone_cnt,
&dev_attr_ioerr_cnt,
NULL
};
......@@ -534,14 +552,6 @@ static int attr_add(struct device *dev, struct device_attribute *attr)
return device_create_file(dev, attr);
}
static void scsi_target_dev_release(struct device *dev)
{
struct scsi_target *starget = to_scsi_target(dev);
struct device *parent = dev->parent;
kfree(starget);
put_device(parent);
}
/**
* scsi_sysfs_add_sdev - add scsi device to sysfs
* @sdev: scsi_device to add
......@@ -551,25 +561,16 @@ static void scsi_target_dev_release(struct device *dev)
**/
int scsi_sysfs_add_sdev(struct scsi_device *sdev)
{
struct scsi_target *starget = sdev->sdev_target;
struct Scsi_Host *shost = sdev->host;
int error, i, create;
struct scsi_target *starget = scsi_target(sdev);
int error, i;
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
create = starget->create;
starget->create = 0;
list_add_tail(&sdev->same_target_siblings, &starget->devices);
list_add_tail(&sdev->siblings, &shost->__devices);
spin_unlock_irqrestore(shost->host_lock, flags);
if (create) {
error = device_add(&starget->dev);
if (error) {
printk(KERN_ERR "Target device_add failed\n");
return error;
}
transport_add_device(&starget->dev);
}
if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0)
return error;
......@@ -617,7 +618,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
out:
return error;
class_device_del(&sdev->sdev_classdev);
clean_device:
scsi_device_set_state(sdev, SDEV_CANCEL);
......@@ -647,12 +647,40 @@ void scsi_remove_device(struct scsi_device *sdev)
sdev->host->hostt->slave_destroy(sdev);
transport_unregister_device(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev);
out:
up(&shost->scan_mutex);
}
EXPORT_SYMBOL(scsi_remove_device);
/**
* scsi_remove_target - try to remove a target and all its devices
* @starget: the target to remove
*
* Note: This is slightly racy. It is possible that if the user
* requests the addition of another device then the target won't be
* removed.
*/
void scsi_remove_target(struct scsi_target *starget)
{
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
unsigned long flags;
struct scsi_device *sdev, *tmp;
spin_lock_irqsave(shost->host_lock, flags);
starget->reap_ref++;
list_for_each_entry_safe(sdev, tmp, &shost->__devices, siblings) {
if (sdev->channel != starget->channel ||
sdev->id != starget->id)
continue;
spin_unlock_irqrestore(shost->host_lock, flags);
scsi_remove_device(sdev);
spin_lock_irqsave(shost->host_lock, flags);
}
spin_unlock_irqrestore(shost->host_lock, flags);
scsi_target_reap(starget);
}
EXPORT_SYMBOL(scsi_remove_target);
int scsi_register_driver(struct device_driver *drv)
{
drv->bus = &scsi_bus_type;
......@@ -754,7 +782,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)
snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE,
"%d:%d:%d:%d", sdev->host->host_no,
sdev->channel, sdev->id, sdev->lun);
sdev->scsi_level = SCSI_2;
transport_setup_device(&sdev->sdev_gendev);
}
......@@ -764,73 +792,6 @@ int scsi_is_sdev_device(const struct device *dev)
}
EXPORT_SYMBOL(scsi_is_sdev_device);
int scsi_sysfs_target_initialize(struct scsi_device *sdev)
{
struct scsi_target *starget = NULL;
struct Scsi_Host *shost = sdev->host;
struct scsi_device *device;
struct device *dev = NULL;
unsigned long flags;
int create = 0;
spin_lock_irqsave(shost->host_lock, flags);
/*
* Search for an existing target for this sdev.
*/
list_for_each_entry(device, &shost->__devices, siblings) {
if (device->id == sdev->id &&
device->channel == sdev->channel) {
list_add_tail(&sdev->same_target_siblings,
&device->same_target_siblings);
sdev->scsi_level = device->scsi_level;
starget = device->sdev_target;
break;
}
}
if (!starget) {
const int size = sizeof(*starget) +
shost->transportt->target_size;
starget = kmalloc(size, GFP_ATOMIC);
if (!starget) {
printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
spin_unlock_irqrestore(shost->host_lock,
flags);
return -ENOMEM;
}
memset(starget, 0, size);
dev = &starget->dev;
device_initialize(dev);
dev->parent = get_device(&shost->shost_gendev);
dev->release = scsi_target_dev_release;
sprintf(dev->bus_id, "target%d:%d:%d",
shost->host_no, sdev->channel, sdev->id);
starget->id = sdev->id;
starget->channel = sdev->channel;
create = starget->create = 1;
/*
* If there wasn't another lun already configured at
* this target, then default this device to SCSI_2
* until we know better
*/
sdev->scsi_level = SCSI_2;
}
get_device(&starget->dev);
sdev->sdev_gendev.parent = &starget->dev;
sdev->sdev_target = starget;
list_add_tail(&sdev->siblings, &shost->__devices);
spin_unlock_irqrestore(shost->host_lock, flags);
if (create)
transport_setup_device(&starget->dev);
return 0;
}
int scsi_is_target_device(const struct device *dev)
{
return dev->release == scsi_target_dev_release;
}
EXPORT_SYMBOL(scsi_is_target_device);
/* A blank transport template that is used in drivers that don't
* yet implement Transport Attributes */
struct scsi_transport_template blank_transport_template = { NULL, };
struct scsi_transport_template blank_transport_template = { { { {0, }, }, }, };
......@@ -254,16 +254,8 @@ static int fc_add_host(struct device *dev)
sizeof(fc_host_symbolic_name(shost)));
fc_host_supported_speeds(shost) = FC_PORTSPEED_UNKNOWN;
fc_host_maxframe_size(shost) = -1;
memset(fc_host_hardware_version(shost), 0,
sizeof(fc_host_hardware_version(shost)));
memset(fc_host_firmware_version(shost), 0,
sizeof(fc_host_firmware_version(shost)));
memset(fc_host_serial_number(shost), 0,
sizeof(fc_host_serial_number(shost)));
memset(fc_host_opt_rom_version(shost), 0,
sizeof(fc_host_opt_rom_version(shost)));
memset(fc_host_driver_version(shost), 0,
sizeof(fc_host_driver_version(shost)));
fc_host_port_id(shost) = -1;
fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
......@@ -539,11 +531,7 @@ fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
fc_private_host_rd_attr(symbolic_name, "%s\n", (FC_SYMBOLIC_NAME_SIZE +1));
fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);
fc_private_host_rd_attr(hardware_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
fc_private_host_rd_attr(firmware_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));
fc_private_host_rd_attr(opt_rom_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
fc_private_host_rd_attr(driver_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
/* Dynamic Host Attributes */
......@@ -734,13 +722,13 @@ static int fc_host_match(struct attribute_container *cont,
return 0;
shost = dev_to_shost(dev);
if (!shost->transportt || shost->transportt->host_attrs.class
if (!shost->transportt || shost->transportt->host_attrs.ac.class
!= &fc_host_class.class)
return 0;
i = to_fc_internal(shost->transportt);
return &i->t.host_attrs == cont;
return &i->t.host_attrs.ac == cont;
}
static int fc_target_match(struct attribute_container *cont,
......@@ -753,13 +741,13 @@ static int fc_target_match(struct attribute_container *cont,
return 0;
shost = dev_to_shost(dev->parent);
if (!shost->transportt || shost->transportt->host_attrs.class
if (!shost->transportt || shost->transportt->host_attrs.ac.class
!= &fc_host_class.class)
return 0;
i = to_fc_internal(shost->transportt);
return &i->t.target_attrs == cont;
return &i->t.target_attrs.ac == cont;
}
......@@ -775,20 +763,21 @@ fc_attach_transport(struct fc_function_template *ft)
memset(i, 0, sizeof(struct fc_internal));
i->t.target_attrs.attrs = &i->starget_attrs[0];
i->t.target_attrs.class = &fc_transport_class.class;
i->t.target_attrs.match = fc_target_match;
attribute_container_register(&i->t.target_attrs);
i->t.target_attrs.ac.attrs = &i->starget_attrs[0];
i->t.target_attrs.ac.class = &fc_transport_class.class;
i->t.target_attrs.ac.match = fc_target_match;
transport_container_register(&i->t.target_attrs);
i->t.target_size = sizeof(struct fc_starget_attrs);
i->t.host_attrs.attrs = &i->host_attrs[0];
i->t.host_attrs.class = &fc_host_class.class;
i->t.host_attrs.match = fc_host_match;
attribute_container_register(&i->t.host_attrs);
i->t.host_attrs.ac.attrs = &i->host_attrs[0];
i->t.host_attrs.ac.class = &fc_host_class.class;
i->t.host_attrs.ac.match = fc_host_match;
i->t.host_size = sizeof(struct fc_host_attrs);
if (ft->get_fc_host_stats)
i->t.host_statistics = &fc_statistics_group;
i->t.host_attrs.statistics = &fc_statistics_group;
transport_container_register(&i->t.host_attrs);
i->f = ft;
......@@ -817,11 +806,7 @@ fc_attach_transport(struct fc_function_template *ft)
SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
SETUP_HOST_ATTRIBUTE_RD(supported_speeds);
SETUP_HOST_ATTRIBUTE_RD(maxframe_size);
SETUP_HOST_ATTRIBUTE_RD(hardware_version);
SETUP_HOST_ATTRIBUTE_RD(firmware_version);
SETUP_HOST_ATTRIBUTE_RD(serial_number);
SETUP_HOST_ATTRIBUTE_RD(opt_rom_version);
SETUP_HOST_ATTRIBUTE_RD(driver_version);
SETUP_HOST_ATTRIBUTE_RD(port_id);
SETUP_HOST_ATTRIBUTE_RD(port_type);
......@@ -847,6 +832,9 @@ void fc_release_transport(struct scsi_transport_template *t)
{
struct fc_internal *i = to_fc_internal(t);
transport_container_unregister(&i->t.target_attrs);
transport_container_unregister(&i->t.host_attrs);
attribute_container_unregister(&i->t.target_attrs);
attribute_container_unregister(&i->t.host_attrs);
......
......@@ -264,13 +264,13 @@ static int iscsi_host_match(struct attribute_container *cont,
return 0;
shost = dev_to_shost(dev);
if (!shost->transportt || shost->transportt->host_attrs.class
if (!shost->transportt || shost->transportt->host_attrs.ac.class
!= &iscsi_host_class.class)
return 0;
i = to_iscsi_internal(shost->transportt);
return &i->t.host_attrs == cont;
return &i->t.host_attrs.ac == cont;
}
static int iscsi_target_match(struct attribute_container *cont,
......@@ -283,13 +283,13 @@ static int iscsi_target_match(struct attribute_container *cont,
return 0;
shost = dev_to_shost(dev->parent);
if (!shost->transportt || shost->transportt->host_attrs.class
if (!shost->transportt || shost->transportt->host_attrs.ac.class
!= &iscsi_host_class.class)
return 0;
i = to_iscsi_internal(shost->transportt);
return &i->t.target_attrs == cont;
return &i->t.target_attrs.ac == cont;
}
struct scsi_transport_template *
......@@ -305,10 +305,10 @@ iscsi_attach_transport(struct iscsi_function_template *fnt)
memset(i, 0, sizeof(struct iscsi_internal));
i->fnt = fnt;
i->t.target_attrs.attrs = &i->session_attrs[0];
i->t.target_attrs.class = &iscsi_transport_class.class;
i->t.target_attrs.match = iscsi_target_match;
attribute_container_register(&i->t.target_attrs);
i->t.target_attrs.ac.attrs = &i->session_attrs[0];
i->t.target_attrs.ac.class = &iscsi_transport_class.class;
i->t.target_attrs.ac.match = iscsi_target_match;
transport_container_register(&i->t.target_attrs);
i->t.target_size = sizeof(struct iscsi_class_session);
SETUP_SESSION_RD_ATTR(tsih);
......@@ -335,10 +335,10 @@ iscsi_attach_transport(struct iscsi_function_template *fnt)
BUG_ON(count > ISCSI_SESSION_ATTRS);
i->session_attrs[count] = NULL;
i->t.host_attrs.attrs = &i->host_attrs[0];
i->t.host_attrs.class = &iscsi_host_class.class;
i->t.host_attrs.match = iscsi_host_match;
attribute_container_register(&i->t.host_attrs);
i->t.host_attrs.ac.attrs = &i->host_attrs[0];
i->t.host_attrs.ac.class = &iscsi_host_class.class;
i->t.host_attrs.ac.match = iscsi_host_match;
transport_container_register(&i->t.host_attrs);
i->t.host_size = 0;
count = 0;
......@@ -357,9 +357,9 @@ void iscsi_release_transport(struct scsi_transport_template *t)
{
struct iscsi_internal *i = to_iscsi_internal(t);
attribute_container_unregister(&i->t.target_attrs);
attribute_container_unregister(&i->t.host_attrs);
transport_container_unregister(&i->t.target_attrs);
transport_container_unregister(&i->t.host_attrs);
kfree(i);
}
......
......@@ -18,15 +18,11 @@
* 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/module.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <asm/scatterlist.h>
#include <asm/io.h>
#include <asm/semaphore.h>
#include <scsi/scsi.h>
#include "scsi_priv.h"
#include <scsi/scsi_device.h>
......@@ -63,27 +59,47 @@ struct spi_internal {
#define to_spi_internal(tmpl) container_of(tmpl, struct spi_internal, t)
static const char *const ppr_to_ns[] = {
static const int ppr_to_ps[] = {
/* The PPR values 0-6 are reserved, fill them in when
* the committee defines them */
NULL, /* 0x00 */
NULL, /* 0x01 */
NULL, /* 0x02 */
NULL, /* 0x03 */
NULL, /* 0x04 */
NULL, /* 0x05 */
NULL, /* 0x06 */
"3.125", /* 0x07 */
"6.25", /* 0x08 */
"12.5", /* 0x09 */
"25", /* 0x0a */
"30.3", /* 0x0b */
"50", /* 0x0c */
-1, /* 0x00 */
-1, /* 0x01 */
-1, /* 0x02 */
-1, /* 0x03 */
-1, /* 0x04 */
-1, /* 0x05 */
-1, /* 0x06 */
3125, /* 0x07 */
6250, /* 0x08 */
12500, /* 0x09 */
25000, /* 0x0a */
30300, /* 0x0b */
50000, /* 0x0c */
};
/* The PPR values at which you calculate the period in ns by multiplying
* by 4 */
#define SPI_STATIC_PPR 0x0c
static int sprint_frac(char *dest, int value, int denom)
{
int frac = value % denom;
int result = sprintf(dest, "%d", value / denom);
if (frac == 0)
return result;
dest[result++] = '.';
do {
denom /= 10;
sprintf(dest + result, "%d", frac / denom);
result++;
frac %= denom;
} while (frac);
dest[result++] = '\0';
return result;
}
static struct {
enum spi_signal_type value;
char *name;
......@@ -142,13 +158,13 @@ static int spi_host_match(struct attribute_container *cont,
return 0;
shost = dev_to_shost(dev);
if (!shost->transportt || shost->transportt->host_attrs.class
if (!shost->transportt || shost->transportt->host_attrs.ac.class
!= &spi_host_class.class)
return 0;
i = to_spi_internal(shost->transportt);
return &i->t.host_attrs == cont;
return &i->t.host_attrs.ac == cont;
}
static int spi_device_configure(struct device *dev)
......@@ -261,7 +277,7 @@ static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf)
struct scsi_target *starget = transport_class_to_starget(cdev);
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
struct spi_transport_attrs *tp;
const char *str;
int len, picosec;
struct spi_internal *i = to_spi_internal(shost->transportt);
tp = (struct spi_transport_attrs *)&starget->starget_data;
......@@ -269,22 +285,20 @@ static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf)
if (i->f->get_period)
i->f->get_period(starget);
switch(tp->period) {
case 0x07 ... SPI_STATIC_PPR:
str = ppr_to_ns[tp->period];
if(!str)
str = "reserved";
break;
case (SPI_STATIC_PPR+1) ... 0xff:
return sprintf(buf, "%d\n", tp->period * 4);
default:
str = "unknown";
if (tp->period < 0 || tp->period > 0xff) {
picosec = -1;
} else if (tp->period <= SPI_STATIC_PPR) {
picosec = ppr_to_ps[tp->period];
} else {
picosec = tp->period * 4000;
}
return sprintf(buf, "%s\n", str);
if (picosec == -1)
return sprintf(buf, "reserved");
len = sprint_frac(buf, picosec, 1000);
buf[len++] = '\n';
buf[len] = '\0';
return len;
}
static ssize_t
......@@ -294,34 +308,30 @@ store_spi_transport_period(struct class_device *cdev, const char *buf,
struct scsi_target *starget = transport_class_to_starget(cdev);
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
struct spi_internal *i = to_spi_internal(shost->transportt);
int j, period = -1;
for (j = 0; j < SPI_STATIC_PPR; j++) {
int len;
if(ppr_to_ns[j] == NULL)
continue;
len = strlen(ppr_to_ns[j]);
if(strncmp(ppr_to_ns[j], buf, len) != 0)
continue;
int j, picosec, period = -1;
char *endp;
picosec = simple_strtoul(buf, &endp, 10) * 1000;
if (*endp == '.') {
int mult = 100;
do {
endp++;
if (!isdigit(*endp))
break;
picosec += (*endp - '0') * mult;
mult /= 10;
} while (mult > 0);
}
if(buf[len] != '\n')
for (j = 0; j <= SPI_STATIC_PPR; j++) {
if (ppr_to_ps[j] < picosec)
continue;
period = j;
break;
}
if (period == -1) {
int val = simple_strtoul(buf, NULL, 0);
/* Should probably check limits here, but this
* gets reasonably close to OK for most things */
period = val/4;
}
if (period == -1)
period = picosec / 4000;
if (period > 0xff)
period = 0xff;
......@@ -330,7 +340,7 @@ store_spi_transport_period(struct class_device *cdev, const char *buf,
return count;
}
static CLASS_DEVICE_ATTR(period, S_IRUGO | S_IWUSR,
show_spi_transport_period,
store_spi_transport_period);
......@@ -795,6 +805,61 @@ spi_schedule_dv_device(struct scsi_device *sdev)
}
EXPORT_SYMBOL(spi_schedule_dv_device);
/**
* spi_display_xfer_agreement - Print the current target transfer agreement
* @starget: The target for which to display the agreement
*
* Each SPI port is required to maintain a transfer agreement for each
* other port on the bus. This function prints a one-line summary of
* the current agreement; more detailed information is available in sysfs.
*/
void spi_display_xfer_agreement(struct scsi_target *starget)
{
struct spi_transport_attrs *tp;
tp = (struct spi_transport_attrs *)&starget->starget_data;
if (tp->offset > 0 && tp->period > 0) {
unsigned int picosec, kb100;
char *scsi = "FAST-?";
char tmp[8];
if (tp->period <= SPI_STATIC_PPR) {
picosec = ppr_to_ps[tp->period];
switch (tp->period) {
case 7: scsi = "FAST-320"; break;
case 8: scsi = "FAST-160"; break;
case 9: scsi = "FAST-80"; break;
case 10:
case 11: scsi = "FAST-40"; break;
case 12: scsi = "FAST-20"; break;
}
} else {
picosec = tp->period * 4000;
if (tp->period < 25)
scsi = "FAST-20";
else if (tp->period < 50)
scsi = "FAST-10";
else
scsi = "FAST-5";
}
kb100 = (10000000 + picosec / 2) / picosec;
if (tp->width)
kb100 *= 2;
sprint_frac(tmp, picosec, 1000);
dev_info(&starget->dev,
"%s %sSCSI %d.%d MB/s %s%s%s (%s ns, offset %d)\n",
scsi, tp->width ? "WIDE " : "", kb100/10, kb100 % 10,
tp->dt ? "DT" : "ST", tp->iu ? " IU" : "",
tp->qas ? " QAS" : "", tmp, tp->offset);
} else {
dev_info(&starget->dev, "%sasynchronous.\n",
tp->width ? "wide " : "");
}
}
EXPORT_SYMBOL(spi_display_xfer_agreement);
#define SETUP_ATTRIBUTE(field) \
i->private_attrs[count] = class_device_attr_##field; \
if (!i->f->set_##field) { \
......@@ -825,7 +890,7 @@ static int spi_device_match(struct attribute_container *cont,
sdev = to_scsi_device(dev);
shost = sdev->host;
if (!shost->transportt || shost->transportt->host_attrs.class
if (!shost->transportt || shost->transportt->host_attrs.ac.class
!= &spi_host_class.class)
return 0;
/* Note: this class has no device attributes, so it has
......@@ -844,13 +909,13 @@ static int spi_target_match(struct attribute_container *cont,
return 0;
shost = dev_to_shost(dev->parent);
if (!shost->transportt || shost->transportt->host_attrs.class
if (!shost->transportt || shost->transportt->host_attrs.ac.class
!= &spi_host_class.class)
return 0;
i = to_spi_internal(shost->transportt);
return &i->t.target_attrs == cont;
return &i->t.target_attrs.ac == cont;
}
static DECLARE_TRANSPORT_CLASS(spi_transport_class,
......@@ -875,15 +940,15 @@ spi_attach_transport(struct spi_function_template *ft)
memset(i, 0, sizeof(struct spi_internal));
i->t.target_attrs.class = &spi_transport_class.class;
i->t.target_attrs.attrs = &i->attrs[0];
i->t.target_attrs.match = spi_target_match;
attribute_container_register(&i->t.target_attrs);
i->t.target_attrs.ac.class = &spi_transport_class.class;
i->t.target_attrs.ac.attrs = &i->attrs[0];
i->t.target_attrs.ac.match = spi_target_match;
transport_container_register(&i->t.target_attrs);
i->t.target_size = sizeof(struct spi_transport_attrs);
i->t.host_attrs.class = &spi_host_class.class;
i->t.host_attrs.attrs = &i->host_attrs[0];
i->t.host_attrs.match = spi_host_match;
attribute_container_register(&i->t.host_attrs);
i->t.host_attrs.ac.class = &spi_host_class.class;
i->t.host_attrs.ac.attrs = &i->host_attrs[0];
i->t.host_attrs.ac.match = spi_host_match;
transport_container_register(&i->t.host_attrs);
i->t.host_size = sizeof(struct spi_host_attrs);
i->f = ft;
......@@ -921,6 +986,9 @@ void spi_release_transport(struct scsi_transport_template *t)
{
struct spi_internal *i = to_spi_internal(t);
transport_container_unregister(&i->t.target_attrs);
transport_container_unregister(&i->t.host_attrs);
attribute_container_unregister(&i->t.target_attrs);
attribute_container_unregister(&i->t.host_attrs);
......
......@@ -784,11 +784,50 @@ static void sd_rescan(struct device *dev)
sd_revalidate_disk(sdkp->disk);
}
#ifdef CONFIG_COMPAT
/*
* This gets directly called from VFS. When the ioctl
* is not recognized we go back to the other translation paths.
*/
static long sd_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct block_device *bdev = file->f_dentry->d_inode->i_bdev;
struct gendisk *disk = bdev->bd_disk;
struct scsi_device *sdev = scsi_disk(disk)->device;
/*
* If we are in the middle of error recovery, don't let anyone
* else try and use this device. Also, if error recovery fails, it
* may try and take the device offline, in which case all further
* access to the device is prohibited.
*/
if (!scsi_block_when_processing_errors(sdev))
return -ENODEV;
if (sdev->host->hostt->compat_ioctl) {
int ret;
ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
return ret;
}
/*
* Let the static ioctl translation table take care of it.
*/
return -ENOIOCTLCMD;
}
#endif
static struct block_device_operations sd_fops = {
.owner = THIS_MODULE,
.open = sd_open,
.release = sd_release,
.ioctl = sd_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = sd_compat_ioctl,
#endif
.media_changed = sd_media_changed,
.revalidate_disk = sd_revalidate_disk,
};
......
......@@ -1031,6 +1031,29 @@ sg_ioctl(struct inode *inode, struct file *filp,
}
}
#ifdef CONFIG_COMPAT
static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
{
Sg_device *sdp;
Sg_fd *sfp;
struct scsi_device *sdev;
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
return -ENXIO;
sdev = sdp->device;
if (sdev->host->hostt->compat_ioctl) {
int ret;
ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
return ret;
}
return -ENOIOCTLCMD;
}
#endif
static unsigned int
sg_poll(struct file *filp, poll_table * wait)
{
......@@ -1340,6 +1363,9 @@ static struct file_operations sg_fops = {
.write = sg_write,
.poll = sg_poll,
.ioctl = sg_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = sg_compat_ioctl,
#endif
.open = sg_open,
.mmap = sg_mmap,
.release = sg_release,
......
......@@ -47,7 +47,7 @@
#define MAX_SLOTS 8
static __u8 __initdata id_array[MAX_SLOTS] = { [0 ... MAX_SLOTS-1] = 7 };
char *sim710; /* command line passed by insmod */
static char *sim710; /* command line passed by insmod */
MODULE_AUTHOR("Richard Hirst");
MODULE_DESCRIPTION("Simple NCR53C710 driver");
......@@ -61,7 +61,7 @@ module_param(sim710, charp, 0);
#define ARG_SEP ','
#endif
__init int
static __init int
param_setup(char *str)
{
char *pos = str, *next;
......@@ -314,7 +314,7 @@ sim710_eisa_probe(struct device *dev)
differential, scsi_id);
}
struct eisa_driver sim710_eisa_driver = {
static struct eisa_driver sim710_eisa_driver = {
.id_table = sim710_eisa_ids,
.driver = {
.name = "sim710",
......
......@@ -518,6 +518,10 @@ static struct block_device_operations sr_bdops =
.release = sr_block_release,
.ioctl = sr_block_ioctl,
.media_changed = sr_block_media_changed,
/*
* No compat_ioctl for now because sr_block_ioctl never
* seems to pass arbitary ioctls down to host drivers.
*/
};
static int sr_open(struct cdrom_device_info *cdi, int purpose)
......
This diff is collapsed.
......@@ -5,6 +5,18 @@
#include <linux/completion.h>
/* Descriptor for analyzed sense data */
struct st_cmdstatus {
int midlevel_result;
struct scsi_sense_hdr sense_hdr;
int have_sense;
u64 uremainder64;
u8 flags;
u8 remainder_valid;
u8 fixed_format;
u8 deferred;
};
/* The tape buffer descriptor. */
struct st_buffer {
unsigned char in_use;
......@@ -15,9 +27,9 @@ struct st_buffer {
int buffer_bytes;
int read_pointer;
int writing;
int midlevel_result;
int syscall_result;
struct scsi_request *last_SRpnt;
struct st_cmdstatus cmdstat;
unsigned char *b_data;
unsigned short use_sg; /* zero or max number of s/g segments for this adapter */
unsigned short sg_segs; /* number of segments in s/g list */
......@@ -192,4 +204,9 @@ struct scsi_tape {
#define EXTENDED_SENSE_START 18
/* Masks for some conditions in the sense data */
#define SENSE_FMK 0x80
#define SENSE_EOM 0x40
#define SENSE_ILI 0x20
#endif
# Makefile for the NCR/SYMBIOS/LSI 53C8XX PCI SCSI controllers driver.
sym53c8xx-objs := sym_fw.o sym_glue.o sym_hipd.o sym_malloc.o sym_misc.o sym_nvram.o
sym53c8xx-objs := sym_fw.o sym_glue.o sym_hipd.o sym_malloc.o sym_nvram.o
obj-$(CONFIG_SCSI_SYM53C8XX_2) := sym53c8xx.o
......@@ -42,10 +42,6 @@
#include <linux/config.h>
#ifdef CONFIG_SCSI_SYM53C8XX_IOMAPPED
#define SYM_CONF_IOMAPPED
#endif
/*
* DMA addressing mode.
*
......@@ -144,10 +140,6 @@ struct sym_driver_setup {
#define SYM_SETUP_HOST_ID sym_driver_setup.host_id
#define boot_verbose sym_driver_setup.verbose
/* Always enable parity. */
#define SYM_SETUP_PCI_PARITY 1
#define SYM_SETUP_SCSI_PARITY 1
/*
* Initial setup.
*
......@@ -170,4 +162,56 @@ extern struct sym_driver_setup sym_driver_setup;
extern unsigned int sym_debug_flags;
#define DEBUG_FLAGS sym_debug_flags
/*
* Max number of targets.
* Maximum is 16 and you are advised not to change this value.
*/
#ifndef SYM_CONF_MAX_TARGET
#define SYM_CONF_MAX_TARGET (16)
#endif
/*
* Max number of logical units.
* SPI-2 allows up to 64 logical units, but in real life, target
* that implements more that 7 logical units are pretty rare.
* Anyway, the cost of accepting up to 64 logical unit is low in
* this driver, thus going with the maximum is acceptable.
*/
#ifndef SYM_CONF_MAX_LUN
#define SYM_CONF_MAX_LUN (64)
#endif
/*
* Max number of IO control blocks queued to the controller.
* Each entry needs 8 bytes and the queues are allocated contiguously.
* Since we donnot want to allocate more than a page, the theorical
* maximum is PAGE_SIZE/8. For safety, we announce a bit less to the
* access method. :)
* When not supplied, as it is suggested, the driver compute some
* good value for this parameter.
*/
/* #define SYM_CONF_MAX_START (PAGE_SIZE/8 - 16) */
/*
* Support for Immediate Arbitration.
* Not advised.
*/
/* #define SYM_CONF_IARB_SUPPORT */
/*
* Only relevant if IARB support configured.
* - Max number of successive settings of IARB hints.
* - Set IARB on arbitration lost.
*/
#define SYM_CONF_IARB_MAX 3
#define SYM_CONF_SET_IARB_ON_ARB_LOST 1
/*
* Returning wrong residuals may make problems.
* When zero, this define tells the driver to
* always return 0 as transfer residual.
* Btw, all my testings of residuals have succeeded.
*/
#define SYM_SETUP_RESIDUAL_SUPPORT 1
#endif /* SYM53C8XX_H */
/*
* Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family
* of PCI-SCSI IO processors.
*
* Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr>
*
* This driver is derived from the Linux sym53c8xx driver.
* Copyright (C) 1998-2000 Gerard Roudier
*
* The sym53c8xx driver is derived from the ncr53c8xx driver that had been
* a port of the FreeBSD ncr driver to Linux-1.2.13.
*
* The original ncr driver has been written for 386bsd and FreeBSD by
* Wolfgang Stanglmeier <wolf@cologne.de>
* Stefan Esser <se@mi.Uni-Koeln.de>
* Copyright (C) 1994 Wolfgang Stanglmeier
*
* Other major contributions:
*
* NVRAM detection and reading.
* Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
*
*-----------------------------------------------------------------------------
*
* 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 SYM_CONF_H
#define SYM_CONF_H
#include "sym53c8xx.h"
/*
* Max number of targets.
* Maximum is 16 and you are advised not to change this value.
*/
#ifndef SYM_CONF_MAX_TARGET
#define SYM_CONF_MAX_TARGET (16)
#endif
/*
* Max number of logical units.
* SPI-2 allows up to 64 logical units, but in real life, target
* that implements more that 7 logical units are pretty rare.
* Anyway, the cost of accepting up to 64 logical unit is low in
* this driver, thus going with the maximum is acceptable.
*/
#ifndef SYM_CONF_MAX_LUN
#define SYM_CONF_MAX_LUN (64)
#endif
/*
* Max number of IO control blocks queued to the controller.
* Each entry needs 8 bytes and the queues are allocated contiguously.
* Since we donnot want to allocate more than a page, the theorical
* maximum is PAGE_SIZE/8. For safety, we announce a bit less to the
* access method. :)
* When not supplied, as it is suggested, the driver compute some
* good value for this parameter.
*/
/* #define SYM_CONF_MAX_START (PAGE_SIZE/8 - 16) */
/*
* Support for Immediate Arbitration.
* Not advised.
*/
/* #define SYM_CONF_IARB_SUPPORT */
/*
* Only relevant if IARB support configured.
* - Max number of successive settings of IARB hints.
* - Set IARB on arbitration lost.
*/
#define SYM_CONF_IARB_MAX 3
#define SYM_CONF_SET_IARB_ON_ARB_LOST 1
/*
* Returning wrong residuals may make problems.
* When zero, this define tells the driver to
* always return 0 as transfer residual.
* Btw, all my testings of residuals have succeeded.
*/
#define SYM_SETUP_RESIDUAL_SUPPORT 1
/*
* Supported maximum number of LUNs to announce to
* the access method.
* The driver supports up to 64 LUNs per target as
* required by SPI-2/SPI-3. However some SCSI devices
* designed prior to these specifications or not being
* conformant may be highly confused when they are
* asked about a LUN > 7.
*/
#ifndef SYM_SETUP_MAX_LUN
#define SYM_SETUP_MAX_LUN (8)
#endif
#endif /* SYM_CONF_H */
......@@ -40,13 +40,13 @@
#ifndef SYM_DEFS_H
#define SYM_DEFS_H
#define SYM_VERSION "2.1.18n"
#define SYM_VERSION "2.2.0"
#define SYM_DRIVER_NAME "sym-" SYM_VERSION
/*
* SYM53C8XX device features descriptor.
*/
struct sym_pci_chip {
struct sym_chip {
u_short device_id;
u_short revision_id;
char *name;
......
......@@ -361,7 +361,7 @@ static struct sym_fw sym_fw2 = SYM_FW_ENTRY(sym_fw2, "LOAD/STORE-based");
* Find the most appropriate firmware for a chip.
*/
struct sym_fw *
sym_find_firmware(struct sym_pci_chip *chip)
sym_find_firmware(struct sym_chip *chip)
{
if (chip->features & FE_LDSTR)
return &sym_fw2;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family
* of PCI-SCSI IO processors.
*
* Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr>
*
* This driver is derived from the Linux sym53c8xx driver.
* Copyright (C) 1998-2000 Gerard Roudier
*
* The sym53c8xx driver is derived from the ncr53c8xx driver that had been
* a port of the FreeBSD ncr driver to Linux-1.2.13.
*
* The original ncr driver has been written for 386bsd and FreeBSD by
* Wolfgang Stanglmeier <wolf@cologne.de>
* Stefan Esser <se@mi.Uni-Koeln.de>
* Copyright (C) 1994 Wolfgang Stanglmeier
*
* Other major contributions:
*
* NVRAM detection and reading.
* Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
*
*-----------------------------------------------------------------------------
*
* 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 "sym_glue.h"
#ifdef SYM_OPT_ANNOUNCE_TRANSFER_RATE
/*
* Announce transfer rate if anything changed since last announcement.
*/
void sym_announce_transfer_rate(struct sym_hcb *np, int target)
{
tcb_p tp = &np->target[target];
#define __tprev tp->tinfo.prev
#define __tcurr tp->tinfo.curr
if (__tprev.options == __tcurr.options &&
__tprev.width == __tcurr.width &&
__tprev.offset == __tcurr.offset &&
!(__tprev.offset && __tprev.period != __tcurr.period))
return;
__tprev.options = __tcurr.options;
__tprev.width = __tcurr.width;
__tprev.offset = __tcurr.offset;
__tprev.period = __tcurr.period;
if (__tcurr.offset && __tcurr.period) {
u_int period, f10, mb10;
char *scsi;
period = f10 = mb10 = 0;
scsi = "FAST-5";
if (__tcurr.period <= 9) {
scsi = "FAST-80";
period = 125;
mb10 = 1600;
}
else {
if (__tcurr.period <= 11) {
scsi = "FAST-40";
period = 250;
if (__tcurr.period == 11)
period = 303;
}
else if (__tcurr.period < 25) {
scsi = "FAST-20";
if (__tcurr.period == 12)
period = 500;
}
else if (__tcurr.period <= 50) {
scsi = "FAST-10";
}
if (!period)
period = 40 * __tcurr.period;
f10 = 100000 << (__tcurr.width ? 1 : 0);
mb10 = (f10 + period/2) / period;
}
printf_info (
"%s:%d: %s %sSCSI %d.%d MB/s %s%s%s (%d.%d ns, offset %d)\n",
sym_name(np), target, scsi, __tcurr.width? "WIDE " : "",
mb10/10, mb10%10,
(__tcurr.options & PPR_OPT_DT) ? "DT" : "ST",
(__tcurr.options & PPR_OPT_IU) ? " IU" : "",
(__tcurr.options & PPR_OPT_QAS) ? " QAS" : "",
period/10, period%10, __tcurr.offset);
}
else
printf_info ("%s:%d: %sasynchronous.\n",
sym_name(np), target, __tcurr.width? "wide " : "");
}
#undef __tprev
#undef __tcurr
#endif /* SYM_OPT_ANNOUNCE_TRANSFER_RATE */
This diff is collapsed.
......@@ -40,7 +40,7 @@
#ifndef SYM_NVRAM_H
#define SYM_NVRAM_H
#include "sym_conf.h"
#include "sym53c8xx.h"
/*
* Symbios NVRAM data format
......@@ -193,17 +193,22 @@ struct sym_nvram {
};
#if SYM_CONF_NVRAM_SUPPORT
void sym_nvram_setup_host (struct sym_hcb *np, struct sym_nvram *nvram);
void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram);
void sym_nvram_setup_target (struct sym_hcb *np, int target, struct sym_nvram *nvp);
int sym_read_nvram (struct sym_device *np, struct sym_nvram *nvp);
char *sym_nvram_type(struct sym_nvram *nvp);
#else
static inline void sym_nvram_setup_host(struct sym_hcb *np, struct sym_nvram *nvram) { }
static inline void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) { }
static inline void sym_nvram_setup_target(struct sym_hcb *np, struct sym_nvram *nvram) { }
static inline int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp)
{
nvp->type = 0;
return 0;
}
static inline char *sym_nvram_type(struct sym_nvram *nvp)
{
return "No NVRAM";
}
#endif
#endif /* SYM_NVRAM_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment