aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-lib.c')
-rw-r--r--drivers/ide/ide-lib.c125
1 files changed, 73 insertions, 52 deletions
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 850ef63cc986..8237d89eec6e 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -71,75 +71,96 @@ EXPORT_SYMBOL(ide_xfer_verbose);
71/** 71/**
72 * ide_dma_speed - compute DMA speed 72 * ide_dma_speed - compute DMA speed
73 * @drive: drive 73 * @drive: drive
74 * @mode; intended mode 74 * @mode: modes available
75 * 75 *
76 * Checks the drive capabilities and returns the speed to use 76 * Checks the drive capabilities and returns the speed to use
77 * for the transfer. Returns -1 if the requested mode is unknown 77 * for the DMA transfer. Returns 0 if the drive is incapable
78 * (eg PIO) 78 * of DMA transfers.
79 */ 79 */
80 80
81u8 ide_dma_speed(ide_drive_t *drive, u8 mode) 81u8 ide_dma_speed(ide_drive_t *drive, u8 mode)
82{ 82{
83 struct hd_driveid *id = drive->id; 83 struct hd_driveid *id = drive->id;
84 ide_hwif_t *hwif = HWIF(drive); 84 ide_hwif_t *hwif = HWIF(drive);
85 u8 ultra_mask, mwdma_mask, swdma_mask;
85 u8 speed = 0; 86 u8 speed = 0;
86 87
87 if (drive->media != ide_disk && hwif->atapi_dma == 0) 88 if (drive->media != ide_disk && hwif->atapi_dma == 0)
88 return 0; 89 return 0;
89 90
90 switch(mode) { 91 /* Capable of UltraDMA modes? */
91 case 0x04: 92 ultra_mask = id->dma_ultra & hwif->ultra_mask;
92 if ((id->dma_ultra & 0x0040) && 93
93 (id->dma_ultra & hwif->ultra_mask)) 94 if (!(id->field_valid & 4))
94 { speed = XFER_UDMA_6; break; } 95 mode = 0; /* fallback to MW/SW DMA if no UltraDMA */
95 case 0x03: 96
96 if ((id->dma_ultra & 0x0020) && 97 switch (mode) {
97 (id->dma_ultra & hwif->ultra_mask)) 98 case 4:
98 { speed = XFER_UDMA_5; break; } 99 if (ultra_mask & 0x40) {
99 case 0x02: 100 speed = XFER_UDMA_6;
100 if ((id->dma_ultra & 0x0010) && 101 break;
101 (id->dma_ultra & hwif->ultra_mask)) 102 }
102 { speed = XFER_UDMA_4; break; } 103 case 3:
103 if ((id->dma_ultra & 0x0008) && 104 if (ultra_mask & 0x20) {
104 (id->dma_ultra & hwif->ultra_mask)) 105 speed = XFER_UDMA_5;
105 { speed = XFER_UDMA_3; break; } 106 break;
106 case 0x01: 107 }
107 if ((id->dma_ultra & 0x0004) && 108 case 2:
108 (id->dma_ultra & hwif->ultra_mask)) 109 if (ultra_mask & 0x10) {
109 { speed = XFER_UDMA_2; break; } 110 speed = XFER_UDMA_4;
110 if ((id->dma_ultra & 0x0002) && 111 break;
111 (id->dma_ultra & hwif->ultra_mask)) 112 }
112 { speed = XFER_UDMA_1; break; } 113 if (ultra_mask & 0x08) {
113 if ((id->dma_ultra & 0x0001) && 114 speed = XFER_UDMA_3;
114 (id->dma_ultra & hwif->ultra_mask)) 115 break;
115 { speed = XFER_UDMA_0; break; } 116 }
116 case 0x00: 117 case 1:
117 if ((id->dma_mword & 0x0004) && 118 if (ultra_mask & 0x04) {
118 (id->dma_mword & hwif->mwdma_mask)) 119 speed = XFER_UDMA_2;
119 { speed = XFER_MW_DMA_2; break; } 120 break;
120 if ((id->dma_mword & 0x0002) && 121 }
121 (id->dma_mword & hwif->mwdma_mask)) 122 if (ultra_mask & 0x02) {
122 { speed = XFER_MW_DMA_1; break; } 123 speed = XFER_UDMA_1;
123 if ((id->dma_mword & 0x0001) && 124 break;
124 (id->dma_mword & hwif->mwdma_mask)) 125 }
125 { speed = XFER_MW_DMA_0; break; } 126 if (ultra_mask & 0x01) {
126 if ((id->dma_1word & 0x0004) && 127 speed = XFER_UDMA_0;
127 (id->dma_1word & hwif->swdma_mask)) 128 break;
128 { speed = XFER_SW_DMA_2; break; } 129 }
129 if ((id->dma_1word & 0x0002) && 130 case 0:
130 (id->dma_1word & hwif->swdma_mask)) 131 mwdma_mask = id->dma_mword & hwif->mwdma_mask;
131 { speed = XFER_SW_DMA_1; break; }
132 if ((id->dma_1word & 0x0001) &&
133 (id->dma_1word & hwif->swdma_mask))
134 { speed = XFER_SW_DMA_0; break; }
135 }
136 132
137// printk("%s: %s: mode 0x%02x, speed 0x%02x\n", 133 if (mwdma_mask & 0x04) {
138// __FUNCTION__, drive->name, mode, speed); 134 speed = XFER_MW_DMA_2;
135 break;
136 }
137 if (mwdma_mask & 0x02) {
138 speed = XFER_MW_DMA_1;
139 break;
140 }
141 if (mwdma_mask & 0x01) {
142 speed = XFER_MW_DMA_0;
143 break;
144 }
145
146 swdma_mask = id->dma_1word & hwif->swdma_mask;
147
148 if (swdma_mask & 0x04) {
149 speed = XFER_SW_DMA_2;
150 break;
151 }
152 if (swdma_mask & 0x02) {
153 speed = XFER_SW_DMA_1;
154 break;
155 }
156 if (swdma_mask & 0x01) {
157 speed = XFER_SW_DMA_0;
158 break;
159 }
160 }
139 161
140 return speed; 162 return speed;
141} 163}
142
143EXPORT_SYMBOL(ide_dma_speed); 164EXPORT_SYMBOL(ide_dma_speed);
144 165
145 166