diff options
author | Hannes Reinecke <hare@suse.de> | 2006-06-22 05:45:00 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-06-26 10:59:18 -0400 |
commit | f89d0a4e1d01168f20f9e8273de7dfc094b2a430 (patch) | |
tree | 192535b673233f57fa7617b99ce593892957cb2f /drivers/scsi/aic7xxx/aic79xx_osm.c | |
parent | 9ba0883cfc5ab69820c05f1bf2b7711bb0a0103c (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.c | 62 |
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 | ||
602 | static void | ||
603 | ahd_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 | |||
1249 | ahd_platform_free(struct ahd_softc *ahd) | 1223 | ahd_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 | ||
1320 | void | 1287 | void |
1321 | ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | 1288 | ahd_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 | ||
1630 | void | 1594 | void |
1631 | ahd_send_async(struct ahd_softc *ahd, char channel, | 1595 | ahd_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 | ||