Commit b3b9be04 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://gkernel.bkbits.net/libata-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 0b103497 12a3949a
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/mm.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
...@@ -1919,7 +1920,24 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) ...@@ -1919,7 +1920,24 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
if (idx) if (idx)
ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
} }
/**
* ata_check_atapi_dma - Check whether ATAPI DMA can be supported
* @qc: Metadata associated with taskfile to check
*
* LOCKING:
* RETURNS: 0 when ATAPI DMA can be used
* nonzero otherwise
*/
int ata_check_atapi_dma(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
int rc = 0; /* Assume ATAPI DMA is OK by default */
if (ap->ops->check_atapi_dma)
rc = ap->ops->check_atapi_dma(qc);
return rc;
}
/** /**
* ata_qc_prep - Prepare taskfile for submission * ata_qc_prep - Prepare taskfile for submission
* @qc: Metadata associated with taskfile to be prepared * @qc: Metadata associated with taskfile to be prepared
...@@ -2369,6 +2387,9 @@ static void ata_pio_task(void *_data) ...@@ -2369,6 +2387,9 @@ static void ata_pio_task(void *_data)
unsigned long timeout = 0; unsigned long timeout = 0;
switch (ap->pio_task_state) { switch (ap->pio_task_state) {
case PIO_ST_IDLE:
return;
case PIO_ST: case PIO_ST:
ata_pio_block(ap); ata_pio_block(ap);
break; break;
...@@ -2385,18 +2406,14 @@ static void ata_pio_task(void *_data) ...@@ -2385,18 +2406,14 @@ static void ata_pio_task(void *_data)
case PIO_ST_TMOUT: case PIO_ST_TMOUT:
case PIO_ST_ERR: case PIO_ST_ERR:
ata_pio_error(ap); ata_pio_error(ap);
break; return;
} }
if ((ap->pio_task_state != PIO_ST_IDLE) && if (timeout)
(ap->pio_task_state != PIO_ST_TMOUT) && queue_delayed_work(ata_wq, &ap->pio_task,
(ap->pio_task_state != PIO_ST_ERR)) { timeout);
if (timeout) else
queue_delayed_work(ata_wq, &ap->pio_task, queue_work(ata_wq, &ap->pio_task);
timeout);
else
queue_work(ata_wq, &ap->pio_task);
}
} }
static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
...@@ -2405,7 +2422,6 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, ...@@ -2405,7 +2422,6 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
DECLARE_COMPLETION(wait); DECLARE_COMPLETION(wait);
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
unsigned long flags; unsigned long flags;
int using_pio = dev->flags & ATA_DFLAG_PIO;
int rc; int rc;
DPRINTK("ATAPI request sense\n"); DPRINTK("ATAPI request sense\n");
...@@ -2426,16 +2442,10 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, ...@@ -2426,16 +2442,10 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
qc->tf.command = ATA_CMD_PACKET; qc->tf.command = ATA_CMD_PACKET;
if (using_pio) { qc->tf.protocol = ATA_PROT_ATAPI;
qc->tf.protocol = ATA_PROT_ATAPI; qc->tf.lbam = (8 * 1024) & 0xff;
qc->tf.lbam = (8 * 1024) & 0xff; qc->tf.lbah = (8 * 1024) >> 8;
qc->tf.lbah = (8 * 1024) >> 8; qc->nbytes = SCSI_SENSE_BUFFERSIZE;
qc->nbytes = SCSI_SENSE_BUFFERSIZE;
} else {
qc->tf.protocol = ATA_PROT_ATAPI_DMA;
qc->tf.feature |= ATAPI_PKT_DMA;
}
qc->waiting = &wait; qc->waiting = &wait;
qc->complete_fn = ata_qc_complete_noop; qc->complete_fn = ata_qc_complete_noop;
......
...@@ -1294,6 +1294,11 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) ...@@ -1294,6 +1294,11 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
int using_pio = (dev->flags & ATA_DFLAG_PIO); int using_pio = (dev->flags & ATA_DFLAG_PIO);
int nodata = (cmd->sc_data_direction == SCSI_DATA_NONE); int nodata = (cmd->sc_data_direction == SCSI_DATA_NONE);
if (!using_pio)
/* Check whether ATAPI DMA is safe */
if (ata_check_atapi_dma(qc))
using_pio = 1;
memcpy(&qc->cdb, scsicmd, qc->ap->cdb_len); memcpy(&qc->cdb, scsicmd, qc->ap->cdb_len);
qc->complete_fn = atapi_qc_complete; qc->complete_fn = atapi_qc_complete;
......
...@@ -38,6 +38,7 @@ struct ata_scsi_args { ...@@ -38,6 +38,7 @@ struct ata_scsi_args {
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
struct ata_device *dev); struct ata_device *dev);
extern int ata_qc_issue(struct ata_queued_cmd *qc); extern int ata_qc_issue(struct ata_queued_cmd *qc);
extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
extern void ata_dev_select(struct ata_port *ap, unsigned int device, extern void ata_dev_select(struct ata_port *ap, unsigned int device,
unsigned int wait, unsigned int can_sleep); unsigned int wait, unsigned int can_sleep);
extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf); extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf);
......
...@@ -32,16 +32,18 @@ ...@@ -32,16 +32,18 @@
#include <linux/libata.h> #include <linux/libata.h>
#define DRV_NAME "sata_uli" #define DRV_NAME "sata_uli"
#define DRV_VERSION "0.2" #define DRV_VERSION "0.5"
enum { enum {
uli_5289 = 0, uli_5289 = 0,
uli_5287 = 1, uli_5287 = 1,
uli_5281 = 2,
/* PCI configuration registers */ /* PCI configuration registers */
ULI_SCR_BASE = 0x90, /* sata0 phy SCR registers */ ULI5287_BASE = 0x90, /* sata0 phy SCR registers */
ULI_SATA1_OFS = 0x10, /* offset from sata0->sata1 phy regs */ ULI5287_OFFS = 0x10, /* offset from sata0->sata1 phy regs */
ULI5281_BASE = 0x60, /* sata0 phy SCR registers */
ULI5281_OFFS = 0x60, /* offset from sata0->sata1 phy regs */
}; };
static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
...@@ -51,6 +53,7 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); ...@@ -51,6 +53,7 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static struct pci_device_id uli_pci_tbl[] = { static struct pci_device_id uli_pci_tbl[] = {
{ PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 }, { PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 },
{ PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 }, { PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 },
{ PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 },
{ } /* terminate list */ { } /* terminate list */
}; };
...@@ -125,33 +128,15 @@ MODULE_LICENSE("GPL"); ...@@ -125,33 +128,15 @@ MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, uli_pci_tbl); MODULE_DEVICE_TABLE(pci, uli_pci_tbl);
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg) static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
{ {
unsigned int addr = ULI_SCR_BASE + (4 * sc_reg); return ap->ioaddr.scr_addr + (4 * sc_reg);
switch (port_no) {
case 0:
break;
case 1:
addr += ULI_SATA1_OFS;
break;
case 2:
addr += ULI_SATA1_OFS*4;
break;
case 3:
addr += ULI_SATA1_OFS*5;
break;
default:
BUG();
break;
}
return addr;
} }
static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
{ {
struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg); unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
u32 val; u32 val;
pci_read_config_dword(pdev, cfg_addr, &val); pci_read_config_dword(pdev, cfg_addr, &val);
...@@ -161,7 +146,7 @@ static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) ...@@ -161,7 +146,7 @@ static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val) static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
{ {
struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr); unsigned int cfg_addr = get_scr_cfg_addr(ap, scr);
pci_write_config_dword(pdev, cfg_addr, val); pci_write_config_dword(pdev, cfg_addr, val);
} }
...@@ -222,9 +207,11 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -222,9 +207,11 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
rc = -ENOMEM; rc = -ENOMEM;
goto err_out_regions; goto err_out_regions;
} }
switch (board_idx) { switch (board_idx) {
case uli_5287: case uli_5287:
probe_ent->port[0].scr_addr = ULI5287_BASE;
probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
probe_ent->n_ports = 4; probe_ent->n_ports = 4;
probe_ent->port[2].cmd_addr = pci_resource_start(pdev, 0) + 8; probe_ent->port[2].cmd_addr = pci_resource_start(pdev, 0) + 8;
...@@ -232,19 +219,27 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -232,19 +219,27 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->port[2].ctl_addr = probe_ent->port[2].ctl_addr =
(pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4; (pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4;
probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16; probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16;
probe_ent->port[2].scr_addr = ULI5287_BASE + ULI5287_OFFS*4;
probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8; probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8;
probe_ent->port[3].altstatus_addr = probe_ent->port[3].altstatus_addr =
probe_ent->port[3].ctl_addr = probe_ent->port[3].ctl_addr =
(pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4; (pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4;
probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24; probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24;
probe_ent->port[3].scr_addr = ULI5287_BASE + ULI5287_OFFS*5;
ata_std_ports(&probe_ent->port[2]); ata_std_ports(&probe_ent->port[2]);
ata_std_ports(&probe_ent->port[3]); ata_std_ports(&probe_ent->port[3]);
break; break;
case uli_5289: case uli_5289:
/* do nothing; ata_pci_init_native_mode did it all */ probe_ent->port[0].scr_addr = ULI5287_BASE;
probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
break;
case uli_5281:
probe_ent->port[0].scr_addr = ULI5281_BASE;
probe_ent->port[1].scr_addr = ULI5281_BASE + ULI5281_OFFS;
break; break;
default: default:
......
...@@ -339,6 +339,8 @@ struct ata_port_operations { ...@@ -339,6 +339,8 @@ struct ata_port_operations {
void (*phy_reset) (struct ata_port *ap); void (*phy_reset) (struct ata_port *ap);
void (*post_set_mode) (struct ata_port *ap); void (*post_set_mode) (struct ata_port *ap);
int (*check_atapi_dma) (struct ata_queued_cmd *qc);
void (*bmdma_setup) (struct ata_queued_cmd *qc); void (*bmdma_setup) (struct ata_queued_cmd *qc);
void (*bmdma_start) (struct ata_queued_cmd *qc); void (*bmdma_start) (struct ata_queued_cmd *qc);
......
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