aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic7xxx/aic79xx_osm.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2006-06-22 05:45:00 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-06-26 10:59:18 -0400
commitf89d0a4e1d01168f20f9e8273de7dfc094b2a430 (patch)
tree192535b673233f57fa7617b99ce593892957cb2f /drivers/scsi/aic7xxx/aic79xx_osm.c
parent9ba0883cfc5ab69820c05f1bf2b7711bb0a0103c (diff)
[SCSI] aic79xx: remove slave_destroy
Even with the latest fixes aic79xx still occasionally triggers the BUG_ON in slave_destroy. Rather than trying to figure out the various levels of interaction here I've decided to remove the callback altogether. The primary reason for the slave_alloc / slave_destroy is to keep an index of pointers to the sdevs associated with a given target. However, by changing the arguments to the affected functions slightly it's possible to avoid the use of that index entirely. The only performance penalty we'll incur is in writing the information for /proc/scsi/XXX, as we'll have to recurse over all available sdevs to find the correct ones. But I doubt that reading from /proc is in any way time-critical. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aic7xxx/aic79xx_osm.c')
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c62
1 files changed, 12 insertions, 50 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index e0ccdf362200..b244c7124179 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -484,7 +484,6 @@ ahd_linux_target_alloc(struct scsi_target *starget)
484 struct seeprom_config *sc = ahd->seep_config; 484 struct seeprom_config *sc = ahd->seep_config;
485 unsigned long flags; 485 unsigned long flags;
486 struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget); 486 struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
487 struct ahd_linux_target *targ = scsi_transport_target_data(starget);
488 struct ahd_devinfo devinfo; 487 struct ahd_devinfo devinfo;
489 struct ahd_initiator_tinfo *tinfo; 488 struct ahd_initiator_tinfo *tinfo;
490 struct ahd_tmode_tstate *tstate; 489 struct ahd_tmode_tstate *tstate;
@@ -495,7 +494,6 @@ ahd_linux_target_alloc(struct scsi_target *starget)
495 BUG_ON(*ahd_targp != NULL); 494 BUG_ON(*ahd_targp != NULL);
496 495
497 *ahd_targp = starget; 496 *ahd_targp = starget;
498 memset(targ, 0, sizeof(*targ));
499 497
500 if (sc) { 498 if (sc) {
501 int flags = sc->device_flags[starget->id]; 499 int flags = sc->device_flags[starget->id];
@@ -551,15 +549,11 @@ ahd_linux_slave_alloc(struct scsi_device *sdev)
551{ 549{
552 struct ahd_softc *ahd = 550 struct ahd_softc *ahd =
553 *((struct ahd_softc **)sdev->host->hostdata); 551 *((struct ahd_softc **)sdev->host->hostdata);
554 struct scsi_target *starget = sdev->sdev_target;
555 struct ahd_linux_target *targ = scsi_transport_target_data(starget);
556 struct ahd_linux_device *dev; 552 struct ahd_linux_device *dev;
557 553
558 if (bootverbose) 554 if (bootverbose)
559 printf("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id); 555 printf("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id);
560 556
561 BUG_ON(targ->sdev[sdev->lun] != NULL);
562
563 dev = scsi_transport_device_data(sdev); 557 dev = scsi_transport_device_data(sdev);
564 memset(dev, 0, sizeof(*dev)); 558 memset(dev, 0, sizeof(*dev));
565 559
@@ -576,8 +570,6 @@ ahd_linux_slave_alloc(struct scsi_device *sdev)
576 */ 570 */
577 dev->maxtags = 0; 571 dev->maxtags = 0;
578 572
579 targ->sdev[sdev->lun] = sdev;
580
581 return (0); 573 return (0);
582} 574}
583 575
@@ -599,23 +591,6 @@ ahd_linux_slave_configure(struct scsi_device *sdev)
599 return 0; 591 return 0;
600} 592}
601 593
602static void
603ahd_linux_slave_destroy(struct scsi_device *sdev)
604{
605 struct ahd_softc *ahd;
606 struct ahd_linux_device *dev = scsi_transport_device_data(sdev);
607 struct ahd_linux_target *targ = scsi_transport_target_data(sdev->sdev_target);
608
609 ahd = *((struct ahd_softc **)sdev->host->hostdata);
610 if (bootverbose)
611 printf("%s: Slave Destroy %d\n", ahd_name(ahd), sdev->id);
612
613 BUG_ON(dev->active);
614
615 targ->sdev[sdev->lun] = NULL;
616
617}
618
619#if defined(__i386__) 594#if defined(__i386__)
620/* 595/*
621 * Return the disk geometry for the given SCSI device. 596 * Return the disk geometry for the given SCSI device.
@@ -822,7 +797,6 @@ struct scsi_host_template aic79xx_driver_template = {
822 .use_clustering = ENABLE_CLUSTERING, 797 .use_clustering = ENABLE_CLUSTERING,
823 .slave_alloc = ahd_linux_slave_alloc, 798 .slave_alloc = ahd_linux_slave_alloc,
824 .slave_configure = ahd_linux_slave_configure, 799 .slave_configure = ahd_linux_slave_configure,
825 .slave_destroy = ahd_linux_slave_destroy,
826 .target_alloc = ahd_linux_target_alloc, 800 .target_alloc = ahd_linux_target_alloc,
827 .target_destroy = ahd_linux_target_destroy, 801 .target_destroy = ahd_linux_target_destroy,
828}; 802};
@@ -1249,20 +1223,13 @@ void
1249ahd_platform_free(struct ahd_softc *ahd) 1223ahd_platform_free(struct ahd_softc *ahd)
1250{ 1224{
1251 struct scsi_target *starget; 1225 struct scsi_target *starget;
1252 int i, j; 1226 int i;
1253 1227
1254 if (ahd->platform_data != NULL) { 1228 if (ahd->platform_data != NULL) {
1255 /* destroy all of the device and target objects */ 1229 /* destroy all of the device and target objects */
1256 for (i = 0; i < AHD_NUM_TARGETS; i++) { 1230 for (i = 0; i < AHD_NUM_TARGETS; i++) {
1257 starget = ahd->platform_data->starget[i]; 1231 starget = ahd->platform_data->starget[i];
1258 if (starget != NULL) { 1232 if (starget != NULL) {
1259 for (j = 0; j < AHD_NUM_LUNS; j++) {
1260 struct ahd_linux_target *targ =
1261 scsi_transport_target_data(starget);
1262 if (targ->sdev[j] == NULL)
1263 continue;
1264 targ->sdev[j] = NULL;
1265 }
1266 ahd->platform_data->starget[i] = NULL; 1233 ahd->platform_data->starget[i] = NULL;
1267 } 1234 }
1268 } 1235 }
@@ -1318,20 +1285,13 @@ ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
1318} 1285}
1319 1286
1320void 1287void
1321ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, 1288ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
1322 ahd_queue_alg alg) 1289 struct ahd_devinfo *devinfo, ahd_queue_alg alg)
1323{ 1290{
1324 struct scsi_target *starget;
1325 struct ahd_linux_target *targ;
1326 struct ahd_linux_device *dev; 1291 struct ahd_linux_device *dev;
1327 struct scsi_device *sdev;
1328 int was_queuing; 1292 int was_queuing;
1329 int now_queuing; 1293 int now_queuing;
1330 1294
1331 starget = ahd->platform_data->starget[devinfo->target];
1332 targ = scsi_transport_target_data(starget);
1333 BUG_ON(targ == NULL);
1334 sdev = targ->sdev[devinfo->lun];
1335 if (sdev == NULL) 1295 if (sdev == NULL)
1336 return; 1296 return;
1337 1297
@@ -1467,11 +1427,15 @@ ahd_linux_device_queue_depth(struct scsi_device *sdev)
1467 tags = ahd_linux_user_tagdepth(ahd, &devinfo); 1427 tags = ahd_linux_user_tagdepth(ahd, &devinfo);
1468 if (tags != 0 && sdev->tagged_supported != 0) { 1428 if (tags != 0 && sdev->tagged_supported != 0) {
1469 1429
1470 ahd_set_tags(ahd, &devinfo, AHD_QUEUE_TAGGED); 1430 ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_TAGGED);
1431 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1432 devinfo.lun, AC_TRANSFER_NEG);
1471 ahd_print_devinfo(ahd, &devinfo); 1433 ahd_print_devinfo(ahd, &devinfo);
1472 printf("Tagged Queuing enabled. Depth %d\n", tags); 1434 printf("Tagged Queuing enabled. Depth %d\n", tags);
1473 } else { 1435 } else {
1474 ahd_set_tags(ahd, &devinfo, AHD_QUEUE_NONE); 1436 ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_NONE);
1437 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1438 devinfo.lun, AC_TRANSFER_NEG);
1475 } 1439 }
1476} 1440}
1477 1441
@@ -1629,7 +1593,7 @@ ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
1629 1593
1630void 1594void
1631ahd_send_async(struct ahd_softc *ahd, char channel, 1595ahd_send_async(struct ahd_softc *ahd, char channel,
1632 u_int target, u_int lun, ac_code code, void *arg) 1596 u_int target, u_int lun, ac_code code)
1633{ 1597{
1634 switch (code) { 1598 switch (code) {
1635 case AC_TRANSFER_NEG: 1599 case AC_TRANSFER_NEG:
@@ -1956,7 +1920,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
1956 } 1920 }
1957 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); 1921 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
1958 ahd_set_scsi_status(scb, SCSI_STATUS_OK); 1922 ahd_set_scsi_status(scb, SCSI_STATUS_OK);
1959 ahd_platform_set_tags(ahd, &devinfo, 1923 ahd_platform_set_tags(ahd, sdev, &devinfo,
1960 (dev->flags & AHD_DEV_Q_BASIC) 1924 (dev->flags & AHD_DEV_Q_BASIC)
1961 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); 1925 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
1962 break; 1926 break;
@@ -1966,7 +1930,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
1966 * as if the target returned BUSY SCSI status. 1930 * as if the target returned BUSY SCSI status.
1967 */ 1931 */
1968 dev->openings = 1; 1932 dev->openings = 1;
1969 ahd_platform_set_tags(ahd, &devinfo, 1933 ahd_platform_set_tags(ahd, sdev, &devinfo,
1970 (dev->flags & AHD_DEV_Q_BASIC) 1934 (dev->flags & AHD_DEV_Q_BASIC)
1971 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); 1935 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
1972 ahd_set_scsi_status(scb, SCSI_STATUS_BUSY); 1936 ahd_set_scsi_status(scb, SCSI_STATUS_BUSY);
@@ -2778,8 +2742,6 @@ ahd_linux_init(void)
2778 if (!ahd_linux_transport_template) 2742 if (!ahd_linux_transport_template)
2779 return -ENODEV; 2743 return -ENODEV;
2780 2744
2781 scsi_transport_reserve_target(ahd_linux_transport_template,
2782 sizeof(struct ahd_linux_target));
2783 scsi_transport_reserve_device(ahd_linux_transport_template, 2745 scsi_transport_reserve_device(ahd_linux_transport_template,
2784 sizeof(struct ahd_linux_device)); 2746 sizeof(struct ahd_linux_device));
2785 2747