aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-disk.c85
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 = &ltf;
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)) {