Automatic merge of rsync://www.parisc-linux.org/~jejb/git/scsi-for-linus-2.6.git
This commit is contained in:
commit
9636273dae
|
@ -41,7 +41,6 @@
|
||||||
|
|
||||||
#include "aic7xxx_osm.h"
|
#include "aic7xxx_osm.h"
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/eisa.h>
|
#include <linux/eisa.h>
|
||||||
|
|
||||||
|
@ -62,13 +61,6 @@ static struct eisa_driver aic7770_driver = {
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct device *aic7770_dev_t;
|
typedef struct device *aic7770_dev_t;
|
||||||
#else
|
|
||||||
#define MINSLOT 1
|
|
||||||
#define NUMSLOTS 16
|
|
||||||
#define IDOFFSET 0x80
|
|
||||||
|
|
||||||
typedef void *aic7770_dev_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int aic7770_linux_config(struct aic7770_identity *entry,
|
static int aic7770_linux_config(struct aic7770_identity *entry,
|
||||||
aic7770_dev_t dev, u_int eisaBase);
|
aic7770_dev_t dev, u_int eisaBase);
|
||||||
|
@ -76,7 +68,6 @@ static int aic7770_linux_config(struct aic7770_identity *entry,
|
||||||
int
|
int
|
||||||
ahc_linux_eisa_init(void)
|
ahc_linux_eisa_init(void)
|
||||||
{
|
{
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
|
|
||||||
struct eisa_device_id *eid;
|
struct eisa_device_id *eid;
|
||||||
struct aic7770_identity *id;
|
struct aic7770_identity *id;
|
||||||
int i;
|
int i;
|
||||||
|
@ -110,44 +101,6 @@ ahc_linux_eisa_init(void)
|
||||||
eid->sig[0] = 0;
|
eid->sig[0] = 0;
|
||||||
|
|
||||||
return eisa_driver_register(&aic7770_driver);
|
return eisa_driver_register(&aic7770_driver);
|
||||||
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */
|
|
||||||
struct aic7770_identity *entry;
|
|
||||||
u_int slot;
|
|
||||||
u_int eisaBase;
|
|
||||||
u_int i;
|
|
||||||
int ret = -ENODEV;
|
|
||||||
|
|
||||||
if (aic7xxx_probe_eisa_vl == 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
|
|
||||||
for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
|
|
||||||
uint32_t eisa_id;
|
|
||||||
size_t id_size;
|
|
||||||
|
|
||||||
if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
eisa_id = 0;
|
|
||||||
id_size = sizeof(eisa_id);
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
/* VLcards require priming*/
|
|
||||||
outb(0x80 + i, eisaBase + IDOFFSET);
|
|
||||||
eisa_id |= inb(eisaBase + IDOFFSET + i)
|
|
||||||
<< ((id_size-i-1) * 8);
|
|
||||||
}
|
|
||||||
release_region(eisaBase, AHC_EISA_IOSIZE);
|
|
||||||
if (eisa_id & 0x80000000)
|
|
||||||
continue; /* no EISA card in slot */
|
|
||||||
|
|
||||||
entry = aic7770_find_device(eisa_id);
|
|
||||||
if (entry != NULL) {
|
|
||||||
aic7770_linux_config(entry, NULL, eisaBase);
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -187,11 +140,10 @@ aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev,
|
||||||
ahc_free(ahc);
|
ahc_free(ahc);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
|
|
||||||
dev->driver_data = (void *)ahc;
|
dev->driver_data = (void *)ahc;
|
||||||
if (aic7xxx_detect_complete)
|
if (aic7xxx_detect_complete)
|
||||||
error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
|
error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
|
||||||
#endif
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +177,6 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq)
|
||||||
return (-error);
|
return (-error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
|
|
||||||
static int
|
static int
|
||||||
aic7770_eisa_dev_probe(struct device *dev)
|
aic7770_eisa_dev_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
|
@ -261,4 +212,3 @@ aic7770_eisa_dev_remove(struct device *dev)
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -59,6 +59,7 @@
|
||||||
#ifndef _AIC7XXX_LINUX_H_
|
#ifndef _AIC7XXX_LINUX_H_
|
||||||
#define _AIC7XXX_LINUX_H_
|
#define _AIC7XXX_LINUX_H_
|
||||||
|
|
||||||
|
#include <linux/config.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
@ -66,18 +67,21 @@
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/smp_lock.h>
|
#include <linux/smp_lock.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#include <linux/interrupt.h> /* For tasklet support. */
|
#include <scsi/scsi.h>
|
||||||
#include <linux/config.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
#include <linux/slab.h>
|
#include <scsi/scsi_eh.h>
|
||||||
|
#include <scsi/scsi_device.h>
|
||||||
|
#include <scsi/scsi_host.h>
|
||||||
|
#include <scsi/scsi_tcq.h>
|
||||||
|
|
||||||
/* Core SCSI definitions */
|
/* Core SCSI definitions */
|
||||||
#define AIC_LIB_PREFIX ahc
|
#define AIC_LIB_PREFIX ahc
|
||||||
#include "scsi.h"
|
|
||||||
#include <scsi/scsi_host.h>
|
|
||||||
|
|
||||||
/* Name space conflict with BSD queue macros */
|
/* Name space conflict with BSD queue macros */
|
||||||
#ifdef LIST_HEAD
|
#ifdef LIST_HEAD
|
||||||
|
@ -106,7 +110,7 @@
|
||||||
/************************* Forward Declarations *******************************/
|
/************************* Forward Declarations *******************************/
|
||||||
struct ahc_softc;
|
struct ahc_softc;
|
||||||
typedef struct pci_dev *ahc_dev_softc_t;
|
typedef struct pci_dev *ahc_dev_softc_t;
|
||||||
typedef Scsi_Cmnd *ahc_io_ctx_t;
|
typedef struct scsi_cmnd *ahc_io_ctx_t;
|
||||||
|
|
||||||
/******************************* Byte Order ***********************************/
|
/******************************* Byte Order ***********************************/
|
||||||
#define ahc_htobe16(x) cpu_to_be16(x)
|
#define ahc_htobe16(x) cpu_to_be16(x)
|
||||||
|
@ -144,7 +148,7 @@ typedef Scsi_Cmnd *ahc_io_ctx_t;
|
||||||
extern u_int aic7xxx_no_probe;
|
extern u_int aic7xxx_no_probe;
|
||||||
extern u_int aic7xxx_allow_memio;
|
extern u_int aic7xxx_allow_memio;
|
||||||
extern int aic7xxx_detect_complete;
|
extern int aic7xxx_detect_complete;
|
||||||
extern Scsi_Host_Template aic7xxx_driver_template;
|
extern struct scsi_host_template aic7xxx_driver_template;
|
||||||
|
|
||||||
/***************************** Bus Space/DMA **********************************/
|
/***************************** Bus Space/DMA **********************************/
|
||||||
|
|
||||||
|
@ -174,11 +178,7 @@ struct ahc_linux_dma_tag
|
||||||
};
|
};
|
||||||
typedef struct ahc_linux_dma_tag* bus_dma_tag_t;
|
typedef struct ahc_linux_dma_tag* bus_dma_tag_t;
|
||||||
|
|
||||||
struct ahc_linux_dmamap
|
typedef dma_addr_t bus_dmamap_t;
|
||||||
{
|
|
||||||
dma_addr_t bus_addr;
|
|
||||||
};
|
|
||||||
typedef struct ahc_linux_dmamap* bus_dmamap_t;
|
|
||||||
|
|
||||||
typedef int bus_dma_filter_t(void*, dma_addr_t);
|
typedef int bus_dma_filter_t(void*, dma_addr_t);
|
||||||
typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
|
typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
|
||||||
|
@ -281,12 +281,6 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec)
|
||||||
/***************************** SMP support ************************************/
|
/***************************** SMP support ************************************/
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK))
|
|
||||||
#define AHC_SCSI_HAS_HOST_LOCK 1
|
|
||||||
#else
|
|
||||||
#define AHC_SCSI_HAS_HOST_LOCK 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define AIC7XXX_DRIVER_VERSION "6.2.36"
|
#define AIC7XXX_DRIVER_VERSION "6.2.36"
|
||||||
|
|
||||||
/**************************** Front End Queues ********************************/
|
/**************************** Front End Queues ********************************/
|
||||||
|
@ -328,20 +322,15 @@ struct ahc_cmd {
|
||||||
*/
|
*/
|
||||||
TAILQ_HEAD(ahc_busyq, ahc_cmd);
|
TAILQ_HEAD(ahc_busyq, ahc_cmd);
|
||||||
typedef enum {
|
typedef enum {
|
||||||
AHC_DEV_UNCONFIGURED = 0x01,
|
|
||||||
AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
|
AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
|
||||||
AHC_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */
|
|
||||||
AHC_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */
|
|
||||||
AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */
|
AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */
|
||||||
AHC_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */
|
AHC_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */
|
||||||
AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */
|
AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */
|
||||||
AHC_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */
|
|
||||||
} ahc_linux_dev_flags;
|
} ahc_linux_dev_flags;
|
||||||
|
|
||||||
struct ahc_linux_target;
|
struct ahc_linux_target;
|
||||||
struct ahc_linux_device {
|
struct ahc_linux_device {
|
||||||
TAILQ_ENTRY(ahc_linux_device) links;
|
TAILQ_ENTRY(ahc_linux_device) links;
|
||||||
struct ahc_busyq busyq;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The number of transactions currently
|
* The number of transactions currently
|
||||||
|
@ -381,11 +370,6 @@ struct ahc_linux_device {
|
||||||
|
|
||||||
ahc_linux_dev_flags flags;
|
ahc_linux_dev_flags flags;
|
||||||
|
|
||||||
/*
|
|
||||||
* Per device timer.
|
|
||||||
*/
|
|
||||||
struct timer_list timer;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The high limit for the tags variable.
|
* The high limit for the tags variable.
|
||||||
*/
|
*/
|
||||||
|
@ -419,7 +403,7 @@ struct ahc_linux_device {
|
||||||
#define AHC_OTAG_THRESH 500
|
#define AHC_OTAG_THRESH 500
|
||||||
|
|
||||||
int lun;
|
int lun;
|
||||||
Scsi_Device *scsi_device;
|
struct scsi_device *scsi_device;
|
||||||
struct ahc_linux_target *target;
|
struct ahc_linux_target *target;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -439,32 +423,16 @@ struct ahc_linux_target {
|
||||||
* manner and are allocated below 4GB, the number of S/G segments is
|
* manner and are allocated below 4GB, the number of S/G segments is
|
||||||
* unrestricted.
|
* unrestricted.
|
||||||
*/
|
*/
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
|
|
||||||
/*
|
|
||||||
* We dynamically adjust the number of segments in pre-2.5 kernels to
|
|
||||||
* avoid fragmentation issues in the SCSI mid-layer's private memory
|
|
||||||
* allocator. See aic7xxx_osm.c ahc_linux_size_nseg() for details.
|
|
||||||
*/
|
|
||||||
extern u_int ahc_linux_nseg;
|
|
||||||
#define AHC_NSEG ahc_linux_nseg
|
|
||||||
#define AHC_LINUX_MIN_NSEG 64
|
|
||||||
#else
|
|
||||||
#define AHC_NSEG 128
|
#define AHC_NSEG 128
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Per-SCB OSM storage.
|
* Per-SCB OSM storage.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
|
||||||
AHC_UP_EH_SEMAPHORE = 0x1
|
|
||||||
} ahc_linux_scb_flags;
|
|
||||||
|
|
||||||
struct scb_platform_data {
|
struct scb_platform_data {
|
||||||
struct ahc_linux_device *dev;
|
struct ahc_linux_device *dev;
|
||||||
dma_addr_t buf_busaddr;
|
dma_addr_t buf_busaddr;
|
||||||
uint32_t xfer_len;
|
uint32_t xfer_len;
|
||||||
uint32_t sense_resid; /* Auto-Sense residual */
|
uint32_t sense_resid; /* Auto-Sense residual */
|
||||||
ahc_linux_scb_flags flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -473,39 +441,24 @@ struct scb_platform_data {
|
||||||
* alignment restrictions of the various platforms supported by
|
* alignment restrictions of the various platforms supported by
|
||||||
* this driver.
|
* this driver.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
|
||||||
AHC_RUN_CMPLT_Q_TIMER = 0x10
|
|
||||||
} ahc_linux_softc_flags;
|
|
||||||
|
|
||||||
TAILQ_HEAD(ahc_completeq, ahc_cmd);
|
|
||||||
|
|
||||||
struct ahc_platform_data {
|
struct ahc_platform_data {
|
||||||
/*
|
/*
|
||||||
* Fields accessed from interrupt context.
|
* Fields accessed from interrupt context.
|
||||||
*/
|
*/
|
||||||
struct ahc_linux_target *targets[AHC_NUM_TARGETS];
|
struct ahc_linux_target *targets[AHC_NUM_TARGETS];
|
||||||
TAILQ_HEAD(, ahc_linux_device) device_runq;
|
|
||||||
struct ahc_completeq completeq;
|
|
||||||
|
|
||||||
spinlock_t spin_lock;
|
spinlock_t spin_lock;
|
||||||
struct tasklet_struct runq_tasklet;
|
|
||||||
u_int qfrozen;
|
u_int qfrozen;
|
||||||
pid_t dv_pid;
|
|
||||||
struct timer_list completeq_timer;
|
|
||||||
struct timer_list reset_timer;
|
struct timer_list reset_timer;
|
||||||
struct semaphore eh_sem;
|
struct semaphore eh_sem;
|
||||||
struct semaphore dv_sem;
|
|
||||||
struct semaphore dv_cmd_sem; /* XXX This needs to be in
|
|
||||||
* the target struct
|
|
||||||
*/
|
|
||||||
struct scsi_device *dv_scsi_dev;
|
|
||||||
struct Scsi_Host *host; /* pointer to scsi host */
|
struct Scsi_Host *host; /* pointer to scsi host */
|
||||||
#define AHC_LINUX_NOIRQ ((uint32_t)~0)
|
#define AHC_LINUX_NOIRQ ((uint32_t)~0)
|
||||||
uint32_t irq; /* IRQ for this adapter */
|
uint32_t irq; /* IRQ for this adapter */
|
||||||
uint32_t bios_address;
|
uint32_t bios_address;
|
||||||
uint32_t mem_busaddr; /* Mem Base Addr */
|
uint32_t mem_busaddr; /* Mem Base Addr */
|
||||||
uint64_t hw_dma_mask;
|
|
||||||
ahc_linux_softc_flags flags;
|
#define AHC_UP_EH_SEMAPHORE 0x1
|
||||||
|
uint32_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/************************** OS Utility Wrappers *******************************/
|
/************************** OS Utility Wrappers *******************************/
|
||||||
|
@ -594,7 +547,7 @@ ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
|
||||||
|
|
||||||
/**************************** Initialization **********************************/
|
/**************************** Initialization **********************************/
|
||||||
int ahc_linux_register_host(struct ahc_softc *,
|
int ahc_linux_register_host(struct ahc_softc *,
|
||||||
Scsi_Host_Template *);
|
struct scsi_host_template *);
|
||||||
|
|
||||||
uint64_t ahc_linux_get_memsize(void);
|
uint64_t ahc_linux_get_memsize(void);
|
||||||
|
|
||||||
|
@ -615,17 +568,6 @@ static __inline void ahc_lockinit(struct ahc_softc *);
|
||||||
static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags);
|
static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags);
|
||||||
static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags);
|
static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags);
|
||||||
|
|
||||||
/* Lock acquisition and release of the above lock in midlayer entry points. */
|
|
||||||
static __inline void ahc_midlayer_entrypoint_lock(struct ahc_softc *,
|
|
||||||
unsigned long *flags);
|
|
||||||
static __inline void ahc_midlayer_entrypoint_unlock(struct ahc_softc *,
|
|
||||||
unsigned long *flags);
|
|
||||||
|
|
||||||
/* Lock held during command compeletion to the upper layer */
|
|
||||||
static __inline void ahc_done_lockinit(struct ahc_softc *);
|
|
||||||
static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags);
|
|
||||||
static __inline void ahc_done_unlock(struct ahc_softc *, unsigned long *flags);
|
|
||||||
|
|
||||||
/* Lock held during ahc_list manipulation and ahc softc frees */
|
/* Lock held during ahc_list manipulation and ahc softc frees */
|
||||||
extern spinlock_t ahc_list_spinlock;
|
extern spinlock_t ahc_list_spinlock;
|
||||||
static __inline void ahc_list_lockinit(void);
|
static __inline void ahc_list_lockinit(void);
|
||||||
|
@ -650,57 +592,6 @@ ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
|
||||||
spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
|
spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void
|
|
||||||
ahc_midlayer_entrypoint_lock(struct ahc_softc *ahc, unsigned long *flags)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* In 2.5.X and some 2.4.X versions, the midlayer takes our
|
|
||||||
* lock just before calling us, so we avoid locking again.
|
|
||||||
* For other kernel versions, the io_request_lock is taken
|
|
||||||
* just before our entry point is called. In this case, we
|
|
||||||
* trade the io_request_lock for our per-softc lock.
|
|
||||||
*/
|
|
||||||
#if AHC_SCSI_HAS_HOST_LOCK == 0
|
|
||||||
spin_unlock(&io_request_lock);
|
|
||||||
spin_lock(&ahc->platform_data->spin_lock);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
ahc_midlayer_entrypoint_unlock(struct ahc_softc *ahc, unsigned long *flags)
|
|
||||||
{
|
|
||||||
#if AHC_SCSI_HAS_HOST_LOCK == 0
|
|
||||||
spin_unlock(&ahc->platform_data->spin_lock);
|
|
||||||
spin_lock(&io_request_lock);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
ahc_done_lockinit(struct ahc_softc *ahc)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* In 2.5.X, our own lock is held during completions.
|
|
||||||
* In previous versions, the io_request_lock is used.
|
|
||||||
* In either case, we can't initialize this lock again.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags)
|
|
||||||
{
|
|
||||||
#if AHC_SCSI_HAS_HOST_LOCK == 0
|
|
||||||
spin_lock_irqsave(&io_request_lock, *flags);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags)
|
|
||||||
{
|
|
||||||
#if AHC_SCSI_HAS_HOST_LOCK == 0
|
|
||||||
spin_unlock_irqrestore(&io_request_lock, *flags);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
ahc_list_lockinit(void)
|
ahc_list_lockinit(void)
|
||||||
{
|
{
|
||||||
|
@ -767,12 +658,6 @@ typedef enum
|
||||||
} ahc_power_state;
|
} ahc_power_state;
|
||||||
|
|
||||||
/**************************** VL/EISA Routines ********************************/
|
/**************************** VL/EISA Routines ********************************/
|
||||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) \
|
|
||||||
&& (defined(__i386__) || defined(__alpha__)) \
|
|
||||||
&& (!defined(CONFIG_EISA)))
|
|
||||||
#define CONFIG_EISA
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_EISA
|
#ifdef CONFIG_EISA
|
||||||
extern uint32_t aic7xxx_probe_eisa_vl;
|
extern uint32_t aic7xxx_probe_eisa_vl;
|
||||||
int ahc_linux_eisa_init(void);
|
int ahc_linux_eisa_init(void);
|
||||||
|
@ -888,22 +773,18 @@ ahc_flush_device_writes(struct ahc_softc *ahc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************** Proc FS Support *********************************/
|
/**************************** Proc FS Support *********************************/
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
|
|
||||||
int ahc_linux_proc_info(char *, char **, off_t, int, int, int);
|
|
||||||
#else
|
|
||||||
int ahc_linux_proc_info(struct Scsi_Host *, char *, char **,
|
int ahc_linux_proc_info(struct Scsi_Host *, char *, char **,
|
||||||
off_t, int, int);
|
off_t, int, int);
|
||||||
#endif
|
|
||||||
|
|
||||||
/*************************** Domain Validation ********************************/
|
/*************************** Domain Validation ********************************/
|
||||||
/*********************** Transaction Access Wrappers *************************/
|
/*********************** Transaction Access Wrappers *************************/
|
||||||
static __inline void ahc_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t);
|
static __inline void ahc_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
|
||||||
static __inline void ahc_set_transaction_status(struct scb *, uint32_t);
|
static __inline void ahc_set_transaction_status(struct scb *, uint32_t);
|
||||||
static __inline void ahc_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t);
|
static __inline void ahc_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
|
||||||
static __inline void ahc_set_scsi_status(struct scb *, uint32_t);
|
static __inline void ahc_set_scsi_status(struct scb *, uint32_t);
|
||||||
static __inline uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd);
|
static __inline uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd);
|
||||||
static __inline uint32_t ahc_get_transaction_status(struct scb *);
|
static __inline uint32_t ahc_get_transaction_status(struct scb *);
|
||||||
static __inline uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd);
|
static __inline uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd);
|
||||||
static __inline uint32_t ahc_get_scsi_status(struct scb *);
|
static __inline uint32_t ahc_get_scsi_status(struct scb *);
|
||||||
static __inline void ahc_set_transaction_tag(struct scb *, int, u_int);
|
static __inline void ahc_set_transaction_tag(struct scb *, int, u_int);
|
||||||
static __inline u_long ahc_get_transfer_length(struct scb *);
|
static __inline u_long ahc_get_transfer_length(struct scb *);
|
||||||
|
@ -922,7 +803,7 @@ static __inline void ahc_platform_scb_free(struct ahc_softc *ahc,
|
||||||
static __inline void ahc_freeze_scb(struct scb *scb);
|
static __inline void ahc_freeze_scb(struct scb *scb);
|
||||||
|
|
||||||
static __inline
|
static __inline
|
||||||
void ahc_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status)
|
void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
|
||||||
{
|
{
|
||||||
cmd->result &= ~(CAM_STATUS_MASK << 16);
|
cmd->result &= ~(CAM_STATUS_MASK << 16);
|
||||||
cmd->result |= status << 16;
|
cmd->result |= status << 16;
|
||||||
|
@ -935,7 +816,7 @@ void ahc_set_transaction_status(struct scb *scb, uint32_t status)
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline
|
static __inline
|
||||||
void ahc_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status)
|
void ahc_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
|
||||||
{
|
{
|
||||||
cmd->result &= ~0xFFFF;
|
cmd->result &= ~0xFFFF;
|
||||||
cmd->result |= status;
|
cmd->result |= status;
|
||||||
|
@ -948,7 +829,7 @@ void ahc_set_scsi_status(struct scb *scb, uint32_t status)
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline
|
static __inline
|
||||||
uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd)
|
uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
return ((cmd->result >> 16) & CAM_STATUS_MASK);
|
return ((cmd->result >> 16) & CAM_STATUS_MASK);
|
||||||
}
|
}
|
||||||
|
@ -960,7 +841,7 @@ uint32_t ahc_get_transaction_status(struct scb *scb)
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline
|
static __inline
|
||||||
uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd)
|
uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
return (cmd->result & 0xFFFF);
|
return (cmd->result & 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,13 +221,11 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
&& ahc_linux_get_memsize() > 0x80000000
|
&& ahc_linux_get_memsize() > 0x80000000
|
||||||
&& pci_set_dma_mask(pdev, mask_39bit) == 0) {
|
&& pci_set_dma_mask(pdev, mask_39bit) == 0) {
|
||||||
ahc->flags |= AHC_39BIT_ADDRESSING;
|
ahc->flags |= AHC_39BIT_ADDRESSING;
|
||||||
ahc->platform_data->hw_dma_mask = mask_39bit;
|
|
||||||
} else {
|
} else {
|
||||||
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
|
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
|
||||||
printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
|
printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
|
||||||
return (-ENODEV);
|
return (-ENODEV);
|
||||||
}
|
}
|
||||||
ahc->platform_data->hw_dma_mask = DMA_32BIT_MASK;
|
|
||||||
}
|
}
|
||||||
ahc->dev_softc = pci;
|
ahc->dev_softc = pci;
|
||||||
error = ahc_pci_config(ahc, entry);
|
error = ahc_pci_config(ahc, entry);
|
||||||
|
@ -236,15 +234,8 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
return (-error);
|
return (-error);
|
||||||
}
|
}
|
||||||
pci_set_drvdata(pdev, ahc);
|
pci_set_drvdata(pdev, ahc);
|
||||||
if (aic7xxx_detect_complete) {
|
if (aic7xxx_detect_complete)
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
|
|
||||||
ahc_linux_register_host(ahc, &aic7xxx_driver_template);
|
ahc_linux_register_host(ahc, &aic7xxx_driver_template);
|
||||||
#else
|
|
||||||
printf("aic7xxx: ignoring PCI device found after "
|
|
||||||
"initialization\n");
|
|
||||||
return (-ENODEV);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -289,13 +289,8 @@ done:
|
||||||
* Return information to handle /proc support for the driver.
|
* Return information to handle /proc support for the driver.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
|
|
||||||
ahc_linux_proc_info(char *buffer, char **start, off_t offset,
|
|
||||||
int length, int hostno, int inout)
|
|
||||||
#else
|
|
||||||
ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
|
ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
|
||||||
off_t offset, int length, int inout)
|
off_t offset, int length, int inout)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
struct ahc_softc *ahc;
|
struct ahc_softc *ahc;
|
||||||
struct info_str info;
|
struct info_str info;
|
||||||
|
@ -307,15 +302,7 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
|
||||||
|
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
ahc_list_lock(&s);
|
ahc_list_lock(&s);
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
|
|
||||||
TAILQ_FOREACH(ahc, &ahc_tailq, links) {
|
|
||||||
if (ahc->platform_data->host->host_no == hostno)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata);
|
ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ahc == NULL)
|
if (ahc == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
|
||||||
/* Core SCSI definitions */
|
/* Core SCSI definitions */
|
||||||
#include "scsi.h"
|
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
#include "aiclib.h"
|
#include "aiclib.h"
|
||||||
#include "cam.h"
|
#include "cam.h"
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
#define SPI_PRINTK(x, l, f, a...) dev_printk(l, &(x)->dev, f , ##a)
|
#define SPI_PRINTK(x, l, f, a...) dev_printk(l, &(x)->dev, f , ##a)
|
||||||
|
|
||||||
#define SPI_NUM_ATTRS 10 /* increase this if you add attributes */
|
#define SPI_NUM_ATTRS 13 /* increase this if you add attributes */
|
||||||
#define SPI_OTHER_ATTRS 1 /* Increase this if you add "always
|
#define SPI_OTHER_ATTRS 1 /* Increase this if you add "always
|
||||||
* on" attributes */
|
* on" attributes */
|
||||||
#define SPI_HOST_ATTRS 1
|
#define SPI_HOST_ATTRS 1
|
||||||
|
@ -219,8 +219,11 @@ static int spi_setup_transport_attrs(struct device *dev)
|
||||||
struct scsi_target *starget = to_scsi_target(dev);
|
struct scsi_target *starget = to_scsi_target(dev);
|
||||||
|
|
||||||
spi_period(starget) = -1; /* illegal value */
|
spi_period(starget) = -1; /* illegal value */
|
||||||
|
spi_min_period(starget) = 0;
|
||||||
spi_offset(starget) = 0; /* async */
|
spi_offset(starget) = 0; /* async */
|
||||||
|
spi_max_offset(starget) = 255;
|
||||||
spi_width(starget) = 0; /* narrow */
|
spi_width(starget) = 0; /* narrow */
|
||||||
|
spi_max_width(starget) = 1;
|
||||||
spi_iu(starget) = 0; /* no IU */
|
spi_iu(starget) = 0; /* no IU */
|
||||||
spi_dt(starget) = 0; /* ST */
|
spi_dt(starget) = 0; /* ST */
|
||||||
spi_qas(starget) = 0;
|
spi_qas(starget) = 0;
|
||||||
|
@ -235,6 +238,34 @@ static int spi_setup_transport_attrs(struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define spi_transport_show_simple(field, format_string) \
|
||||||
|
\
|
||||||
|
static ssize_t \
|
||||||
|
show_spi_transport_##field(struct class_device *cdev, char *buf) \
|
||||||
|
{ \
|
||||||
|
struct scsi_target *starget = transport_class_to_starget(cdev); \
|
||||||
|
struct spi_transport_attrs *tp; \
|
||||||
|
\
|
||||||
|
tp = (struct spi_transport_attrs *)&starget->starget_data; \
|
||||||
|
return snprintf(buf, 20, format_string, tp->field); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define spi_transport_store_simple(field, format_string) \
|
||||||
|
\
|
||||||
|
static ssize_t \
|
||||||
|
store_spi_transport_##field(struct class_device *cdev, const char *buf, \
|
||||||
|
size_t count) \
|
||||||
|
{ \
|
||||||
|
int val; \
|
||||||
|
struct scsi_target *starget = transport_class_to_starget(cdev); \
|
||||||
|
struct spi_transport_attrs *tp; \
|
||||||
|
\
|
||||||
|
tp = (struct spi_transport_attrs *)&starget->starget_data; \
|
||||||
|
val = simple_strtoul(buf, NULL, 0); \
|
||||||
|
tp->field = val; \
|
||||||
|
return count; \
|
||||||
|
}
|
||||||
|
|
||||||
#define spi_transport_show_function(field, format_string) \
|
#define spi_transport_show_function(field, format_string) \
|
||||||
\
|
\
|
||||||
static ssize_t \
|
static ssize_t \
|
||||||
|
@ -265,6 +296,25 @@ store_spi_transport_##field(struct class_device *cdev, const char *buf, \
|
||||||
return count; \
|
return count; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define spi_transport_store_max(field, format_string) \
|
||||||
|
static ssize_t \
|
||||||
|
store_spi_transport_##field(struct class_device *cdev, const char *buf, \
|
||||||
|
size_t count) \
|
||||||
|
{ \
|
||||||
|
int val; \
|
||||||
|
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); \
|
||||||
|
struct spi_transport_attrs *tp \
|
||||||
|
= (struct spi_transport_attrs *)&starget->starget_data; \
|
||||||
|
\
|
||||||
|
val = simple_strtoul(buf, NULL, 0); \
|
||||||
|
if (val > tp->max_##field) \
|
||||||
|
val = tp->max_##field; \
|
||||||
|
i->f->set_##field(starget, val); \
|
||||||
|
return count; \
|
||||||
|
}
|
||||||
|
|
||||||
#define spi_transport_rd_attr(field, format_string) \
|
#define spi_transport_rd_attr(field, format_string) \
|
||||||
spi_transport_show_function(field, format_string) \
|
spi_transport_show_function(field, format_string) \
|
||||||
spi_transport_store_function(field, format_string) \
|
spi_transport_store_function(field, format_string) \
|
||||||
|
@ -272,9 +322,24 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \
|
||||||
show_spi_transport_##field, \
|
show_spi_transport_##field, \
|
||||||
store_spi_transport_##field);
|
store_spi_transport_##field);
|
||||||
|
|
||||||
|
#define spi_transport_simple_attr(field, format_string) \
|
||||||
|
spi_transport_show_simple(field, format_string) \
|
||||||
|
spi_transport_store_simple(field, format_string) \
|
||||||
|
static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \
|
||||||
|
show_spi_transport_##field, \
|
||||||
|
store_spi_transport_##field);
|
||||||
|
|
||||||
|
#define spi_transport_max_attr(field, format_string) \
|
||||||
|
spi_transport_show_function(field, format_string) \
|
||||||
|
spi_transport_store_max(field, format_string) \
|
||||||
|
spi_transport_simple_attr(max_##field, format_string) \
|
||||||
|
static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \
|
||||||
|
show_spi_transport_##field, \
|
||||||
|
store_spi_transport_##field);
|
||||||
|
|
||||||
/* The Parallel SCSI Tranport Attributes: */
|
/* The Parallel SCSI Tranport Attributes: */
|
||||||
spi_transport_rd_attr(offset, "%d\n");
|
spi_transport_max_attr(offset, "%d\n");
|
||||||
spi_transport_rd_attr(width, "%d\n");
|
spi_transport_max_attr(width, "%d\n");
|
||||||
spi_transport_rd_attr(iu, "%d\n");
|
spi_transport_rd_attr(iu, "%d\n");
|
||||||
spi_transport_rd_attr(dt, "%d\n");
|
spi_transport_rd_attr(dt, "%d\n");
|
||||||
spi_transport_rd_attr(qas, "%d\n");
|
spi_transport_rd_attr(qas, "%d\n");
|
||||||
|
@ -300,26 +365,18 @@ static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate);
|
||||||
|
|
||||||
/* Translate the period into ns according to the current spec
|
/* Translate the period into ns according to the current spec
|
||||||
* for SDTR/PPR messages */
|
* for SDTR/PPR messages */
|
||||||
static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf)
|
static ssize_t
|
||||||
|
show_spi_transport_period_helper(struct class_device *cdev, char *buf,
|
||||||
|
int period)
|
||||||
{
|
{
|
||||||
struct scsi_target *starget = transport_class_to_starget(cdev);
|
|
||||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
|
||||||
struct spi_transport_attrs *tp;
|
|
||||||
int len, picosec;
|
int len, picosec;
|
||||||
struct spi_internal *i = to_spi_internal(shost->transportt);
|
|
||||||
|
|
||||||
tp = (struct spi_transport_attrs *)&starget->starget_data;
|
if (period < 0 || period > 0xff) {
|
||||||
|
|
||||||
if (i->f->get_period)
|
|
||||||
i->f->get_period(starget);
|
|
||||||
|
|
||||||
if (tp->period < 0 || tp->period > 0xff) {
|
|
||||||
picosec = -1;
|
picosec = -1;
|
||||||
} else if (tp->period <= SPI_STATIC_PPR) {
|
} else if (period <= SPI_STATIC_PPR) {
|
||||||
picosec = ppr_to_ps[tp->period];
|
picosec = ppr_to_ps[period];
|
||||||
} else {
|
} else {
|
||||||
picosec = tp->period * 4000;
|
picosec = period * 4000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (picosec == -1) {
|
if (picosec == -1) {
|
||||||
|
@ -334,12 +391,9 @@ static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
store_spi_transport_period(struct class_device *cdev, const char *buf,
|
store_spi_transport_period_helper(struct class_device *cdev, const char *buf,
|
||||||
size_t count)
|
size_t count, int *periodp)
|
||||||
{
|
{
|
||||||
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, picosec, period = -1;
|
int j, picosec, period = -1;
|
||||||
char *endp;
|
char *endp;
|
||||||
|
|
||||||
|
@ -368,15 +422,79 @@ store_spi_transport_period(struct class_device *cdev, const char *buf,
|
||||||
if (period > 0xff)
|
if (period > 0xff)
|
||||||
period = 0xff;
|
period = 0xff;
|
||||||
|
|
||||||
i->f->set_period(starget, period);
|
*periodp = period;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_internal *i = to_spi_internal(shost->transportt);
|
||||||
|
struct spi_transport_attrs *tp =
|
||||||
|
(struct spi_transport_attrs *)&starget->starget_data;
|
||||||
|
|
||||||
|
if (i->f->get_period)
|
||||||
|
i->f->get_period(starget);
|
||||||
|
|
||||||
|
return show_spi_transport_period_helper(cdev, buf, tp->period);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
store_spi_transport_period(struct class_device *cdev, const char *buf,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
struct spi_transport_attrs *tp =
|
||||||
|
(struct spi_transport_attrs *)&starget->starget_data;
|
||||||
|
int period, retval;
|
||||||
|
|
||||||
|
retval = store_spi_transport_period_helper(cdev, buf, count, &period);
|
||||||
|
|
||||||
|
if (period < tp->min_period)
|
||||||
|
period = tp->min_period;
|
||||||
|
|
||||||
|
i->f->set_period(starget, period);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static CLASS_DEVICE_ATTR(period, S_IRUGO | S_IWUSR,
|
static CLASS_DEVICE_ATTR(period, S_IRUGO | S_IWUSR,
|
||||||
show_spi_transport_period,
|
show_spi_transport_period,
|
||||||
store_spi_transport_period);
|
store_spi_transport_period);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
show_spi_transport_min_period(struct class_device *cdev, char *buf)
|
||||||
|
{
|
||||||
|
struct scsi_target *starget = transport_class_to_starget(cdev);
|
||||||
|
struct spi_transport_attrs *tp =
|
||||||
|
(struct spi_transport_attrs *)&starget->starget_data;
|
||||||
|
|
||||||
|
return show_spi_transport_period_helper(cdev, buf, tp->min_period);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
store_spi_transport_min_period(struct class_device *cdev, const char *buf,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
struct scsi_target *starget = transport_class_to_starget(cdev);
|
||||||
|
struct spi_transport_attrs *tp =
|
||||||
|
(struct spi_transport_attrs *)&starget->starget_data;
|
||||||
|
|
||||||
|
return store_spi_transport_period_helper(cdev, buf, count,
|
||||||
|
&tp->min_period);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static CLASS_DEVICE_ATTR(min_period, S_IRUGO | S_IWUSR,
|
||||||
|
show_spi_transport_min_period,
|
||||||
|
store_spi_transport_min_period);
|
||||||
|
|
||||||
|
|
||||||
static ssize_t show_spi_host_signalling(struct class_device *cdev, char *buf)
|
static ssize_t show_spi_host_signalling(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = transport_class_to_shost(cdev);
|
struct Scsi_Host *shost = transport_class_to_shost(cdev);
|
||||||
|
@ -642,6 +760,7 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer)
|
||||||
{
|
{
|
||||||
struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt);
|
struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt);
|
||||||
struct scsi_device *sdev = sreq->sr_device;
|
struct scsi_device *sdev = sreq->sr_device;
|
||||||
|
struct scsi_target *starget = sdev->sdev_target;
|
||||||
int len = sdev->inquiry_len;
|
int len = sdev->inquiry_len;
|
||||||
/* first set us up for narrow async */
|
/* first set us up for narrow async */
|
||||||
DV_SET(offset, 0);
|
DV_SET(offset, 0);
|
||||||
|
@ -655,9 +774,11 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test width */
|
/* test width */
|
||||||
if (i->f->set_width && sdev->wdtr) {
|
if (i->f->set_width && spi_max_width(starget) && sdev->wdtr) {
|
||||||
i->f->set_width(sdev->sdev_target, 1);
|
i->f->set_width(sdev->sdev_target, 1);
|
||||||
|
|
||||||
|
printk("WIDTH IS %d\n", spi_max_width(starget));
|
||||||
|
|
||||||
if (spi_dv_device_compare_inquiry(sreq, buffer,
|
if (spi_dv_device_compare_inquiry(sreq, buffer,
|
||||||
buffer + len,
|
buffer + len,
|
||||||
DV_LOOPS)
|
DV_LOOPS)
|
||||||
|
@ -684,8 +805,8 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer)
|
||||||
retry:
|
retry:
|
||||||
|
|
||||||
/* now set up to the maximum */
|
/* now set up to the maximum */
|
||||||
DV_SET(offset, 255);
|
DV_SET(offset, spi_max_offset(starget));
|
||||||
DV_SET(period, 1);
|
DV_SET(period, spi_min_period(starget));
|
||||||
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
SPI_PRINTK(sdev->sdev_target, KERN_INFO, "Domain Validation skipping write tests\n");
|
SPI_PRINTK(sdev->sdev_target, KERN_INFO, "Domain Validation skipping write tests\n");
|
||||||
|
@ -892,6 +1013,16 @@ EXPORT_SYMBOL(spi_display_xfer_agreement);
|
||||||
if (i->f->show_##field) \
|
if (i->f->show_##field) \
|
||||||
count++
|
count++
|
||||||
|
|
||||||
|
#define SETUP_RELATED_ATTRIBUTE(field, rel_field) \
|
||||||
|
i->private_attrs[count] = class_device_attr_##field; \
|
||||||
|
if (!i->f->set_##rel_field) { \
|
||||||
|
i->private_attrs[count].attr.mode = S_IRUGO; \
|
||||||
|
i->private_attrs[count].store = NULL; \
|
||||||
|
} \
|
||||||
|
i->attrs[count] = &i->private_attrs[count]; \
|
||||||
|
if (i->f->show_##rel_field) \
|
||||||
|
count++
|
||||||
|
|
||||||
#define SETUP_HOST_ATTRIBUTE(field) \
|
#define SETUP_HOST_ATTRIBUTE(field) \
|
||||||
i->private_host_attrs[count] = class_device_attr_##field; \
|
i->private_host_attrs[count] = class_device_attr_##field; \
|
||||||
if (!i->f->set_##field) { \
|
if (!i->f->set_##field) { \
|
||||||
|
@ -975,8 +1106,11 @@ spi_attach_transport(struct spi_function_template *ft)
|
||||||
i->f = ft;
|
i->f = ft;
|
||||||
|
|
||||||
SETUP_ATTRIBUTE(period);
|
SETUP_ATTRIBUTE(period);
|
||||||
|
SETUP_RELATED_ATTRIBUTE(min_period, period);
|
||||||
SETUP_ATTRIBUTE(offset);
|
SETUP_ATTRIBUTE(offset);
|
||||||
|
SETUP_RELATED_ATTRIBUTE(max_offset, offset);
|
||||||
SETUP_ATTRIBUTE(width);
|
SETUP_ATTRIBUTE(width);
|
||||||
|
SETUP_RELATED_ATTRIBUTE(max_width, width);
|
||||||
SETUP_ATTRIBUTE(iu);
|
SETUP_ATTRIBUTE(iu);
|
||||||
SETUP_ATTRIBUTE(dt);
|
SETUP_ATTRIBUTE(dt);
|
||||||
SETUP_ATTRIBUTE(qas);
|
SETUP_ATTRIBUTE(qas);
|
||||||
|
|
|
@ -27,8 +27,11 @@ struct scsi_transport_template;
|
||||||
|
|
||||||
struct spi_transport_attrs {
|
struct spi_transport_attrs {
|
||||||
int period; /* value in the PPR/SDTR command */
|
int period; /* value in the PPR/SDTR command */
|
||||||
|
int min_period;
|
||||||
int offset;
|
int offset;
|
||||||
|
int max_offset;
|
||||||
unsigned int width:1; /* 0 - narrow, 1 - wide */
|
unsigned int width:1; /* 0 - narrow, 1 - wide */
|
||||||
|
unsigned int max_width:1;
|
||||||
unsigned int iu:1; /* Information Units enabled */
|
unsigned int iu:1; /* Information Units enabled */
|
||||||
unsigned int dt:1; /* DT clocking enabled */
|
unsigned int dt:1; /* DT clocking enabled */
|
||||||
unsigned int qas:1; /* Quick Arbitration and Selection enabled */
|
unsigned int qas:1; /* Quick Arbitration and Selection enabled */
|
||||||
|
@ -63,8 +66,11 @@ struct spi_host_attrs {
|
||||||
|
|
||||||
/* accessor functions */
|
/* accessor functions */
|
||||||
#define spi_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->period)
|
#define spi_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->period)
|
||||||
|
#define spi_min_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->min_period)
|
||||||
#define spi_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->offset)
|
#define spi_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->offset)
|
||||||
|
#define spi_max_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_offset)
|
||||||
#define spi_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->width)
|
#define spi_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->width)
|
||||||
|
#define spi_max_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_width)
|
||||||
#define spi_iu(x) (((struct spi_transport_attrs *)&(x)->starget_data)->iu)
|
#define spi_iu(x) (((struct spi_transport_attrs *)&(x)->starget_data)->iu)
|
||||||
#define spi_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dt)
|
#define spi_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dt)
|
||||||
#define spi_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->qas)
|
#define spi_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->qas)
|
||||||
|
|
Loading…
Reference in New Issue