Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 21764
b: refs/heads/master
c: d2927cb
h: refs/heads/master
v: v3
  • Loading branch information
Jeff Garzik committed Oct 30, 2005
1 parent efd5430 commit 8ec9725
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 72 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: 9359ede748ff1461bf0632fb4182f61da4a2f9e2
refs/heads/master: d2927cbe40b29ceda96c7a2412f7daee70026aad
4 changes: 2 additions & 2 deletions trunk/drivers/scsi/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ static void ahci_eng_timeout(struct ata_port *ap)
* not being called from the SCSI EH.
*/
qc->scsidone = scsi_finish_command;
ata_qc_complete(qc, ATA_ERR);
ata_qc_complete(qc, AC_ERR_OTHER);
}

spin_unlock_irqrestore(&host_set->lock, flags);
Expand Down Expand Up @@ -629,7 +629,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
if (status & PORT_IRQ_FATAL) {
ahci_intr_error(ap, status);
if (qc)
ata_qc_complete(qc, ATA_ERR);
ata_qc_complete(qc, AC_ERR_OTHER);
}

return 1;
Expand Down
31 changes: 15 additions & 16 deletions trunk/drivers/scsi/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2663,15 +2663,15 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
* None. (grabs host lock)
*/

void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
{
struct ata_port *ap = qc->ap;
unsigned long flags;

spin_lock_irqsave(&ap->host_set->lock, flags);
ap->flags &= ~ATA_FLAG_NOINTR;
ata_irq_on(ap);
ata_qc_complete(qc, drv_stat);
ata_qc_complete(qc, err_mask);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
}

Expand Down Expand Up @@ -2768,7 +2768,7 @@ static int ata_pio_complete (struct ata_port *ap)

ap->hsm_task_state = HSM_ST_IDLE;

ata_poll_qc_complete(qc, drv_stat);
ata_poll_qc_complete(qc, 0);

/* another command may start at this point */

Expand Down Expand Up @@ -3136,18 +3136,15 @@ static void ata_pio_block(struct ata_port *ap)
static void ata_pio_error(struct ata_port *ap)
{
struct ata_queued_cmd *qc;
u8 drv_stat;

printk(KERN_WARNING "ata%u: PIO error\n", ap->id);

qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL);

drv_stat = ata_chk_status(ap);
printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n",
ap->id, drv_stat);

ap->hsm_task_state = HSM_ST_IDLE;

ata_poll_qc_complete(qc, drv_stat | ATA_ERR);
ata_poll_qc_complete(qc, AC_ERR_ATA_BUS);
}

static void ata_pio_task(void *_data)
Expand Down Expand Up @@ -3270,7 +3267,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
ap->id, qc->tf.command, drv_stat, host_stat);

/* complete taskfile transaction */
ata_qc_complete(qc, drv_stat);
ata_qc_complete(qc, ac_err_mask(drv_stat));
break;
}

Expand Down Expand Up @@ -3375,7 +3372,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
return qc;
}

int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask)
{
return 0;
}
Expand Down Expand Up @@ -3434,7 +3431,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
* spin_lock_irqsave(host_set lock)
*/

void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
{
int rc;

Expand All @@ -3451,7 +3448,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
qc->flags &= ~ATA_QCFLAG_ACTIVE;

/* call completion callback */
rc = qc->complete_fn(qc, drv_stat);
rc = qc->complete_fn(qc, err_mask);

/* if callback indicates not to complete command (non-zero),
* return immediately
Expand Down Expand Up @@ -3889,7 +3886,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
ap->ops->irq_clear(ap);

/* complete taskfile transaction */
ata_qc_complete(qc, status);
ata_qc_complete(qc, ac_err_mask(status));
break;

default:
Expand Down Expand Up @@ -3984,7 +3981,7 @@ static void atapi_packet_task(void *_data)
/* sleep-wait for BSY to clear */
DPRINTK("busy wait\n");
if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB))
goto err_out;
goto err_out_status;

/* make sure DRQ is set */
status = ata_chk_status(ap);
Expand Down Expand Up @@ -4021,8 +4018,10 @@ static void atapi_packet_task(void *_data)

return;

err_out_status:
status = ata_chk_status(ap);
err_out:
ata_poll_qc_complete(qc, ATA_ERR);
ata_poll_qc_complete(qc, __ac_err_mask(status));
}


Expand Down
46 changes: 28 additions & 18 deletions trunk/drivers/scsi/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
* Use ata_to_sense_error() to map status register bits
* onto sense key, asc & ascq.
*/
if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) {
if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
&sb[1], &sb[2], &sb[3]);
sb[1] &= 0x0f;
Expand Down Expand Up @@ -635,7 +635,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
* Use ata_to_sense_error() to map status register bits
* onto sense key, asc & ascq.
*/
if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) {
if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
&sb[2], &sb[12], &sb[13]);
sb[2] &= 0x0f;
Expand All @@ -644,14 +644,22 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
sb[0] = 0x70;
sb[7] = 0x0a;

if (tf->flags & ATA_TFLAG_LBA && !(tf->flags & ATA_TFLAG_LBA48)) {
if (tf->flags & ATA_TFLAG_LBA48) {
/* TODO: find solution for LBA48 descriptors */
}

else if (tf->flags & ATA_TFLAG_LBA) {
/* A small (28b) LBA will fit in the 32b info field */
sb[0] |= 0x80; /* set valid bit */
sb[3] = tf->device & 0x0f;
sb[4] = tf->lbah;
sb[5] = tf->lbam;
sb[6] = tf->lbal;
}

else {
/* TODO: C/H/S */
}
}

/**
Expand Down Expand Up @@ -1193,10 +1201,12 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
return 1;
}

static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
static int ata_scsi_qc_complete(struct ata_queued_cmd *qc,
unsigned int err_mask)
{
struct scsi_cmnd *cmd = qc->scsicmd;
int need_sense = drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ);
u8 *cdb = cmd->cmnd;
int need_sense = (err_mask != 0);

/* For ATA pass thru (SAT) commands, generate a sense block if
* user mandated it or if there's an error. Note that if we
Expand All @@ -1205,8 +1215,8 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
* whether the command completed successfully or not. If there
* was no error, SK, ASC and ASCQ will all be zero.
*/
if (((cmd->cmnd[0] == ATA_16) || (cmd->cmnd[0] == ATA_12)) &&
((cmd->cmnd[2] & 0x20) || need_sense)) {
if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
((cdb[2] & 0x20) || need_sense)) {
ata_gen_ata_desc_sense(qc);
} else {
if (!need_sense) {
Expand Down Expand Up @@ -1989,21 +1999,13 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
DPRINTK("EXIT\n");
}

static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
{
struct scsi_cmnd *cmd = qc->scsicmd;

VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat);

if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ)))
/* FIXME: not quite right; we don't want the
* translation of taskfile registers into
* a sense descriptors, since that's only
* correct for ATA, not ATAPI
*/
ata_gen_ata_desc_sense(qc);
VPRINTK("ENTER, err_mask 0x%X\n", err_mask);

else if (unlikely(drv_stat & ATA_ERR)) {
if (unlikely(err_mask & AC_ERR_DEV)) {
DPRINTK("request check condition\n");

/* FIXME: command completion with check condition
Expand All @@ -2020,6 +2022,14 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
return 1;
}

else if (unlikely(err_mask))
/* FIXME: not quite right; we don't want the
* translation of taskfile registers into
* a sense descriptors, since that's only
* correct for ATA, not ATAPI
*/
ata_gen_ata_desc_sense(qc);

else {
u8 *scsicmd = cmd->cmnd;

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/scsi/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct ata_scsi_args {

/* libata-core.c */
extern int atapi_enabled;
extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
struct ata_device *dev);
extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
Expand Down
13 changes: 8 additions & 5 deletions trunk/drivers/scsi/pdc_adma.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
struct adma_port_priv *pp;
struct ata_queued_cmd *qc;
void __iomem *chan = ADMA_REGS(mmio_base, port_no);
u8 drv_stat = 0, status = readb(chan + ADMA_STATUS);
u8 status = readb(chan + ADMA_STATUS);

if (status == 0)
continue;
Expand All @@ -464,11 +464,14 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
continue;
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
unsigned int err_mask = 0;

if ((status & (aPERR | aPSD | aUIRQ)))
drv_stat = ATA_ERR;
err_mask = AC_ERR_OTHER;
else if (pp->pkt[0] != cDONE)
drv_stat = ATA_ERR;
ata_qc_complete(qc, drv_stat);
err_mask = AC_ERR_OTHER;

ata_qc_complete(qc, err_mask);
}
}
return handled;
Expand Down Expand Up @@ -498,7 +501,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)

/* complete taskfile transaction */
pp->state = adma_state_idle;
ata_qc_complete(qc, status);
ata_qc_complete(qc, ac_err_mask(status));
handled = 1;
}
}
Expand Down
11 changes: 6 additions & 5 deletions trunk/drivers/scsi/sata_mv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
struct ata_queued_cmd *qc;
u32 hc_irq_cause;
int shift, port, port0, hard_port, handled;
unsigned int err_mask;
u8 ata_status = 0;

if (hc == 0) {
Expand Down Expand Up @@ -1100,15 +1101,15 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
handled++;
}

err_mask = ac_err_mask(ata_status);

shift = port << 1; /* (port * 2) */
if (port >= MV_PORTS_PER_HC) {
shift++; /* skip bit 8 in the HC Main IRQ reg */
}
if ((PORT0_ERR << shift) & relevant) {
mv_err_intr(ap);
/* OR in ATA_ERR to ensure libata knows we took one */
ata_status = readb((void __iomem *)
ap->ioaddr.status_addr) | ATA_ERR;
err_mask |= AC_ERR_OTHER;
handled++;
}

Expand All @@ -1118,7 +1119,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
VPRINTK("port %u IRQ found for qc, "
"ata_status 0x%x\n", port,ata_status);
/* mark qc status appropriately */
ata_qc_complete(qc, ata_status);
ata_qc_complete(qc, err_mask);
}
}
}
Expand Down Expand Up @@ -1294,7 +1295,7 @@ static void mv_eng_timeout(struct ata_port *ap)
*/
spin_lock_irqsave(&ap->host_set->lock, flags);
qc->scsidone = scsi_finish_command;
ata_qc_complete(qc, ATA_ERR);
ata_qc_complete(qc, AC_ERR_OTHER);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
}
}
Expand Down
16 changes: 7 additions & 9 deletions trunk/drivers/scsi/sata_promise.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
drv_stat = ata_wait_idle(ap);
ata_qc_complete(qc, __ac_err_mask(drv_stat));
break;

default:
Expand All @@ -408,7 +409,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
ap->id, qc->tf.command, drv_stat);

ata_qc_complete(qc, drv_stat);
ata_qc_complete(qc, ac_err_mask(drv_stat));
break;
}

Expand All @@ -420,24 +421,21 @@ static void pdc_eng_timeout(struct ata_port *ap)
static inline unsigned int pdc_host_intr( struct ata_port *ap,
struct ata_queued_cmd *qc)
{
u8 status;
unsigned int handled = 0, have_err = 0;
unsigned int handled = 0, err_mask = 0;
u32 tmp;
void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;

tmp = readl(mmio);
if (tmp & PDC_ERR_MASK) {
have_err = 1;
err_mask = AC_ERR_DEV;
pdc_reset_port(ap);
}

switch (qc->tf.protocol) {
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
status = ata_wait_idle(ap);
if (have_err)
status |= ATA_ERR;
ata_qc_complete(qc, status);
err_mask |= ac_err_mask(ata_wait_idle(ap));
ata_qc_complete(qc, err_mask);
handled = 1;
break;

Expand Down
Loading

0 comments on commit 8ec9725

Please sign in to comment.