Beispiel #1
0
static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
{
	struct request_pm_state *pm = rq->data;

	if (blk_pm_suspend_request(rq) &&
	    pm->pm_step == IDE_PM_START_SUSPEND)
		/* Mark drive blocked when starting the suspend sequence. */
		drive->dev_flags |= IDE_DFLAG_BLOCKED;
	else if (blk_pm_resume_request(rq) &&
		 pm->pm_step == IDE_PM_START_RESUME) {
		/* 
		 * The first thing we do on wakeup is to wait for BSY bit to
		 * go away (with a looong timeout) as a drive on this hwif may
		 * just be POSTing itself.
		 * We do that before even selecting as the "other" device on
		 * the bus may be broken enough to walk on our toes at this
		 * point.
		 */
		ide_hwif_t *hwif = drive->hwif;
		int rc;
#ifdef DEBUG_PM
		printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name);
#endif
		rc = ide_wait_not_busy(hwif, 35000);
		if (rc)
			printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
		SELECT_DRIVE(drive);
		hwif->tp_ops->set_irq(hwif, 1);
		rc = ide_wait_not_busy(hwif, 100000);
		if (rc)
			printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
	}
}
Beispiel #2
0
void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
{
	struct request_pm_state *pm = rq->special;

	if (rq->cmd_type == REQ_TYPE_PM_SUSPEND &&
	    pm->pm_step == IDE_PM_START_SUSPEND)
		/* Mark drive blocked when starting the suspend sequence. */
		drive->dev_flags |= IDE_DFLAG_BLOCKED;
	else if (rq->cmd_type == REQ_TYPE_PM_RESUME &&
		 pm->pm_step == IDE_PM_START_RESUME) {
		/*
		 * The first thing we do on wakeup is to wait for BSY bit to
		 * go away (with a looong timeout) as a drive on this hwif may
		 * just be POSTing itself.
		 * We do that before even selecting as the "other" device on
		 * the bus may be broken enough to walk on our toes at this
		 * point.
		 */
		ide_hwif_t *hwif = drive->hwif;
		const struct ide_tp_ops *tp_ops = hwif->tp_ops;
		struct request_queue *q = drive->queue;
		unsigned long flags;
		int rc;
#ifdef DEBUG_PM
#ifdef CONFIG_DEBUG_PRINTK
		printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name);
#else
		;
#endif
#endif
		rc = ide_wait_not_busy(hwif, 35000);
		if (rc)
#ifdef CONFIG_DEBUG_PRINTK
			printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
#else
			;
#endif
		tp_ops->dev_select(drive);
		tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
		rc = ide_wait_not_busy(hwif, 100000);
		if (rc)
#ifdef CONFIG_DEBUG_PRINTK
			printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
#else
			;
#endif

		spin_lock_irqsave(q->queue_lock, flags);
		blk_start_queue(q);
		spin_unlock_irqrestore(q->queue_lock, flags);
	}
}
static int idescsi_eh_abort (struct scsi_cmnd *cmd)
{
	idescsi_scsi_t *scsi  = scsihost_to_idescsi(cmd->device->host);
	ide_drive_t    *drive = scsi->drive;
	int		busy;
	int             ret   = FAILED;

	/* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */

	if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
		printk (KERN_WARNING "ide-scsi: abort called for %lu\n", cmd->serial_number);

	if (!drive) {
		printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_abort\n");
		WARN_ON(1);
		goto no_drive;
	}

	/* First give it some more time, how much is "right" is hard to say :-( */

	busy = ide_wait_not_busy(HWIF(drive), 100);	/* FIXME - uses mdelay which causes latency? */
	if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
		printk (KERN_WARNING "ide-scsi: drive did%s become ready\n", busy?" not":"");

	spin_lock_irq(&ide_lock);

	/* If there is no pc running we're done (our interrupt took care of it) */
	if (!scsi->pc) {
		ret = SUCCESS;
		goto ide_unlock;
	}

	/* It's somewhere in flight. Does ide subsystem agree? */
	if (scsi->pc->scsi_cmd->serial_number == cmd->serial_number && !busy &&
	    elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != scsi->pc->rq) {
		/*
		 * FIXME - not sure this condition can ever occur
		 */
		printk (KERN_ERR "ide-scsi: cmd aborted!\n");

		if (blk_sense_request(scsi->pc->rq))
			kfree(scsi->pc->buf);
		/* we need to call blk_put_request twice. */
		blk_put_request(scsi->pc->rq);
		blk_put_request(scsi->pc->rq);
		kfree(scsi->pc);
		scsi->pc = NULL;

		ret = SUCCESS;
	}

ide_unlock:
	spin_unlock_irq(&ide_lock);
no_drive:
	if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
		printk (KERN_WARNING "ide-scsi: abort returns %s\n", ret == SUCCESS?"success":"failed");

	return ret;
}