diff options
-rw-r--r-- | drivers/ide/ide-disk.c | 85 |
1 files changed, 42 insertions, 43 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 9b63e15d67e2..20d357e9329d 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -140,6 +140,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
140 | u8 lba48 = (drive->addressing == 1) ? 1 : 0; | 140 | u8 lba48 = (drive->addressing == 1) ? 1 : 0; |
141 | u8 command = WIN_NOP; | 141 | u8 command = WIN_NOP; |
142 | ata_nsector_t nsectors; | 142 | ata_nsector_t nsectors; |
143 | struct ide_taskfile ltf, *tf = <f; | ||
143 | 144 | ||
144 | nsectors.all = (u16) rq->nr_sectors; | 145 | nsectors.all = (u16) rq->nr_sectors; |
145 | 146 | ||
@@ -160,53 +161,36 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
160 | 161 | ||
161 | /* FIXME: SELECT_MASK(drive, 0) ? */ | 162 | /* FIXME: SELECT_MASK(drive, 0) ? */ |
162 | 163 | ||
164 | memset(tf, 0, sizeof(*tf)); | ||
165 | |||
163 | if (drive->select.b.lba) { | 166 | if (drive->select.b.lba) { |
164 | if (lba48) { | 167 | if (lba48) { |
165 | u8 tasklets[10]; | ||
166 | |||
167 | pr_debug("%s: LBA=0x%012llx\n", drive->name, | 168 | pr_debug("%s: LBA=0x%012llx\n", drive->name, |
168 | (unsigned long long)block); | 169 | (unsigned long long)block); |
169 | 170 | ||
170 | tasklets[0] = 0; | 171 | tf->hob_nsect = nsectors.b.high; |
171 | tasklets[1] = 0; | 172 | tf->hob_lbal = (u8)(block >> 24); |
172 | tasklets[2] = nsectors.b.low; | 173 | if (sizeof(block) != 4) { |
173 | tasklets[3] = nsectors.b.high; | 174 | tf->hob_lbam = (u8)((u64)block >> 32); |
174 | tasklets[4] = (u8) block; | 175 | tf->hob_lbah = (u8)((u64)block >> 40); |
175 | tasklets[5] = (u8)(block >> 8); | ||
176 | tasklets[6] = (u8)(block >> 16); | ||
177 | tasklets[7] = (u8)(block >> 24); | ||
178 | if (sizeof(block) == 4) { | ||
179 | tasklets[8] = 0; | ||
180 | tasklets[9] = 0; | ||
181 | } else { | ||
182 | tasklets[8] = (u8)((u64)block >> 32); | ||
183 | tasklets[9] = (u8)((u64)block >> 40); | ||
184 | } | 176 | } |
177 | |||
178 | tf->nsect = nsectors.b.low; | ||
179 | tf->lbal = (u8) block; | ||
180 | tf->lbam = (u8)(block >> 8); | ||
181 | tf->lbah = (u8)(block >> 16); | ||
185 | #ifdef DEBUG | 182 | #ifdef DEBUG |
186 | printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n", | 183 | printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n", |
187 | drive->name, tasklets[3], tasklets[2], | 184 | drive->name, tf->hob_nsect, tf->nsect, |
188 | tasklets[9], tasklets[8], tasklets[7], | 185 | tf->hob_lbah, tf->hob_lbam, tf->hob_lbal, |
189 | tasklets[6], tasklets[5], tasklets[4]); | 186 | tf->lbah, tf->lbam, tf->lbal); |
190 | #endif | 187 | #endif |
191 | hwif->OUTB(tasklets[1], IDE_FEATURE_REG); | ||
192 | hwif->OUTB(tasklets[3], IDE_NSECTOR_REG); | ||
193 | hwif->OUTB(tasklets[7], IDE_SECTOR_REG); | ||
194 | hwif->OUTB(tasklets[8], IDE_LCYL_REG); | ||
195 | hwif->OUTB(tasklets[9], IDE_HCYL_REG); | ||
196 | |||
197 | hwif->OUTB(tasklets[0], IDE_FEATURE_REG); | ||
198 | hwif->OUTB(tasklets[2], IDE_NSECTOR_REG); | ||
199 | hwif->OUTB(tasklets[4], IDE_SECTOR_REG); | ||
200 | hwif->OUTB(tasklets[5], IDE_LCYL_REG); | ||
201 | hwif->OUTB(tasklets[6], IDE_HCYL_REG); | ||
202 | hwif->OUTB(0x00|drive->select.all,IDE_SELECT_REG); | ||
203 | } else { | 188 | } else { |
204 | hwif->OUTB(0x00, IDE_FEATURE_REG); | 189 | tf->nsect = nsectors.b.low; |
205 | hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG); | 190 | tf->lbal = block; |
206 | hwif->OUTB(block, IDE_SECTOR_REG); | 191 | tf->lbam = block >>= 8; |
207 | hwif->OUTB(block>>=8, IDE_LCYL_REG); | 192 | tf->lbah = block >>= 8; |
208 | hwif->OUTB(block>>=8, IDE_HCYL_REG); | 193 | tf->device = (block >> 8) & 0xf; |
209 | hwif->OUTB(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG); | ||
210 | } | 194 | } |
211 | } else { | 195 | } else { |
212 | unsigned int sect,head,cyl,track; | 196 | unsigned int sect,head,cyl,track; |
@@ -217,14 +201,29 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
217 | 201 | ||
218 | pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect); | 202 | pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect); |
219 | 203 | ||
220 | hwif->OUTB(0x00, IDE_FEATURE_REG); | 204 | tf->nsect = nsectors.b.low; |
221 | hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG); | 205 | tf->lbal = sect; |
222 | hwif->OUTB(sect, IDE_SECTOR_REG); | 206 | tf->lbam = cyl; |
223 | hwif->OUTB(cyl, IDE_LCYL_REG); | 207 | tf->lbah = cyl >> 8; |
224 | hwif->OUTB(cyl>>8, IDE_HCYL_REG); | 208 | tf->device = head; |
225 | hwif->OUTB(head|drive->select.all,IDE_SELECT_REG); | ||
226 | } | 209 | } |
227 | 210 | ||
211 | if (drive->select.b.lba && lba48) { | ||
212 | hwif->OUTB(tf->hob_feature, IDE_FEATURE_REG); | ||
213 | hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG); | ||
214 | hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG); | ||
215 | hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG); | ||
216 | hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG); | ||
217 | } | ||
218 | |||
219 | hwif->OUTB(tf->feature, IDE_FEATURE_REG); | ||
220 | hwif->OUTB(tf->nsect, IDE_NSECTOR_REG); | ||
221 | hwif->OUTB(tf->lbal, IDE_SECTOR_REG); | ||
222 | hwif->OUTB(tf->lbam, IDE_LCYL_REG); | ||
223 | hwif->OUTB(tf->lbah, IDE_HCYL_REG); | ||
224 | |||
225 | hwif->OUTB(tf->device | drive->select.all, IDE_SELECT_REG); | ||
226 | |||
228 | if (dma) { | 227 | if (dma) { |
229 | if (!hwif->dma_setup(drive)) { | 228 | if (!hwif->dma_setup(drive)) { |
230 | if (rq_data_dir(rq)) { | 229 | if (rq_data_dir(rq)) { |