Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 29379
b: refs/heads/master
c: ca7d5e4
h: refs/heads/master
i:
  29377: 49377c3
  29375: 53a0d58
v: v3
  • Loading branch information
Jeff Garzik committed Feb 10, 2006
1 parent 76229b7 commit 1cc2cb4
Show file tree
Hide file tree
Showing 20 changed files with 114 additions and 84 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a0819750024a0056d760a936d72f76882a7e393f
refs/heads/master: ca7d5e42d783e54f0057317c9226262d68ab7717
57 changes: 27 additions & 30 deletions trunk/drivers/scsi/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ static struct scsi_host_template ahci_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_timed_out = ata_scsi_timed_out,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
Expand Down Expand Up @@ -506,6 +507,15 @@ static unsigned int ahci_dev_classify(struct ata_port *ap)
return ata_dev_classify(&tf);
}

static void ahci_fill_cmd_slot(struct ata_port *ap, u32 opts)
{
struct ahci_port_priv *pp = ap->private_data;
pp->cmd_slot[0].opts = cpu_to_le32(opts);
pp->cmd_slot[0].status = 0;
pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff);
pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
}

static void ahci_phy_reset(struct ata_port *ap)
{
void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
Expand Down Expand Up @@ -584,42 +594,35 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ahci_port_priv *pp = ap->private_data;
int is_atapi = is_atapi_taskfile(&qc->tf);
u32 opts;
const u32 cmd_fis_len = 5; /* five dwords */
unsigned int n_elem;

/*
* Fill in command slot information (currently only one slot,
* slot 0, is currently since we don't do queueing)
*/

opts = cmd_fis_len;
if (qc->tf.flags & ATA_TFLAG_WRITE)
opts |= AHCI_CMD_WRITE;
if (is_atapi_taskfile(&qc->tf))
opts |= AHCI_CMD_ATAPI;

pp->cmd_slot[0].opts = cpu_to_le32(opts);
pp->cmd_slot[0].status = 0;
pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff);
pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);

/*
* Fill in command table information. First, the header,
* a SATA Register - Host to Device command FIS.
*/
ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0);
if (opts & AHCI_CMD_ATAPI) {
if (is_atapi) {
memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len);
}

if (!(qc->flags & ATA_QCFLAG_DMAMAP))
return;
n_elem = 0;
if (qc->flags & ATA_QCFLAG_DMAMAP)
n_elem = ahci_fill_sg(qc);

n_elem = ahci_fill_sg(qc);
/*
* Fill in command slot information.
*/
opts = cmd_fis_len | n_elem << 16;
if (qc->tf.flags & ATA_TFLAG_WRITE)
opts |= AHCI_CMD_WRITE;
if (is_atapi)
opts |= AHCI_CMD_ATAPI;

pp->cmd_slot[0].opts |= cpu_to_le32(n_elem << 16);
ahci_fill_cmd_slot(ap, opts);
}

static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
Expand Down Expand Up @@ -676,19 +679,13 @@ static void ahci_eng_timeout(struct ata_port *ap)

spin_lock_irqsave(&host_set->lock, flags);

ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT));
qc = ata_qc_from_tag(ap, ap->active_tag);
if (!qc) {
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
ap->id);
} else {
ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT));
qc->err_mask |= AC_ERR_TIMEOUT;
}
qc->err_mask |= AC_ERR_TIMEOUT;

spin_unlock_irqrestore(&host_set->lock, flags);

if (qc)
ata_eh_qc_complete(qc);
ata_eh_qc_complete(qc);
}

static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/scsi/ata_piix.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ static struct scsi_host_template piix_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_timed_out = ata_scsi_timed_out,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
Expand Down
46 changes: 22 additions & 24 deletions trunk/drivers/scsi/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3702,20 +3702,10 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)

void ata_eng_timeout(struct ata_port *ap)
{
struct ata_queued_cmd *qc;

DPRINTK("ENTER\n");

qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc)
ata_qc_timeout(qc);
else {
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
ap->id);
goto out;
}
ata_qc_timeout(ata_qc_from_tag(ap, ap->active_tag));

out:
DPRINTK("EXIT\n");
}

Expand Down Expand Up @@ -3798,19 +3788,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
}
}

/**
* ata_qc_complete - Complete an active ATA command
* @qc: Command to complete
* @err_mask: 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)
*/

void ata_qc_complete(struct ata_queued_cmd *qc)
inline void __ata_qc_complete(struct ata_queued_cmd *qc)
{
assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */
assert(qc->flags & ATA_QCFLAG_ACTIVE);
Expand All @@ -3828,6 +3806,25 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
qc->complete_fn(qc);
}

/**
* ata_qc_complete - Complete an active ATA command
* @qc: Command to complete
* @err_mask: 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)
*/
void ata_qc_complete(struct ata_queued_cmd *qc)
{
if (unlikely(qc->flags & ATA_QCFLAG_EH_SCHEDULED))
return;

__ata_qc_complete(qc);
}

static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
Expand Down Expand Up @@ -5183,6 +5180,7 @@ EXPORT_SYMBOL_GPL(ata_ratelimit);
EXPORT_SYMBOL_GPL(ata_busy_sleep);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_timed_out);
EXPORT_SYMBOL_GPL(ata_scsi_error);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
EXPORT_SYMBOL_GPL(ata_scsi_release);
Expand Down
44 changes: 43 additions & 1 deletion trunk/drivers/scsi/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,47 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
return 0; /* scsi layer doesn't check return value, sigh */
}

/**
* ata_scsi_timed_out - SCSI layer time out callback
* @cmd: timed out SCSI command
*
* Handles SCSI layer timeout. We race with normal completion of
* the qc for @cmd. If the qc is already gone, we lose and let
* the scsi command finish (EH_HANDLED). Otherwise, the qc has
* timed out and EH should be invoked. Prevent ata_qc_complete()
* from finishing it by setting EH_SCHEDULED and return
* EH_NOT_HANDLED.
*
* LOCKING:
* Called from timer context
*
* RETURNS:
* EH_HANDLED or EH_NOT_HANDLED
*/
enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
{
struct Scsi_Host *host = cmd->device->host;
struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
unsigned long flags;
struct ata_queued_cmd *qc;
enum scsi_eh_timer_return ret = EH_HANDLED;

DPRINTK("ENTER\n");

spin_lock_irqsave(&ap->host_set->lock, flags);
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc) {
assert(qc->scsicmd == cmd);
qc->flags |= ATA_QCFLAG_EH_SCHEDULED;
qc->err_mask |= AC_ERR_TIMEOUT;
ret = EH_NOT_HANDLED;
}
spin_unlock_irqrestore(&ap->host_set->lock, flags);

DPRINTK("EXIT, ret=%d\n", ret);
return ret;
}

/**
* ata_scsi_error - SCSI layer error handler callback
* @host: SCSI host on which error occurred
Expand All @@ -741,6 +782,7 @@ int ata_scsi_error(struct Scsi_Host *host)
spin_lock_irqsave(&ap->host_set->lock, flags);
assert(!(ap->flags & ATA_FLAG_IN_EH));
ap->flags |= ATA_FLAG_IN_EH;
assert(ata_qc_from_tag(ap, ap->active_tag) != NULL);
spin_unlock_irqrestore(&ap->host_set->lock, flags);

ap->ops->eng_timeout(ap);
Expand Down Expand Up @@ -770,7 +812,7 @@ static void __ata_eh_qc_complete(struct ata_queued_cmd *qc)

spin_lock_irqsave(&ap->host_set->lock, flags);
qc->scsidone = ata_eh_scsidone;
ata_qc_complete(qc);
__ata_qc_complete(qc);
assert(!ata_tag_valid(qc->tag));
spin_unlock_irqrestore(&ap->host_set->lock, flags);

Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/scsi/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
extern void ata_qc_free(struct ata_queued_cmd *qc);
extern unsigned int ata_qc_issue(struct ata_queued_cmd *qc);
extern void __ata_qc_complete(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,
unsigned int wait, unsigned int can_sleep);
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/scsi/pdc_adma.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ static struct scsi_host_template adma_ata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_timed_out = ata_scsi_timed_out,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
Expand Down
10 changes: 3 additions & 7 deletions trunk/drivers/scsi/sata_mv.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ static struct scsi_host_template mv_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_timed_out = ata_scsi_timed_out,
.eh_strategy_handler = ata_scsi_error,
.can_queue = MV_USE_Q_DEPTH,
.this_id = ATA_SHT_THIS_ID,
Expand Down Expand Up @@ -2025,13 +2026,8 @@ static void mv_eng_timeout(struct ata_port *ap)
mv_err_intr(ap);
mv_stop_and_reset(ap);

if (!qc) {
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
ap->id);
} else {
qc->err_mask |= AC_ERR_TIMEOUT;
ata_eh_qc_complete(qc);
}
qc->err_mask |= AC_ERR_TIMEOUT;
ata_eh_qc_complete(qc);
}

/**
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/scsi/sata_nv.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ static struct scsi_host_template nv_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_timed_out = ata_scsi_timed_out,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
Expand Down
10 changes: 2 additions & 8 deletions trunk/drivers/scsi/sata_promise.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ static struct scsi_host_template pdc_ata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_timed_out = ata_scsi_timed_out,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
Expand Down Expand Up @@ -432,11 +433,6 @@ static void pdc_eng_timeout(struct ata_port *ap)
spin_lock_irqsave(&host_set->lock, flags);

qc = ata_qc_from_tag(ap, ap->active_tag);
if (!qc) {
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
ap->id);
goto out;
}

switch (qc->tf.protocol) {
case ATA_PROT_DMA:
Expand All @@ -456,10 +452,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
break;
}

out:
spin_unlock_irqrestore(&host_set->lock, flags);
if (qc)
ata_eh_qc_complete(qc);
ata_eh_qc_complete(qc);
DPRINTK("EXIT\n");
}

Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/scsi/sata_qstor.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ static struct scsi_host_template qs_ata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_timed_out = ata_scsi_timed_out,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/scsi/sata_sil.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ static struct scsi_host_template sil_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_timed_out = ata_scsi_timed_out,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
Expand Down
6 changes: 1 addition & 5 deletions trunk/drivers/scsi/sata_sil24.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ static struct scsi_host_template sil24_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_timed_out = ata_scsi_timed_out,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
Expand Down Expand Up @@ -638,11 +639,6 @@ static void sil24_eng_timeout(struct ata_port *ap)
struct ata_queued_cmd *qc;

qc = ata_qc_from_tag(ap, ap->active_tag);
if (!qc) {
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
ap->id);
return;
}

printk(KERN_ERR "ata%u: command timeout\n", ap->id);
qc->err_mask |= AC_ERR_TIMEOUT;
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/scsi/sata_sis.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ static struct scsi_host_template sis_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_timed_out = ata_scsi_timed_out,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/scsi/sata_svw.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ static struct scsi_host_template k2_sata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_timed_out = ata_scsi_timed_out,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
Expand Down
Loading

0 comments on commit 1cc2cb4

Please sign in to comment.