Commit 82718086 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 dd582fa6 a034f8d6
...@@ -406,6 +406,14 @@ config SCSI_SATA ...@@ -406,6 +406,14 @@ config SCSI_SATA
If unsure, say N. If unsure, say N.
config SCSI_SATA_AHCI
tristate "AHCI SATA support"
depends on SCSI_SATA && PCI && EXPERIMENTAL
help
This option enables support for AHCI Serial ATA.
If unsure, say N.
config SCSI_SATA_SVW config SCSI_SATA_SVW
tristate "ServerWorks Frodo / Apple K2 SATA support (EXPERIMENTAL)" tristate "ServerWorks Frodo / Apple K2 SATA support (EXPERIMENTAL)"
depends on SCSI_SATA && PCI && EXPERIMENTAL depends on SCSI_SATA && PCI && EXPERIMENTAL
......
...@@ -121,6 +121,7 @@ obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o ...@@ -121,6 +121,7 @@ obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
obj-$(CONFIG_SCSI_NSP32) += nsp32.o obj-$(CONFIG_SCSI_NSP32) += nsp32.o
obj-$(CONFIG_SCSI_IPR) += ipr.o obj-$(CONFIG_SCSI_IPR) += ipr.o
obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/
obj-$(CONFIG_SCSI_SATA_AHCI) += libata.o ahci.o
obj-$(CONFIG_SCSI_SATA_SVW) += libata.o sata_svw.o obj-$(CONFIG_SCSI_SATA_SVW) += libata.o sata_svw.o
obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o
obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o
......
This diff is collapsed.
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include "scsi.h" #include "scsi.h"
#include "scsi_priv.h"
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <linux/libata.h> #include <linux/libata.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -58,6 +59,7 @@ static int ata_choose_xfer_mode(struct ata_port *ap, ...@@ -58,6 +59,7 @@ static int ata_choose_xfer_mode(struct ata_port *ap,
u8 *xfer_mode_out, u8 *xfer_mode_out,
unsigned int *xfer_shift_out); unsigned int *xfer_shift_out);
static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat); static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
static void __ata_qc_complete(struct ata_queued_cmd *qc);
static unsigned int ata_unique_id = 1; static unsigned int ata_unique_id = 1;
static struct workqueue_struct *ata_wq; static struct workqueue_struct *ata_wq;
...@@ -2193,11 +2195,50 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) ...@@ -2193,11 +2195,50 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
kunmap(page); kunmap(page);
} }
static void atapi_pio_sector(struct ata_queued_cmd *qc) static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
{
int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
struct scatterlist *sg = qc->sg;
struct ata_port *ap = qc->ap;
struct page *page;
unsigned char *buf;
unsigned int count;
if (qc->curbytes == qc->nbytes - bytes)
ap->pio_task_state = PIO_ST_LAST;
next_sg:
sg = &qc->sg[qc->cursg];
page = sg->page;
count = min(sg_dma_len(sg) - qc->cursg_ofs, bytes);
buf = kmap(page) + sg->offset + qc->cursg_ofs;
bytes -= count;
qc->curbytes += count;
qc->cursg_ofs += count;
if (qc->cursg_ofs == sg_dma_len(sg)) {
qc->cursg++;
qc->cursg_ofs = 0;
}
DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
/* do the actual data transfer */
ata_data_xfer(ap, buf, count, do_write);
kunmap(page);
if (bytes)
goto next_sg;
}
static void atapi_pio_bytes(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct ata_device *dev = qc->dev; struct ata_device *dev = qc->dev;
unsigned int i, ireason, bc_lo, bc_hi, bytes; unsigned int ireason, bc_lo, bc_hi, bytes;
int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0; int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
ap->ops->tf_read(ap, &qc->tf); ap->ops->tf_read(ap, &qc->tf);
...@@ -2215,16 +2256,7 @@ static void atapi_pio_sector(struct ata_queued_cmd *qc) ...@@ -2215,16 +2256,7 @@ static void atapi_pio_sector(struct ata_queued_cmd *qc)
if (do_write != i_write) if (do_write != i_write)
goto err_out; goto err_out;
/* make sure byte count is multiple of sector size; not __atapi_pio_bytes(qc, bytes);
* required by standard (warning! warning!), but IDE driver
* does this to simplify things a bit. We are lazy, and
* follow suit.
*/
if (bytes & (ATA_SECT_SIZE - 1))
goto err_out;
for (i = 0; i < (bytes >> 9); i++)
ata_pio_sector(qc);
return; return;
...@@ -2265,19 +2297,30 @@ static void ata_pio_block(struct ata_port *ap) ...@@ -2265,19 +2297,30 @@ static void ata_pio_block(struct ata_port *ap)
} }
} }
qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL);
if (is_atapi_taskfile(&qc->tf)) {
/* no more data to transfer or unsupported ATAPI command */
if ((status & ATA_DRQ) == 0) {
ap->pio_task_state = PIO_ST_IDLE;
ata_irq_on(ap);
ata_qc_complete(qc, status);
return;
}
atapi_pio_bytes(qc);
} else {
/* handle BSY=0, DRQ=0 as error */ /* handle BSY=0, DRQ=0 as error */
if ((status & ATA_DRQ) == 0) { if ((status & ATA_DRQ) == 0) {
ap->pio_task_state = PIO_ST_ERR; ap->pio_task_state = PIO_ST_ERR;
return; return;
} }
qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL);
if (is_atapi_taskfile(&qc->tf))
atapi_pio_sector(qc);
else
ata_pio_sector(qc); ata_pio_sector(qc);
}
} }
static void ata_pio_error(struct ata_port *ap) static void ata_pio_error(struct ata_port *ap)
...@@ -2335,6 +2378,59 @@ static void ata_pio_task(void *_data) ...@@ -2335,6 +2378,59 @@ static void ata_pio_task(void *_data)
} }
} }
static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd)
{
DECLARE_COMPLETION(wait);
struct ata_queued_cmd *qc;
unsigned long flags;
int using_pio = dev->flags & ATA_DFLAG_PIO;
int rc;
DPRINTK("ATAPI request sense\n");
qc = ata_qc_new_init(ap, dev);
BUG_ON(qc == NULL);
/* FIXME: is this needed? */
memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
qc->pci_dma_dir = PCI_DMA_FROMDEVICE;
memset(&qc->cdb, 0, sizeof(ap->cdb_len));
qc->cdb[0] = REQUEST_SENSE;
qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
qc->tf.command = ATA_CMD_PACKET;
if (using_pio) {
qc->tf.protocol = ATA_PROT_ATAPI;
qc->tf.lbam = (8 * 1024) & 0xff;
qc->tf.lbah = (8 * 1024) >> 8;
qc->nbytes = SCSI_SENSE_BUFFERSIZE;
} else {
qc->tf.protocol = ATA_PROT_ATAPI_DMA;
qc->tf.feature |= ATAPI_PKT_DMA;
}
qc->waiting = &wait;
qc->complete_fn = ata_qc_complete_noop;
spin_lock_irqsave(&ap->host_set->lock, flags);
rc = ata_qc_issue(qc);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
if (rc)
ata_port_disable(ap);
else
wait_for_completion(&wait);
DPRINTK("EXIT\n");
}
/** /**
* ata_qc_timeout - Handle timeout of queued command * ata_qc_timeout - Handle timeout of queued command
* @qc: Command that timed out * @qc: Command that timed out
...@@ -2356,10 +2452,29 @@ static void ata_pio_task(void *_data) ...@@ -2356,10 +2452,29 @@ static void ata_pio_task(void *_data)
static void ata_qc_timeout(struct ata_queued_cmd *qc) static void ata_qc_timeout(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct ata_device *dev = qc->dev;
u8 host_stat = 0, drv_stat; u8 host_stat = 0, drv_stat;
DPRINTK("ENTER\n"); DPRINTK("ENTER\n");
/* FIXME: doesn't this conflict with timeout handling? */
if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) {
struct scsi_cmnd *cmd = qc->scsicmd;
if (!scsi_eh_eflags_chk(cmd, SCSI_EH_CANCEL_CMD)) {
/* finish completing original command */
__ata_qc_complete(qc);
atapi_request_sense(ap, dev, cmd);
cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
scsi_finish_command(cmd);
goto out;
}
}
/* hack alert! We cannot use the supplied completion /* hack alert! We cannot use the supplied completion
* function from inside the ->eh_strategy_handler() thread. * function from inside the ->eh_strategy_handler() thread.
* libata is the only user of ->eh_strategy_handler() in * libata is the only user of ->eh_strategy_handler() in
...@@ -2393,7 +2508,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) ...@@ -2393,7 +2508,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
ata_qc_complete(qc, drv_stat); ata_qc_complete(qc, drv_stat);
break; break;
} }
out:
DPRINTK("EXIT\n"); DPRINTK("EXIT\n");
} }
...@@ -2482,6 +2597,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, ...@@ -2482,6 +2597,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
qc->dev = dev; qc->dev = dev;
qc->cursect = qc->cursg = qc->cursg_ofs = 0; qc->cursect = qc->cursg = qc->cursg_ofs = 0;
qc->nsect = 0; qc->nsect = 0;
qc->nbytes = qc->curbytes = 0;
ata_tf_init(ap, &qc->tf, dev->devno); ata_tf_init(ap, &qc->tf, dev->devno);
...@@ -2497,6 +2613,30 @@ static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat) ...@@ -2497,6 +2613,30 @@ static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
return 0; return 0;
} }
static void __ata_qc_complete(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int tag, do_clear = 0;
qc->flags = 0;
tag = qc->tag;
if (likely(ata_tag_valid(tag))) {
if (tag == ap->active_tag)
ap->active_tag = ATA_TAG_POISON;
qc->tag = ATA_TAG_POISON;
do_clear = 1;
}
if (qc->waiting) {
struct completion *waiting = qc->waiting;
qc->waiting = NULL;
complete(waiting);
}
if (likely(do_clear))
clear_bit(tag, &ap->qactive);
}
/** /**
* ata_qc_complete - Complete an active ATA command * ata_qc_complete - Complete an active ATA command
* @qc: Command to complete * @qc: Command to complete
...@@ -2508,8 +2648,6 @@ static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat) ...@@ -2508,8 +2648,6 @@ static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
{ {
struct ata_port *ap = qc->ap;
unsigned int tag, do_clear = 0;
int rc; int rc;
assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */ assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */
...@@ -2527,23 +2665,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) ...@@ -2527,23 +2665,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
if (rc != 0) if (rc != 0)
return; return;
qc->flags = 0; __ata_qc_complete(qc);
tag = qc->tag;
if (likely(ata_tag_valid(tag))) {
if (tag == ap->active_tag)
ap->active_tag = ATA_TAG_POISON;
qc->tag = ATA_TAG_POISON;
do_clear = 1;
}
if (qc->waiting) {
struct completion *waiting = qc->waiting;
qc->waiting = NULL;
complete(waiting);
}
if (likely(do_clear))
clear_bit(tag, &ap->qactive);
VPRINTK("EXIT\n"); VPRINTK("EXIT\n");
} }
......
...@@ -1248,9 +1248,15 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) ...@@ -1248,9 +1248,15 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
{ {
struct scsi_cmnd *cmd = qc->scsicmd; struct scsi_cmnd *cmd = qc->scsicmd;
if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
DPRINTK("request check condition\n");
cmd->result = SAM_STAT_CHECK_CONDITION; cmd->result = SAM_STAT_CHECK_CONDITION;
else {
qc->scsidone(cmd);
return 1;
} else {
u8 *scsicmd = cmd->cmnd; u8 *scsicmd = cmd->cmnd;
if (scsicmd[0] == INQUIRY) { if (scsicmd[0] == INQUIRY) {
...@@ -1322,6 +1328,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) ...@@ -1322,6 +1328,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
#endif #endif
} }
qc->nbytes = cmd->bufflen;
return 0; return 0;
} }
......
...@@ -333,6 +333,14 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d ...@@ -333,6 +333,14 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
pci_set_master(pdev); pci_set_master(pdev);
/*
* Config offset 0x98 is "Extended Control and Status Register 0"
* Default value is (1 << 28). All bits except bit 28 are reserved in
* DPA mode. If bit 28 is set, LED 0 reflects all ports' activity.
* If bit 28 is clear, each port has its own LED.
*/
pci_write_config_dword(pdev, 0x98, 0);
/* FIXME: check ata_device_add return value */ /* FIXME: check ata_device_add return value */
ata_device_add(probe_ent); ata_device_add(probe_ent);
kfree(probe_ent); kfree(probe_ent);
......
...@@ -230,6 +230,10 @@ struct ata_queued_cmd { ...@@ -230,6 +230,10 @@ struct ata_queued_cmd {
unsigned int nsect; unsigned int nsect;
unsigned int cursect; unsigned int cursect;
unsigned int nbytes;
unsigned int curbytes;
unsigned int cursg; unsigned int cursg;
unsigned int cursg_ofs; unsigned int cursg_ofs;
......
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