mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
Automatic merge of /spare/repo/linux-2.6/.git branch HEAD
This commit is contained in:
commit
ae20ea8525
629 changed files with 35548 additions and 14471 deletions
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include "scsi.h"
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <linux/libata.h>
|
||||
|
|
@ -289,6 +290,8 @@ static void ahci_host_stop(struct ata_host_set *host_set)
|
|||
{
|
||||
struct ahci_host_priv *hpriv = host_set->private_data;
|
||||
kfree(hpriv);
|
||||
|
||||
ata_host_stop(host_set);
|
||||
}
|
||||
|
||||
static int ahci_port_start(struct ata_port *ap)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
#include "aic7xxx_osm.h"
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
|
||||
#include <linux/device.h>
|
||||
#include <linux/eisa.h>
|
||||
|
||||
|
|
@ -62,13 +61,6 @@ static struct eisa_driver aic7770_driver = {
|
|||
};
|
||||
|
||||
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,
|
||||
aic7770_dev_t dev, u_int eisaBase);
|
||||
|
|
@ -76,7 +68,6 @@ static int aic7770_linux_config(struct aic7770_identity *entry,
|
|||
int
|
||||
ahc_linux_eisa_init(void)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
|
||||
struct eisa_device_id *eid;
|
||||
struct aic7770_identity *id;
|
||||
int i;
|
||||
|
|
@ -110,44 +101,6 @@ ahc_linux_eisa_init(void)
|
|||
eid->sig[0] = 0;
|
||||
|
||||
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
|
||||
|
|
@ -187,11 +140,10 @@ aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev,
|
|||
ahc_free(ahc);
|
||||
return (error);
|
||||
}
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
|
||||
|
||||
dev->driver_data = (void *)ahc;
|
||||
if (aic7xxx_detect_complete)
|
||||
error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
|
||||
#endif
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +177,6 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq)
|
|||
return (-error);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
|
||||
static int
|
||||
aic7770_eisa_dev_probe(struct device *dev)
|
||||
{
|
||||
|
|
@ -261,4 +212,3 @@ aic7770_eisa_dev_remove(struct device *dev)
|
|||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2488,7 +2488,7 @@ ahd_linux_dv_thread(void *data)
|
|||
sprintf(current->comm, "ahd_dv_%d", ahd->unit);
|
||||
#else
|
||||
daemonize("ahd_dv_%d", ahd->unit);
|
||||
current->flags |= PF_FREEZE;
|
||||
current->flags |= PF_NOFREEZE;
|
||||
#endif
|
||||
unlock_kernel();
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -59,6 +59,7 @@
|
|||
#ifndef _AIC7XXX_LINUX_H_
|
||||
#define _AIC7XXX_LINUX_H_
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/delay.h>
|
||||
|
|
@ -66,18 +67,21 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <linux/interrupt.h> /* For tasklet support. */
|
||||
#include <linux/config.h>
|
||||
#include <linux/slab.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_eh.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_tcq.h>
|
||||
|
||||
/* Core SCSI definitions */
|
||||
#define AIC_LIB_PREFIX ahc
|
||||
#include "scsi.h"
|
||||
#include <scsi/scsi_host.h>
|
||||
|
||||
/* Name space conflict with BSD queue macros */
|
||||
#ifdef LIST_HEAD
|
||||
|
|
@ -106,7 +110,7 @@
|
|||
/************************* Forward Declarations *******************************/
|
||||
struct ahc_softc;
|
||||
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 ***********************************/
|
||||
#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_allow_memio;
|
||||
extern int aic7xxx_detect_complete;
|
||||
extern Scsi_Host_Template aic7xxx_driver_template;
|
||||
extern struct scsi_host_template aic7xxx_driver_template;
|
||||
|
||||
/***************************** Bus Space/DMA **********************************/
|
||||
|
||||
|
|
@ -174,11 +178,7 @@ struct ahc_linux_dma_tag
|
|||
};
|
||||
typedef struct ahc_linux_dma_tag* bus_dma_tag_t;
|
||||
|
||||
struct ahc_linux_dmamap
|
||||
{
|
||||
dma_addr_t bus_addr;
|
||||
};
|
||||
typedef struct ahc_linux_dmamap* bus_dmamap_t;
|
||||
typedef dma_addr_t bus_dmamap_t;
|
||||
|
||||
typedef int bus_dma_filter_t(void*, dma_addr_t);
|
||||
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 ************************************/
|
||||
#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"
|
||||
|
||||
/**************************** Front End Queues ********************************/
|
||||
|
|
@ -328,20 +322,15 @@ struct ahc_cmd {
|
|||
*/
|
||||
TAILQ_HEAD(ahc_busyq, ahc_cmd);
|
||||
typedef enum {
|
||||
AHC_DEV_UNCONFIGURED = 0x01,
|
||||
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_TAGGED = 0x20, /* Allow full SCSI2 command queueing */
|
||||
AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */
|
||||
AHC_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */
|
||||
} ahc_linux_dev_flags;
|
||||
|
||||
struct ahc_linux_target;
|
||||
struct ahc_linux_device {
|
||||
TAILQ_ENTRY(ahc_linux_device) links;
|
||||
struct ahc_busyq busyq;
|
||||
|
||||
/*
|
||||
* The number of transactions currently
|
||||
|
|
@ -381,11 +370,6 @@ struct ahc_linux_device {
|
|||
|
||||
ahc_linux_dev_flags flags;
|
||||
|
||||
/*
|
||||
* Per device timer.
|
||||
*/
|
||||
struct timer_list timer;
|
||||
|
||||
/*
|
||||
* The high limit for the tags variable.
|
||||
*/
|
||||
|
|
@ -419,7 +403,7 @@ struct ahc_linux_device {
|
|||
#define AHC_OTAG_THRESH 500
|
||||
|
||||
int lun;
|
||||
Scsi_Device *scsi_device;
|
||||
struct scsi_device *scsi_device;
|
||||
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
|
||||
* 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
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Per-SCB OSM storage.
|
||||
*/
|
||||
typedef enum {
|
||||
AHC_UP_EH_SEMAPHORE = 0x1
|
||||
} ahc_linux_scb_flags;
|
||||
|
||||
struct scb_platform_data {
|
||||
struct ahc_linux_device *dev;
|
||||
dma_addr_t buf_busaddr;
|
||||
uint32_t xfer_len;
|
||||
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
|
||||
* this driver.
|
||||
*/
|
||||
typedef enum {
|
||||
AHC_RUN_CMPLT_Q_TIMER = 0x10
|
||||
} ahc_linux_softc_flags;
|
||||
|
||||
TAILQ_HEAD(ahc_completeq, ahc_cmd);
|
||||
|
||||
struct ahc_platform_data {
|
||||
/*
|
||||
* Fields accessed from interrupt context.
|
||||
*/
|
||||
struct ahc_linux_target *targets[AHC_NUM_TARGETS];
|
||||
TAILQ_HEAD(, ahc_linux_device) device_runq;
|
||||
struct ahc_completeq completeq;
|
||||
|
||||
spinlock_t spin_lock;
|
||||
struct tasklet_struct runq_tasklet;
|
||||
u_int qfrozen;
|
||||
pid_t dv_pid;
|
||||
struct timer_list completeq_timer;
|
||||
struct timer_list reset_timer;
|
||||
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 */
|
||||
#define AHC_LINUX_NOIRQ ((uint32_t)~0)
|
||||
uint32_t irq; /* IRQ for this adapter */
|
||||
uint32_t bios_address;
|
||||
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 *******************************/
|
||||
|
|
@ -594,7 +547,7 @@ ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
|
|||
|
||||
/**************************** Initialization **********************************/
|
||||
int ahc_linux_register_host(struct ahc_softc *,
|
||||
Scsi_Host_Template *);
|
||||
struct scsi_host_template *);
|
||||
|
||||
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_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 */
|
||||
extern spinlock_t ahc_list_spinlock;
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
ahc_list_lockinit(void)
|
||||
{
|
||||
|
|
@ -767,12 +658,6 @@ typedef enum
|
|||
} ahc_power_state;
|
||||
|
||||
/**************************** 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
|
||||
extern uint32_t aic7xxx_probe_eisa_vl;
|
||||
int ahc_linux_eisa_init(void);
|
||||
|
|
@ -888,22 +773,18 @@ ahc_flush_device_writes(struct ahc_softc *ahc)
|
|||
}
|
||||
|
||||
/**************************** 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 **,
|
||||
off_t, int, int);
|
||||
#endif
|
||||
|
||||
/*************************** Domain Validation ********************************/
|
||||
/*********************** 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_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 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_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 void ahc_set_transaction_tag(struct scb *, int, u_int);
|
||||
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_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 |= status << 16;
|
||||
|
|
@ -935,7 +816,7 @@ void ahc_set_transaction_status(struct scb *scb, uint32_t status)
|
|||
}
|
||||
|
||||
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 |= status;
|
||||
|
|
@ -948,7 +829,7 @@ void ahc_set_scsi_status(struct scb *scb, uint32_t status)
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
@ -960,7 +841,7 @@ uint32_t ahc_get_transaction_status(struct scb *scb)
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,13 +221,11 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
&& ahc_linux_get_memsize() > 0x80000000
|
||||
&& pci_set_dma_mask(pdev, mask_39bit) == 0) {
|
||||
ahc->flags |= AHC_39BIT_ADDRESSING;
|
||||
ahc->platform_data->hw_dma_mask = mask_39bit;
|
||||
} else {
|
||||
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
|
||||
printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
|
||||
return (-ENODEV);
|
||||
}
|
||||
ahc->platform_data->hw_dma_mask = DMA_32BIT_MASK;
|
||||
}
|
||||
ahc->dev_softc = pci;
|
||||
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);
|
||||
}
|
||||
pci_set_drvdata(pdev, ahc);
|
||||
if (aic7xxx_detect_complete) {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
|
||||
if (aic7xxx_detect_complete)
|
||||
ahc_linux_register_host(ahc, &aic7xxx_driver_template);
|
||||
#else
|
||||
printf("aic7xxx: ignoring PCI device found after "
|
||||
"initialization\n");
|
||||
return (-ENODEV);
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -289,13 +289,8 @@ done:
|
|||
* Return information to handle /proc support for the driver.
|
||||
*/
|
||||
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,
|
||||
off_t offset, int length, int inout)
|
||||
#endif
|
||||
{
|
||||
struct ahc_softc *ahc;
|
||||
struct info_str info;
|
||||
|
|
@ -307,15 +302,7 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
|
|||
|
||||
retval = -EINVAL;
|
||||
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);
|
||||
#endif
|
||||
|
||||
if (ahc == NULL)
|
||||
goto done;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@
|
|||
#include <linux/version.h>
|
||||
|
||||
/* Core SCSI definitions */
|
||||
#include "scsi.h"
|
||||
#include <scsi/scsi_host.h>
|
||||
#include "aiclib.h"
|
||||
#include "cam.h"
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ static struct ata_port_operations piix_pata_ops = {
|
|||
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = ata_host_stop,
|
||||
};
|
||||
|
||||
static struct ata_port_operations piix_sata_ops = {
|
||||
|
|
@ -180,6 +181,7 @@ static struct ata_port_operations piix_sata_ops = {
|
|||
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = ata_host_stop,
|
||||
};
|
||||
|
||||
static struct ata_port_info piix_port_info[] = {
|
||||
|
|
@ -663,15 +665,6 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
return ata_pci_init_one(pdev, port_info, n_ports);
|
||||
}
|
||||
|
||||
/**
|
||||
* piix_init -
|
||||
*
|
||||
* LOCKING:
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
*/
|
||||
|
||||
static int __init piix_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
|
@ -687,13 +680,6 @@ static int __init piix_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* piix_exit -
|
||||
*
|
||||
* LOCKING:
|
||||
*
|
||||
*/
|
||||
|
||||
static void __exit piix_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&piix_pci_driver);
|
||||
|
|
|
|||
|
|
@ -179,8 +179,18 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
|
|||
return;
|
||||
}
|
||||
count = min(pc->sg->length - pc->b_count, bcount);
|
||||
buf = page_address(pc->sg->page) + pc->sg->offset;
|
||||
drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
|
||||
if (PageHighMem(pc->sg->page)) {
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
|
||||
drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
|
||||
kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
|
||||
local_irq_restore(flags);
|
||||
} else {
|
||||
buf = page_address(pc->sg->page) + pc->sg->offset;
|
||||
drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
|
||||
}
|
||||
bcount -= count; pc->b_count += count;
|
||||
if (pc->b_count == pc->sg->length) {
|
||||
pc->sg++;
|
||||
|
|
@ -201,8 +211,18 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
|
|||
return;
|
||||
}
|
||||
count = min(pc->sg->length - pc->b_count, bcount);
|
||||
buf = page_address(pc->sg->page) + pc->sg->offset;
|
||||
drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
|
||||
if (PageHighMem(pc->sg->page)) {
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
|
||||
drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
|
||||
kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
|
||||
local_irq_restore(flags);
|
||||
} else {
|
||||
buf = page_address(pc->sg->page) + pc->sg->offset;
|
||||
drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
|
||||
}
|
||||
bcount -= count; pc->b_count += count;
|
||||
if (pc->b_count == pc->sg->length) {
|
||||
pc->sg++;
|
||||
|
|
@ -713,7 +733,6 @@ static void idescsi_add_settings(ide_drive_t *drive)
|
|||
*/
|
||||
static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
|
||||
{
|
||||
DRIVER(drive)->busy++;
|
||||
if (drive->id && (drive->id->config & 0x0060) == 0x20)
|
||||
set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
|
||||
set_bit(IDESCSI_TRANSFORM, &scsi->transform);
|
||||
|
|
@ -722,17 +741,16 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
|
|||
set_bit(IDESCSI_LOG_CMD, &scsi->log);
|
||||
#endif /* IDESCSI_DEBUG_LOG */
|
||||
idescsi_add_settings(drive);
|
||||
DRIVER(drive)->busy--;
|
||||
}
|
||||
|
||||
static int idescsi_cleanup (ide_drive_t *drive)
|
||||
static int ide_scsi_remove(struct device *dev)
|
||||
{
|
||||
ide_drive_t *drive = to_ide_device(dev);
|
||||
struct Scsi_Host *scsihost = drive->driver_data;
|
||||
struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);
|
||||
struct gendisk *g = scsi->disk;
|
||||
|
||||
if (ide_unregister_subdriver(drive))
|
||||
return 1;
|
||||
ide_unregister_subdriver(drive, scsi->driver);
|
||||
|
||||
ide_unregister_region(g);
|
||||
|
||||
|
|
@ -746,7 +764,7 @@ static int idescsi_cleanup (ide_drive_t *drive)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int idescsi_attach(ide_drive_t *drive);
|
||||
static int ide_scsi_probe(struct device *);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static ide_proc_entry_t idescsi_proc[] = {
|
||||
|
|
@ -757,24 +775,22 @@ static ide_proc_entry_t idescsi_proc[] = {
|
|||
# define idescsi_proc NULL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IDE subdriver functions, registered with ide.c
|
||||
*/
|
||||
static ide_driver_t idescsi_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ide-scsi",
|
||||
.gen_driver = {
|
||||
.name = "ide-scsi",
|
||||
.bus = &ide_bus_type,
|
||||
.probe = ide_scsi_probe,
|
||||
.remove = ide_scsi_remove,
|
||||
},
|
||||
.version = IDESCSI_VERSION,
|
||||
.media = ide_scsi,
|
||||
.busy = 0,
|
||||
.supports_dsc_overlap = 0,
|
||||
.proc = idescsi_proc,
|
||||
.attach = idescsi_attach,
|
||||
.cleanup = idescsi_cleanup,
|
||||
.do_request = idescsi_do_request,
|
||||
.end_request = idescsi_end_request,
|
||||
.error = idescsi_atapi_error,
|
||||
.abort = idescsi_atapi_abort,
|
||||
.drives = LIST_HEAD_INIT(idescsi_driver.drives),
|
||||
};
|
||||
|
||||
static int idescsi_ide_open(struct inode *inode, struct file *filp)
|
||||
|
|
@ -821,8 +837,6 @@ static struct block_device_operations idescsi_ops = {
|
|||
.ioctl = idescsi_ide_ioctl,
|
||||
};
|
||||
|
||||
static int idescsi_attach(ide_drive_t *drive);
|
||||
|
||||
static int idescsi_slave_configure(struct scsi_device * sdp)
|
||||
{
|
||||
/* Configure detected device */
|
||||
|
|
@ -1095,8 +1109,9 @@ static struct scsi_host_template idescsi_template = {
|
|||
.proc_name = "ide-scsi",
|
||||
};
|
||||
|
||||
static int idescsi_attach(ide_drive_t *drive)
|
||||
static int ide_scsi_probe(struct device *dev)
|
||||
{
|
||||
ide_drive_t *drive = to_ide_device(dev);
|
||||
idescsi_scsi_t *idescsi;
|
||||
struct Scsi_Host *host;
|
||||
struct gendisk *g;
|
||||
|
|
@ -1112,7 +1127,7 @@ static int idescsi_attach(ide_drive_t *drive)
|
|||
!drive->present ||
|
||||
drive->media == ide_disk ||
|
||||
!(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
|
||||
g = alloc_disk(1 << PARTN_BITS);
|
||||
if (!g)
|
||||
|
|
@ -1138,20 +1153,19 @@ static int idescsi_attach(ide_drive_t *drive)
|
|||
idescsi->host = host;
|
||||
idescsi->disk = g;
|
||||
g->private_data = &idescsi->driver;
|
||||
err = ide_register_subdriver(drive, &idescsi_driver);
|
||||
ide_register_subdriver(drive, &idescsi_driver);
|
||||
err = 0;
|
||||
idescsi_setup(drive, idescsi);
|
||||
g->fops = &idescsi_ops;
|
||||
ide_register_region(g);
|
||||
err = scsi_add_host(host, &drive->gendev);
|
||||
if (!err) {
|
||||
idescsi_setup (drive, idescsi);
|
||||
g->fops = &idescsi_ops;
|
||||
ide_register_region(g);
|
||||
err = scsi_add_host(host, &drive->gendev);
|
||||
if (!err) {
|
||||
scsi_scan_host(host);
|
||||
return 0;
|
||||
}
|
||||
/* fall through on error */
|
||||
ide_unregister_region(g);
|
||||
ide_unregister_subdriver(drive);
|
||||
scsi_scan_host(host);
|
||||
return 0;
|
||||
}
|
||||
/* fall through on error */
|
||||
ide_unregister_region(g);
|
||||
ide_unregister_subdriver(drive, &idescsi_driver);
|
||||
|
||||
put_disk(g);
|
||||
out_host_put:
|
||||
|
|
@ -1161,12 +1175,12 @@ out_host_put:
|
|||
|
||||
static int __init init_idescsi_module(void)
|
||||
{
|
||||
return ide_register_driver(&idescsi_driver);
|
||||
return driver_register(&idescsi_driver.gen_driver);
|
||||
}
|
||||
|
||||
static void __exit exit_idescsi_module(void)
|
||||
{
|
||||
ide_unregister_driver(&idescsi_driver);
|
||||
driver_unregister(&idescsi_driver.gen_driver);
|
||||
}
|
||||
|
||||
module_init(init_idescsi_module);
|
||||
|
|
|
|||
|
|
@ -186,6 +186,28 @@ static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
|
|||
ata_wait_idle(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_tf_load - send taskfile registers to host controller
|
||||
* @ap: Port to which output is sent
|
||||
* @tf: ATA taskfile register set
|
||||
*
|
||||
* Outputs ATA taskfile to standard ATA host controller using MMIO
|
||||
* or PIO as indicated by the ATA_FLAG_MMIO flag.
|
||||
* Writes the control, feature, nsect, lbal, lbam, and lbah registers.
|
||||
* Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
|
||||
* hob_lbal, hob_lbam, and hob_lbah.
|
||||
*
|
||||
* This function waits for idle (!BUSY and !DRQ) after writing
|
||||
* registers. If the control register has a new value, this
|
||||
* function also waits for idle after writing control and before
|
||||
* writing the remaining registers.
|
||||
*
|
||||
* May be used as the tf_load() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
if (ap->flags & ATA_FLAG_MMIO)
|
||||
|
|
@ -195,11 +217,11 @@ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
|
|||
}
|
||||
|
||||
/**
|
||||
* ata_exec_command - issue ATA command to host controller
|
||||
* ata_exec_command_pio - issue ATA command to host controller
|
||||
* @ap: port to which command is being issued
|
||||
* @tf: ATA taskfile register set
|
||||
*
|
||||
* Issues PIO/MMIO write to ATA command register, with proper
|
||||
* Issues PIO write to ATA command register, with proper
|
||||
* synchronization with interrupt handler / other threads.
|
||||
*
|
||||
* LOCKING:
|
||||
|
|
@ -235,6 +257,18 @@ static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
|
|||
ata_pause(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_exec_command - issue ATA command to host controller
|
||||
* @ap: port to which command is being issued
|
||||
* @tf: ATA taskfile register set
|
||||
*
|
||||
* Issues PIO/MMIO write to ATA command register, with proper
|
||||
* synchronization with interrupt handler / other threads.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*/
|
||||
void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
if (ap->flags & ATA_FLAG_MMIO)
|
||||
|
|
@ -305,7 +339,7 @@ void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf)
|
|||
}
|
||||
|
||||
/**
|
||||
* ata_tf_read - input device's ATA taskfile shadow registers
|
||||
* ata_tf_read_pio - input device's ATA taskfile shadow registers
|
||||
* @ap: Port from which input is read
|
||||
* @tf: ATA taskfile register set for storing input
|
||||
*
|
||||
|
|
@ -368,6 +402,23 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_tf_read - input device's ATA taskfile shadow registers
|
||||
* @ap: Port from which input is read
|
||||
* @tf: ATA taskfile register set for storing input
|
||||
*
|
||||
* Reads ATA taskfile registers for currently-selected device
|
||||
* into @tf.
|
||||
*
|
||||
* Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48
|
||||
* is set, also reads the hob registers.
|
||||
*
|
||||
* May be used as the tf_read() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
if (ap->flags & ATA_FLAG_MMIO)
|
||||
|
|
@ -381,7 +432,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
|||
* @ap: port where the device is
|
||||
*
|
||||
* Reads ATA taskfile status register for currently-selected device
|
||||
* and return it's value. This also clears pending interrupts
|
||||
* and return its value. This also clears pending interrupts
|
||||
* from this device
|
||||
*
|
||||
* LOCKING:
|
||||
|
|
@ -397,7 +448,7 @@ static u8 ata_check_status_pio(struct ata_port *ap)
|
|||
* @ap: port where the device is
|
||||
*
|
||||
* Reads ATA taskfile status register for currently-selected device
|
||||
* via MMIO and return it's value. This also clears pending interrupts
|
||||
* via MMIO and return its value. This also clears pending interrupts
|
||||
* from this device
|
||||
*
|
||||
* LOCKING:
|
||||
|
|
@ -408,6 +459,20 @@ static u8 ata_check_status_mmio(struct ata_port *ap)
|
|||
return readb((void __iomem *) ap->ioaddr.status_addr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_check_status - Read device status reg & clear interrupt
|
||||
* @ap: port where the device is
|
||||
*
|
||||
* Reads ATA taskfile status register for currently-selected device
|
||||
* and return its value. This also clears pending interrupts
|
||||
* from this device
|
||||
*
|
||||
* May be used as the check_status() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
u8 ata_check_status(struct ata_port *ap)
|
||||
{
|
||||
if (ap->flags & ATA_FLAG_MMIO)
|
||||
|
|
@ -415,6 +480,20 @@ u8 ata_check_status(struct ata_port *ap)
|
|||
return ata_check_status_pio(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_altstatus - Read device alternate status reg
|
||||
* @ap: port where the device is
|
||||
*
|
||||
* Reads ATA taskfile alternate status register for
|
||||
* currently-selected device and return its value.
|
||||
*
|
||||
* Note: may NOT be used as the check_altstatus() entry in
|
||||
* ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
u8 ata_altstatus(struct ata_port *ap)
|
||||
{
|
||||
if (ap->ops->check_altstatus)
|
||||
|
|
@ -425,6 +504,20 @@ u8 ata_altstatus(struct ata_port *ap)
|
|||
return inb(ap->ioaddr.altstatus_addr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_chk_err - Read device error reg
|
||||
* @ap: port where the device is
|
||||
*
|
||||
* Reads ATA taskfile error register for
|
||||
* currently-selected device and return its value.
|
||||
*
|
||||
* Note: may NOT be used as the check_err() entry in
|
||||
* ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
u8 ata_chk_err(struct ata_port *ap)
|
||||
{
|
||||
if (ap->ops->check_err)
|
||||
|
|
@ -873,10 +966,24 @@ void ata_dev_id_string(u16 *id, unsigned char *s,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_noop_dev_select - Select device 0/1 on ATA bus
|
||||
* @ap: ATA channel to manipulate
|
||||
* @device: ATA device (numbered from zero) to select
|
||||
*
|
||||
* This function performs no actual function.
|
||||
*
|
||||
* May be used as the dev_select() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* caller.
|
||||
*/
|
||||
void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_std_dev_select - Select device 0/1 on ATA bus
|
||||
* @ap: ATA channel to manipulate
|
||||
|
|
@ -884,7 +991,9 @@ void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
|
|||
*
|
||||
* Use the method defined in the ATA specification to
|
||||
* make either device 0, or device 1, active on the
|
||||
* ATA channel.
|
||||
* ATA channel. Works with both PIO and MMIO.
|
||||
*
|
||||
* May be used as the dev_select() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* caller.
|
||||
|
|
@ -1190,7 +1299,12 @@ err_out:
|
|||
* ata_bus_probe - Reset and probe ATA bus
|
||||
* @ap: Bus to probe
|
||||
*
|
||||
* Master ATA bus probing function. Initiates a hardware-dependent
|
||||
* bus reset, then attempts to identify any devices found on
|
||||
* the bus.
|
||||
*
|
||||
* LOCKING:
|
||||
* PCI/etc. bus probe sem.
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, non-zero on error.
|
||||
|
|
@ -1229,10 +1343,14 @@ err_out:
|
|||
}
|
||||
|
||||
/**
|
||||
* ata_port_probe -
|
||||
* @ap:
|
||||
* ata_port_probe - Mark port as enabled
|
||||
* @ap: Port for which we indicate enablement
|
||||
*
|
||||
* LOCKING:
|
||||
* Modify @ap data structure such that the system
|
||||
* thinks that the entire port is enabled.
|
||||
*
|
||||
* LOCKING: host_set lock, or some other form of
|
||||
* serialization.
|
||||
*/
|
||||
|
||||
void ata_port_probe(struct ata_port *ap)
|
||||
|
|
@ -1241,10 +1359,15 @@ void ata_port_probe(struct ata_port *ap)
|
|||
}
|
||||
|
||||
/**
|
||||
* __sata_phy_reset -
|
||||
* @ap:
|
||||
* __sata_phy_reset - Wake/reset a low-level SATA PHY
|
||||
* @ap: SATA port associated with target SATA PHY.
|
||||
*
|
||||
* This function issues commands to standard SATA Sxxx
|
||||
* PHY registers, to wake up the phy (and device), and
|
||||
* clear any reset condition.
|
||||
*
|
||||
* LOCKING:
|
||||
* PCI/etc. bus probe sem.
|
||||
*
|
||||
*/
|
||||
void __sata_phy_reset(struct ata_port *ap)
|
||||
|
|
@ -1253,11 +1376,11 @@ void __sata_phy_reset(struct ata_port *ap)
|
|||
unsigned long timeout = jiffies + (HZ * 5);
|
||||
|
||||
if (ap->flags & ATA_FLAG_SATA_RESET) {
|
||||
scr_write(ap, SCR_CONTROL, 0x301); /* issue phy wake/reset */
|
||||
scr_read(ap, SCR_STATUS); /* dummy read; flush */
|
||||
/* issue phy wake/reset */
|
||||
scr_write_flush(ap, SCR_CONTROL, 0x301);
|
||||
udelay(400); /* FIXME: a guess */
|
||||
}
|
||||
scr_write(ap, SCR_CONTROL, 0x300); /* issue phy wake/clear reset */
|
||||
scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
|
||||
|
||||
/* wait for phy to become ready, if necessary */
|
||||
do {
|
||||
|
|
@ -1289,10 +1412,14 @@ void __sata_phy_reset(struct ata_port *ap)
|
|||
}
|
||||
|
||||
/**
|
||||
* __sata_phy_reset -
|
||||
* @ap:
|
||||
* sata_phy_reset - Reset SATA bus.
|
||||
* @ap: SATA port associated with target SATA PHY.
|
||||
*
|
||||
* This function resets the SATA bus, and then probes
|
||||
* the bus for devices.
|
||||
*
|
||||
* LOCKING:
|
||||
* PCI/etc. bus probe sem.
|
||||
*
|
||||
*/
|
||||
void sata_phy_reset(struct ata_port *ap)
|
||||
|
|
@ -1304,10 +1431,16 @@ void sata_phy_reset(struct ata_port *ap)
|
|||
}
|
||||
|
||||
/**
|
||||
* ata_port_disable -
|
||||
* @ap:
|
||||
* ata_port_disable - Disable port.
|
||||
* @ap: Port to be disabled.
|
||||
*
|
||||
* LOCKING:
|
||||
* Modify @ap data structure such that the system
|
||||
* thinks that the entire port is disabled, and should
|
||||
* never attempt to probe or communicate with devices
|
||||
* on this port.
|
||||
*
|
||||
* LOCKING: host_set lock, or some other form of
|
||||
* serialization.
|
||||
*/
|
||||
|
||||
void ata_port_disable(struct ata_port *ap)
|
||||
|
|
@ -1416,7 +1549,10 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
|
|||
* ata_set_mode - Program timings and issue SET FEATURES - XFER
|
||||
* @ap: port on which timings will be programmed
|
||||
*
|
||||
* Set ATA device disk transfer mode (PIO3, UDMA6, etc.).
|
||||
*
|
||||
* LOCKING:
|
||||
* PCI/etc. bus probe sem.
|
||||
*
|
||||
*/
|
||||
static void ata_set_mode(struct ata_port *ap)
|
||||
|
|
@ -1467,7 +1603,10 @@ err_out:
|
|||
* @tmout_pat: impatience timeout
|
||||
* @tmout: overall timeout
|
||||
*
|
||||
* LOCKING:
|
||||
* Sleep until ATA Status register bit BSY clears,
|
||||
* or a timeout occurs.
|
||||
*
|
||||
* LOCKING: None.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -1553,10 +1692,14 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
|
|||
}
|
||||
|
||||
/**
|
||||
* ata_bus_edd -
|
||||
* @ap:
|
||||
* ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command.
|
||||
* @ap: Port to reset and probe
|
||||
*
|
||||
* Use the EXECUTE DEVICE DIAGNOSTIC command to reset and
|
||||
* probe the bus. Not often used these days.
|
||||
*
|
||||
* LOCKING:
|
||||
* PCI/etc. bus probe sem.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -1633,8 +1776,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
|
|||
* the device is ATA or ATAPI.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller. Some functions called by this function
|
||||
* obtain the host_set lock.
|
||||
* PCI/etc. bus probe sem.
|
||||
* Obtains host_set lock.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
* Sets ATA_FLAG_PORT_DISABLED if bus reset fails.
|
||||
|
|
@ -1876,7 +2019,11 @@ static int fgb(u32 bitmap)
|
|||
* @xfer_mode_out: (output) SET FEATURES - XFER MODE code
|
||||
* @xfer_shift_out: (output) bit shift that selects this mode
|
||||
*
|
||||
* Based on host and device capabilities, determine the
|
||||
* maximum transfer mode that is amenable to all.
|
||||
*
|
||||
* LOCKING:
|
||||
* PCI/etc. bus probe sem.
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, negative on error.
|
||||
|
|
@ -1909,7 +2056,11 @@ static int ata_choose_xfer_mode(struct ata_port *ap,
|
|||
* @ap: Port associated with device @dev
|
||||
* @dev: Device to which command will be sent
|
||||
*
|
||||
* Issue SET FEATURES - XFER MODE command to device @dev
|
||||
* on port @ap.
|
||||
*
|
||||
* LOCKING:
|
||||
* PCI/etc. bus probe sem.
|
||||
*/
|
||||
|
||||
static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
|
||||
|
|
@ -1947,10 +2098,13 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
|
|||
}
|
||||
|
||||
/**
|
||||
* ata_sg_clean -
|
||||
* @qc:
|
||||
* ata_sg_clean - Unmap DMA memory associated with command
|
||||
* @qc: Command containing DMA memory to be released
|
||||
*
|
||||
* Unmap all mapped DMA memory associated with this command.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*/
|
||||
|
||||
static void ata_sg_clean(struct ata_queued_cmd *qc)
|
||||
|
|
@ -1981,7 +2135,11 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
|
|||
* ata_fill_sg - Fill PCI IDE PRD table
|
||||
* @qc: Metadata associated with taskfile to be transferred
|
||||
*
|
||||
* Fill PCI IDE PRD (scatter-gather) table with segments
|
||||
* associated with the current disk command.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*
|
||||
*/
|
||||
static void ata_fill_sg(struct ata_queued_cmd *qc)
|
||||
|
|
@ -2028,7 +2186,13 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
|
|||
* ata_check_atapi_dma - Check whether ATAPI DMA can be supported
|
||||
* @qc: Metadata associated with taskfile to check
|
||||
*
|
||||
* Allow low-level driver to filter ATA PACKET commands, returning
|
||||
* a status indicating whether or not it is OK to use DMA for the
|
||||
* supplied PACKET command.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*
|
||||
* RETURNS: 0 when ATAPI DMA can be used
|
||||
* nonzero otherwise
|
||||
*/
|
||||
|
|
@ -2046,6 +2210,8 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
|
|||
* ata_qc_prep - Prepare taskfile for submission
|
||||
* @qc: Metadata associated with taskfile to be prepared
|
||||
*
|
||||
* Prepare ATA taskfile for submission.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*/
|
||||
|
|
@ -2057,6 +2223,32 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
|
|||
ata_fill_sg(qc);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_sg_init_one - Associate command with memory buffer
|
||||
* @qc: Command to be associated
|
||||
* @buf: Memory buffer
|
||||
* @buflen: Length of memory buffer, in bytes.
|
||||
*
|
||||
* Initialize the data-related elements of queued_cmd @qc
|
||||
* to point to a single memory buffer, @buf of byte length @buflen.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ata_sg_init_one - Prepare a one-entry scatter-gather list.
|
||||
* @qc: Queued command
|
||||
* @buf: transfer buffer
|
||||
* @buflen: length of buf
|
||||
*
|
||||
* Builds a single-entry scatter-gather list to initiate a
|
||||
* transfer utilizing the specified buffer.
|
||||
*
|
||||
* LOCKING:
|
||||
*/
|
||||
void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
|
||||
{
|
||||
struct scatterlist *sg;
|
||||
|
|
@ -2071,9 +2263,35 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
|
|||
sg = qc->sg;
|
||||
sg->page = virt_to_page(buf);
|
||||
sg->offset = (unsigned long) buf & ~PAGE_MASK;
|
||||
sg_dma_len(sg) = buflen;
|
||||
sg->length = buflen;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_sg_init - Associate command with scatter-gather table.
|
||||
* @qc: Command to be associated
|
||||
* @sg: Scatter-gather table.
|
||||
* @n_elem: Number of elements in s/g table.
|
||||
*
|
||||
* Initialize the data-related elements of queued_cmd @qc
|
||||
* to point to a scatter-gather table @sg, containing @n_elem
|
||||
* elements.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* ata_sg_init - Assign a scatter gather list to a queued command
|
||||
* @qc: Queued command
|
||||
* @sg: Scatter-gather list
|
||||
* @n_elem: length of sg list
|
||||
*
|
||||
* Attaches a scatter-gather list to a queued command.
|
||||
*
|
||||
* LOCKING:
|
||||
*/
|
||||
|
||||
void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
|
||||
unsigned int n_elem)
|
||||
{
|
||||
|
|
@ -2083,14 +2301,16 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
|
|||
}
|
||||
|
||||
/**
|
||||
* ata_sg_setup_one -
|
||||
* @qc:
|
||||
* ata_sg_setup_one - DMA-map the memory buffer associated with a command.
|
||||
* @qc: Command with memory buffer to be mapped.
|
||||
*
|
||||
* DMA-map the memory buffer associated with queued_cmd @qc.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Zero on success, negative on error.
|
||||
*/
|
||||
|
||||
static int ata_sg_setup_one(struct ata_queued_cmd *qc)
|
||||
|
|
@ -2101,11 +2321,12 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
|
|||
dma_addr_t dma_address;
|
||||
|
||||
dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
|
||||
sg_dma_len(sg), dir);
|
||||
sg->length, dir);
|
||||
if (dma_mapping_error(dma_address))
|
||||
return -1;
|
||||
|
||||
sg_dma_address(sg) = dma_address;
|
||||
sg_dma_len(sg) = sg->length;
|
||||
|
||||
DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg),
|
||||
qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
|
||||
|
|
@ -2114,13 +2335,16 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
|
|||
}
|
||||
|
||||
/**
|
||||
* ata_sg_setup -
|
||||
* @qc:
|
||||
* ata_sg_setup - DMA-map the scatter-gather table associated with a command.
|
||||
* @qc: Command with scatter-gather table to be mapped.
|
||||
*
|
||||
* DMA-map the scatter-gather table associated with queued_cmd @qc.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, negative on error.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -2150,6 +2374,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
|
|||
* @ap:
|
||||
*
|
||||
* LOCKING:
|
||||
* None. (executing in kernel thread context)
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
|
|
@ -2197,6 +2422,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
|
|||
* @ap:
|
||||
*
|
||||
* LOCKING:
|
||||
* None. (executing in kernel thread context)
|
||||
*/
|
||||
|
||||
static void ata_pio_complete (struct ata_port *ap)
|
||||
|
|
@ -2239,6 +2465,18 @@ static void ata_pio_complete (struct ata_port *ap)
|
|||
ata_qc_complete(qc, drv_stat);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* swap_buf_le16 -
|
||||
* @buf: Buffer to swap
|
||||
* @buf_words: Number of 16-bit words in buffer.
|
||||
*
|
||||
* Swap halves of 16-bit words if needed to convert from
|
||||
* little-endian byte order to native cpu byte order, or
|
||||
* vice-versa.
|
||||
*
|
||||
* LOCKING:
|
||||
*/
|
||||
void swap_buf_le16(u16 *buf, unsigned int buf_words)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN
|
||||
|
|
@ -2310,7 +2548,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
|
|||
qc->cursect++;
|
||||
qc->cursg_ofs++;
|
||||
|
||||
if ((qc->cursg_ofs * ATA_SECT_SIZE) == sg_dma_len(&sg[qc->cursg])) {
|
||||
if ((qc->cursg_ofs * ATA_SECT_SIZE) == (&sg[qc->cursg])->length) {
|
||||
qc->cursg++;
|
||||
qc->cursg_ofs = 0;
|
||||
}
|
||||
|
|
@ -2347,7 +2585,7 @@ next_page:
|
|||
page = nth_page(page, (offset >> PAGE_SHIFT));
|
||||
offset %= PAGE_SIZE;
|
||||
|
||||
count = min(sg_dma_len(sg) - qc->cursg_ofs, bytes);
|
||||
count = min(sg->length - qc->cursg_ofs, bytes);
|
||||
|
||||
/* don't cross page boundaries */
|
||||
count = min(count, (unsigned int)PAGE_SIZE - offset);
|
||||
|
|
@ -2358,7 +2596,7 @@ next_page:
|
|||
qc->curbytes += count;
|
||||
qc->cursg_ofs += count;
|
||||
|
||||
if (qc->cursg_ofs == sg_dma_len(sg)) {
|
||||
if (qc->cursg_ofs == sg->length) {
|
||||
qc->cursg++;
|
||||
qc->cursg_ofs = 0;
|
||||
}
|
||||
|
|
@ -2371,7 +2609,7 @@ next_page:
|
|||
kunmap(page);
|
||||
|
||||
if (bytes) {
|
||||
if (qc->cursg_ofs < sg_dma_len(sg))
|
||||
if (qc->cursg_ofs < sg->length)
|
||||
goto next_page;
|
||||
goto next_sg;
|
||||
}
|
||||
|
|
@ -2414,6 +2652,7 @@ err_out:
|
|||
* @ap:
|
||||
*
|
||||
* LOCKING:
|
||||
* None. (executing in kernel thread context)
|
||||
*/
|
||||
|
||||
static void ata_pio_block(struct ata_port *ap)
|
||||
|
|
@ -2539,7 +2778,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
|
|||
ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
|
||||
qc->dma_dir = DMA_FROM_DEVICE;
|
||||
|
||||
memset(&qc->cdb, 0, sizeof(ap->cdb_len));
|
||||
memset(&qc->cdb, 0, ap->cdb_len);
|
||||
qc->cdb[0] = REQUEST_SENSE;
|
||||
qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
|
||||
|
||||
|
|
@ -2582,6 +2821,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
|
|||
* transaction completed successfully.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from SCSI layer (none, can sleep)
|
||||
*/
|
||||
|
||||
static void ata_qc_timeout(struct ata_queued_cmd *qc)
|
||||
|
|
@ -2691,6 +2931,7 @@ out:
|
|||
* @dev: Device from whom we request an available command structure
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*/
|
||||
|
||||
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
|
||||
|
|
@ -2716,6 +2957,7 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
|
|||
* @dev: Device from whom we request an available command structure
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*/
|
||||
|
||||
struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
|
||||
|
|
@ -2780,6 +3022,7 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
|
|||
* in case something prevents using it.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*
|
||||
*/
|
||||
void ata_qc_free(struct ata_queued_cmd *qc)
|
||||
|
|
@ -2793,9 +3036,13 @@ void ata_qc_free(struct ata_queued_cmd *qc)
|
|||
/**
|
||||
* ata_qc_complete - Complete an active ATA command
|
||||
* @qc: Command to complete
|
||||
* @drv_stat: ATA status register contents
|
||||
* @drv_stat: ATA Status register contents
|
||||
*
|
||||
* Indicate to the mid and upper layers that an ATA
|
||||
* command has completed, with either an ok or not-ok status.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -2811,6 +3058,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
|
|||
|
||||
/* call completion callback */
|
||||
rc = qc->complete_fn(qc, drv_stat);
|
||||
qc->flags &= ~ATA_QCFLAG_ACTIVE;
|
||||
|
||||
/* if callback indicates not to complete command (non-zero),
|
||||
* return immediately
|
||||
|
|
@ -2890,6 +3138,7 @@ err_out:
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
|
||||
* @qc: command to issue to device
|
||||
|
|
@ -2899,6 +3148,8 @@ err_out:
|
|||
* classes called "protocols", and issuing each type of protocol
|
||||
* is slightly different.
|
||||
*
|
||||
* May be used as the qc_issue() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*
|
||||
|
|
@ -2956,7 +3207,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
|
|||
}
|
||||
|
||||
/**
|
||||
* ata_bmdma_setup - Set up PCI IDE BMDMA transaction
|
||||
* ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction
|
||||
* @qc: Info associated with this ATA transaction.
|
||||
*
|
||||
* LOCKING:
|
||||
|
|
@ -3063,6 +3314,18 @@ static void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
|
|||
ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_bmdma_start - Start a PCI IDE BMDMA transaction
|
||||
* @qc: Info associated with this ATA transaction.
|
||||
*
|
||||
* Writes the ATA_DMA_START flag to the DMA command register.
|
||||
*
|
||||
* May be used as the bmdma_start() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*/
|
||||
void ata_bmdma_start(struct ata_queued_cmd *qc)
|
||||
{
|
||||
if (qc->ap->flags & ATA_FLAG_MMIO)
|
||||
|
|
@ -3071,6 +3334,20 @@ void ata_bmdma_start(struct ata_queued_cmd *qc)
|
|||
ata_bmdma_start_pio(qc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_bmdma_setup - Set up PCI IDE BMDMA transaction
|
||||
* @qc: Info associated with this ATA transaction.
|
||||
*
|
||||
* Writes address of PRD table to device's PRD Table Address
|
||||
* register, sets the DMA control register, and calls
|
||||
* ops->exec_command() to start the transfer.
|
||||
*
|
||||
* May be used as the bmdma_setup() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*/
|
||||
void ata_bmdma_setup(struct ata_queued_cmd *qc)
|
||||
{
|
||||
if (qc->ap->flags & ATA_FLAG_MMIO)
|
||||
|
|
@ -3079,6 +3356,19 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)
|
|||
ata_bmdma_setup_pio(qc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
|
||||
* @ap: Port associated with this ATA transaction.
|
||||
*
|
||||
* Clear interrupt and error flags in DMA status register.
|
||||
*
|
||||
* May be used as the irq_clear() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*/
|
||||
|
||||
void ata_bmdma_irq_clear(struct ata_port *ap)
|
||||
{
|
||||
if (ap->flags & ATA_FLAG_MMIO) {
|
||||
|
|
@ -3091,6 +3381,19 @@ void ata_bmdma_irq_clear(struct ata_port *ap)
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_bmdma_status - Read PCI IDE BMDMA status
|
||||
* @ap: Port associated with this ATA transaction.
|
||||
*
|
||||
* Read and return BMDMA status register.
|
||||
*
|
||||
* May be used as the bmdma_status() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*/
|
||||
|
||||
u8 ata_bmdma_status(struct ata_port *ap)
|
||||
{
|
||||
u8 host_stat;
|
||||
|
|
@ -3102,6 +3405,19 @@ u8 ata_bmdma_status(struct ata_port *ap)
|
|||
return host_stat;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_bmdma_stop - Stop PCI IDE BMDMA transfer
|
||||
* @ap: Port associated with this ATA transaction.
|
||||
*
|
||||
* Clears the ATA_DMA_START flag in the dma control register
|
||||
*
|
||||
* May be used as the bmdma_stop() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host_set lock)
|
||||
*/
|
||||
|
||||
void ata_bmdma_stop(struct ata_port *ap)
|
||||
{
|
||||
if (ap->flags & ATA_FLAG_MMIO) {
|
||||
|
|
@ -3201,13 +3517,18 @@ idle_irq:
|
|||
|
||||
/**
|
||||
* ata_interrupt - Default ATA host interrupt handler
|
||||
* @irq: irq line
|
||||
* @dev_instance: pointer to our host information structure
|
||||
* @irq: irq line (unused)
|
||||
* @dev_instance: pointer to our ata_host_set information structure
|
||||
* @regs: unused
|
||||
*
|
||||
* Default interrupt handler for PCI IDE devices. Calls
|
||||
* ata_host_intr() for each port that is not disabled.
|
||||
*
|
||||
* LOCKING:
|
||||
* Obtains host_set lock during operation.
|
||||
*
|
||||
* RETURNS:
|
||||
* IRQ_NONE or IRQ_HANDLED.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -3229,7 +3550,8 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
|
|||
struct ata_queued_cmd *qc;
|
||||
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
if (qc && (!(qc->tf.ctl & ATA_NIEN)))
|
||||
if (qc && (!(qc->tf.ctl & ATA_NIEN)) &&
|
||||
(qc->flags & ATA_QCFLAG_ACTIVE))
|
||||
handled |= ata_host_intr(ap, qc);
|
||||
}
|
||||
}
|
||||
|
|
@ -3299,6 +3621,19 @@ err_out:
|
|||
ata_qc_complete(qc, ATA_ERR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_port_start - Set port up for dma.
|
||||
* @ap: Port to initialize
|
||||
*
|
||||
* Called just after data structures for each port are
|
||||
* initialized. Allocates space for PRD table.
|
||||
*
|
||||
* May be used as the port_start() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
*/
|
||||
|
||||
int ata_port_start (struct ata_port *ap)
|
||||
{
|
||||
struct device *dev = ap->host_set->dev;
|
||||
|
|
@ -3312,6 +3647,18 @@ int ata_port_start (struct ata_port *ap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_port_stop - Undo ata_port_start()
|
||||
* @ap: Port to shut down
|
||||
*
|
||||
* Frees the PRD table.
|
||||
*
|
||||
* May be used as the port_stop() entry in ata_port_operations.
|
||||
*
|
||||
* LOCKING:
|
||||
*/
|
||||
|
||||
void ata_port_stop (struct ata_port *ap)
|
||||
{
|
||||
struct device *dev = ap->host_set->dev;
|
||||
|
|
@ -3319,6 +3666,13 @@ void ata_port_stop (struct ata_port *ap)
|
|||
dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
|
||||
}
|
||||
|
||||
void ata_host_stop (struct ata_host_set *host_set)
|
||||
{
|
||||
if (host_set->mmio_base)
|
||||
iounmap(host_set->mmio_base);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_host_remove - Unregister SCSI host structure with upper layers
|
||||
* @ap: Port to unregister
|
||||
|
|
@ -3347,7 +3701,11 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
|
|||
* @ent: Probe information provided by low-level driver
|
||||
* @port_no: Port number associated with this ata_port
|
||||
*
|
||||
* Initialize a new ata_port structure, and its associated
|
||||
* scsi_host.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -3402,9 +3760,13 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
|
|||
* @host_set: Collections of ports to which we add
|
||||
* @port_no: Port number associated with this host
|
||||
*
|
||||
* Attach low-level ATA driver to system.
|
||||
*
|
||||
* LOCKING:
|
||||
* PCI/etc. bus probe sem.
|
||||
*
|
||||
* RETURNS:
|
||||
* New ata_port on success, for NULL on error.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -3437,12 +3799,22 @@ err_out:
|
|||
}
|
||||
|
||||
/**
|
||||
* ata_device_add -
|
||||
* @ent:
|
||||
* ata_device_add - Register hardware device with ATA and SCSI layers
|
||||
* @ent: Probe information describing hardware device to be registered
|
||||
*
|
||||
* This function processes the information provided in the probe
|
||||
* information struct @ent, allocates the necessary ATA and SCSI
|
||||
* host information structures, initializes them, and registers
|
||||
* everything with requisite kernel subsystems.
|
||||
*
|
||||
* This function requests irqs, probes the ATA bus, and probes
|
||||
* the SCSI bus.
|
||||
*
|
||||
* LOCKING:
|
||||
* PCI/etc. bus probe sem.
|
||||
*
|
||||
* RETURNS:
|
||||
* Number of ports registered. Zero on error (no ports registered).
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -3594,7 +3966,15 @@ int ata_scsi_release(struct Scsi_Host *host)
|
|||
/**
|
||||
* ata_std_ports - initialize ioaddr with standard port offsets.
|
||||
* @ioaddr: IO address structure to be initialized
|
||||
*
|
||||
* Utility function which initializes data_addr, error_addr,
|
||||
* feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr,
|
||||
* device_addr, status_addr, and command_addr to standard offsets
|
||||
* relative to cmd_addr.
|
||||
*
|
||||
* Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
|
||||
*/
|
||||
|
||||
void ata_std_ports(struct ata_ioports *ioaddr)
|
||||
{
|
||||
ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
|
||||
|
|
@ -3636,6 +4016,20 @@ ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port)
|
|||
return probe_ent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ata_pci_init_native_mode - Initialize native-mode driver
|
||||
* @pdev: pci device to be initialized
|
||||
* @port: array[2] of pointers to port info structures.
|
||||
*
|
||||
* Utility function which allocates and initializes an
|
||||
* ata_probe_ent structure for a standard dual-port
|
||||
* PIO-based IDE controller. The returned ata_probe_ent
|
||||
* structure can be passed to ata_device_add(). The returned
|
||||
* ata_probe_ent structure should then be freed with kfree().
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
struct ata_probe_ent *
|
||||
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
|
||||
|
|
@ -3717,10 +4111,19 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
|
|||
* @port_info: Information from low-level host driver
|
||||
* @n_ports: Number of ports attached to host controller
|
||||
*
|
||||
* This is a helper function which can be called from a driver's
|
||||
* xxx_init_one() probe function if the hardware uses traditional
|
||||
* IDE taskfile registers.
|
||||
*
|
||||
* This function calls pci_enable_device(), reserves its register
|
||||
* regions, sets the dma mask, enables bus master mode, and calls
|
||||
* ata_device_add()
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from PCI layer (may sleep).
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, negative on errno-based value on error.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -3875,10 +4278,6 @@ void ata_pci_remove_one (struct pci_dev *pdev)
|
|||
}
|
||||
|
||||
free_irq(host_set->irq, host_set);
|
||||
if (host_set->ops->host_stop)
|
||||
host_set->ops->host_stop(host_set);
|
||||
if (host_set->mmio_base)
|
||||
iounmap(host_set->mmio_base);
|
||||
|
||||
for (i = 0; i < host_set->n_ports; i++) {
|
||||
ap = host_set->ports[i];
|
||||
|
|
@ -3897,6 +4296,9 @@ void ata_pci_remove_one (struct pci_dev *pdev)
|
|||
scsi_host_put(ap->host);
|
||||
}
|
||||
|
||||
if (host_set->ops->host_stop)
|
||||
host_set->ops->host_stop(host_set);
|
||||
|
||||
kfree(host_set);
|
||||
|
||||
pci_release_regions(pdev);
|
||||
|
|
@ -3940,15 +4342,6 @@ int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits)
|
|||
#endif /* CONFIG_PCI */
|
||||
|
||||
|
||||
/**
|
||||
* ata_init -
|
||||
*
|
||||
* LOCKING:
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
*/
|
||||
|
||||
static int __init ata_init(void)
|
||||
{
|
||||
ata_wq = create_workqueue("ata");
|
||||
|
|
@ -3994,6 +4387,7 @@ EXPORT_SYMBOL_GPL(ata_chk_err);
|
|||
EXPORT_SYMBOL_GPL(ata_exec_command);
|
||||
EXPORT_SYMBOL_GPL(ata_port_start);
|
||||
EXPORT_SYMBOL_GPL(ata_port_stop);
|
||||
EXPORT_SYMBOL_GPL(ata_host_stop);
|
||||
EXPORT_SYMBOL_GPL(ata_interrupt);
|
||||
EXPORT_SYMBOL_GPL(ata_qc_prep);
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
|
||||
|
|
|
|||
|
|
@ -347,7 +347,10 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
|
|||
*/
|
||||
if ((dev->flags & ATA_DFLAG_LBA48) &&
|
||||
((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) {
|
||||
sdev->host->max_sectors = 2048;
|
||||
/*
|
||||
* do not overwrite sdev->host->max_sectors, since
|
||||
* other drives on this host may not support LBA48
|
||||
*/
|
||||
blk_queue_max_sectors(sdev->request_queue, 2048);
|
||||
}
|
||||
}
|
||||
|
|
@ -944,7 +947,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
|
|||
}
|
||||
|
||||
/**
|
||||
* ata_scsiop_noop -
|
||||
* ata_scsiop_noop - Command handler that simply returns success.
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
* @buflen: Response buffer length.
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#define __LIBATA_H__
|
||||
|
||||
#define DRV_NAME "libata"
|
||||
#define DRV_VERSION "1.10" /* must be exactly four chars */
|
||||
#define DRV_VERSION "1.11" /* must be exactly four chars */
|
||||
|
||||
struct ata_scsi_args {
|
||||
u16 *id;
|
||||
|
|
|
|||
|
|
@ -507,6 +507,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||
int ret, i;
|
||||
unsigned int id, lun;
|
||||
unsigned long serial;
|
||||
unsigned long flags;
|
||||
|
||||
if (!CMD_SP(cmd))
|
||||
return FAILED;
|
||||
|
|
@ -519,7 +520,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||
|
||||
/* Check active list for command command. */
|
||||
spin_unlock_irq(ha->host->host_lock);
|
||||
spin_lock(&ha->hardware_lock);
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
|
||||
sp = ha->outstanding_cmds[i];
|
||||
|
||||
|
|
@ -534,7 +535,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||
sp->state));
|
||||
DEBUG3(qla2x00_print_scsi_cmd(cmd);)
|
||||
|
||||
spin_unlock(&ha->hardware_lock);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
if (qla2x00_abort_command(ha, sp)) {
|
||||
DEBUG2(printk("%s(%ld): abort_command "
|
||||
"mbx failed.\n", __func__, ha->host_no));
|
||||
|
|
@ -543,20 +544,19 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||
"mbx success.\n", __func__, ha->host_no));
|
||||
ret = SUCCESS;
|
||||
}
|
||||
spin_lock(&ha->hardware_lock);
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
/* Wait for the command to be returned. */
|
||||
if (ret == SUCCESS) {
|
||||
spin_unlock(&ha->hardware_lock);
|
||||
if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) {
|
||||
qla_printk(KERN_ERR, ha,
|
||||
"scsi(%ld:%d:%d): Abort handler timed out -- %lx "
|
||||
"%x.\n", ha->host_no, id, lun, serial, ret);
|
||||
}
|
||||
spin_lock(&ha->hardware_lock);
|
||||
}
|
||||
spin_lock_irq(ha->host->host_lock);
|
||||
|
||||
|
|
@ -588,6 +588,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
|
|||
int status;
|
||||
srb_t *sp;
|
||||
struct scsi_cmnd *cmd;
|
||||
unsigned long flags;
|
||||
|
||||
status = 0;
|
||||
|
||||
|
|
@ -596,11 +597,11 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
|
|||
* array
|
||||
*/
|
||||
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
|
||||
spin_lock(&ha->hardware_lock);
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
sp = ha->outstanding_cmds[cnt];
|
||||
if (sp) {
|
||||
cmd = sp->cmd;
|
||||
spin_unlock(&ha->hardware_lock);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
if (cmd->device->id == t) {
|
||||
if (!qla2x00_eh_wait_on_command(ha, cmd)) {
|
||||
status = 1;
|
||||
|
|
@ -608,7 +609,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
spin_unlock(&ha->hardware_lock);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
}
|
||||
}
|
||||
return (status);
|
||||
|
|
@ -740,6 +741,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
|
|||
int status;
|
||||
srb_t *sp;
|
||||
struct scsi_cmnd *cmd;
|
||||
unsigned long flags;
|
||||
|
||||
status = 1;
|
||||
|
||||
|
|
@ -748,17 +750,17 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
|
|||
* array
|
||||
*/
|
||||
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
|
||||
spin_lock(&ha->hardware_lock);
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
sp = ha->outstanding_cmds[cnt];
|
||||
if (sp) {
|
||||
cmd = sp->cmd;
|
||||
spin_unlock(&ha->hardware_lock);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
status = qla2x00_eh_wait_on_command(ha, cmd);
|
||||
if (status == 0)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
spin_unlock(&ha->hardware_lock);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
}
|
||||
}
|
||||
return (status);
|
||||
|
|
|
|||
|
|
@ -329,6 +329,8 @@ static void nv_host_stop (struct ata_host_set *host_set)
|
|||
host->host_desc->disable_hotplug(host_set);
|
||||
|
||||
kfree(host);
|
||||
|
||||
ata_host_stop(host_set);
|
||||
}
|
||||
|
||||
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ static struct ata_port_operations pdc_ata_ops = {
|
|||
.scr_write = pdc_sata_scr_write,
|
||||
.port_start = pdc_port_start,
|
||||
.port_stop = pdc_port_stop,
|
||||
.host_stop = ata_host_stop,
|
||||
};
|
||||
|
||||
static struct ata_port_info pdc_port_info[] = {
|
||||
|
|
@ -163,6 +164,8 @@ static struct ata_port_info pdc_port_info[] = {
|
|||
static struct pci_device_id pdc_ata_pci_tbl[] = {
|
||||
{ PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
board_2037x },
|
||||
{ PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
board_2037x },
|
||||
{ PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
board_2037x },
|
||||
{ PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
|
|
|
|||
|
|
@ -536,6 +536,8 @@ static void qs_host_stop(struct ata_host_set *host_set)
|
|||
|
||||
writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
|
||||
writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
|
||||
|
||||
ata_host_stop(host_set);
|
||||
}
|
||||
|
||||
static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ static struct pci_device_id sil_pci_tbl[] = {
|
|||
{ 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
|
||||
{ 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
|
||||
{ 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
|
||||
{ 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
|
|
@ -160,6 +161,7 @@ static struct ata_port_operations sil_ops = {
|
|||
.scr_write = sil_scr_write,
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = ata_host_stop,
|
||||
};
|
||||
|
||||
static struct ata_port_info sil_port_info[] = {
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ static struct ata_port_operations sis_ops = {
|
|||
.scr_write = sis_scr_write,
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = ata_host_stop,
|
||||
};
|
||||
|
||||
static struct ata_port_info sis_port_info = {
|
||||
|
|
|
|||
|
|
@ -313,6 +313,7 @@ static struct ata_port_operations k2_sata_ops = {
|
|||
.scr_write = k2_sata_scr_write,
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = ata_host_stop,
|
||||
};
|
||||
|
||||
static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base)
|
||||
|
|
@ -395,7 +396,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
|
|||
|
||||
/* Clear a magic bit in SCR1 according to Darwin, those help
|
||||
* some funky seagate drives (though so far, those were already
|
||||
* set by the firmware on the machines I had access to
|
||||
* set by the firmware on the machines I had access to)
|
||||
*/
|
||||
writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000,
|
||||
mmio_base + K2_SATA_SICR1_OFFSET);
|
||||
|
|
|
|||
|
|
@ -245,6 +245,8 @@ static void pdc20621_host_stop(struct ata_host_set *host_set)
|
|||
|
||||
iounmap(dimm_mmio);
|
||||
kfree(hpriv);
|
||||
|
||||
ata_host_stop(host_set);
|
||||
}
|
||||
|
||||
static int pdc_port_start(struct ata_port *ap)
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ static struct ata_port_operations uli_ops = {
|
|||
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = ata_host_stop,
|
||||
};
|
||||
|
||||
static struct ata_port_info uli_port_info = {
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ static struct ata_port_operations svia_sata_ops = {
|
|||
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = ata_host_stop,
|
||||
};
|
||||
|
||||
static struct ata_port_info svia_port_info = {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/blkdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include "scsi.h"
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <linux/libata.h>
|
||||
|
|
@ -230,6 +231,7 @@ static struct ata_port_operations vsc_sata_ops = {
|
|||
.scr_write = vsc_sata_scr_write,
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = ata_host_stop,
|
||||
};
|
||||
|
||||
static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base)
|
||||
|
|
|
|||
|
|
@ -1197,6 +1197,7 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
|
|||
if (!starget)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
get_device(&starget->dev);
|
||||
down(&shost->scan_mutex);
|
||||
res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
|
||||
if (res != SCSI_SCAN_LUN_PRESENT)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#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
|
||||
* on" attributes */
|
||||
#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);
|
||||
|
||||
spi_period(starget) = -1; /* illegal value */
|
||||
spi_min_period(starget) = 0;
|
||||
spi_offset(starget) = 0; /* async */
|
||||
spi_max_offset(starget) = 255;
|
||||
spi_width(starget) = 0; /* narrow */
|
||||
spi_max_width(starget) = 1;
|
||||
spi_iu(starget) = 0; /* no IU */
|
||||
spi_dt(starget) = 0; /* ST */
|
||||
spi_qas(starget) = 0;
|
||||
|
|
@ -235,6 +238,34 @@ static int spi_setup_transport_attrs(struct device *dev)
|
|||
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) \
|
||||
\
|
||||
static ssize_t \
|
||||
|
|
@ -261,6 +292,25 @@ store_spi_transport_##field(struct class_device *cdev, const char *buf, \
|
|||
struct spi_internal *i = to_spi_internal(shost->transportt); \
|
||||
\
|
||||
val = simple_strtoul(buf, NULL, 0); \
|
||||
i->f->set_##field(starget, val); \
|
||||
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; \
|
||||
}
|
||||
|
|
@ -272,9 +322,24 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \
|
|||
show_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: */
|
||||
spi_transport_rd_attr(offset, "%d\n");
|
||||
spi_transport_rd_attr(width, "%d\n");
|
||||
spi_transport_max_attr(offset, "%d\n");
|
||||
spi_transport_max_attr(width, "%d\n");
|
||||
spi_transport_rd_attr(iu, "%d\n");
|
||||
spi_transport_rd_attr(dt, "%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
|
||||
* 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;
|
||||
struct spi_internal *i = to_spi_internal(shost->transportt);
|
||||
|
||||
tp = (struct spi_transport_attrs *)&starget->starget_data;
|
||||
|
||||
if (i->f->get_period)
|
||||
i->f->get_period(starget);
|
||||
|
||||
if (tp->period < 0 || tp->period > 0xff) {
|
||||
if (period < 0 || period > 0xff) {
|
||||
picosec = -1;
|
||||
} else if (tp->period <= SPI_STATIC_PPR) {
|
||||
picosec = ppr_to_ps[tp->period];
|
||||
} else if (period <= SPI_STATIC_PPR) {
|
||||
picosec = ppr_to_ps[period];
|
||||
} else {
|
||||
picosec = tp->period * 4000;
|
||||
picosec = period * 4000;
|
||||
}
|
||||
|
||||
if (picosec == -1) {
|
||||
|
|
@ -334,12 +391,9 @@ static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf)
|
|||
}
|
||||
|
||||
static ssize_t
|
||||
store_spi_transport_period(struct class_device *cdev, const char *buf,
|
||||
size_t count)
|
||||
store_spi_transport_period_helper(struct class_device *cdev, const char *buf,
|
||||
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;
|
||||
char *endp;
|
||||
|
||||
|
|
@ -368,15 +422,79 @@ store_spi_transport_period(struct class_device *cdev, const char *buf,
|
|||
if (period > 0xff)
|
||||
period = 0xff;
|
||||
|
||||
i->f->set_period(starget, period);
|
||||
*periodp = period;
|
||||
|
||||
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,
|
||||
show_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)
|
||||
{
|
||||
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 scsi_device *sdev = sreq->sr_device;
|
||||
struct scsi_target *starget = sdev->sdev_target;
|
||||
int len = sdev->inquiry_len;
|
||||
/* first set us up for narrow async */
|
||||
DV_SET(offset, 0);
|
||||
|
|
@ -655,9 +774,11 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer)
|
|||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
printk("WIDTH IS %d\n", spi_max_width(starget));
|
||||
|
||||
if (spi_dv_device_compare_inquiry(sreq, buffer,
|
||||
buffer + len,
|
||||
DV_LOOPS)
|
||||
|
|
@ -684,8 +805,8 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer)
|
|||
retry:
|
||||
|
||||
/* now set up to the maximum */
|
||||
DV_SET(offset, 255);
|
||||
DV_SET(period, 1);
|
||||
DV_SET(offset, spi_max_offset(starget));
|
||||
DV_SET(period, spi_min_period(starget));
|
||||
|
||||
if (len == 0) {
|
||||
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) \
|
||||
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) \
|
||||
i->private_host_attrs[count] = class_device_attr_##field; \
|
||||
if (!i->f->set_##field) { \
|
||||
|
|
@ -975,8 +1106,11 @@ spi_attach_transport(struct spi_function_template *ft)
|
|||
i->f = ft;
|
||||
|
||||
SETUP_ATTRIBUTE(period);
|
||||
SETUP_RELATED_ATTRIBUTE(min_period, period);
|
||||
SETUP_ATTRIBUTE(offset);
|
||||
SETUP_RELATED_ATTRIBUTE(max_offset, offset);
|
||||
SETUP_ATTRIBUTE(width);
|
||||
SETUP_RELATED_ATTRIBUTE(max_width, width);
|
||||
SETUP_ATTRIBUTE(iu);
|
||||
SETUP_ATTRIBUTE(dt);
|
||||
SETUP_ATTRIBUTE(qas);
|
||||
|
|
|
|||
Loading…
Reference in a new issue