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

Commit 62717f53 authored by Finn Thain's avatar Finn Thain Committed by Martin K. Petersen
Browse files

ncr5380: Implement new eh_bus_reset_handler



NCR5380.c lacks a sane eh_bus_reset_handler. The atari_NCR5380.c code is
much better but it should not throw out the issue queue (that would be
a host reset) and it neglects to set the result code for commands that it
throws out. Fix these bugs and keep the two core drivers in sync.

Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Tested-by: default avatarOndrej Zary <linux@rainbow-software.org>
Tested-by: default avatarMichael Schmitz <schmitzmic@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 707d62b3
Loading
Loading
Loading
Loading
+49 −1
Original line number Diff line number Diff line
@@ -2482,18 +2482,66 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
{
	struct Scsi_Host *instance = cmd->device->host;
	struct NCR5380_hostdata *hostdata = shost_priv(instance);
	int i;
	unsigned long flags;
	struct NCR5380_cmd *ncmd;

	spin_lock_irqsave(&hostdata->lock, flags);

#if (NDEBUG & NDEBUG_ANY)
	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
	scmd_printk(KERN_INFO, cmd, __func__);
#endif
	NCR5380_dprint(NDEBUG_ANY, instance);
	NCR5380_dprint_phase(NDEBUG_ANY, instance);

	do_reset(instance);

	/* reset NCR registers */
	NCR5380_write(MODE_REG, MR_BASE);
	NCR5380_write(TARGET_COMMAND_REG, 0);
	NCR5380_write(SELECT_ENABLE_REG, 0);

	/* After the reset, there are no more connected or disconnected commands
	 * and no busy units; so clear the low-level status here to avoid
	 * conflicts when the mid-level code tries to wake up the affected
	 * commands!
	 */

	hostdata->selecting = NULL;

	list_for_each_entry(ncmd, &hostdata->disconnected, list) {
		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);

		set_host_byte(cmd, DID_RESET);
		cmd->scsi_done(cmd);
	}

	list_for_each_entry(ncmd, &hostdata->autosense, list) {
		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);

		set_host_byte(cmd, DID_RESET);
		cmd->scsi_done(cmd);
	}

	if (hostdata->connected) {
		set_host_byte(hostdata->connected, DID_RESET);
		complete_cmd(instance, hostdata->connected);
		hostdata->connected = NULL;
	}

	if (hostdata->sensing) {
		set_host_byte(hostdata->connected, DID_RESET);
		complete_cmd(instance, hostdata->sensing);
		hostdata->sensing = NULL;
	}

	for (i = 0; i < 8; ++i)
		hostdata->busy[i] = 0;
#ifdef REAL_DMA
	hostdata->dma_len = 0;
#endif

	queue_work(hostdata->work_q, &hostdata->main_task);
	spin_unlock_irqrestore(&hostdata->lock, flags);

	return SUCCESS;
+23 −16
Original line number Diff line number Diff line
@@ -2694,11 +2694,12 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
	struct NCR5380_hostdata *hostdata = shost_priv(instance);
	int i;
	unsigned long flags;
	struct NCR5380_cmd *ncmd;

	spin_lock_irqsave(&hostdata->lock, flags);

#if (NDEBUG & NDEBUG_ANY)
	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
	scmd_printk(KERN_INFO, cmd, __func__);
#endif
	NCR5380_dprint(NDEBUG_ANY, instance);
	NCR5380_dprint_phase(NDEBUG_ANY, instance);
@@ -2718,27 +2719,32 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)

	hostdata->selecting = NULL;

	if (hostdata->connected)
		dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
	list_for_each_entry(ncmd, &hostdata->disconnected, list) {
		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);

		set_host_byte(cmd, DID_RESET);
		cmd->scsi_done(cmd);
	}

	list_for_each_entry(ncmd, &hostdata->autosense, list) {
		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);

		set_host_byte(cmd, DID_RESET);
		cmd->scsi_done(cmd);
	}

	if (hostdata->connected) {
		set_host_byte(hostdata->connected, DID_RESET);
		complete_cmd(instance, hostdata->connected);
		hostdata->connected = NULL;
	}

	if (hostdata->sensing) {
		set_host_byte(hostdata->connected, DID_RESET);
		complete_cmd(instance, hostdata->sensing);
		hostdata->sensing = NULL;
	}

	if (!list_empty(&hostdata->autosense))
		dsprintk(NDEBUG_ABORT, instance, "reset aborted autosense list\n");
	INIT_LIST_HEAD(&hostdata->autosense);

	if (!list_empty(&hostdata->unissued))
		dsprintk(NDEBUG_ABORT, instance, "reset aborted unissued list\n");
	INIT_LIST_HEAD(&hostdata->unissued);

	if (!list_empty(&hostdata->disconnected))
		dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected list\n");
	INIT_LIST_HEAD(&hostdata->disconnected);

#ifdef SUPPORT_TAGS
	free_all_tags(hostdata);
#endif
@@ -2748,6 +2754,7 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
	hostdata->dma_len = 0;
#endif

	queue_work(hostdata->work_q, &hostdata->main_task);
	maybe_release_dma_irq(instance);
	spin_unlock_irqrestore(&hostdata->lock, flags);