aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-io.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 16:57:26 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 16:57:26 -0500
commitf31c338675872875e24f124af0689131b0c72600 (patch)
treecf12b28d52da1675ab32871abd2db455ffbfe920 /drivers/ide/ide-io.c
parent0008bf54408d4c0637c24d34642f1038c299be95 (diff)
parent61a368c216897aa3bbee35b3f2e6db76ec73fad0 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (67 commits) ide: remove redundant DMA blacklist check from __ide_dma_on() ide: cleanup ide_set_dma() ide: remove redundant ->ide_dma_on call from set_using_dma() sc1200: move DMA timings to timing tables ide: add IDE_HFLAG_ABUSE_SET_DMA_MODE host flag sis5513: factor out UDMA programming code pdc202xx_new: move PIO programming code to pdcnew_set_pio_mode() ide: make 'extra' field in struct ide_port_info u8 ide: kill duplicate code in ide_dump_{ata,atapi}_status() ide-disk: use ide_get_lba_addr() ide: printk fix ide: add ide_tf_read() helper ide: fix registers loading order in ide_dump_ata_status() ide-disk: use do_rw_taskfile() (take 2) ide-disk: add ide_tf_set_cmd() helper ide-disk: extend timeout for PIO-in commands ide: remove 'handler' field from ide_task_t (take 2) ide: use ->data_phase to set ->handler in do_rw_taskfile() ide: convert do_rw_taskfile() to use ->data_phase ide: merge flagged_taskfile() into do_rw_taskfile() ...
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r--drivers/ide/ide-io.c293
1 files changed, 139 insertions, 154 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index bef781fec500..2711b5a6962d 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -189,18 +189,14 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
189 return ide_stopped; 189 return ide_stopped;
190 } 190 }
191 if (ide_id_has_flush_cache_ext(drive->id)) 191 if (ide_id_has_flush_cache_ext(drive->id))
192 args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT; 192 args->tf.command = WIN_FLUSH_CACHE_EXT;
193 else 193 else
194 args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE; 194 args->tf.command = WIN_FLUSH_CACHE;
195 args->command_type = IDE_DRIVE_TASK_NO_DATA; 195 goto out_do_tf;
196 args->handler = &task_no_data_intr;
197 return do_rw_taskfile(drive, args);
198 196
199 case idedisk_pm_standby: /* Suspend step 2 (standby) */ 197 case idedisk_pm_standby: /* Suspend step 2 (standby) */
200 args->tfRegister[IDE_COMMAND_OFFSET] = WIN_STANDBYNOW1; 198 args->tf.command = WIN_STANDBYNOW1;
201 args->command_type = IDE_DRIVE_TASK_NO_DATA; 199 goto out_do_tf;
202 args->handler = &task_no_data_intr;
203 return do_rw_taskfile(drive, args);
204 200
205 case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */ 201 case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */
206 ide_set_max_pio(drive); 202 ide_set_max_pio(drive);
@@ -214,10 +210,8 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
214 return ide_stopped; 210 return ide_stopped;
215 211
216 case idedisk_pm_idle: /* Resume step 2 (idle) */ 212 case idedisk_pm_idle: /* Resume step 2 (idle) */
217 args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE; 213 args->tf.command = WIN_IDLEIMMEDIATE;
218 args->command_type = IDE_DRIVE_TASK_NO_DATA; 214 goto out_do_tf;
219 args->handler = task_no_data_intr;
220 return do_rw_taskfile(drive, args);
221 215
222 case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */ 216 case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */
223 /* 217 /*
@@ -227,7 +221,6 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
227 */ 221 */
228 if (drive->hwif->ide_dma_on == NULL) 222 if (drive->hwif->ide_dma_on == NULL)
229 break; 223 break;
230 drive->hwif->dma_off_quietly(drive);
231 /* 224 /*
232 * TODO: respect ->using_dma setting 225 * TODO: respect ->using_dma setting
233 */ 226 */
@@ -236,6 +229,11 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
236 } 229 }
237 pm->pm_step = ide_pm_state_completed; 230 pm->pm_step = ide_pm_state_completed;
238 return ide_stopped; 231 return ide_stopped;
232
233out_do_tf:
234 args->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
235 args->data_phase = TASKFILE_NO_DATA;
236 return do_rw_taskfile(drive, args);
239} 237}
240 238
241/** 239/**
@@ -298,6 +296,48 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
298 spin_unlock_irqrestore(&ide_lock, flags); 296 spin_unlock_irqrestore(&ide_lock, flags);
299} 297}
300 298
299void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
300{
301 ide_hwif_t *hwif = drive->hwif;
302 struct ide_taskfile *tf = &task->tf;
303
304 if (task->tf_flags & IDE_TFLAG_IN_DATA) {
305 u16 data = hwif->INW(IDE_DATA_REG);
306
307 tf->data = data & 0xff;
308 tf->hob_data = (data >> 8) & 0xff;
309 }
310
311 /* be sure we're looking at the low order bits */
312 hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
313
314 if (task->tf_flags & IDE_TFLAG_IN_NSECT)
315 tf->nsect = hwif->INB(IDE_NSECTOR_REG);
316 if (task->tf_flags & IDE_TFLAG_IN_LBAL)
317 tf->lbal = hwif->INB(IDE_SECTOR_REG);
318 if (task->tf_flags & IDE_TFLAG_IN_LBAM)
319 tf->lbam = hwif->INB(IDE_LCYL_REG);
320 if (task->tf_flags & IDE_TFLAG_IN_LBAH)
321 tf->lbah = hwif->INB(IDE_HCYL_REG);
322 if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
323 tf->device = hwif->INB(IDE_SELECT_REG);
324
325 if (task->tf_flags & IDE_TFLAG_LBA48) {
326 hwif->OUTB(drive->ctl | 0x80, IDE_CONTROL_REG);
327
328 if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
329 tf->hob_feature = hwif->INB(IDE_FEATURE_REG);
330 if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
331 tf->hob_nsect = hwif->INB(IDE_NSECTOR_REG);
332 if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
333 tf->hob_lbal = hwif->INB(IDE_SECTOR_REG);
334 if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
335 tf->hob_lbam = hwif->INB(IDE_LCYL_REG);
336 if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
337 tf->hob_lbah = hwif->INB(IDE_HCYL_REG);
338 }
339}
340
301/** 341/**
302 * ide_end_drive_cmd - end an explicit drive command 342 * ide_end_drive_cmd - end an explicit drive command
303 * @drive: command 343 * @drive: command
@@ -332,51 +372,22 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
332 args[1] = err; 372 args[1] = err;
333 args[2] = hwif->INB(IDE_NSECTOR_REG); 373 args[2] = hwif->INB(IDE_NSECTOR_REG);
334 } 374 }
335 } else if (rq->cmd_type == REQ_TYPE_ATA_TASK) {
336 u8 *args = (u8 *) rq->buffer;
337 if (rq->errors == 0)
338 rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
339
340 if (args) {
341 args[0] = stat;
342 args[1] = err;
343 /* be sure we're looking at the low order bits */
344 hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
345 args[2] = hwif->INB(IDE_NSECTOR_REG);
346 args[3] = hwif->INB(IDE_SECTOR_REG);
347 args[4] = hwif->INB(IDE_LCYL_REG);
348 args[5] = hwif->INB(IDE_HCYL_REG);
349 args[6] = hwif->INB(IDE_SELECT_REG);
350 }
351 } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { 375 } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
352 ide_task_t *args = (ide_task_t *) rq->special; 376 ide_task_t *args = (ide_task_t *) rq->special;
353 if (rq->errors == 0) 377 if (rq->errors == 0)
354 rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); 378 rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
355 379
356 if (args) { 380 if (args) {
357 if (args->tf_in_flags.b.data) { 381 struct ide_taskfile *tf = &args->tf;
358 u16 data = hwif->INW(IDE_DATA_REG); 382
359 args->tfRegister[IDE_DATA_OFFSET] = (data) & 0xFF; 383 tf->error = err;
360 args->hobRegister[IDE_DATA_OFFSET] = (data >> 8) & 0xFF; 384 tf->status = stat;
361 } 385
362 args->tfRegister[IDE_ERROR_OFFSET] = err; 386 args->tf_flags |= (IDE_TFLAG_IN_TF|IDE_TFLAG_IN_DEVICE);
363 /* be sure we're looking at the low order bits */ 387 if (args->tf_flags & IDE_TFLAG_LBA48)
364 hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG); 388 args->tf_flags |= IDE_TFLAG_IN_HOB;
365 args->tfRegister[IDE_NSECTOR_OFFSET] = hwif->INB(IDE_NSECTOR_REG); 389
366 args->tfRegister[IDE_SECTOR_OFFSET] = hwif->INB(IDE_SECTOR_REG); 390 ide_tf_read(drive, args);
367 args->tfRegister[IDE_LCYL_OFFSET] = hwif->INB(IDE_LCYL_REG);
368 args->tfRegister[IDE_HCYL_OFFSET] = hwif->INB(IDE_HCYL_REG);
369 args->tfRegister[IDE_SELECT_OFFSET] = hwif->INB(IDE_SELECT_REG);
370 args->tfRegister[IDE_STATUS_OFFSET] = stat;
371
372 if (drive->addressing == 1) {
373 hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
374 args->hobRegister[IDE_FEATURE_OFFSET] = hwif->INB(IDE_FEATURE_REG);
375 args->hobRegister[IDE_NSECTOR_OFFSET] = hwif->INB(IDE_NSECTOR_REG);
376 args->hobRegister[IDE_SECTOR_OFFSET] = hwif->INB(IDE_SECTOR_REG);
377 args->hobRegister[IDE_LCYL_OFFSET] = hwif->INB(IDE_LCYL_REG);
378 args->hobRegister[IDE_HCYL_OFFSET] = hwif->INB(IDE_HCYL_REG);
379 }
380 } 391 }
381 } else if (blk_pm_request(rq)) { 392 } else if (blk_pm_request(rq)) {
382 struct request_pm_state *pm = rq->data; 393 struct request_pm_state *pm = rq->data;
@@ -616,28 +627,6 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg)
616} 627}
617 628
618/** 629/**
619 * ide_cmd - issue a simple drive command
620 * @drive: drive the command is for
621 * @cmd: command byte
622 * @nsect: sector byte
623 * @handler: handler for the command completion
624 *
625 * Issue a simple drive command with interrupts.
626 * The drive must be selected beforehand.
627 */
628
629static void ide_cmd (ide_drive_t *drive, u8 cmd, u8 nsect,
630 ide_handler_t *handler)
631{
632 ide_hwif_t *hwif = HWIF(drive);
633 if (IDE_CONTROL_REG)
634 hwif->OUTB(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */
635 SELECT_MASK(drive,0);
636 hwif->OUTB(nsect,IDE_NSECTOR_REG);
637 ide_execute_command(drive, cmd, handler, WAIT_CMD, NULL);
638}
639
640/**
641 * drive_cmd_intr - drive command completion interrupt 630 * drive_cmd_intr - drive command completion interrupt
642 * @drive: drive the completion interrupt occurred on 631 * @drive: drive the completion interrupt occurred on
643 * 632 *
@@ -673,32 +662,26 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
673 return ide_stopped; 662 return ide_stopped;
674} 663}
675 664
676static void ide_init_specify_cmd(ide_drive_t *drive, ide_task_t *task) 665static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
677{ 666{
678 task->tfRegister[IDE_NSECTOR_OFFSET] = drive->sect; 667 tf->nsect = drive->sect;
679 task->tfRegister[IDE_SECTOR_OFFSET] = drive->sect; 668 tf->lbal = drive->sect;
680 task->tfRegister[IDE_LCYL_OFFSET] = drive->cyl; 669 tf->lbam = drive->cyl;
681 task->tfRegister[IDE_HCYL_OFFSET] = drive->cyl>>8; 670 tf->lbah = drive->cyl >> 8;
682 task->tfRegister[IDE_SELECT_OFFSET] = ((drive->head-1)|drive->select.all)&0xBF; 671 tf->device = ((drive->head - 1) | drive->select.all) & ~ATA_LBA;
683 task->tfRegister[IDE_COMMAND_OFFSET] = WIN_SPECIFY; 672 tf->command = WIN_SPECIFY;
684
685 task->handler = &set_geometry_intr;
686} 673}
687 674
688static void ide_init_restore_cmd(ide_drive_t *drive, ide_task_t *task) 675static void ide_tf_set_restore_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
689{ 676{
690 task->tfRegister[IDE_NSECTOR_OFFSET] = drive->sect; 677 tf->nsect = drive->sect;
691 task->tfRegister[IDE_COMMAND_OFFSET] = WIN_RESTORE; 678 tf->command = WIN_RESTORE;
692
693 task->handler = &recal_intr;
694} 679}
695 680
696static void ide_init_setmult_cmd(ide_drive_t *drive, ide_task_t *task) 681static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
697{ 682{
698 task->tfRegister[IDE_NSECTOR_OFFSET] = drive->mult_req; 683 tf->nsect = drive->mult_req;
699 task->tfRegister[IDE_COMMAND_OFFSET] = WIN_SETMULT; 684 tf->command = WIN_SETMULT;
700
701 task->handler = &set_multmode_intr;
702} 685}
703 686
704static ide_startstop_t ide_disk_special(ide_drive_t *drive) 687static ide_startstop_t ide_disk_special(ide_drive_t *drive)
@@ -707,19 +690,19 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
707 ide_task_t args; 690 ide_task_t args;
708 691
709 memset(&args, 0, sizeof(ide_task_t)); 692 memset(&args, 0, sizeof(ide_task_t));
710 args.command_type = IDE_DRIVE_TASK_NO_DATA; 693 args.data_phase = TASKFILE_NO_DATA;
711 694
712 if (s->b.set_geometry) { 695 if (s->b.set_geometry) {
713 s->b.set_geometry = 0; 696 s->b.set_geometry = 0;
714 ide_init_specify_cmd(drive, &args); 697 ide_tf_set_specify_cmd(drive, &args.tf);
715 } else if (s->b.recalibrate) { 698 } else if (s->b.recalibrate) {
716 s->b.recalibrate = 0; 699 s->b.recalibrate = 0;
717 ide_init_restore_cmd(drive, &args); 700 ide_tf_set_restore_cmd(drive, &args.tf);
718 } else if (s->b.set_multmode) { 701 } else if (s->b.set_multmode) {
719 s->b.set_multmode = 0; 702 s->b.set_multmode = 0;
720 if (drive->mult_req > drive->id->max_multsect) 703 if (drive->mult_req > drive->id->max_multsect)
721 drive->mult_req = drive->id->max_multsect; 704 drive->mult_req = drive->id->max_multsect;
722 ide_init_setmult_cmd(drive, &args); 705 ide_tf_set_setmult_cmd(drive, &args.tf);
723 } else if (s->all) { 706 } else if (s->all) {
724 int special = s->all; 707 int special = s->all;
725 s->all = 0; 708 s->all = 0;
@@ -727,6 +710,9 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
727 return ide_stopped; 710 return ide_stopped;
728 } 711 }
729 712
713 args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
714 IDE_TFLAG_CUSTOM_HANDLER;
715
730 do_rw_taskfile(drive, &args); 716 do_rw_taskfile(drive, &args);
731 717
732 return ide_started; 718 return ide_started;
@@ -861,13 +847,17 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
861 struct request *rq) 847 struct request *rq)
862{ 848{
863 ide_hwif_t *hwif = HWIF(drive); 849 ide_hwif_t *hwif = HWIF(drive);
850 u8 *args = rq->buffer;
851 ide_task_t ltask;
852 struct ide_taskfile *tf = &ltask.tf;
853
864 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { 854 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
865 ide_task_t *args = rq->special; 855 ide_task_t *task = rq->special;
866 856
867 if (!args) 857 if (task == NULL)
868 goto done; 858 goto done;
869 859
870 hwif->data_phase = args->data_phase; 860 hwif->data_phase = task->data_phase;
871 861
872 switch (hwif->data_phase) { 862 switch (hwif->data_phase) {
873 case TASKFILE_MULTI_OUT: 863 case TASKFILE_MULTI_OUT:
@@ -880,55 +870,34 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
880 break; 870 break;
881 } 871 }
882 872
883 if (args->tf_out_flags.all != 0) 873 return do_rw_taskfile(drive, task);
884 return flagged_taskfile(drive, args); 874 }
885 return do_rw_taskfile(drive, args); 875
886 } else if (rq->cmd_type == REQ_TYPE_ATA_TASK) { 876 if (args == NULL)
887 u8 *args = rq->buffer; 877 goto done;
888 878
889 if (!args) 879 memset(&ltask, 0, sizeof(ltask));
890 goto done; 880 if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
891#ifdef DEBUG
892 printk("%s: DRIVE_TASK_CMD ", drive->name);
893 printk("cmd=0x%02x ", args[0]);
894 printk("fr=0x%02x ", args[1]);
895 printk("ns=0x%02x ", args[2]);
896 printk("sc=0x%02x ", args[3]);
897 printk("lcyl=0x%02x ", args[4]);
898 printk("hcyl=0x%02x ", args[5]);
899 printk("sel=0x%02x\n", args[6]);
900#endif
901 hwif->OUTB(args[1], IDE_FEATURE_REG);
902 hwif->OUTB(args[3], IDE_SECTOR_REG);
903 hwif->OUTB(args[4], IDE_LCYL_REG);
904 hwif->OUTB(args[5], IDE_HCYL_REG);
905 hwif->OUTB((args[6] & 0xEF)|drive->select.all, IDE_SELECT_REG);
906 ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
907 return ide_started;
908 } else if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
909 u8 *args = rq->buffer;
910
911 if (!args)
912 goto done;
913#ifdef DEBUG 881#ifdef DEBUG
914 printk("%s: DRIVE_CMD ", drive->name); 882 printk("%s: DRIVE_CMD\n", drive->name);
915 printk("cmd=0x%02x ", args[0]);
916 printk("sc=0x%02x ", args[1]);
917 printk("fr=0x%02x ", args[2]);
918 printk("xx=0x%02x\n", args[3]);
919#endif 883#endif
920 if (args[0] == WIN_SMART) { 884 tf->feature = args[2];
921 hwif->OUTB(0x4f, IDE_LCYL_REG); 885 if (args[0] == WIN_SMART) {
922 hwif->OUTB(0xc2, IDE_HCYL_REG); 886 tf->nsect = args[3];
923 hwif->OUTB(args[2],IDE_FEATURE_REG); 887 tf->lbal = args[1];
924 hwif->OUTB(args[1],IDE_SECTOR_REG); 888 tf->lbam = 0x4f;
925 ide_cmd(drive, args[0], args[3], &drive_cmd_intr); 889 tf->lbah = 0xc2;
926 return ide_started; 890 ltask.tf_flags = IDE_TFLAG_OUT_TF;
927 } 891 } else {
928 hwif->OUTB(args[2],IDE_FEATURE_REG); 892 tf->nsect = args[1];
929 ide_cmd(drive, args[0], args[1], &drive_cmd_intr); 893 ltask.tf_flags = IDE_TFLAG_OUT_FEATURE |
930 return ide_started; 894 IDE_TFLAG_OUT_NSECT;
895 }
931 } 896 }
897 tf->command = args[0];
898 ide_tf_load(drive, &ltask);
899 ide_execute_command(drive, args[0], &drive_cmd_intr, WAIT_WORSTCASE, NULL);
900 return ide_started;
932 901
933done: 902done:
934 /* 903 /*
@@ -1003,6 +972,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
1003 972
1004 /* bail early if we've exceeded max_failures */ 973 /* bail early if we've exceeded max_failures */
1005 if (drive->max_failures && (drive->failures > drive->max_failures)) { 974 if (drive->max_failures && (drive->failures > drive->max_failures)) {
975 rq->cmd_flags |= REQ_FAILED;
1006 goto kill_rq; 976 goto kill_rq;
1007 } 977 }
1008 978
@@ -1035,7 +1005,6 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
1035 ide_config_drive_speed(drive, drive->desired_speed); 1005 ide_config_drive_speed(drive, drive->desired_speed);
1036 1006
1037 if (rq->cmd_type == REQ_TYPE_ATA_CMD || 1007 if (rq->cmd_type == REQ_TYPE_ATA_CMD ||
1038 rq->cmd_type == REQ_TYPE_ATA_TASK ||
1039 rq->cmd_type == REQ_TYPE_ATA_TASKFILE) 1008 rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
1040 return execute_drive_cmd(drive, rq); 1009 return execute_drive_cmd(drive, rq);
1041 else if (blk_pm_request(rq)) { 1010 else if (blk_pm_request(rq)) {
@@ -1247,8 +1216,12 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
1247 if (hwgroup->hwif->sharing_irq && 1216 if (hwgroup->hwif->sharing_irq &&
1248 hwif != hwgroup->hwif && 1217 hwif != hwgroup->hwif &&
1249 hwif->io_ports[IDE_CONTROL_OFFSET]) { 1218 hwif->io_ports[IDE_CONTROL_OFFSET]) {
1250 /* set nIEN for previous hwif */ 1219 /*
1251 SELECT_INTERRUPT(drive); 1220 * set nIEN for previous hwif, drives in the
1221 * quirk_list may not like intr setups/cleanups
1222 */
1223 if (drive->quirk_list != 1)
1224 hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
1252 } 1225 }
1253 hwgroup->hwif = hwif; 1226 hwgroup->hwif = hwif;
1254 hwgroup->drive = drive; 1227 hwgroup->drive = drive;
@@ -1454,12 +1427,8 @@ void ide_timer_expiry (unsigned long data)
1454 */ 1427 */
1455 spin_unlock(&ide_lock); 1428 spin_unlock(&ide_lock);
1456 hwif = HWIF(drive); 1429 hwif = HWIF(drive);
1457#if DISABLE_IRQ_NOSYNC
1458 disable_irq_nosync(hwif->irq);
1459#else
1460 /* disable_irq_nosync ?? */ 1430 /* disable_irq_nosync ?? */
1461 disable_irq(hwif->irq); 1431 disable_irq(hwif->irq);
1462#endif /* DISABLE_IRQ_NOSYNC */
1463 /* local CPU only, 1432 /* local CPU only,
1464 * as if we were handling an interrupt */ 1433 * as if we were handling an interrupt */
1465 local_irq_disable(); 1434 local_irq_disable();
@@ -1785,3 +1754,19 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
1785} 1754}
1786 1755
1787EXPORT_SYMBOL(ide_do_drive_cmd); 1756EXPORT_SYMBOL(ide_do_drive_cmd);
1757
1758void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
1759{
1760 ide_task_t task;
1761
1762 memset(&task, 0, sizeof(task));
1763 task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
1764 IDE_TFLAG_OUT_FEATURE | tf_flags;
1765 task.tf.feature = dma; /* Use PIO/DMA */
1766 task.tf.lbam = bcount & 0xff;
1767 task.tf.lbah = (bcount >> 8) & 0xff;
1768
1769 ide_tf_load(drive, &task);
1770}
1771
1772EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load);