Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 054ee8fd authored by Jeff Garzik's avatar Jeff Garzik
Browse files

Merge branch 'upstream'

parents f0612bbc a7dac447
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -608,7 +608,7 @@ static void ahci_eng_timeout(struct ata_port *ap)
	 	 * not being called from the SCSI EH.
	 	 * not being called from the SCSI EH.
	 	 */
	 	 */
		qc->scsidone = scsi_finish_command;
		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);
	spin_unlock_irqrestore(&host_set->lock, flags);
@@ -637,7 +637,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
	if (status & PORT_IRQ_FATAL) {
	if (status & PORT_IRQ_FATAL) {
		ahci_intr_error(ap, status);
		ahci_intr_error(ap, status);
		if (qc)
		if (qc)
			ata_qc_complete(qc, ATA_ERR);
			ata_qc_complete(qc, AC_ERR_OTHER);
	}
	}


	return 1;
	return 1;
+15 −16
Original line number Original line Diff line number Diff line
@@ -2750,7 +2750,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 *	None.  (grabs host lock)
 *	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;
	struct ata_port *ap = qc->ap;
	unsigned long flags;
	unsigned long flags;
@@ -2758,7 +2758,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
	spin_lock_irqsave(&ap->host_set->lock, flags);
	spin_lock_irqsave(&ap->host_set->lock, flags);
	ap->flags &= ~ATA_FLAG_NOINTR;
	ap->flags &= ~ATA_FLAG_NOINTR;
	ata_irq_on(ap);
	ata_irq_on(ap);
	ata_qc_complete(qc, drv_stat);
	ata_qc_complete(qc, err_mask);
	spin_unlock_irqrestore(&ap->host_set->lock, flags);
	spin_unlock_irqrestore(&ap->host_set->lock, flags);
}
}


@@ -2855,7 +2855,7 @@ static int ata_pio_complete (struct ata_port *ap)


	ap->hsm_task_state = HSM_ST_IDLE;
	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 */
	/* another command may start at this point */


@@ -3223,18 +3223,15 @@ static void ata_pio_block(struct ata_port *ap)
static void ata_pio_error(struct ata_port *ap)
static void ata_pio_error(struct ata_port *ap)
{
{
	struct ata_queued_cmd *qc;
	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);
	qc = ata_qc_from_tag(ap, ap->active_tag);
	assert(qc != NULL);
	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;
	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)
static void ata_pio_task(void *_data)
@@ -3357,7 +3354,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
		       ap->id, qc->tf.command, drv_stat, host_stat);
		       ap->id, qc->tf.command, drv_stat, host_stat);


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


@@ -3462,7 +3459,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
	return qc;
	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;
	return 0;
}
}
@@ -3521,7 +3518,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
 *	spin_lock_irqsave(host_set lock)
 *	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;
	int rc;


@@ -3538,7 +3535,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
	qc->flags &= ~ATA_QCFLAG_ACTIVE;
	qc->flags &= ~ATA_QCFLAG_ACTIVE;


	/* call completion callback */
	/* 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),
	/* if callback indicates not to complete command (non-zero),
	 * return immediately
	 * return immediately
@@ -3976,7 +3973,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
		ap->ops->irq_clear(ap);
		ap->ops->irq_clear(ap);


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


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


	/* make sure DRQ is set */
	/* make sure DRQ is set */
	status = ata_chk_status(ap);
	status = ata_chk_status(ap);
@@ -4108,8 +4105,10 @@ static void atapi_packet_task(void *_data)


	return;
	return;


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




+28 −18
Original line number Original line Diff line number Diff line
@@ -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
	 * Use ata_to_sense_error() to map status register bits
	 * onto sense key, asc & ascq.
	 * 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,
		ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
				   &sb[1], &sb[2], &sb[3]);
				   &sb[1], &sb[2], &sb[3]);
		sb[1] &= 0x0f;
		sb[1] &= 0x0f;
@@ -635,7 +635,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
	 * Use ata_to_sense_error() to map status register bits
	 * Use ata_to_sense_error() to map status register bits
	 * onto sense key, asc & ascq.
	 * 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,
		ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
				   &sb[2], &sb[12], &sb[13]);
				   &sb[2], &sb[12], &sb[13]);
		sb[2] &= 0x0f;
		sb[2] &= 0x0f;
@@ -644,7 +644,11 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
	sb[0] = 0x70;
	sb[0] = 0x70;
	sb[7] = 0x0a;
	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 */
		/* A small (28b) LBA will fit in the 32b info field */
		sb[0] |= 0x80;		/* set valid bit */
		sb[0] |= 0x80;		/* set valid bit */
		sb[3] = tf->device & 0x0f;
		sb[3] = tf->device & 0x0f;
@@ -652,6 +656,10 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
		sb[5] = tf->lbam;
		sb[5] = tf->lbam;
		sb[6] = tf->lbal;
		sb[6] = tf->lbal;
	}
	}

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


/**
/**
@@ -1209,10 +1217,12 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
	return 1;
	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;
	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
	/* For ATA pass thru (SAT) commands, generate a sense block if
	 * user mandated it or if there's an error.  Note that if we
	 * user mandated it or if there's an error.  Note that if we
@@ -1221,8 +1231,8 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
	 * whether the command completed successfully or not. If there
	 * whether the command completed successfully or not. If there
	 * was no error, SK, ASC and ASCQ will all be zero.
	 * was no error, SK, ASC and ASCQ will all be zero.
	 */
	 */
	if (((cmd->cmnd[0] == ATA_16) || (cmd->cmnd[0] == ATA_12)) &&
	if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
 	    ((cmd->cmnd[2] & 0x20) || need_sense)) {
 	    ((cdb[2] & 0x20) || need_sense)) {
 		ata_gen_ata_desc_sense(qc);
 		ata_gen_ata_desc_sense(qc);
	} else {
	} else {
		if (!need_sense) {
		if (!need_sense) {
@@ -2005,21 +2015,13 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
	DPRINTK("EXIT\n");
	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;
	struct scsi_cmnd *cmd = qc->scsicmd;


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

	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);


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


		/* FIXME: command completion with check condition
		/* FIXME: command completion with check condition
@@ -2036,6 +2038,14 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
		return 1;
		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 {
	else {
		u8 *scsicmd = cmd->cmnd;
		u8 *scsicmd = cmd->cmnd;


+1 −1
Original line number Original line Diff line number Diff line
@@ -39,7 +39,7 @@ struct ata_scsi_args {


/* libata-core.c */
/* libata-core.c */
extern int atapi_enabled;
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,
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
				      struct ata_device *dev);
				      struct ata_device *dev);
extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
+8 −5
Original line number Original line Diff line number Diff line
@@ -451,7 +451,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
		struct adma_port_priv *pp;
		struct adma_port_priv *pp;
		struct ata_queued_cmd *qc;
		struct ata_queued_cmd *qc;
		void __iomem *chan = ADMA_REGS(mmio_base, port_no);
		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)
		if (status == 0)
			continue;
			continue;
@@ -464,11 +464,14 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
			continue;
			continue;
		qc = ata_qc_from_tag(ap, ap->active_tag);
		qc = ata_qc_from_tag(ap, ap->active_tag);
		if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
		if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
			unsigned int err_mask = 0;

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

			ata_qc_complete(qc, err_mask);
		}
		}
	}
	}
	return handled;
	return handled;
@@ -498,7 +501,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
		
		
				/* complete taskfile transaction */
				/* complete taskfile transaction */
				pp->state = adma_state_idle;
				pp->state = adma_state_idle;
				ata_qc_complete(qc, status);
				ata_qc_complete(qc, ac_err_mask(status));
				handled = 1;
				handled = 1;
			}
			}
		}
		}
Loading