Commit a5f635f8 authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/spare/repo/linux-2.6

into redhat.com:/spare/repo/libata-2.6
parents 49838689 26cf2696
......@@ -449,6 +449,14 @@ config SCSI_SATA_SIL
If unsure, say N.
config SCSI_SATA_SIS
tristate "SiS 964/180 SATA support"
depends on SCSI_SATA && PCI
help
This option enables support for SiS Serial ATA 964/180.
If unsure, say N.
config SCSI_SATA_VIA
tristate "VIA SATA support"
depends on SCSI_SATA && PCI && EXPERIMENTAL
......
......@@ -123,6 +123,7 @@ obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o
obj-$(CONFIG_SCSI_SATA_SIL) += libata.o sata_sil.o
obj-$(CONFIG_SCSI_SATA_VIA) += libata.o sata_via.o
obj-$(CONFIG_SCSI_SATA_VITESSE) += libata.o sata_vsc.o
obj-$(CONFIG_SCSI_SATA_SIS) += libata.o sata_sis.o
obj-$(CONFIG_ARM) += arm/
......
......@@ -28,17 +28,24 @@
#include <linux/libata.h>
#define DRV_NAME "ata_piix"
#define DRV_VERSION "1.01"
#define DRV_VERSION "1.02"
enum {
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
ICH5_PMR = 0x90, /* port mapping register */
ICH5_PCS = 0x92, /* port control and status */
PIIX_FLAG_CHECKINTR = (1 << 29), /* make sure PCI INTx enabled */
PIIX_FLAG_COMBINED = (1 << 30), /* combined mode possible */
PIIX_COMB_PRI = (1 << 0), /* combined mode, PATA primary */
PIIX_COMB_SEC = (1 << 1), /* combined mode, PATA secondary */
/* combined mode. if set, PATA is channel 0.
* if clear, PATA is channel 1.
*/
PIIX_COMB_PATA_P0 = (1 << 1),
PIIX_COMB = (1 << 2), /* combined mode enabled? */
PIIX_PORT_PRESENT = (1 << 0),
PIIX_PORT_ENABLED = (1 << 4),
PIIX_80C_PRI = (1 << 5) | (1 << 4),
PIIX_80C_SEC = (1 << 7) | (1 << 6),
......@@ -53,7 +60,6 @@ static int piix_init_one (struct pci_dev *pdev,
static void piix_pata_phy_reset(struct ata_port *ap);
static void piix_sata_phy_reset(struct ata_port *ap);
static void piix_sata_port_disable(struct ata_port *ap);
static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev,
unsigned int pio);
static void piix_set_udmamode (struct ata_port *ap, struct ata_device *adev,
......@@ -137,7 +143,7 @@ static struct ata_port_operations piix_pata_ops = {
};
static struct ata_port_operations piix_sata_ops = {
.port_disable = piix_sata_port_disable,
.port_disable = ata_port_disable,
.set_piomode = piix_set_piomode,
.set_udmamode = piix_set_udmamode,
......@@ -259,54 +265,48 @@ static void piix_pata_phy_reset(struct ata_port *ap)
}
/**
* piix_pcs_probe - Probe SATA port configuration and status register
* @ap: Port to probe
* @have_port: (output) Non-zero if SATA port is enabled
* @have_device: (output) Non-zero if SATA phy indicates device present
* piix_sata_probe - Probe PCI device for present SATA devices
* @pdev: PCI device to probe
*
* Reads SATA PCI device's PCI config register Port Configuration
* and Status (PCS) to determine port and device availability.
*
* LOCKING:
* None (inherited from caller).
*/
static void piix_pcs_probe (struct ata_port *ap, unsigned int *have_port,
unsigned int *have_device)
{
struct pci_dev *pdev = ap->host_set->pdev;
u16 pcs;
pci_read_config_word(pdev, ICH5_PCS, &pcs);
/* is SATA port enabled? */
if (pcs & (1 << ap->port_no)) {
*have_port = 1;
if (pcs & (1 << (ap->port_no + 4)))
*have_device = 1;
}
}
/**
* piix_pcs_disable - Disable SATA port
* @ap: Port to disable
*
* Disable SATA phy for specified port.
*
* LOCKING:
* None (inherited from caller).
* RETURNS:
* Non-zero if device detected, zero otherwise.
*/
static void piix_pcs_disable (struct ata_port *ap)
static int piix_sata_probe (struct ata_port *ap)
{
struct pci_dev *pdev = ap->host_set->pdev;
u16 pcs;
int combined = (ap->flags & ATA_FLAG_SLAVE_POSS);
int orig_mask, mask, i;
u8 pcs;
mask = (PIIX_PORT_PRESENT << ap->port_no) |
(PIIX_PORT_ENABLED << ap->port_no);
pci_read_config_byte(pdev, ICH5_PCS, &pcs);
orig_mask = (int) pcs & 0xff;
/* TODO: this is vaguely wrong for ICH6 combined mode,
* where only two of the four SATA ports are mapped
* onto a single ATA channel. It is also vaguely inaccurate
* for ICH5, which has only two ports. However, this is ok,
* as further device presence detection code will handle
* any false positives produced here.
*/
pci_read_config_word(pdev, ICH5_PCS, &pcs);
for (i = 0; i < 4; i++) {
mask = (PIIX_PORT_PRESENT << i) | (PIIX_PORT_ENABLED << i);
if (pcs & (1 << ap->port_no)) {
pcs &= ~(1 << ap->port_no);
pci_write_config_word(pdev, ICH5_PCS, pcs);
if ((orig_mask & mask) == mask)
if (combined || (i == ap->port_no))
return 1;
}
return 0;
}
/**
......@@ -321,8 +321,6 @@ static void piix_pcs_disable (struct ata_port *ap)
static void piix_sata_phy_reset(struct ata_port *ap)
{
unsigned int have_port = 0, have_dev = 0;
if (!pci_test_config_bits(ap->host_set->pdev,
&piix_enable_bits[ap->port_no])) {
ata_port_disable(ap);
......@@ -330,21 +328,9 @@ static void piix_sata_phy_reset(struct ata_port *ap)
return;
}
piix_pcs_probe(ap, &have_port, &have_dev);
/* if port not enabled, exit */
if (!have_port) {
if (!piix_sata_probe(ap)) {
ata_port_disable(ap);
printk(KERN_INFO "ata%u: SATA port disabled. ignoring.\n",
ap->id);
return;
}
/* if port enabled but no device, disable port and exit */
if (!have_dev) {
piix_sata_port_disable(ap);
printk(KERN_INFO "ata%u: SATA port has no device. disabling.\n",
ap->id);
printk(KERN_INFO "ata%u: SATA port has no device.\n", ap->id);
return;
}
......@@ -355,22 +341,6 @@ static void piix_sata_phy_reset(struct ata_port *ap)
ata_bus_reset(ap);
}
/**
* piix_sata_port_disable - Disable SATA port
* @ap: Port to disable.
*
* Disable SATA port.
*
* LOCKING:
* None (inherited from caller).
*/
static void piix_sata_port_disable(struct ata_port *ap)
{
ata_port_disable(ap);
piix_pcs_disable(ap);
}
/**
* piix_set_piomode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring
......@@ -493,31 +463,6 @@ static void piix_set_udmamode (struct ata_port *ap, struct ata_device *adev,
}
}
/**
* piix_probe_combined - Determine if PATA and SATA are combined
* @pdev: PCI device to examine
* @mask: (output) zero, %PIIX_COMB_PRI or %PIIX_COMB_SEC
*
* Determine if BIOS has secretly stuffed a PATA port into our
* otherwise-beautiful SATA PCI device.
*
* LOCKING:
* Inherited from PCI layer (may sleep).
*/
static void piix_probe_combined (struct pci_dev *pdev, unsigned int *mask)
{
u8 tmp;
pci_read_config_byte(pdev, 0x90, &tmp); /* combined mode reg */
tmp &= 0x6; /* interesting bits 2:1, PATA primary/secondary */
/* backwards from what one might expect */
if (tmp == 0x4) /* bits 10x */
*mask |= PIIX_COMB_SEC;
if (tmp == 0x6) /* bits 11x */
*mask |= PIIX_COMB_PRI;
}
/* move to PCI layer, integrate w/ MSI stuff */
static void pci_enable_intx(struct pci_dev *pdev)
{
......@@ -550,7 +495,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
static int printed_version;
struct ata_port_info *port_info[2];
unsigned int combined = 0, n_ports = 1;
unsigned int pata_comb = 0, sata_comb = 0;
unsigned int pata_chan = 0, sata_chan = 0;
if (!printed_version++)
printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
......@@ -561,8 +506,19 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
port_info[0] = &piix_port_info[ent->driver_data];
port_info[1] = NULL;
if (port_info[0]->host_flags & PIIX_FLAG_COMBINED)
piix_probe_combined(pdev, &combined);
if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) {
u8 tmp;
pci_read_config_byte(pdev, ICH5_PMR, &tmp);
if (tmp & PIIX_COMB) {
combined = 1;
if (tmp & PIIX_COMB_PATA_P0)
sata_chan = 1;
else
pata_chan = 1;
}
}
/* On ICH5, some BIOSen disable the interrupt using the
* PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.
......@@ -573,15 +529,10 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (port_info[0]->host_flags & PIIX_FLAG_CHECKINTR)
pci_enable_intx(pdev);
if (combined & PIIX_COMB_PRI)
sata_comb = 1;
else if (combined & PIIX_COMB_SEC)
pata_comb = 1;
if (pata_comb || sata_comb) {
port_info[sata_comb] = &piix_port_info[ent->driver_data];
port_info[sata_comb]->host_flags |= ATA_FLAG_SLAVE_POSS; /* sigh */
port_info[pata_comb] = &piix_port_info[ich5_pata]; /*ich5-specific*/
if (combined) {
port_info[sata_chan] = &piix_port_info[ent->driver_data];
port_info[sata_chan]->host_flags |= ATA_FLAG_SLAVE_POSS;
port_info[pata_chan] = &piix_port_info[ich5_pata];
n_ports++;
printk(KERN_WARNING DRV_NAME ": combined mode detected\n");
......
......@@ -439,6 +439,81 @@ u8 ata_check_status_mmio(struct ata_port *ap)
return readb((void *) ap->ioaddr.status_addr);
}
/**
* ata_prot_to_cmd - determine which read/write opcodes to use
* @protocol: ATA_PROT_xxx taskfile protocol
* @lba48: true is lba48 is present
*
* Given necessary input, determine which read/write commands
* to use to transfer data.
*
* LOCKING:
* None.
*/
static int ata_prot_to_cmd(int protocol, int lba48)
{
int rcmd = 0, wcmd = 0;
switch (protocol) {
case ATA_PROT_PIO:
if (lba48) {
rcmd = ATA_CMD_PIO_READ_EXT;
wcmd = ATA_CMD_PIO_WRITE_EXT;
} else {
rcmd = ATA_CMD_PIO_READ;
wcmd = ATA_CMD_PIO_WRITE;
}
break;
case ATA_PROT_DMA:
if (lba48) {
rcmd = ATA_CMD_READ_EXT;
wcmd = ATA_CMD_WRITE_EXT;
} else {
rcmd = ATA_CMD_READ;
wcmd = ATA_CMD_WRITE;
}
break;
default:
return -1;
}
return rcmd | (wcmd << 8);
}
/**
* ata_dev_set_protocol - set taskfile protocol and r/w commands
* @dev: device to examine and configure
*
* Examine the device configuration, after we have
* read the identify-device page and configured the
* data transfer mode. Set internal state related to
* the ATA taskfile protocol (pio, pio mult, dma, etc.)
* and calculate the proper read/write commands to use.
*
* LOCKING:
* caller.
*/
static void ata_dev_set_protocol(struct ata_device *dev)
{
int pio = (dev->flags & ATA_DFLAG_PIO);
int lba48 = (dev->flags & ATA_DFLAG_LBA48);
int proto, cmd;
if (pio)
proto = dev->xfer_protocol = ATA_PROT_PIO;
else
proto = dev->xfer_protocol = ATA_PROT_DMA;
cmd = ata_prot_to_cmd(proto, lba48);
if (cmd < 0)
BUG();
dev->read_cmd = cmd & 0xff;
dev->write_cmd = (cmd >> 8) & 0xff;
}
static const char * udma_str[] = {
"UDMA/16",
"UDMA/25",
......@@ -478,12 +553,21 @@ static const char *ata_udma_string(unsigned int udma_mask)
}
/**
* ata_pio_devchk -
* @ap:
* @device:
* ata_pio_devchk - PATA device presence detection
* @ap: ATA channel to examine
* @device: Device to examine (starting at zero)
*
* LOCKING:
* This technique was originally described in
* Hale Landis's ATADRVR (www.ata-atapi.com), and
* later found its way into the ATA/ATAPI spec.
*
* Write a pattern to the ATA shadow registers,
* and if a device is present, it will respond by
* correctly storing and echoing back the
* ATA shadow register contents.
*
* LOCKING:
* caller.
*/
static unsigned int ata_pio_devchk(struct ata_port *ap,
......@@ -513,12 +597,21 @@ static unsigned int ata_pio_devchk(struct ata_port *ap,
}
/**
* ata_mmio_devchk -
* @ap:
* @device:
* ata_mmio_devchk - PATA device presence detection
* @ap: ATA channel to examine
* @device: Device to examine (starting at zero)
*
* LOCKING:
* This technique was originally described in
* Hale Landis's ATADRVR (www.ata-atapi.com), and
* later found its way into the ATA/ATAPI spec.
*
* Write a pattern to the ATA shadow registers,
* and if a device is present, it will respond by
* correctly storing and echoing back the
* ATA shadow register contents.
*
* LOCKING:
* caller.
*/
static unsigned int ata_mmio_devchk(struct ata_port *ap,
......@@ -548,12 +641,16 @@ static unsigned int ata_mmio_devchk(struct ata_port *ap,
}
/**
* ata_dev_devchk -
* @ap:
* @device:
* ata_dev_devchk - PATA device presence detection
* @ap: ATA channel to examine
* @device: Device to examine (starting at zero)
*
* LOCKING:
* Dispatch ATA device presence detection, depending
* on whether we are using PIO or MMIO to talk to the
* ATA shadow registers.
*
* LOCKING:
* caller.
*/
static unsigned int ata_dev_devchk(struct ata_port *ap,
......@@ -604,16 +701,24 @@ static unsigned int ata_dev_classify(struct ata_taskfile *tf)
}
/**
* ata_dev_try_classify -
* @ap:
* @device:
* ata_dev_try_classify - Parse returned ATA device signature
* @ap: ATA channel to examine
* @device: Device to examine (starting at zero)
*
* LOCKING:
* After an event -- SRST, E.D.D., or SATA COMRESET -- occurs,
* an ATA/ATAPI-defined set of values is placed in the ATA
* shadow registers, indicating the results of device detection
* and diagnostics.
*
* Select the ATA device, and read the values from the ATA shadow
* registers. Then parse according to the Error register value,
* and the spec-defined values examined by ata_dev_classify().
*
* LOCKING:
* caller.
*/
static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device,
unsigned int maybe_have_dev)
static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
{
struct ata_device *dev = &ap->device[device];
struct ata_taskfile tf;
......@@ -650,44 +755,51 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device,
}
/**
* ata_dev_id_string -
* @dev:
* @s:
* @ofs:
* @len:
* ata_dev_id_string - Convert IDENTIFY DEVICE page into string
* @dev: Device whose IDENTIFY DEVICE results we will examine
* @s: string into which data is output
* @ofs: offset into identify device page
* @len: length of string to return
*
* LOCKING:
*
* RETURNS:
* The strings in the IDENTIFY DEVICE page are broken up into
* 16-bit chunks. Run through the string, and output each
* 8-bit chunk linearly, regardless of platform.
*
* LOCKING:
* caller.
*/
unsigned int ata_dev_id_string(struct ata_device *dev, unsigned char *s,
unsigned int ofs, unsigned int len)
void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
unsigned int ofs, unsigned int len)
{
unsigned int c, ret = 0;
unsigned int c;
while (len > 0) {
c = dev->id[ofs] >> 8;
*s = c;
s++;
ret = c = dev->id[ofs] & 0xff;
c = dev->id[ofs] & 0xff;
*s = c;
s++;
ofs++;
len -= 2;
}
return ret;
}
/**
* ata_dev_parse_strings -
* @dev:
* ata_dev_parse_strings - Store useful IDENTIFY DEVICE page strings
* @dev: Device whose IDENTIFY DEVICE page info we use
*
* We store 'vendor' and 'product' strings read from the device,
* for later use in the SCSI simulator's INQUIRY data.
*
* Set these strings here, in the case of 'product', using
* data read from the ATA IDENTIFY DEVICE page.
*
* LOCKING:
* caller.
*/
static void ata_dev_parse_strings(struct ata_device *dev)
......@@ -700,12 +812,16 @@ static void ata_dev_parse_strings(struct ata_device *dev)
}
/**
* __ata_dev_select -
* @ap:
* @device:
* __ata_dev_select - Select device 0/1 on ATA bus
* @ap: ATA channel to manipulate
* @device: ATA device (numbered from zero) to select
*
* LOCKING:
* Use the method defined in the ATA specification to
* make either device 0, or device 1, active on the
* ATA channel.
*
* LOCKING:
* caller.
*/
static void __ata_dev_select (struct ata_port *ap, unsigned int device)
......@@ -726,16 +842,22 @@ static void __ata_dev_select (struct ata_port *ap, unsigned int device)
}
/**
* ata_dev_select -
* @ap:
* @device:
* @wait:
* @can_sleep:
* ata_dev_select - Select device 0/1 on ATA bus
* @ap: ATA channel to manipulate
* @device: ATA device (numbered from zero) to select
* @wait: non-zero to wait for Status register BSY bit to clear
* @can_sleep: non-zero if context allows sleeping
*
* LOCKING:
* Use the method defined in the ATA specification to
* make either device 0, or device 1, active on the
* ATA channel.
*
* RETURNS:
* This is a high-level version of __ata_dev_select(),
* which additionally provides the services of inserting
* the proper pauses and status polling, where needed.
*
* LOCKING:
* caller.
*/
void ata_dev_select(struct ata_port *ap, unsigned int device,
......@@ -757,10 +879,14 @@ void ata_dev_select(struct ata_port *ap, unsigned int device,
}
/**
* ata_dump_id -
* @dev:
* ata_dump_id - IDENTIFY DEVICE info debugging output
* @dev: Device whose IDENTIFY DEVICE page we will dump
*
* Dump selected 16-bit words from a detected device's
* IDENTIFY PAGE page.
*
* LOCKING:
* caller.
*/
static inline void ata_dump_id(struct ata_device *dev)
......@@ -843,7 +969,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
retry:
ata_tf_init(ap, &tf, device);
tf.ctl |= ATA_NIEN;
tf.protocol = ATA_PROT_PIO_READ;
tf.protocol = ATA_PROT_PIO;
if (dev->class == ATA_DEV_ATA) {
tf.command = ATA_CMD_ID_ATA;
......@@ -1129,7 +1255,7 @@ void ata_port_disable(struct ata_port *ap)
*/
static void ata_set_mode(struct ata_port *ap)
{
unsigned int force_pio;
unsigned int force_pio, i;
ata_host_set_pio(ap);
if (ap->flags & ATA_FLAG_PORT_DISABLED)
......@@ -1148,19 +1274,21 @@ static void ata_set_mode(struct ata_port *ap)
if (force_pio) {
ata_dev_set_pio(ap, 0);
ata_dev_set_pio(ap, 1);
if (ap->flags & ATA_FLAG_PORT_DISABLED)
return;
} else {
ata_dev_set_udma(ap, 0);
ata_dev_set_udma(ap, 1);
if (ap->flags & ATA_FLAG_PORT_DISABLED)
return;
}
if (ap->flags & ATA_FLAG_PORT_DISABLED)
return;
if (ap->ops->post_set_mode)
ap->ops->post_set_mode(ap);
for (i = 0; i < 2; i++) {
struct ata_device *dev = &ap->device[i];
ata_dev_set_protocol(dev);
}
}
/**
......@@ -1386,9 +1514,9 @@ void ata_bus_reset(struct ata_port *ap)
/*
* determine by signature whether we have ATA or ATAPI devices
*/
err = ata_dev_try_classify(ap, 0, dev0);
err = ata_dev_try_classify(ap, 0);
if ((slave_possible) && (err != 0x81))
ata_dev_try_classify(ap, 1, dev1);
ata_dev_try_classify(ap, 1);
/* re-enable interrupts */
ata_irq_on(ap);
......@@ -1725,6 +1853,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
struct scatterlist *sg = qc->sg;
unsigned int have_sg = (qc->flags & ATA_QCFLAG_SG);
dma_addr_t dma_address;
assert(sg == &qc->sgent);
assert(qc->n_elem == 1);
......@@ -1736,12 +1865,15 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
if (!have_sg)
return 0;
sg_dma_address(sg) = pci_map_single(ap->host_set->pdev,
cmd->request_buffer,
cmd->request_bufflen, dir);
dma_address = pci_map_single(ap->host_set->pdev, cmd->request_buffer,
cmd->request_bufflen, dir);
if (pci_dma_mapping_error(dma_address))
return -1;
sg_dma_address(sg) = dma_address;
DPRINTK("mapped buffer of %d bytes for %s\n", cmd->request_bufflen,
qc->flags & ATA_QCFLAG_WRITE ? "write" : "read");
qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
return 0;
}
......@@ -1842,8 +1974,7 @@ static void ata_pio_start (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
assert((qc->tf.protocol == ATA_PROT_PIO_READ) ||
(qc->tf.protocol == ATA_PROT_PIO_WRITE));
assert(qc->tf.protocol == ATA_PROT_PIO);
qc->flags |= ATA_QCFLAG_POLL;
qc->tf.ctl |= ATA_NIEN; /* disable interrupts */
......@@ -1963,12 +2094,12 @@ static void ata_pio_sector(struct ata_port *ap)
}
DPRINTK("data %s, drv_stat 0x%X\n",
qc->flags & ATA_QCFLAG_WRITE ? "write" : "read",
qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read",
status);
/* do the actual data transfer */
/* FIXME: mmio-ize */
if (qc->flags & ATA_QCFLAG_WRITE)
if (qc->tf.flags & ATA_TFLAG_WRITE)
outsl(ap->ioaddr.data_addr, buf, ATA_SECT_DWORDS);
else
insl(ap->ioaddr.data_addr, buf, ATA_SECT_DWORDS);
......@@ -2033,8 +2164,7 @@ void ata_eng_timeout(struct ata_port *ap)
qc->scsidone = scsi_finish_command;
switch (qc->tf.protocol) {
case ATA_PROT_DMA_READ:
case ATA_PROT_DMA_WRITE:
case ATA_PROT_DMA:
if (ap->flags & ATA_FLAG_MMIO) {
void *mmio = (void *) ap->ioaddr.bmdma_addr;
host_stat = readb(mmio + ATA_DMA_STATUS);
......@@ -2258,7 +2388,7 @@ int ata_qc_issue(struct ata_queued_cmd *qc)
void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int rw = (qc->flags & ATA_QCFLAG_WRITE);
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
u8 host_stat, dmactl;
void *mmio = (void *) ap->ioaddr.bmdma_addr;
......@@ -2307,7 +2437,7 @@ void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int rw = (qc->flags & ATA_QCFLAG_WRITE);
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
u8 host_stat, dmactl;
/* load PRD table addr. */
......@@ -2402,8 +2532,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
unsigned int handled = 0;
switch (qc->tf.protocol) {
case ATA_PROT_DMA_READ:
case ATA_PROT_DMA_WRITE:
case ATA_PROT_DMA:
if (ap->flags & ATA_FLAG_MMIO) {
void *mmio = (void *) ap->ioaddr.bmdma_addr;
host_stat = readb(mmio + ATA_DMA_STATUS);
......@@ -2810,6 +2939,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
host->unique_id = ata_unique_id++;
host->max_cmd_len = 12;
scsi_set_device(host, &ent->pdev->dev);
scsi_assign_lock(host, &host_set->lock);
ap->flags = ATA_FLAG_PORT_DISABLED;
ap->id = host->unique_id;
......
......@@ -32,17 +32,28 @@
#include "libata.h"
static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *));
/**
* ata_std_bios_param - generic bios head/sector/cylinder calculator
* used by sd. Most BIOSes nowadays expect a XXX/255/16 (CHS)
* mapping. Some situations may arise where the disk is not
* bootable if this is not used.
* ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd.
* @sdev: SCSI device for which BIOS geometry is to be determined
* @bdev: block device associated with @sdev
* @capacity: capacity of SCSI device
* @geom: location to which geometry will be output
*
* Generic bios head/sector/cylinder calculator
* used by sd. Most BIOSes nowadays expect a XXX/255/16 (CHS)
* mapping. Some situations may arise where the disk is not
* bootable if this is not used.
*
* LOCKING:
* Defined by the SCSI layer. We don't really care.
*
* RETURNS:
*
* Zero.
*/
int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int geom[])
......@@ -56,6 +67,27 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
}
/**
* ata_scsi_qc_new - acquire new ata_queued_cmd reference
* @ap: ATA port to which the new command is attached
* @dev: ATA device to which the new command is attached
* @cmd: SCSI command that originated this ATA command
* @done: SCSI command completion function
*
* Obtain a reference to an unused ata_queued_cmd structure,
* which is the basic libata structure representing a single
* ATA command sent to the hardware.
*
* If a command was available, fill in the SCSI-specific
* portions of the structure with information on the
* current command.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
* RETURNS:
* Command allocated, or %NULL if none available.
*/
struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap,
struct ata_device *dev,
struct scsi_cmnd *cmd,
......@@ -84,11 +116,18 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap,
}
/**
* ata_to_sense_error -
* @qc:
* @cmd:
* ata_to_sense_error - convert ATA error to SCSI error
* @qc: Command that we are erroring out
*
* Converts an ATA error into a SCSI error.
*
* Right now, this routine is laughably primitive. We
* don't even examine what ATA told us, we just look at
* the command data direction, and return a fatal SCSI
* sense error based on that.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
void ata_to_sense_error(struct ata_queued_cmd *qc)
......@@ -102,7 +141,7 @@ void ata_to_sense_error(struct ata_queued_cmd *qc)
cmd->sense_buffer[7] = 14 - 8; /* addnl. sense len. FIXME: correct? */
/* additional-sense-code[-qualifier] */
if ((qc->flags & ATA_QCFLAG_WRITE) == 0) {
if (cmd->sc_data_direction == SCSI_DATA_READ) {
cmd->sense_buffer[12] = 0x11; /* "unrecovered read error" */
cmd->sense_buffer[13] = 0x04;
} else {
......@@ -112,11 +151,15 @@ void ata_to_sense_error(struct ata_queued_cmd *qc)
}
/**
* ata_scsi_slave_config -
* @sdev:
* ata_scsi_slave_config - Set SCSI device attributes
* @sdev: SCSI device to examine
*
* LOCKING:
* This is called before we actually start reading
* and writing to the device, to configure certain
* SCSI mid-layer behaviors.
*
* LOCKING:
* Defined by SCSI layer. We don't really care.
*/
int ata_scsi_slave_config(struct scsi_device *sdev)
......@@ -155,24 +198,29 @@ int ata_scsi_error(struct Scsi_Host *host)
}
/**
* ata_scsi_rw_xlat -
* @qc:
* @scsicmd:
* @cmd_size:
* ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
* @qc: Storage for translated ATA taskfile
* @scsicmd: SCSI command to translate
*
* Converts any of six SCSI read/write commands into the
* ATA counterpart, including starting sector (LBA),
* sector count, and taking into account the device's LBA48
* support.
*
* Commands %READ_6, %READ_10, %READ_16, %WRITE_6, %WRITE_10, and
* %WRITE_16 are currently supported.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
* RETURNS:
*
* Zero on success, non-zero on error.
*/
static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
unsigned int cmd_size)
static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
unsigned int dma = qc->flags & ATA_QCFLAG_DMA;
qc->cursect = qc->cursg = qc->cursg_ofs = 0;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
......@@ -180,43 +228,18 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
tf->hob_lbal = 0;
tf->hob_lbam = 0;
tf->hob_lbah = 0;
tf->protocol = qc->dev->xfer_protocol;
tf->device |= ATA_LBA;
if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 ||
scsicmd[0] == READ_16) {
if (likely(dma)) {
if (lba48)
tf->command = ATA_CMD_READ_EXT;
else
tf->command = ATA_CMD_READ;
tf->protocol = ATA_PROT_DMA_READ;
} else {
if (lba48)
tf->command = ATA_CMD_PIO_READ_EXT;
else
tf->command = ATA_CMD_PIO_READ;
tf->protocol = ATA_PROT_PIO_READ;
}
qc->flags &= ~ATA_QCFLAG_WRITE;
VPRINTK("reading\n");
tf->command = qc->dev->read_cmd;
} else {
if (likely(dma)) {
if (lba48)
tf->command = ATA_CMD_WRITE_EXT;
else
tf->command = ATA_CMD_WRITE;
tf->protocol = ATA_PROT_DMA_WRITE;
} else {
if (lba48)
tf->command = ATA_CMD_PIO_WRITE_EXT;
else
tf->command = ATA_CMD_PIO_WRITE;
tf->protocol = ATA_PROT_PIO_WRITE;
}
qc->flags |= ATA_QCFLAG_WRITE;
VPRINTK("writing\n");
tf->command = qc->dev->write_cmd;
tf->flags |= ATA_TFLAG_WRITE;
}
if (cmd_size == 10) {
if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) {
if (lba48) {
tf->hob_nsect = scsicmd[7];
tf->hob_lbal = scsicmd[2];
......@@ -234,7 +257,6 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
qc->nsect = scsicmd[8];
}
tf->device |= ATA_LBA;
tf->nsect = scsicmd[8];
tf->lbal = scsicmd[5];
......@@ -245,7 +267,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
return 0;
}
if (cmd_size == 6) {
if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
qc->nsect = tf->nsect = scsicmd[4];
tf->lbal = scsicmd[3];
tf->lbam = scsicmd[2];
......@@ -257,7 +279,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
return 0;
}
if (cmd_size == 16) {
if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) {
/* rule out impossible LBAs and sector counts */
if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11])
return 1;
......@@ -281,7 +303,6 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
qc->nsect = scsicmd[13];
}
tf->device |= ATA_LBA;
tf->nsect = scsicmd[13];
tf->lbal = scsicmd[9];
......@@ -297,20 +318,26 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
}
/**
* ata_scsi_rw_queue -
* @ap:
* @dev:
* @cmd:
* @done:
* @cmd_size:
* ata_scsi_translate - Translate then issue SCSI command to ATA device
* @ap: ATA port to which the command is addressed
* @dev: ATA device to which the command is addressed
* @cmd: SCSI command to execute
* @done: SCSI command completion function
*
* Our ->queuecommand() function has decided that the SCSI
* command issued can be directly translated into an ATA
* command, rather than handled internally.
*
* This function sets up an ata_queued_cmd structure for the
* SCSI command, and sends that ata_queued_cmd to the hardware.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
void ata_scsi_rw_queue(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
unsigned int cmd_size)
static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
struct ata_queued_cmd *qc;
u8 *scsicmd = cmd->cmnd;
......@@ -329,7 +356,7 @@ void ata_scsi_rw_queue(struct ata_port *ap, struct ata_device *dev,
qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */
if (ata_scsi_rw_xlat(qc, scsicmd, cmd_size))
if (ata_scsi_rw_xlat(qc, scsicmd))
goto err_out;
/* select device, send command to hardware */
......@@ -353,7 +380,6 @@ void ata_scsi_rw_queue(struct ata_port *ap, struct ata_device *dev,
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
* FIXME: kmap inside spin_lock_irqsave ok?
*
* RETURNS:
* Length of response buffer.
......@@ -368,7 +394,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
buf = kmap(sg->page) + sg->offset;
buf = kmap_atomic(sg->page, KM_USER0) + sg->offset;
buflen = sg->length;
} else {
buf = cmd->request_buffer;
......@@ -396,7 +422,7 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd)
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
kunmap(sg->page);
kunmap_atomic(sg->page, KM_USER0);
}
}
......@@ -595,30 +621,6 @@ unsigned int ata_scsiop_noop(struct ata_scsi_args *args, u8 *rbuf,
return 0;
}
/**
* ata_scsiop_sync_cache - Simulate SYNCHRONIZE CACHE command
* @args: Port / device / SCSI command of interest.
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* @buflen: Response buffer length.
*
* Initiates flush of device's cache.
*
* TODO:
* Actually do this :)
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
unsigned int ata_scsiop_sync_cache(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen)
{
VPRINTK("ENTER\n");
/* FIXME */
return 1;
}
/**
* ata_msense_push - Push data onto MODE SENSE data output buffer
* @ptr_io: (input/output) Location to store more output data
......@@ -649,9 +651,9 @@ static void ata_msense_push(u8 **ptr_io, const u8 *last,
/**
* ata_msense_caching - Simulate MODE SENSE caching info page
* @dev:
* @ptr_io:
* @last:
* @dev: Device associated with this MODE SENSE command
* @ptr_io: (input/output) Location to store more output data
* @last: End of output data buffer
*
* Generate a caching info page, which conditionally indicates
* write caching to the SCSI layer, depending on device
......@@ -674,9 +676,9 @@ static unsigned int ata_msense_caching(struct ata_device *dev, u8 **ptr_io,
/**
* ata_msense_ctl_mode - Simulate MODE SENSE control mode page
* @dev:
* @ptr_io:
* @last:
* @dev: Device associated with this MODE SENSE command
* @ptr_io: (input/output) Location to store more output data
* @last: End of output data buffer
*
* Generate a generic MODE SENSE control mode page.
*
......@@ -834,11 +836,15 @@ unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
}
/**
* ata_scsi_badcmd -
* @cmd:
* @done:
* @asc:
* @ascq:
* ata_scsi_badcmd - End a SCSI request with an error
* @cmd: SCSI request to be handled
* @done: SCSI command completion function
* @asc: SCSI-defined additional sense code
* @ascq: SCSI-defined additional sense code qualifier
*
* Helper function that completes a SCSI command with
* %SAM_STAT_CHECK_CONDITION, with a sense key %ILLEGAL_REQUEST
* and the specified additional sense codes.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
......@@ -912,7 +918,7 @@ static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev,
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
if (cmd->sc_data_direction == SCSI_DATA_WRITE) {
qc->flags |= ATA_QCFLAG_WRITE;
qc->tf.flags |= ATA_TFLAG_WRITE;
DPRINTK("direction: write\n");
}
......@@ -966,6 +972,99 @@ static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev,
DPRINTK("EXIT - badcmd\n");
}
/**
* ata_scsi_find_dev - lookup ata_device from scsi_cmnd
* @ap: ATA port to which the device is attached
* @cmd: SCSI command to be sent to the device
*
* Given various information provided in struct scsi_cmnd,
* map that onto an ATA bus, and using that mapping
* determine which ata_device is associated with the
* SCSI command to be sent.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
* RETURNS:
* Associated ATA device, or %NULL if not found.
*/
static inline struct ata_device *
ata_scsi_find_dev(struct ata_port *ap, struct scsi_cmnd *cmd)
{
struct ata_device *dev;
/* skip commands not addressed to targets we simulate */
if (likely(cmd->device->id < ATA_MAX_DEVICES))
dev = &ap->device[cmd->device->id];
else
return NULL;
if (unlikely((cmd->device->channel != 0) ||
(cmd->device->lun != 0)))
return NULL;
if (unlikely(!ata_dev_present(dev)))
return NULL;
#ifndef ATA_ENABLE_ATAPI
if (unlikely(dev->class == ATA_DEV_ATAPI))
return NULL;
#endif
return dev;
}
/**
* ata_scsi_xlat_possible - check if SCSI to ATA translation is possible
* @cmd: SCSI command opcode to consider
*
* Look up the SCSI command given, and determine whether the
* SCSI command is to be translated or simulated.
*
* RETURNS:
* Non-zero if possible, zero if not.
*/
static inline int ata_scsi_xlat_possible(u8 cmd)
{
switch (cmd) {
case READ_6:
case READ_10:
case READ_16:
case WRITE_6:
case WRITE_10:
case WRITE_16:
return 1;
}
return 0;
}
/**
* ata_scsi_dump_cdb - dump SCSI command contents to dmesg
* @ap: ATA port to which the command was being sent
* @cmd: SCSI command to dump
*
* Prints the contents of a SCSI command via printk().
*/
static inline void ata_scsi_dump_cdb(struct ata_port *ap,
struct scsi_cmnd *cmd)
{
#ifdef ATA_DEBUG
u8 *scsicmd = cmd->cmnd;
DPRINTK("CDB (%u:%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
ap->id,
cmd->device->channel, cmd->device->id, cmd->device->lun,
scsicmd[0], scsicmd[1], scsicmd[2], scsicmd[3],
scsicmd[4], scsicmd[5], scsicmd[6], scsicmd[7],
scsicmd[8]);
#endif
}
/**
* ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device
* @cmd: SCSI command to be sent
......@@ -987,83 +1086,52 @@ static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev,
int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
u8 *scsicmd = cmd->cmnd;
struct ata_port *ap;
struct ata_device *dev;
struct ata_scsi_args args;
const unsigned int atapi_support =
#ifdef ATA_ENABLE_ATAPI
1;
#else
0;
#endif
/* Note: spin_lock_irqsave is held by caller... */
spin_unlock(cmd->device->host->host_lock);
ap = (struct ata_port *) &cmd->device->host->hostdata[0];
DPRINTK("CDB (%u:%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
ap->id,
cmd->device->channel, cmd->device->id, cmd->device->lun,
scsicmd[0], scsicmd[1], scsicmd[2], scsicmd[3],
scsicmd[4], scsicmd[5], scsicmd[6], scsicmd[7],
scsicmd[8]);
/* skip commands not addressed to targets we care about */
if ((cmd->device->channel != 0) || (cmd->device->lun != 0) ||
(cmd->device->id >= ATA_MAX_DEVICES)) {
cmd->result = (DID_BAD_TARGET << 16); /* FIXME: correct? */
done(cmd);
goto out;
}
ata_scsi_dump_cdb(ap, cmd);
spin_lock(&ap->host_set->lock);
dev = &ap->device[cmd->device->id];
if (!ata_dev_present(dev)) {
DPRINTK("no device\n");
cmd->result = (DID_BAD_TARGET << 16); /* FIXME: correct? */
dev = ata_scsi_find_dev(ap, cmd);
if (unlikely(!dev)) {
cmd->result = (DID_BAD_TARGET << 16);
done(cmd);
goto out_unlock;
}
if (dev->class == ATA_DEV_ATAPI) {
if (atapi_support)
atapi_scsi_queuecmd(ap, dev, cmd, done);
else {
cmd->result = (DID_BAD_TARGET << 16); /* correct? */
done(cmd);
}
goto out_unlock;
}
if (dev->class == ATA_DEV_ATA) {
if (ata_scsi_xlat_possible(cmd->cmnd[0]))
ata_scsi_translate(ap, dev, cmd, done);
else
ata_scsi_simulate(ap, dev, cmd, done);
} else
atapi_scsi_queuecmd(ap, dev, cmd, done);
/* fast path */
switch(scsicmd[0]) {
case READ_6:
case WRITE_6:
ata_scsi_rw_queue(ap, dev, cmd, done, 6);
goto out_unlock;
case READ_10:
case WRITE_10:
ata_scsi_rw_queue(ap, dev, cmd, done, 10);
goto out_unlock;
case READ_16:
case WRITE_16:
ata_scsi_rw_queue(ap, dev, cmd, done, 16);
goto out_unlock;
out_unlock:
return 0;
}
default:
/* do nothing */
break;
}
/**
* ata_scsi_simulate - simulate SCSI command on ATA device
* @ap: Port to which ATA device is attached.
* @dev: Target device for CDB.
* @cmd: SCSI command being sent to device.
* @done: SCSI command completion function.
*
* Interprets and directly executes a select list of SCSI commands
* that can be handled internally.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
/*
* slow path
*/
static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
struct ata_scsi_args args;
u8 *scsicmd = cmd->cmnd;
args.ap = ap;
args.dev = dev;
......@@ -1102,13 +1170,6 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
ata_bad_cdb(cmd, done);
break;
case SYNCHRONIZE_CACHE:
if ((dev->flags & ATA_DFLAG_WCACHE) == 0)
ata_bad_scsiop(cmd, done);
else
ata_scsi_rbuf_fill(&args, ata_scsiop_sync_cache);
break;
case READ_CAPACITY:
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
break;
......@@ -1132,11 +1193,5 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
ata_bad_scsiop(cmd, done);
break;
}
out_unlock:
spin_unlock(&ap->host_set->lock);
out:
spin_lock(cmd->device->host->host_lock);
return 0;
}
......@@ -37,8 +37,8 @@ struct ata_scsi_args {
/* libata-core.c */
extern unsigned int ata_dev_id_string(struct ata_device *dev, unsigned char *s,
unsigned int ofs, unsigned int len);
extern void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
unsigned int ofs, unsigned int len);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
struct ata_device *dev);
extern int ata_qc_issue(struct ata_queued_cmd *qc);
......@@ -50,9 +50,6 @@ extern void ata_thread_wake(struct ata_port *ap, unsigned int thr_state);
/* libata-scsi.c */
extern void ata_to_sense_error(struct ata_queued_cmd *qc);
extern void ata_scsi_rw_queue(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
unsigned int cmd_size);
extern int ata_scsi_error(struct Scsi_Host *host);
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen);
......
......@@ -28,13 +28,14 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include "scsi.h"
#include "hosts.h"
#include <linux/libata.h>
#include <asm/io.h>
#define DRV_NAME "sata_promise"
#define DRV_VERSION "0.91"
#define DRV_VERSION "0.92"
enum {
......@@ -45,10 +46,13 @@ enum {
PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
PDC_TBG_MODE = 0x41, /* TBG mode */
PDC_FLASH_CTL = 0x44, /* Flash control register */
PDC_CTLSTAT = 0x60, /* IDE control and status register */
PDC_PCI_CTL = 0x48, /* PCI control and status register */
PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */
PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */
PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */
PDC_SLEW_CTL = 0x470, /* slew rate control reg */
PDC_HDMA_CTLSTAT = 0x12C, /* Host DMA control / status */
PDC_20621_SEQCTL = 0x400,
PDC_20621_SEQMASK = 0x480,
PDC_20621_GENERAL_CTL = 0x484,
......@@ -73,12 +77,19 @@ enum {
PDC_CHIP0_OFS = 0xC0000, /* offset of chip #0 */
PDC_20621_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) |
(1<<23),
PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) |
(1<<8) | (1<<9) | (1<<10),
board_2037x = 0, /* FastTrak S150 TX2plus */
board_20319 = 1, /* FastTrak S150 TX4 */
board_20621 = 2, /* FastTrak S150 SX4 */
PDC_HAS_PATA = (1 << 1), /* PDC20375 has PATA */
PDC_FLAG_20621 = (1 << 30), /* we have a 20621 */
PDC_HDMA_RESET = (1 << 11), /* HDMA reset */
PDC_RESET = (1 << 11), /* HDMA reset */
PDC_MAX_HDMA = 32,
PDC_HDMA_Q_MASK = (PDC_MAX_HDMA - 1),
......@@ -154,13 +165,14 @@ static void pdc_eng_timeout(struct ata_port *ap);
static void pdc_20621_phy_reset (struct ata_port *ap);
static int pdc_port_start(struct ata_port *ap);
static void pdc_port_stop(struct ata_port *ap);
static void pdc_phy_reset(struct ata_port *ap);
static void pdc_fill_sg(struct ata_queued_cmd *qc);
static void pdc20621_fill_sg(struct ata_queued_cmd *qc);
static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
static void pdc20621_host_stop(struct ata_host_set *host_set);
static inline void pdc_dma_complete (struct ata_port *ap,
struct ata_queued_cmd *qc);
struct ata_queued_cmd *qc, int have_err);
static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe,
......@@ -199,7 +211,7 @@ static struct ata_port_operations pdc_sata_ops = {
.tf_read = ata_tf_read_mmio,
.check_status = ata_check_status_mmio,
.exec_command = pdc_exec_command_mmio,
.phy_reset = sata_phy_reset,
.phy_reset = pdc_phy_reset,
.bmdma_start = pdc_dma_start,
.fill_sg = pdc_fill_sg,
.eng_timeout = pdc_eng_timeout,
......@@ -351,6 +363,34 @@ static void pdc_20621_phy_reset (struct ata_port *ap)
ata_bus_reset(ap);
}
static void pdc_reset_port(struct ata_port *ap)
{
void *mmio = (void *) ap->ioaddr.cmd_addr + PDC_CTLSTAT;
unsigned int i;
u32 tmp;
for (i = 11; i > 0; i--) {
tmp = readl(mmio);
if (tmp & PDC_RESET)
break;
udelay(100);
tmp |= PDC_RESET;
writel(tmp, mmio);
}
tmp &= ~PDC_RESET;
writel(tmp, mmio);
readl(mmio); /* flush */
}
static void pdc_phy_reset(struct ata_port *ap)
{
pdc_reset_port(ap);
sata_phy_reset(ap);
}
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
......@@ -390,12 +430,11 @@ static inline unsigned int pdc_pkt_header(struct ata_taskfile *tf,
* and seq id (byte 2)
*/
switch (tf->protocol) {
case ATA_PROT_DMA_READ:
buf32[0] = cpu_to_le32(PDC_PKT_READ);
break;
case ATA_PROT_DMA_WRITE:
buf32[0] = 0;
case ATA_PROT_DMA:
if (!(tf->flags & ATA_TFLAG_WRITE))
buf32[0] = cpu_to_le32(PDC_PKT_READ);
else
buf32[0] = 0;
break;
case ATA_PROT_NODATA:
......@@ -554,7 +593,7 @@ static inline unsigned int pdc20621_ata_pkt(struct ata_taskfile *tf,
/*
* Set up ATA packet
*/
if (tf->protocol == ATA_PROT_DMA_READ)
if ((tf->protocol == ATA_PROT_DMA) && (!(tf->flags & ATA_TFLAG_WRITE)))
buf[i++] = PDC_PKT_READ;
else if (tf->protocol == ATA_PROT_NODATA)
buf[i++] = PDC_PKT_NODATA;
......@@ -606,7 +645,7 @@ static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf,
/*
* Set up Host DMA packet
*/
if (tf->protocol == ATA_PROT_DMA_READ)
if ((tf->protocol == ATA_PROT_DMA) && (!(tf->flags & ATA_TFLAG_WRITE)))
tmp = PDC_PKT_READ;
else
tmp = 0;
......@@ -768,7 +807,7 @@ static void pdc20621_dma_start(struct ata_queued_cmd *qc)
struct ata_host_set *host_set = ap->host_set;
unsigned int port_no = ap->port_no;
void *mmio = host_set->mmio_base;
unsigned int rw = (qc->flags & ATA_QCFLAG_WRITE);
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
u8 seq = (u8) (port_no + 1);
unsigned int doing_hdma = 0, port_ofs;
......@@ -821,13 +860,14 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
VPRINTK("ENTER\n");
switch (qc->tf.protocol) {
case ATA_PROT_DMA_READ:
if ((qc->tf.protocol == ATA_PROT_DMA) && /* read */
(!(qc->tf.flags & ATA_TFLAG_WRITE))) {
/* step two - DMA from DIMM to host */
if (doing_hdma) {
VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
pdc_dma_complete(ap, qc);
pdc_dma_complete(ap, qc, 0);
pdc20621_pop_hdma(qc);
}
......@@ -843,9 +883,9 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
port_ofs + PDC_DIMM_HOST_PKT);
}
handled = 1;
break;
case ATA_PROT_DMA_WRITE:
} else if (qc->tf.protocol == ATA_PROT_DMA) { /* write */
/* step one - DMA from host to DIMM */
if (doing_hdma) {
u8 seq = (u8) (port_no + 1);
......@@ -864,25 +904,24 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
else {
VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
pdc_dma_complete(ap, qc);
pdc_dma_complete(ap, qc, 0);
pdc20621_pop_hdma(qc);
}
handled = 1;
break;
case ATA_PROT_NODATA: /* command completion, but no data xfer */
/* command completion, but no data xfer */
} else if (qc->tf.protocol == ATA_PROT_NODATA) {
status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
ata_qc_complete(qc, status, 0);
handled = 1;
break;
default:
ap->stats.idle_irq++;
break;
}
} else {
ap->stats.idle_irq++;
}
return handled;
return handled;
}
static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
......@@ -918,7 +957,7 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
return IRQ_NONE;
}
spin_lock_irq(&host_set->lock);
spin_lock(&host_set->lock);
for (i = 1; i < 9; i++) {
port_no = i - 1;
......@@ -940,7 +979,7 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
}
}
spin_unlock_irq(&host_set->lock);
spin_unlock(&host_set->lock);
VPRINTK("mask == 0x%x\n", mask);
......@@ -969,11 +1008,14 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc)
}
static inline void pdc_dma_complete (struct ata_port *ap,
struct ata_queued_cmd *qc)
struct ata_queued_cmd *qc,
int have_err)
{
u8 err_bit = have_err ? ATA_ERR : 0;
/* get drive status; clear intr; complete txn */
ata_qc_complete(ata_qc_from_tag(ap, ap->active_tag),
ata_wait_idle(ap), 0);
ata_wait_idle(ap) | err_bit, 0);
}
static void pdc_eng_timeout(struct ata_port *ap)
......@@ -999,8 +1041,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
qc->scsidone = scsi_finish_command;
switch (qc->tf.protocol) {
case ATA_PROT_DMA_READ:
case ATA_PROT_DMA_WRITE:
case ATA_PROT_DMA:
printk(KERN_ERR "ata%u: DMA timeout\n", ap->id);
ata_qc_complete(ata_qc_from_tag(ap, ap->active_tag),
ata_wait_idle(ap) | ATA_ERR, 0);
......@@ -1033,18 +1074,27 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
struct ata_queued_cmd *qc)
{
u8 status;
unsigned int handled = 0;
unsigned int handled = 0, have_err = 0;
u32 tmp;
void *mmio = (void *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
tmp = readl(mmio);
if (tmp & PDC_ERR_MASK) {
have_err = 1;
pdc_reset_port(ap);
}
switch (qc->tf.protocol) {
case ATA_PROT_DMA_READ:
case ATA_PROT_DMA_WRITE:
pdc_dma_complete(ap, qc);
case ATA_PROT_DMA:
pdc_dma_complete(ap, qc, have_err);
handled = 1;
break;
case ATA_PROT_NODATA: /* command completion, but no data xfer */
status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
if (have_err)
status |= ATA_ERR;
ata_qc_complete(qc, status, 0);
handled = 1;
break;
......@@ -1088,7 +1138,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
return IRQ_NONE;
}
spin_lock_irq(&host_set->lock);
spin_lock(&host_set->lock);
for (i = 0; i < host_set->n_ports; i++) {
VPRINTK("port %u\n", i);
......@@ -1103,7 +1153,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
}
}
spin_unlock_irq(&host_set->lock);
spin_unlock(&host_set->lock);
VPRINTK("EXIT\n");
......@@ -1130,16 +1180,14 @@ static void pdc_dma_start(struct ata_queued_cmd *qc)
static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
{
if ((tf->protocol != ATA_PROT_DMA_READ) &&
(tf->protocol != ATA_PROT_DMA_WRITE))
if (tf->protocol != ATA_PROT_DMA)
ata_tf_load_mmio(ap, tf);
}
static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
{
if ((tf->protocol != ATA_PROT_DMA_READ) &&
(tf->protocol != ATA_PROT_DMA_WRITE))
if (tf->protocol != ATA_PROT_DMA)
ata_exec_command_mmio(ap, tf);
}
......@@ -1592,14 +1640,14 @@ static void pdc_20621_init(struct ata_probe_ent *pe)
* Reset Host DMA
*/
tmp = readl(mmio + PDC_HDMA_CTLSTAT);
tmp |= PDC_HDMA_RESET;
tmp |= PDC_RESET;
writel(tmp, mmio + PDC_HDMA_CTLSTAT);
readl(mmio + PDC_HDMA_CTLSTAT); /* flush */
udelay(10);
tmp = readl(mmio + PDC_HDMA_CTLSTAT);
tmp &= ~PDC_HDMA_RESET;
tmp &= ~PDC_RESET;
writel(tmp, mmio + PDC_HDMA_CTLSTAT);
readl(mmio + PDC_HDMA_CTLSTAT); /* flush */
}
......@@ -1610,14 +1658,18 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
u32 tmp;
if (chip_id == board_20621)
return;
BUG();
/* change FIFO_SHD to 8 dwords. Promise driver does this...
* dunno why.
/*
* Except for the hotplug stuff, this is voodoo from the
* Promise driver. Label this entire section
* "TODO: figure out why we do this"
*/
/* change FIFO_SHD to 8 dwords, enable BMR_BURST */
tmp = readl(mmio + PDC_FLASH_CTL);
if ((tmp & (1 << 16)) == 0)
writel(tmp | (1 << 16), mmio + PDC_FLASH_CTL);
tmp |= 0x12000; /* bit 16 (fifo 8 dw) and 13 (bmr burst?) */
writel(tmp, mmio + PDC_FLASH_CTL);
/* clear plug/unplug flags for all ports */
tmp = readl(mmio + PDC_SATA_PLUG_CSR);
......@@ -1627,13 +1679,17 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
tmp = readl(mmio + PDC_SATA_PLUG_CSR);
writel(tmp | 0xff0000, mmio + PDC_SATA_PLUG_CSR);
/* reduce TBG clock to 133 Mhz. FIXME: why? */
/* reduce TBG clock to 133 Mhz. */
tmp = readl(mmio + PDC_TBG_MODE);
tmp &= ~0x30000; /* clear bit 17, 16*/
tmp |= 0x10000; /* set bit 17:16 = 0:1 */
writel(tmp, mmio + PDC_TBG_MODE);
/* adjust slew rate control register. FIXME: why? */
readl(mmio + PDC_TBG_MODE); /* flush */
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(10));
/* adjust slew rate control register. */
tmp = readl(mmio + PDC_SLEW_CTL);
tmp &= 0xFFFFF03F; /* clear bit 11 ~ 6 */
tmp |= 0x00000900; /* set bit 11-9 = 100b , bit 8-6 = 100 */
......
/*
* sata_sis.c - Silicon Integrated Systems SATA
*
* Copyright 2004 Uwe Koziolek
*
* The contents of this file are subject to the Open
* Software License version 1.1 that can be found at
* http://www.opensource.org/licenses/osl-1.1.txt and is included herein
* by reference.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License version 2 (the "GPL") as distributed
* in the kernel source COPYING file, in which case the provisions of
* the GPL are applicable instead of the above. If you wish to allow
* the use of your version of this file only under the terms of the
* GPL and not to allow others to use your version of this file under
* the OSL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the GPL.
* If you do not delete the provisions above, a recipient may use your
* version of this file under either the OSL or the GPL.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include "scsi.h"
#include "hosts.h"
#include <linux/libata.h>
#define DRV_NAME "sata_sis"
#define DRV_VERSION "0.04"
enum {
sis_180 = 0,
};
static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static struct pci_device_id sis_pci_tbl[] = {
{ PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
{ } /* terminate list */
};
static struct pci_driver sis_pci_driver = {
.name = DRV_NAME,
.id_table = sis_pci_tbl,
.probe = sis_init_one,
.remove = ata_pci_remove_one,
};
static Scsi_Host_Template sis_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = ATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
static struct ata_port_operations sis_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load_pio,
.tf_read = ata_tf_read_pio,
.check_status = ata_check_status_pio,
.exec_command = ata_exec_command_pio,
.phy_reset = sata_phy_reset,
.bmdma_start = ata_bmdma_start_pio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt,
.scr_read = sis_scr_read,
.scr_write = sis_scr_write,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
};
MODULE_AUTHOR("Uwe Koziolek");
MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg >= 16)
return 0xffffffffU;
return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
if (sc_reg >= 16)
return;
outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
/* move to PCI layer, integrate w/ MSI stuff */
static void pci_enable_intx(struct pci_dev *pdev)
{
u16 pci_command;
pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
if (pci_command & PCI_COMMAND_INTX_DISABLE) {
pci_command &= ~PCI_COMMAND_INTX_DISABLE;
pci_write_config_word(pdev, PCI_COMMAND, pci_command);
}
}
static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct ata_probe_ent *probe_ent = NULL;
int rc;
rc = pci_enable_device(pdev);
if (rc)
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
goto err_out;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
goto err_out_regions;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
goto err_out_regions;
probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
if (!probe_ent) {
rc = -ENOMEM;
goto err_out_regions;
}
memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->pdev = pdev;
INIT_LIST_HEAD(&probe_ent->node);
probe_ent->sht = &sis_sht;
probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
ATA_FLAG_NO_LEGACY;
probe_ent->pio_mask = 0x03;
probe_ent->udma_mask = 0x7f;
probe_ent->port_ops = &sis_ops;
probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
ata_std_ports(&probe_ent->port[0]);
probe_ent->port[0].ctl_addr =
pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
probe_ent->port[0].scr_addr = pci_resource_start(pdev, 5);
probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
ata_std_ports(&probe_ent->port[1]);
probe_ent->port[1].ctl_addr =
pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
probe_ent->port[1].scr_addr = pci_resource_start(pdev, 5) + 64;
probe_ent->n_ports = 2;
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
pci_set_master(pdev);
pci_enable_intx(pdev);
/* FIXME: check ata_device_add return value */
ata_device_add(probe_ent);
kfree(probe_ent);
return 0;
err_out_regions:
pci_release_regions(pdev);
err_out:
pci_disable_device(pdev);
return rc;
}
static int __init sis_init(void)
{
return pci_module_init(&sis_pci_driver);
}
static void __exit sis_exit(void)
{
pci_unregister_driver(&sis_pci_driver);
}
module_init(sis_init);
module_exit(sis_exit);
......@@ -102,16 +102,6 @@ enum {
ATA_REG_DEVSEL = ATA_REG_DEVICE,
ATA_REG_IRQ = ATA_REG_NSECT,
/* ATA taskfile protocols */
ATA_PROT_UNKNOWN = 0,
ATA_PROT_NODATA = 1,
ATA_PROT_PIO_READ = 2,
ATA_PROT_PIO_WRITE = 3,
ATA_PROT_DMA_READ = 4,
ATA_PROT_DMA_WRITE = 5,
ATA_PROT_ATAPI = 6,
ATA_PROT_ATAPI_DMA = 7,
/* ATA device commands */
ATA_CMD_EDD = 0x90, /* execute device diagnostic */
ATA_CMD_ID_ATA = 0xEC,
......@@ -156,14 +146,55 @@ enum {
SCR_CONTROL = 2,
SCR_ACTIVE = 3,
SCR_NOTIFICATION = 4,
/* struct ata_taskfile flags */
ATA_TFLAG_LBA48 = (1 << 0), /* enable 48-bit LBA and "HOB" */
ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */
ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */
ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */
};
enum ata_tf_protocols {
/* ATA taskfile protocols */
ATA_PROT_UNKNOWN, /* unknown/invalid */
ATA_PROT_NODATA, /* no data */
ATA_PROT_PIO, /* PIO single sector */
ATA_PROT_PIO_MULT, /* PIO multiple sector */
ATA_PROT_DMA, /* DMA */
ATA_PROT_ATAPI, /* packet command */
ATA_PROT_ATAPI_DMA, /* packet command with special DMA sauce */
};
/* core structures */
struct ata_prd {
u32 addr;
u32 flags_len;
} __attribute__((packed));
struct ata_taskfile {
unsigned long flags; /* ATA_TFLAG_xxx */
u8 protocol; /* ATA_PROT_xxx */
u8 ctl; /* control reg */
u8 hob_feature; /* additional data */
u8 hob_nsect; /* to support LBA48 */
u8 hob_lbal;
u8 hob_lbam;
u8 hob_lbah;
u8 feature;
u8 nsect;
u8 lbal;
u8 lbam;
u8 lbah;
u8 device;
u8 command; /* IO operation */
};
#define ata_id_is_ata(dev) (((dev)->id[0] & (1 << 15)) == 0)
#define ata_id_has_lba48(dev) ((dev)->id[83] & (1 << 10))
#define ata_id_has_lba(dev) ((dev)->id[49] & (1 << 8))
......
......@@ -107,12 +107,6 @@ enum {
ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */
ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */
/* struct ata_taskfile flags */
ATA_TFLAG_LBA48 = (1 << 0),
ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */
ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */
ATA_QCFLAG_WRITE = (1 << 0), /* read==0, write==1 */
ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */
ATA_QCFLAG_DMA = (1 << 2), /* data delivered via DMA */
ATA_QCFLAG_ATAPI = (1 << 3), /* is ATAPI packet command? */
......@@ -223,29 +217,6 @@ struct ata_host_set {
struct ata_port * ports[0];
};
struct ata_taskfile {
unsigned long flags; /* ATA_TFLAG_xxx */
u8 protocol; /* ATA_PROT_xxx */
u8 ctl; /* control reg */
u8 hob_feature; /* additional data */
u8 hob_nsect; /* to support LBA48 */
u8 hob_lbal;
u8 hob_lbam;
u8 hob_lbah;
u8 feature;
u8 nsect;
u8 lbal;
u8 lbam;
u8 lbah;
u8 device;
u8 command; /* IO operation */
};
struct ata_queued_cmd {
struct ata_port *ap;
struct ata_device *dev;
......@@ -293,6 +264,11 @@ struct ata_device {
* ATAPI7 spec size, 40 ASCII
* characters
*/
/* cache info about current transfer mode */
u8 xfer_protocol; /* taskfile xfer protocol */
u8 read_cmd; /* opcode to use on read */
u8 write_cmd; /* opcode to use on write */
};
struct ata_engine {
......@@ -408,7 +384,6 @@ extern int ata_scsi_detect(Scsi_Host_Template *sht);
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
extern int ata_scsi_error(struct Scsi_Host *host);
extern int ata_scsi_release(struct Scsi_Host *host);
extern int ata_scsi_slave_config(struct scsi_device *sdev);
extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
/*
* Default driver ops implementations
......@@ -433,6 +408,7 @@ extern void ata_eng_timeout(struct ata_port *ap);
extern int ata_std_bios_param(struct scsi_device *sdev,
struct block_device *bdev,
sector_t capacity, int geom[]);
extern int ata_scsi_slave_config(struct scsi_device *sdev);
static inline unsigned long msecs_to_jiffies(unsigned long msecs)
......
......@@ -572,6 +572,7 @@
#define PCI_DEVICE_ID_SI_503 0x0008
#define PCI_DEVICE_ID_SI_ACPI 0x0009
#define PCI_DEVICE_ID_SI_LPC 0x0018
#define PCI_DEVICE_ID_SI_180 0x0180
#define PCI_DEVICE_ID_SI_5597_VGA 0x0200
#define PCI_DEVICE_ID_SI_6205 0x0205
#define PCI_DEVICE_ID_SI_501 0x0406
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment