diff options
author | Tejun Heo <htejun@gmail.com> | 2006-04-02 04:54:47 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-02 10:02:58 -0400 |
commit | 565083e1f14e7771aa6bac2d3d4aae0b08d48d78 (patch) | |
tree | 8e6a81175297d3d03aa1eede59fcb635d65380e2 | |
parent | 14d2bac1877ed4e2cc940d1680db1a4f29225811 (diff) |
[PATCH] libata: consider disabled devices in ata_dev_xfermask()
ata_bus_probe() now marks failed devices properly and leaves
meaningful transfer mode masks. This patch makes ata_dev_xfermask()
consider disable devices when determining PIO mode to avoid violating
device selection timing.
While at it, move port-wide resttriction out of device iteration loop
and try to make the function look a bit prettier.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/scsi/libata-core.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 33b5bff58cc3..00018705582b 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -2913,23 +2913,34 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) | |||
2913 | unsigned long xfer_mask; | 2913 | unsigned long xfer_mask; |
2914 | int i; | 2914 | int i; |
2915 | 2915 | ||
2916 | xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, | 2916 | xfer_mask = ata_pack_xfermask(ap->pio_mask, |
2917 | ap->udma_mask); | 2917 | ap->mwdma_mask, ap->udma_mask); |
2918 | |||
2919 | /* Apply cable rule here. Don't apply it early because when | ||
2920 | * we handle hot plug the cable type can itself change. | ||
2921 | */ | ||
2922 | if (ap->cbl == ATA_CBL_PATA40) | ||
2923 | xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); | ||
2918 | 2924 | ||
2919 | /* FIXME: Use port-wide xfermask for now */ | 2925 | /* FIXME: Use port-wide xfermask for now */ |
2920 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 2926 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
2921 | struct ata_device *d = &ap->device[i]; | 2927 | struct ata_device *d = &ap->device[i]; |
2922 | if (!ata_dev_enabled(d)) | 2928 | |
2929 | if (ata_dev_absent(d)) | ||
2930 | continue; | ||
2931 | |||
2932 | if (ata_dev_disabled(d)) { | ||
2933 | /* to avoid violating device selection timing */ | ||
2934 | xfer_mask &= ata_pack_xfermask(d->pio_mask, | ||
2935 | UINT_MAX, UINT_MAX); | ||
2923 | continue; | 2936 | continue; |
2924 | xfer_mask &= ata_pack_xfermask(d->pio_mask, d->mwdma_mask, | 2937 | } |
2925 | d->udma_mask); | 2938 | |
2939 | xfer_mask &= ata_pack_xfermask(d->pio_mask, | ||
2940 | d->mwdma_mask, d->udma_mask); | ||
2926 | xfer_mask &= ata_id_xfermask(d->id); | 2941 | xfer_mask &= ata_id_xfermask(d->id); |
2927 | if (ata_dma_blacklisted(d)) | 2942 | if (ata_dma_blacklisted(d)) |
2928 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | 2943 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); |
2929 | /* Apply cable rule here. Don't apply it early because when | ||
2930 | we handle hot plug the cable type can itself change */ | ||
2931 | if (ap->cbl == ATA_CBL_PATA40) | ||
2932 | xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); | ||
2933 | } | 2944 | } |
2934 | 2945 | ||
2935 | if (ata_dma_blacklisted(dev)) | 2946 | if (ata_dma_blacklisted(dev)) |
@@ -2940,11 +2951,12 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) | |||
2940 | if (hs->simplex_claimed) | 2951 | if (hs->simplex_claimed) |
2941 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | 2952 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); |
2942 | } | 2953 | } |
2954 | |||
2943 | if (ap->ops->mode_filter) | 2955 | if (ap->ops->mode_filter) |
2944 | xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask); | 2956 | xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask); |
2945 | 2957 | ||
2946 | ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, | 2958 | ata_unpack_xfermask(xfer_mask, &dev->pio_mask, |
2947 | &dev->udma_mask); | 2959 | &dev->mwdma_mask, &dev->udma_mask); |
2948 | } | 2960 | } |
2949 | 2961 | ||
2950 | /** | 2962 | /** |