Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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: Juergen E. Fischer <fischer@linux-buechse.de>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by

J�rgen E. Fischer and committed by
James Bottomley
e2482fa1 23ff51e9

+54 -37
+52 -33
drivers/scsi/aha152x.c
··· 1260 1260 * Reset the bus 1261 1261 * 1262 1262 */ 1263 - static int aha152x_bus_reset(Scsi_Cmnd *SCpnt) 1263 + static int aha152x_bus_reset_host(struct Scsi_Host *shpnt) 1264 1264 { 1265 - struct Scsi_Host *shpnt = SCpnt->device->host; 1266 1265 unsigned long flags; 1267 1266 1268 1267 DO_LOCK(flags); 1269 1268 1270 1269 #if defined(AHA152X_DEBUG) 1271 1270 if(HOSTDATA(shpnt)->debug & debug_eh) { 1272 - printk(DEBUG_LEAD "aha152x_bus_reset(%p)", CMDINFO(SCpnt), SCpnt); 1271 + printk(KERN_DEBUG "scsi%d: bus reset", shpnt->host_no); 1273 1272 show_queues(shpnt); 1274 1273 } 1275 1274 #endif ··· 1276 1277 free_hard_reset_SCs(shpnt, &ISSUE_SC); 1277 1278 free_hard_reset_SCs(shpnt, &DISCONNECTED_SC); 1278 1279 1279 - DPRINTK(debug_eh, DEBUG_LEAD "resetting bus\n", CMDINFO(SCpnt)); 1280 + DPRINTK(debug_eh, KERN_DEBUG "scsi%d: resetting bus\n", shpnt->host_no); 1280 1281 1281 1282 SETPORT(SCSISEQ, SCSIRSTO); 1282 1283 mdelay(256); 1283 1284 SETPORT(SCSISEQ, 0); 1284 1285 mdelay(DELAY); 1285 1286 1286 - DPRINTK(debug_eh, DEBUG_LEAD "bus resetted\n", CMDINFO(SCpnt)); 1287 + DPRINTK(debug_eh, KERN_DEBUG "scsi%d: bus resetted\n", shpnt->host_no); 1287 1288 1288 1289 setup_expected_interrupts(shpnt); 1289 1290 if(HOSTDATA(shpnt)->commands==0) ··· 1294 1295 return SUCCESS; 1295 1296 } 1296 1297 1298 + /* 1299 + * Reset the bus 1300 + * 1301 + */ 1302 + static int aha152x_bus_reset(Scsi_Cmnd *SCpnt) 1303 + { 1304 + return aha152x_bus_reset_host(SCpnt->device->host); 1305 + } 1297 1306 1298 1307 /* 1299 1308 * Restore default values to the AIC-6260 registers and reset the fifos ··· 1344 1337 * Reset the host (bus and controller) 1345 1338 * 1346 1339 */ 1347 - int aha152x_host_reset(Scsi_Cmnd * SCpnt) 1340 + int aha152x_host_reset_host(struct Scsi_Host *shpnt) 1348 1341 { 1349 - #if defined(AHA152X_DEBUG) 1350 - struct Scsi_Host *shpnt = SCpnt->device->host; 1351 - #endif 1342 + DPRINTK(debug_eh, KERN_DEBUG "scsi%d: host reset\n", shpnt->host_no); 1352 1343 1353 - DPRINTK(debug_eh, DEBUG_LEAD "aha152x_host_reset(%p)\n", CMDINFO(SCpnt), SCpnt); 1344 + aha152x_bus_reset_host(shpnt); 1354 1345 1355 - aha152x_bus_reset(SCpnt); 1356 - 1357 - DPRINTK(debug_eh, DEBUG_LEAD "resetting ports\n", CMDINFO(SCpnt)); 1358 - reset_ports(SCpnt->device->host); 1346 + DPRINTK(debug_eh, KERN_DEBUG "scsi%d: resetting ports\n", shpnt->host_no); 1347 + reset_ports(shpnt); 1359 1348 1360 1349 return SUCCESS; 1350 + } 1351 + 1352 + /* 1353 + * Reset the host (bus and controller) 1354 + * 1355 + */ 1356 + static int aha152x_host_reset(Scsi_Cmnd *SCpnt) 1357 + { 1358 + return aha152x_host_reset_host(SCpnt->device->host); 1361 1359 } 1362 1360 1363 1361 /* ··· 1443 1431 { 1444 1432 int i; 1445 1433 for (i = 0; i<ARRAY_SIZE(aha152x_host); i++) { 1446 - struct Scsi_Host *shpnt = aha152x_host[i]; 1447 - if (shpnt && HOSTDATA(shpnt)->service) { 1448 - HOSTDATA(shpnt)->service=0; 1449 - is_complete(shpnt); 1450 - } 1434 + is_complete(aha152x_host[i]); 1451 1435 } 1452 1436 } 1453 1437 1454 1438 /* 1455 - * Interrupts handler 1439 + * Interrupt handler 1456 1440 * 1457 1441 */ 1458 - 1459 1442 static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs) 1460 1443 { 1461 1444 struct Scsi_Host *shpnt = lookup_irq(irqno); 1445 + unsigned long flags; 1462 1446 unsigned char rev, dmacntrl0; 1463 1447 1464 1448 if (!shpnt) { ··· 1480 1472 if ((rev == 0xFF) && (dmacntrl0 == 0xFF)) 1481 1473 return IRQ_NONE; 1482 1474 1475 + if( TESTLO(DMASTAT, INTSTAT) ) 1476 + return IRQ_NONE; 1477 + 1483 1478 /* no more interrupts from the controller, while we're busy. 1484 1479 INTEN is restored by the BH handler */ 1485 1480 CLRBITS(DMACNTRL0, INTEN); 1486 1481 1487 - #if 0 1488 - /* check if there is already something to be 1489 - serviced; should not happen */ 1490 - if(HOSTDATA(shpnt)->service) { 1491 - printk(KERN_ERR "aha152x%d: lost interrupt (%d)\n", HOSTNO, HOSTDATA(shpnt)->service); 1492 - show_queues(shpnt); 1482 + DO_LOCK(flags); 1483 + if( HOSTDATA(shpnt)->service==0 ) { 1484 + HOSTDATA(shpnt)->service=1; 1485 + 1486 + /* Poke the BH handler */ 1487 + INIT_WORK(&aha152x_tq, (void *) run, NULL); 1488 + schedule_work(&aha152x_tq); 1493 1489 } 1494 - #endif 1495 - 1496 - /* Poke the BH handler */ 1497 - HOSTDATA(shpnt)->service++; 1498 - INIT_WORK(&aha152x_tq, (void *) run, NULL); 1499 - schedule_work(&aha152x_tq); 1490 + DO_UNLOCK(flags); 1491 + 1500 1492 return IRQ_HANDLED; 1501 1493 } 1502 1494 ··· 2535 2527 unsigned long flags; 2536 2528 int pending; 2537 2529 2530 + if(!shpnt) 2531 + return; 2532 + 2538 2533 DO_LOCK(flags); 2534 + 2535 + if( HOSTDATA(shpnt)->service==0 ) { 2536 + DO_UNLOCK(flags); 2537 + return; 2538 + } 2539 + 2540 + HOSTDATA(shpnt)->service = 0; 2541 + 2539 2542 if(HOSTDATA(shpnt)->in_intr) { 2540 2543 DO_UNLOCK(flags); 2541 2544 /* aha152x_error never returns.. */
+1 -1
drivers/scsi/aha152x.h
··· 332 332 333 333 struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *); 334 334 void aha152x_release(struct Scsi_Host *); 335 - int aha152x_host_reset(Scsi_Cmnd *); 335 + int aha152x_host_reset_host(struct Scsi_Host *); 336 336 337 337 #endif /* _AHA152X_H */
+1 -3
drivers/scsi/pcmcia/aha152x_stub.c
··· 275 275 276 276 link->state &= ~DEV_SUSPEND; 277 277 if (link->state & DEV_CONFIG) { 278 - Scsi_Cmnd tmp; 279 278 pcmcia_request_configuration(link->handle, &link->conf); 280 - tmp.device->host = info->host; 281 - aha152x_host_reset(&tmp); 279 + aha152x_host_reset_host(info->host); 282 280 } 283 281 284 282 return 0;