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

Commit e2482fa1 authored by Jürgen E. Fischer's avatar Jürgen E. Fischer Committed by James Bottomley
Browse files

[SCSI] aha152x: fix variable use before initialisation and other bugs



- change interface of the reset functions from Scsi_Cmnd to Scsi_Host.
- add functions with the original interface and rename the new
  functions to reflect the new interface.
- call these from the pcmcia driver, thereby avoiding the need to
  construct a (broken) Scsi_Cmnd from a Scsi_Host.
- just run the bh if the interrupt is from the controller and if so
  ensure that it's only called once per interrupt.

Signed-off-by: default avatarJuergen E. Fischer <fischer@linux-buechse.de>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 23ff51e9
Loading
Loading
Loading
Loading
+52 −33
Original line number Diff line number Diff line
@@ -1260,16 +1260,15 @@ static void free_hard_reset_SCs(struct Scsi_Host *shpnt, Scsi_Cmnd **SCs)
 * Reset the bus
 *
 */
static int aha152x_bus_reset(Scsi_Cmnd *SCpnt)
static int aha152x_bus_reset_host(struct Scsi_Host *shpnt)
{
	struct Scsi_Host *shpnt = SCpnt->device->host;
	unsigned long flags;

	DO_LOCK(flags);

#if defined(AHA152X_DEBUG)
	if(HOSTDATA(shpnt)->debug & debug_eh) {
		printk(DEBUG_LEAD "aha152x_bus_reset(%p)", CMDINFO(SCpnt), SCpnt);
		printk(KERN_DEBUG "scsi%d: bus reset", shpnt->host_no);
		show_queues(shpnt);
	}
#endif
@@ -1277,14 +1276,14 @@ static int aha152x_bus_reset(Scsi_Cmnd *SCpnt)
	free_hard_reset_SCs(shpnt, &ISSUE_SC);
	free_hard_reset_SCs(shpnt, &DISCONNECTED_SC);

	DPRINTK(debug_eh, DEBUG_LEAD "resetting bus\n", CMDINFO(SCpnt));
	DPRINTK(debug_eh, KERN_DEBUG "scsi%d: resetting bus\n", shpnt->host_no);

	SETPORT(SCSISEQ, SCSIRSTO);
	mdelay(256);
	SETPORT(SCSISEQ, 0);
	mdelay(DELAY);

	DPRINTK(debug_eh, DEBUG_LEAD "bus resetted\n", CMDINFO(SCpnt));
	DPRINTK(debug_eh, KERN_DEBUG "scsi%d: bus resetted\n", shpnt->host_no);

	setup_expected_interrupts(shpnt);
	if(HOSTDATA(shpnt)->commands==0)
@@ -1295,6 +1294,14 @@ static int aha152x_bus_reset(Scsi_Cmnd *SCpnt)
	return SUCCESS;
}

/*
 * Reset the bus
 *
 */
static int aha152x_bus_reset(Scsi_Cmnd *SCpnt)
{
	return aha152x_bus_reset_host(SCpnt->device->host);
}

/*
 *  Restore default values to the AIC-6260 registers and reset the fifos
@@ -1337,22 +1344,27 @@ static void reset_ports(struct Scsi_Host *shpnt)
 * Reset the host (bus and controller)
 *
 */
int aha152x_host_reset(Scsi_Cmnd * SCpnt)
int aha152x_host_reset_host(struct Scsi_Host *shpnt)
{
#if defined(AHA152X_DEBUG)
	struct Scsi_Host *shpnt = SCpnt->device->host;
#endif
	DPRINTK(debug_eh, KERN_DEBUG "scsi%d: host reset\n", shpnt->host_no);

	DPRINTK(debug_eh, DEBUG_LEAD "aha152x_host_reset(%p)\n", CMDINFO(SCpnt), SCpnt);
	aha152x_bus_reset_host(shpnt);

	aha152x_bus_reset(SCpnt);

	DPRINTK(debug_eh, DEBUG_LEAD "resetting ports\n", CMDINFO(SCpnt));
	reset_ports(SCpnt->device->host);
	DPRINTK(debug_eh, KERN_DEBUG "scsi%d: resetting ports\n", shpnt->host_no);
	reset_ports(shpnt);

	return SUCCESS;
}

/*
 * Reset the host (bus and controller)
 * 
 */
static int aha152x_host_reset(Scsi_Cmnd *SCpnt)
{
	return aha152x_host_reset_host(SCpnt->device->host);
}

/*
 * Return the "logical geometry"
 *
@@ -1431,22 +1443,18 @@ static void run(void)
{
	int i;
	for (i = 0; i<ARRAY_SIZE(aha152x_host); i++) {
		struct Scsi_Host *shpnt = aha152x_host[i];
		if (shpnt && HOSTDATA(shpnt)->service) {
			HOSTDATA(shpnt)->service=0;
			is_complete(shpnt);
		}
		is_complete(aha152x_host[i]);
	}
}

/*
 *    Interrupts handler
 * Interrupt handler
 *
 */

static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs)
{
	struct Scsi_Host *shpnt = lookup_irq(irqno);
	unsigned long flags;
	unsigned char rev, dmacntrl0;

	if (!shpnt) {
@@ -1472,23 +1480,23 @@ static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs)
	if ((rev == 0xFF) && (dmacntrl0 == 0xFF))
		return IRQ_NONE;

	if( TESTLO(DMASTAT, INTSTAT) )
		return IRQ_NONE;	

	/* no more interrupts from the controller, while we're busy.
	   INTEN is restored by the BH handler */
	CLRBITS(DMACNTRL0, INTEN);

#if 0
	/* check if there is already something to be
           serviced; should not happen */
	if(HOSTDATA(shpnt)->service) {
		printk(KERN_ERR "aha152x%d: lost interrupt (%d)\n", HOSTNO, HOSTDATA(shpnt)->service);
	        show_queues(shpnt);
	}
#endif
	DO_LOCK(flags);
	if( HOSTDATA(shpnt)->service==0 ) {
		HOSTDATA(shpnt)->service=1;

		/* Poke the BH handler */
	HOSTDATA(shpnt)->service++;
		INIT_WORK(&aha152x_tq, (void *) run, NULL);
		schedule_work(&aha152x_tq);
	}
	DO_UNLOCK(flags);

	return IRQ_HANDLED;
}

@@ -2527,7 +2535,18 @@ static void is_complete(struct Scsi_Host *shpnt)
	unsigned long flags;
	int pending;

	if(!shpnt)
		return;

	DO_LOCK(flags);

	if( HOSTDATA(shpnt)->service==0 )  {
		DO_UNLOCK(flags);
		return;
	}

	HOSTDATA(shpnt)->service = 0;

	if(HOSTDATA(shpnt)->in_intr) {
		DO_UNLOCK(flags);
		/* aha152x_error never returns.. */
+1 −1
Original line number Diff line number Diff line
@@ -332,6 +332,6 @@ struct aha152x_setup {

struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *);
void aha152x_release(struct Scsi_Host *);
int aha152x_host_reset(Scsi_Cmnd *);
int aha152x_host_reset_host(struct Scsi_Host *);

#endif /* _AHA152X_H */
+1 −3
Original line number Diff line number Diff line
@@ -275,10 +275,8 @@ static int aha152x_resume(struct pcmcia_device *dev)

	link->state &= ~DEV_SUSPEND;
	if (link->state & DEV_CONFIG) {
		Scsi_Cmnd tmp;
		pcmcia_request_configuration(link->handle, &link->conf);
		tmp.device->host = info->host;
		aha152x_host_reset(&tmp);
		aha152x_host_reset_host(info->host);
	}

	return 0;