bk://bart.bkbits.net/ide-dev-2.6
bzolnier@trik.(none)|ChangeSet|20050324132144|59660 bzolnier

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/03/30 12:33:07-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-ide-dev
# 
# drivers/ide/ide-disk.c
#   2005/03/30 12:33:02-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/29 12:21:11-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-ide-dev
# 
# include/linux/pci_ids.h
#   2005/03/29 12:21:05-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/blkdev.h
#   2005/03/29 12:21:05-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/27 16:55:40-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-ide-dev
# 
# include/linux/pci_ids.h
#   2005/03/27 16:55:34-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/24 14:21:44+01:00 bzolnier@trik.(none) 
#   hand-merging fixup (thanks Andrew)
# 
# drivers/ide/ide-floppy.c
#   2005/03/24 14:21:29+01:00 bzolnier@trik.(none) +0 -1
#   hand-merging fixup (thanks Andrew)
# 
# drivers/ide/ide-disk.c
#   2005/03/24 14:21:29+01:00 bzolnier@trik.(none) +0 -1
#   hand-merging fixup (thanks Andrew)
# 
# drivers/ide/ide-cd.c
#   2005/03/24 14:21:29+01:00 bzolnier@trik.(none) +0 -1
#   hand-merging fixup (thanks Andrew)
# 
# ChangeSet
#   2005/03/18 15:48:37-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-ide-dev
# 
# include/linux/pci_ids.h
#   2005/03/18 15:48:32-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/18 18:23:33+01:00 bzolnier@trik.(none) 
#   hand-merge with linux-2.6
# 
# include/linux/ide.h
#   2005/03/18 18:23:22+01:00 bzolnier@trik.(none) +0 -1
#   hand-merge with linux-2.6
# 
# drivers/scsi/ide-scsi.c
#   2005/03/18 18:23:22+01:00 bzolnier@trik.(none) +0 -56
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-tape.c
#   2005/03/18 18:23:22+01:00 bzolnier@trik.(none) +0 -132
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-floppy.c
#   2005/03/18 18:23:22+01:00 bzolnier@trik.(none) +0 -90
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-disk.c
#   2005/03/18 18:23:22+01:00 bzolnier@trik.(none) +0 -87
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-cd.h
#   2005/03/18 18:23:22+01:00 bzolnier@trik.(none) +0 -2
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-cd.c
#   2005/03/18 18:23:22+01:00 bzolnier@trik.(none) +0 -79
#   hand-merge with linux-2.6
# 
# include/linux/pci_ids.h
#   2005/03/18 18:08:53+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide.c
#   2005/03/18 18:08:53+01:00 bzolnier@trik.(none) +0 -1
#   Auto merged
# 
# ChangeSet
#   2005/03/18 10:01:14+01:00 bzolnier@trik.(none) 
#   fixup after linux-2.6 merge
# 
# drivers/ide/ide-proc.c
#   2005/03/18 09:52:41+01:00 bzolnier@trik.(none) +0 -2
#   fixup after linux-2.6 merge
# 
# ChangeSet
#   2005/03/16 11:53:26+01:00 bzolnier@trik.(none) 
#   hand-merge with linux-2.6
# 
# drivers/scsi/ide-scsi.c
#   2005/03/16 11:53:16+01:00 bzolnier@trik.(none) +0 -10
#   hand-merge with linux-2.6
# 
# drivers/ide/ide.c
#   2005/03/16 11:53:16+01:00 bzolnier@trik.(none) +0 -3
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-tape.c
#   2005/03/16 11:53:16+01:00 bzolnier@trik.(none) +0 -8
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-io.c
#   2005/03/16 11:53:16+01:00 bzolnier@trik.(none) +0 -165
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-floppy.c
#   2005/03/16 11:53:16+01:00 bzolnier@trik.(none) +0 -13
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-disk.c
#   2005/03/16 11:53:16+01:00 bzolnier@trik.(none) +0 -14
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-cd.c
#   2005/03/16 11:53:16+01:00 bzolnier@trik.(none) +1 -24
#   hand-merge with linux-2.6
# 
# include/linux/pci_ids.h
#   2005/03/16 11:38:00+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# include/linux/ide.h
#   2005/03/16 11:38:00+01:00 bzolnier@trik.(none) +0 -1
#   Auto merged
# 
# drivers/ide/ide-taskfile.c
#   2005/03/16 11:38:00+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-proc.c
#   2005/03/16 11:38:00+01:00 bzolnier@trik.(none) +0 -1
#   Auto merged
# 
# drivers/ide/ide-probe.c
#   2005/03/16 11:38:00+01:00 bzolnier@trik.(none) +0 -60
#   Auto merged
# 
# drivers/ide/ide-iops.c
#   2005/03/16 11:38:00+01:00 bzolnier@trik.(none) +0 -19
#   Auto merged
# 
# BitKeeper/deleted/.del-ide-default.c~ad4e75ad8a193ed5
#   2005/03/16 11:37:59+01:00 bzolnier@trik.(none) +0 -10
#   Auto merged
# 
# drivers/ide/Kconfig
#   2005/03/16 11:37:59+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/block/ll_rw_blk.c
#   2005/03/16 11:37:59+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# BitKeeper/deleted/.del-ide-default.c~ad4e75ad8a193ed5
#   2005/03/16 11:37:59+01:00 bzolnier@trik.(none) +0 -0
#   Merge rename: drivers/ide/ide-default.c -> BitKeeper/deleted/.del-ide-default.c~ad4e75ad8a193ed5
# 
# ChangeSet
#   2005/03/10 15:15:14+01:00 bzolnier@trik.(none) 
#   hand-merge with linux-2.6 again
#   
#   bad Jens ;)
# 
# drivers/ide/ide-disk.c
#   2005/03/10 15:15:02+01:00 bzolnier@trik.(none) +4 -4
#   hand-merge with linux-2.6 again
# 
# include/linux/pci_ids.h
#   2005/03/10 15:06:30+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# include/linux/blkdev.h
#   2005/03/10 15:06:30+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/block/ll_rw_blk.c
#   2005/03/10 15:06:30+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/10 15:04:52+01:00 bzolnier@trik.(none) 
#   fixup after linux-2.6 merge
# 
# include/linux/ide.h
#   2005/03/09 22:36:45+01:00 bzolnier@trik.(none) +17 -19
#   fixup after linux-2.6 merge
# 
# drivers/ide/ide-disk.c
#   2005/03/09 22:36:45+01:00 bzolnier@trik.(none) +10 -5
#   fixup after linux-2.6 merge
# 
# ChangeSet
#   2005/03/09 19:40:16+01:00 bzolnier@trik.(none) 
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-io.c
#   2005/03/09 19:40:05+01:00 bzolnier@trik.(none) +0 -0
#   hand-merge with linux-2.6
# 
# drivers/ide/ide-disk.c
#   2005/03/09 19:40:04+01:00 bzolnier@trik.(none) +4 -3
#   hand-merge with linux-2.6
# 
# include/linux/pci_ids.h
#   2005/03/09 19:22:00+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# include/linux/ide.h
#   2005/03/09 19:22:00+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# include/linux/blkdev.h
#   2005/03/09 19:22:00+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-tape.c
#   2005/03/09 19:22:00+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/block/ll_rw_blk.c
#   2005/03/09 19:22:00+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/08 11:39:32+01:00 bzolnier@trik.(none) 
#   [ide] fix driver->probe return codes
# 
# drivers/scsi/ide-scsi.c
#   2005/03/08 11:39:20+01:00 bzolnier@trik.(none) +9 -5
#   [ide] fix driver->probe return codes
# 
# drivers/ide/ide-tape.c
#   2005/03/08 11:39:20+01:00 bzolnier@trik.(none) +1 -1
#   [ide] fix driver->probe return codes
# 
# drivers/ide/ide-floppy.c
#   2005/03/08 11:39:20+01:00 bzolnier@trik.(none) +1 -1
#   [ide] fix driver->probe return codes
# 
# drivers/ide/ide-disk.c
#   2005/03/08 11:39:20+01:00 bzolnier@trik.(none) +1 -1
#   [ide] fix driver->probe return codes
# 
# drivers/ide/ide-cd.c
#   2005/03/08 11:39:20+01:00 bzolnier@trik.(none) +1 -1
#   [ide] fix driver->probe return codes
# 
# ChangeSet
#   2005/03/08 11:10:27+01:00 bzolnier@trik.(none) 
#   [ide] convert device drivers to driver-model
#   
#   * add ide_bus_match() and export ide_bus_type
#   * split ide_remove_driver_from_hwgroup() out of ide_unregister()
#   * move device cleanup from ide_unregister() to drive_release_dev()
#   * convert ide_driver_t->name to driver->name
#   * convert ide_driver_t->{attach,cleanup} to driver->{probe,remove}
#   * remove ide_driver_t->busy as ide_bus_type->subsys.rwsem
#     protects against concurrent ->{probe,remove} calls
#   * make ide_{un}register_driver() void as it cannot fail now
#   * use driver_{un}register() directly, remove ide_{un}register_driver()
#   * use device_register() instead of ata_attach(), remove ata_attach()
#   * add proc_print_driver() and ide_drivers_show(), remove ide_drivers_op
#   * fix ide_replace_subdriver() and move it to ide-proc.c
#   * remove ide_driver_t->drives, ide_drives and drives_lock
#   * remove ide_driver_t->drivers, drivers and drivers_lock
#   * remove ide_drive_t->driver and DRIVER() macro
# 
# include/linux/ide.h
#   2005/02/04 03:32:30+01:00 bzolnier@trik.(none) +4 -16
#   [ide] convert device drivers to driver-model
# 
# drivers/scsi/ide-scsi.c
#   2005/02/04 03:32:30+01:00 bzolnier@trik.(none) +17 -21
#   [ide] convert device drivers to driver-model
# 
# drivers/ide/ide.c
#   2005/02/04 03:32:30+01:00 bzolnier@trik.(none) +25 -282
#   [ide] convert device drivers to driver-model
# 
# drivers/ide/ide-tape.c
#   2005/02/04 03:32:30+01:00 bzolnier@trik.(none) +18 -31
#   [ide] convert device drivers to driver-model
# 
# drivers/ide/ide-proc.c
#   2005/02/04 03:32:30+01:00 bzolnier@trik.(none) +46 -6
#   [ide] convert device drivers to driver-model
# 
# drivers/ide/ide-probe.c
#   2005/02/04 03:32:30+01:00 bzolnier@trik.(none) +44 -3
#   [ide] convert device drivers to driver-model
# 
# drivers/ide/ide-floppy.c
#   2005/02/04 03:32:30+01:00 bzolnier@trik.(none) +16 -24
#   [ide] convert device drivers to driver-model
# 
# drivers/ide/ide-disk.c
#   2005/02/04 03:32:30+01:00 bzolnier@trik.(none) +16 -23
#   [ide] convert device drivers to driver-model
# 
# drivers/ide/ide-cd.c
#   2005/02/04 03:32:30+01:00 bzolnier@trik.(none) +17 -28
#   [ide] convert device drivers to driver-model
# 
# ChangeSet
#   2005/03/08 11:06:41+01:00 htejun@gmail.com 
#   [ide] remove unused REQ_DRIVE_TASK handling
#   
#   Signed-off-by: Tejun Heo <htejun@gmail.com>
# 
# include/linux/blkdev.h
#   2005/02/24 15:30:14+01:00 htejun@gmail.com +0 -2
#   [ide] remove unused REQ_DRIVE_TASK handling
# 
# drivers/ide/ide-lib.c
#   2005/02/24 15:30:14+01:00 htejun@gmail.com +1 -1
#   [ide] remove unused REQ_DRIVE_TASK handling
# 
# drivers/ide/ide-io.c
#   2005/02/24 15:30:14+01:00 htejun@gmail.com +4 -44
#   [ide] remove unused REQ_DRIVE_TASK handling
# 
# drivers/block/ll_rw_blk.c
#   2005/02/24 15:30:14+01:00 htejun@gmail.com +0 -1
#   [ide] remove unused REQ_DRIVE_TASK handling
# 
# ChangeSet
#   2005/03/08 11:04:32+01:00 htejun@gmail.com 
#   [ide] make ide_task_ioctl() use REQ_DRIVE_TASKFILE
#   
#   ide_task_ioctl() rewritten to use taskfile transport.
#   This is the last user of REQ_DRIVE_TASK.
#   
#   bart: ported to recent IDE changes by me
#   
#   Signed-off-by: Tejun Heo <htejun@gmail.com>
# 
# drivers/ide/ide-taskfile.c
#   2005/02/24 15:30:02+01:00 htejun@gmail.com +31 -19
#   [ide] make ide_task_ioctl() use REQ_DRIVE_TASKFILE
# 
# ChangeSet
#   2005/03/08 10:58:29+01:00 bzolnier@trik.(none) 
#   [ide] convert disk flush functions to use REQ_DRIVE_TASKFILE
#   
#   Original patch from Tejun Heo <htejun@gmail.com>,
#   ported over recent IDE changes by me.
#   
#   * teach ide_tf_get_address() about CHS
#   * use ide_tf_get_address() and remove ide_get_error_location()
#   * use ide_task_init_flush() and remove ide_fill_flush_cmd()
#   * convert idedisk_issue_flush() to use REQ_DRIVE_TASKFILE.
#     This and switching to ide_tf_get_address() removes
#     a possible race condition between getting the failed
#     sector number and other requests.
#   * convert ide_queue_flush_cmd() to use REQ_DRIVE_TASKFILE
#   
#   By this change, when WIN_FLUSH_CACHE_EXT is used, full HOB
#   registers are written and read.  This isn't optimal but
#   shouldn't be noticeable either.
# 
# include/linux/ide.h
#   2005/03/08 10:58:17+01:00 bzolnier@trik.(none) +7 -8
#   [ide] convert disk flush functions to use REQ_DRIVE_TASKFILE
# 
# drivers/ide/ide-io.c
#   2005/03/08 10:58:17+01:00 bzolnier@trik.(none) +30 -67
#   [ide] convert disk flush functions to use REQ_DRIVE_TASKFILE
# 
# drivers/ide/ide-disk.c
#   2005/03/08 10:58:17+01:00 bzolnier@trik.(none) +8 -14
#   [ide] convert disk flush functions to use REQ_DRIVE_TASKFILE
# 
# ChangeSet
#   2005/03/08 10:51:00+01:00 bzolnier@trik.(none) 
#   [ide] check capacity in ide_task_init_flush()
#   
#   Use WIN_FLUSH_CACHE_EXT only if disk requires LBA48.
# 
# drivers/ide/ide-io.c
#   2005/02/23 20:58:16+01:00 bzolnier@trik.(none) +2 -1
#   [ide] check capacity in ide_task_init_flush()
# 
# ChangeSet
#   2005/03/08 10:49:27+01:00 bzolnier@trik.(none) 
#   [ide] fix setting LBA bit in Device register for REQ_DRIVE_TASKFILE
#   
#   * Power Management requests
#     (WIN_STANDBYNOW1, WIN_IDLEIMMEDIATE commands)
#   * special commands (WIN_SPECIFY, WIN_RESTORE, WIN_SETMULT)
#   * /proc/ide/ SMART support (WIN_SMART with SMART_ENABLE,
#     SMART_READ_VALUES and SMART_READ_THRESHOLDS subcommands)
#   * write cache enabling/disabling in ide-disk
#     (WIN_SETFEATURES with SETFEATURES_{EN,DIS}_WCACHE)
#   * acoustic management in ide-disk
#     (WIN_SETFEATURES with SETFEATURES_{EN,DIS}_AAM)
#   * door (un)locking in ide-disk (WIN_DOORLOCK, WIN_DOORUNLOCK)
#   * /proc/ide/hd?/identify support (WIN_IDENTIFY)
# 
# drivers/ide/ide-taskfile.c
#   2005/03/08 10:49:17+01:00 bzolnier@trik.(none) +5 -2
#   [ide] fix setting LBA bit in Device register for REQ_DRIVE_TASKFILE
# 
# drivers/ide/ide-io.c
#   2005/03/08 10:49:17+01:00 bzolnier@trik.(none) +3 -0
#   [ide] fix setting LBA bit in Device register for REQ_DRIVE_TASKFILE
# 
# ChangeSet
#   2005/03/08 10:42:08+01:00 bzolnier@trik.(none) 
#   [ide] add ide_task_init_flush() helper
#   
#   * add ide_task_init_flush() helper
#   * use it in do_idedisk_cacheflush() and ide_start_power_step()
#   * inline do_idedisk_cacheflush() into ide_cacheflush_p()
# 
# include/linux/ide.h
#   2005/02/19 17:22:58+01:00 bzolnier@trik.(none) +15 -13
#   [ide] add ide_task_init_flush() helper
# 
# drivers/ide/ide-io.c
#   2005/02/19 17:22:58+01:00 bzolnier@trik.(none) +19 -7
#   [ide] add ide_task_init_flush() helper
# 
# drivers/ide/ide-disk.c
#   2005/02/19 17:22:58+01:00 bzolnier@trik.(none) +5 -19
#   [ide] add ide_task_init_flush() helper
# 
# ChangeSet
#   2005/03/08 10:35:44+01:00 bzolnier@trik.(none) 
#   [ide] merge LBA28 and LBA48 Host Protected Area support code
#   
#   * merge idedisk_read_native_max_address()
#     and idedisk_read_native_max_address_ext()
#   * merge idedisk_set_max_address()
#     and idedisk_set_max_address_ext()
# 
# drivers/ide/ide-disk.c
#   2005/03/08 10:35:30+01:00 bzolnier@trik.(none) +26 -77
#   [ide] merge LBA28 and LBA48 Host Protected Area support code
# 
# ChangeSet
#   2005/03/08 09:51:54+01:00 bzolnier@trik.(none) 
#   [ide] add ide_tf_get_address() helper
#   
#   * add ide_tf_get_address() helper
#   * use it in idedisk_read_native_max_address[_ext]()
#     and idedisk_set_max_address[_ext]()
# 
# include/linux/ide.h
#   2005/02/19 17:22:32+01:00 bzolnier@trik.(none) +2 -0
#   [ide] add ide_tf_get_address() helper
# 
# drivers/ide/ide-io.c
#   2005/02/19 17:22:32+01:00 bzolnier@trik.(none) +16 -0
#   [ide] add ide_tf_get_address() helper
# 
# drivers/ide/ide-disk.c
#   2005/02/19 17:22:32+01:00 bzolnier@trik.(none) +4 -10
#   [ide] add ide_tf_get_address() helper
# 
# ChangeSet
#   2005/03/08 09:48:13+01:00 bzolnier@trik.(none) 
#   [ide] use struct ata_taskfile in ide_task_t
#   
#   * use struct ata_taskfile instead of .flags,
#     .tfRegister[] and .hobRegister[] in ide_task_t
#   * add #ifndef __KERNEL__ around definitions of {task,hob}_struct_t
#   * don't set write-only .hobRegister[6] and .hobRegister[7]
#     in idedisk_set_max_address_ext()
#   * remove no longer needed IDE_CONTROL_OFFSET_HOB define
#   * use ATA_LBA define in ide-disk.c (suggested by Tejun Heo)
# 
# include/linux/ide.h
#   2005/03/08 09:48:02+01:00 bzolnier@trik.(none) +2 -11
#   [ide] use struct ata_taskfile in ide_task_t
# 
# include/linux/hdreg.h
#   2005/03/08 09:48:02+01:00 bzolnier@trik.(none) +3 -1
#   [ide] use struct ata_taskfile in ide_task_t
# 
# include/linux/ata.h
#   2005/03/08 09:48:02+01:00 bzolnier@trik.(none) +6 -5
#   [ide] use struct ata_taskfile in ide_task_t
# 
# drivers/ide/ide-taskfile.c
#   2005/03/08 09:48:02+01:00 bzolnier@trik.(none) +84 -58
#   [ide] use struct ata_taskfile in ide_task_t
# 
# drivers/ide/ide-lib.c
#   2005/03/08 09:48:02+01:00 bzolnier@trik.(none) +1 -2
#   [ide] use struct ata_taskfile in ide_task_t
# 
# drivers/ide/ide-iops.c
#   2005/03/08 09:48:02+01:00 bzolnier@trik.(none) +6 -6
#   [ide] use struct ata_taskfile in ide_task_t
# 
# drivers/ide/ide-io.c
#   2005/03/08 09:48:02+01:00 bzolnier@trik.(none) +47 -33
#   [ide] use struct ata_taskfile in ide_task_t
# 
# drivers/ide/ide-disk.c
#   2005/03/08 09:48:02+01:00 bzolnier@trik.(none) +85 -71
#   [ide] use struct ata_taskfile in ide_task_t
# 
# ChangeSet
#   2005/03/08 09:38:03+01:00 htejun@gmail.com 
#   [ide] ide_dma_intr() OOPS fix
#   
#   This patch fixes ide_dma_intr() OOPS which occurs
#   for HDIO_DRIVE_TASKFILE ioctl using DMA dataphases.
#   
#   Signed-off-by: Tejun Heo <htejun@gmail.com>
# 
# drivers/ide/ide-dma.c
#   2005/03/03 04:00:08+01:00 htejun@gmail.com +7 -3
#   [ide] ide_dma_intr() OOPS fix
# 
# ChangeSet
#   2005/03/08 09:32:03+01:00 bzolnier@trik.(none) 
#   Merge trik.(none):/home/bzolnier/bk/linux-2.6
#   into trik.(none):/home/bzolnier/bk/ide-dev-2.6
# 
# include/linux/pci_ids.h
#   2005/03/08 09:31:57+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/08 09:16:28+01:00 akpm@osdl.org 
#   [ide] ide_init_disk() fix
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
# 
# drivers/ide/ide-probe.c
#   2005/02/23 17:24:55+01:00 akpm@osdl.org +1 -1
#   [ide] ide_init_disk() fix
# 
# ChangeSet
#   2005/03/03 21:00:39+01:00 bzolnier@trik.(none) 
#   Merge trik.(none):/home/bzolnier/bk/linux-2.6
#   into trik.(none):/home/bzolnier/bk/ide-dev-2.6
# 
# include/linux/pci_ids.h
#   2005/03/03 21:00:34+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# include/linux/ide.h
#   2005/03/03 21:00:34+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# include/linux/ata.h
#   2005/03/03 21:00:34+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide.c
#   2005/03/03 21:00:34+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-io.c
#   2005/03/03 21:00:33+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-disk.c
#   2005/03/03 21:00:33+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/Kconfig
#   2005/03/03 21:00:33+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/02/11 20:41:18+01:00 bzolnier@trik.(none) 
#   [ide] fix io_32bit race in ide_taskfile_ioctl()
#   
#   In ide_taskfile_ioctl(), there was a race condition involving
#   drive->io_32bit.  It was cleared and restored during ioctl
#   requests but there was no synchronization with other requests.
#   So, other requests could execute with the altered io_32bit
#   setting or updated drive->io_32bit could be overwritten by
#   ide_taskfile_ioctl().
#   
#   This patch adds ATA_TFLAG_IO_16BIT flag to indicate to
#   ide_pio_datablock() that 16bit IO is needed regardless of
#   drive->io_32bit settting.
#   
#   Signed-off-by: Tejun Heo <htejun@gmail.com>
# 
# include/linux/ata.h
#   2005/02/11 20:41:06+01:00 bzolnier@trik.(none) +1 -0
#   [ide] fix io_32bit race in ide_taskfile_ioctl()
# 
# drivers/ide/ide-taskfile.c
#   2005/02/11 20:41:06+01:00 bzolnier@trik.(none) +12 -4
#   [ide] fix io_32bit race in ide_taskfile_ioctl()
# 
# ChangeSet
#   2005/02/11 19:47:30+01:00 bzolnier@trik.(none) 
#   [ide] fix unneeded LBA48 taskfile registers access
#   
#   This small patch fixes unneeded writes/reads to LBA48 taskfile registers
#   on LBA48 capable disks for following cases:
#   
#   * Power Management requests
#     (WIN_FLUSH_CACHE, WIN_STANDBYNOW1, WIN_IDLEIMMEDIATE commands)
#   * special commands (WIN_SPECIFY, WIN_RESTORE, WIN_SETMULT)
#   * Host Protected Area support (WIN_READ_NATIVE_MAX, WIN_SET_MAX)
#   * /proc/ide/ SMART support (WIN_SMART with SMART_ENABLE,
#     SMART_READ_VALUES and SMART_READ_THRESHOLDS subcommands)
#   * write cache enabling/disabling in ide-disk
#    (WIN_SETFEATURES with SETFEATURES_{EN,DIS}_WCACHE)
#   * write cache flushing in ide-disk (WIN_FLUSH_CACHE)
#   * acoustic management in ide-disk
#     (WIN_SETFEATURES with SETFEATURES_{EN,DIS}_AAM)
#   * door (un)locking in ide-disk (WIN_DOORLOCK, WIN_DOORUNLOCK)
#   * /proc/ide/hd?/identify support (WIN_IDENTIFY)
#   
#   Patch adds 'unsinged long flags' to ide_task_t and uses ATA_TFLAG_LBA48
#   flag (from <linux/ata.h>) to indicate need of access to LBA48 taskfile
#   registers.
# 
# include/linux/ide.h
#   2005/02/11 19:47:18+01:00 bzolnier@trik.(none) +1 -0
#   [ide] fix unneeded LBA48 taskfile registers access
# 
# drivers/ide/ide-taskfile.c
#   2005/02/11 19:47:18+01:00 bzolnier@trik.(none) +5 -2
#   [ide] fix unneeded LBA48 taskfile registers access
# 
# drivers/ide/ide-io.c
#   2005/02/11 19:47:18+01:00 bzolnier@trik.(none) +4 -3
#   [ide] fix unneeded LBA48 taskfile registers access
# 
# drivers/ide/ide-disk.c
#   2005/02/11 19:47:18+01:00 bzolnier@trik.(none) +9 -2
#   [ide] fix unneeded LBA48 taskfile registers access
# 
# ChangeSet
#   2005/02/11 19:31:17+01:00 bzolnier@trik.(none) 
#   [ide via82cxxx] add VIA VT6410 support
#   
#   From: Mathias Kretschmer <posting@blx4.net>
# 
# include/linux/pci_ids.h
#   2005/02/11 19:31:06+01:00 bzolnier@trik.(none) +1 -0
#   [ide via82cxxx] add VIA VT6410 support
# 
# drivers/ide/pci/via82cxxx.c
#   2005/02/11 19:31:06+01:00 bzolnier@trik.(none) +21 -9
#   [ide via82cxxx] add VIA VT6410 support
# 
# ChangeSet
#   2005/02/11 18:54:27+01:00 bzolnier@trik.(none) 
#   [ide] fix OOPS in task_end_request()
#   
#   Requests generated by /proc/ide/hd?/identify
#   and /proc/ide/hd?/smart_{thresholds,values}
#   don't have valid rq->rq_disk set.
#   
#   Use ide_end_request() instead of ->end_request().
# 
# drivers/ide/ide-taskfile.c
#   2005/02/11 18:54:16+01:00 bzolnier@trik.(none) +1 -4
#   [ide] fix OOPS in task_end_request()
# 
# ChangeSet
#   2005/02/06 21:08:16+01:00 bzolnier@trik.(none) 
#   [ide] fix ATAPI Power Management
#   
#   I've introduced bug in ATAPI Power Management handling,
#   idedisk_pm_idle shouldn't be done for ATAPI devices.
# 
# drivers/ide/ide-io.c
#   2005/02/05 01:44:33+01:00 bzolnier@trik.(none) +6 -0
#   [ide] fix ATAPI Power Management
# 
# ChangeSet
#   2005/02/06 21:07:35+01:00 bzolnier@trik.(none) 
#   [ide] fix pdc202xx_{new,old}.c after linux-2.6 merge
# 
# drivers/ide/pci/pdc202xx_old.c
#   2005/02/06 21:07:20+01:00 bzolnier@trik.(none) +0 -17
#   [ide] fix pdc202xx_{new,old}.c after linux-2.6 merge
# 
# drivers/ide/pci/pdc202xx_new.c
#   2005/02/06 21:07:20+01:00 bzolnier@trik.(none) +0 -6
#   [ide] fix pdc202xx_{new,old}.c after linux-2.6 merge
# 
# ChangeSet
#   2005/02/06 21:02:13+01:00 bzolnier@trik.(none) 
#   Merge trik.(none):/home/bzolnier/bk/linux-2.6
#   into trik.(none):/home/bzolnier/bk/ide-dev-2.6
# 
# BitKeeper/deleted/.del-pdc202xx_old.h~5487981ee32153be
#   2005/02/06 21:02:08+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# BitKeeper/deleted/.del-pdc202xx_new.h~2890994593a7ec02
#   2005/02/06 21:02:08+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# include/linux/ide.h
#   2005/02/06 21:02:08+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-probe.c
#   2005/02/06 21:02:08+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# BitKeeper/deleted/.del-pdc202xx_old.h~5487981ee32153be
#   2005/02/06 21:02:08+01:00 bzolnier@trik.(none) +0 -0
#   Merge rename: drivers/ide/pci/pdc202xx_old.h -> BitKeeper/deleted/.del-pdc202xx_old.h~5487981ee32153be
# 
# BitKeeper/deleted/.del-pdc202xx_new.h~2890994593a7ec02
#   2005/02/06 21:02:08+01:00 bzolnier@trik.(none) +0 -0
#   Merge rename: drivers/ide/pci/pdc202xx_new.h -> BitKeeper/deleted/.del-pdc202xx_new.h~2890994593a7ec02
# 
# ChangeSet
#   2005/02/04 00:40:24+01:00 bzolnier@trik.(none) 
#   [ide] kill ide-default
#   
#   * add ide_drives list to list devices without a driver
#   * add __ide_add_setting() and use it for adding no auto remove entries
#   * kill ide-default pseudo-driver
# 
# drivers/ide/ide.c
#   2005/01/25 02:40:20+01:00 bzolnier@trik.(none) +31 -28
#   [ide] kill ide-default
# 
# drivers/ide/ide-proc.c
#   2005/01/25 02:40:20+01:00 bzolnier@trik.(none) +5 -4
#   [ide] kill ide-default
# 
# drivers/ide/Makefile
#   2005/01/25 02:40:20+01:00 bzolnier@trik.(none) +1 -2
#   [ide] kill ide-default
# 
# BitKeeper/deleted/.del-ide-default.c~ad4e75ad8a193ed5
#   2005/02/04 00:40:13+01:00 bzolnier@trik.(none) +0 -0
#   [ide] kill ide-default
# 
# ChangeSet
#   2005/02/04 00:38:26+01:00 bzolnier@trik.(none) 
#   [ide] get driver from rq->rq_disk->private_data
#   
#   * add ide_driver_t * to device drivers objects
#   * set it to point at driver's ide_driver_t
#   * store address of this entry in disk->private_data
#   * fix ide_{cd,disk,floppy,tape,scsi}_g accordingly
#   * use rq->rq_disk->private_data instead of drive->driver
#     to obtain driver (this allows us to kill ide-default)
# 
# drivers/scsi/ide-scsi.c
#   2005/01/25 02:40:10+01:00 bzolnier@trik.(none) +13 -4
#   [ide] get driver from rq->rq_disk->private_data
# 
# drivers/ide/ide.c
#   2005/01/25 02:40:10+01:00 bzolnier@trik.(none) +3 -1
#   [ide] get driver from rq->rq_disk->private_data
# 
# drivers/ide/ide-taskfile.c
#   2005/01/25 02:40:10+01:00 bzolnier@trik.(none) +11 -3
#   [ide] get driver from rq->rq_disk->private_data
# 
# drivers/ide/ide-tape.c
#   2005/01/25 02:40:10+01:00 bzolnier@trik.(none) +6 -2
#   [ide] get driver from rq->rq_disk->private_data
# 
# drivers/ide/ide-io.c
#   2005/01/25 02:40:10+01:00 bzolnier@trik.(none) +36 -8
#   [ide] get driver from rq->rq_disk->private_data
# 
# drivers/ide/ide-floppy.c
#   2005/01/25 02:40:10+01:00 bzolnier@trik.(none) +6 -2
#   [ide] get driver from rq->rq_disk->private_data
# 
# drivers/ide/ide-dma.c
#   2005/01/25 02:40:10+01:00 bzolnier@trik.(none) +3 -1
#   [ide] get driver from rq->rq_disk->private_data
# 
# drivers/ide/ide-disk.c
#   2005/01/25 02:40:10+01:00 bzolnier@trik.(none) +6 -2
#   [ide] get driver from rq->rq_disk->private_data
# 
# drivers/ide/ide-cd.h
#   2005/01/25 02:40:10+01:00 bzolnier@trik.(none) +1 -0
#   [ide] get driver from rq->rq_disk->private_data
# 
# drivers/ide/ide-cd.c
#   2005/01/25 02:40:10+01:00 bzolnier@trik.(none) +5 -2
#   [ide] get driver from rq->rq_disk->private_data
# 
# ChangeSet
#   2005/02/04 00:35:41+01:00 bzolnier@trik.(none) 
#   [ide] kill ide_drive_t->disk
#   
#   * move ->disk from ide_drive_t to driver specific objects
#   * make drivers allocate struct gendisk and setup rq->rq_disk
#     (there is no need to do this for REQ_DRIVE_TASKFILE requests)
#   * add ide_init_disk() helper and kill alloc_disks() in ide-probe.c
#   * kill no longer needed ide_open() and ide_fops[] in ide.c
# 
# include/linux/ide.h
#   2005/01/25 02:39:59+01:00 bzolnier@trik.(none) +1 -2
#   [ide] kill ide_drive_t->disk
# 
# drivers/scsi/ide-scsi.c
#   2005/01/25 02:39:59+01:00 bzolnier@trik.(none) +18 -5
#   [ide] kill ide_drive_t->disk
# 
# drivers/ide/ide.c
#   2005/01/25 02:39:59+01:00 bzolnier@trik.(none) +0 -17
#   [ide] kill ide_drive_t->disk
# 
# drivers/ide/ide-tape.c
#   2005/01/25 02:39:59+01:00 bzolnier@trik.(none) +25 -6
#   [ide] kill ide_drive_t->disk
# 
# drivers/ide/ide-probe.c
#   2005/01/25 02:39:59+01:00 bzolnier@trik.(none) +13 -39
#   [ide] kill ide_drive_t->disk
# 
# drivers/ide/ide-io.c
#   2005/01/25 02:39:59+01:00 bzolnier@trik.(none) +0 -2
#   [ide] kill ide_drive_t->disk
# 
# drivers/ide/ide-floppy.c
#   2005/01/25 02:39:59+01:00 bzolnier@trik.(none) +30 -10
#   [ide] kill ide_drive_t->disk
# 
# drivers/ide/ide-disk.c
#   2005/01/25 02:39:59+01:00 bzolnier@trik.(none) +17 -5
#   [ide] kill ide_drive_t->disk
# 
# drivers/ide/ide-cd.h
#   2005/01/25 02:39:59+01:00 bzolnier@trik.(none) +1 -0
#   [ide] kill ide_drive_t->disk
# 
# drivers/ide/ide-cd.c
#   2005/01/25 02:39:59+01:00 bzolnier@trik.(none) +38 -22
#   [ide] kill ide_drive_t->disk
# 
# ChangeSet
#   2005/02/04 00:31:44+01:00 bzolnier@trik.(none) 
#   [ide] add ide_{un}register_region()
#   
#   Add ide_{un}register_region() and fix ide-{tape,scsi}.c to register
#   block device number ranges.  In ata_probe() only probe for modules.
#   
#   Behavior is unchanged because:
#   * if driver is already loaded and attached to drive ata_probe()
#     is not called et all
#   * if driver is loaded by ata_probe() it will register new number range
#     for a drive and this range will be found by kobj_lookup()
#   
#   If this is not clear please read http://lwn.net/Articles/25711/
#   and see drivers/base/map.c.
#   
#   This patch makes it possible to move drive->disk allocation from
#   ide-probe.c to device drivers.
# 
# include/linux/ide.h
#   2005/01/25 02:39:47+01:00 bzolnier@trik.(none) +3 -0
#   [ide] add ide_{un}register_region()
# 
# drivers/scsi/ide-scsi.c
#   2005/01/25 02:39:47+01:00 bzolnier@trik.(none) +4 -0
#   [ide] add ide_{un}register_region()
# 
# drivers/ide/ide-tape.c
#   2005/01/25 02:39:47+01:00 bzolnier@trik.(none) +3 -0
#   [ide] add ide_{un}register_region()
# 
# drivers/ide/ide-probe.c
#   2005/01/25 02:39:47+01:00 bzolnier@trik.(none) +44 -17
#   [ide] add ide_{un}register_region()
# 
# ChangeSet
#   2005/02/04 00:30:10+01:00 bzolnier@trik.(none) 
#   [ide] destroy_proc_ide_device() cleanup
#   
#   When this function is called device is already unbinded from a
#   driver so there are no driver /proc entries to remove.
# 
# drivers/ide/ide-proc.c
#   2005/01/25 02:39:35+01:00 bzolnier@trik.(none) +0 -3
#   [ide] destroy_proc_ide_device() cleanup
# 
# ChangeSet
#   2005/02/04 00:29:13+01:00 bzolnier@trik.(none) 
#   [ide] drive->dsc_overlap fix
#   
#   drive->dsc_overlap is supported only by ide-{cd,tape} drivers.
#   Add missing clearing of ->dsc_overlap to ide_{cd,tape}_release()
#   and move ->dsc_overlap setup from ide_register_subdriver() to
#   ide_cdrom_setup() (ide-tape enables it unconditionally).
# 
# drivers/ide/ide.c
#   2005/01/25 02:39:24+01:00 bzolnier@trik.(none) +0 -5
#   [ide] drive->dsc_overlap fix
# 
# drivers/ide/ide-tape.c
#   2005/01/25 02:39:24+01:00 bzolnier@trik.(none) +1 -0
#   [ide] drive->dsc_overlap fix
# 
# drivers/ide/ide-cd.c
#   2005/01/25 02:39:24+01:00 bzolnier@trik.(none) +4 -0
#   [ide] drive->dsc_overlap fix
# 
# ChangeSet
#   2005/02/04 00:28:20+01:00 bzolnier@trik.(none) 
#   [ide] drive->nice1 fix
#   
#   It is drive's property independent of the driver being used so move
#   drive->nice1 setup from ide_register_subdriver() to probe_hwif() in
#   ide-probe.c.  As a result changing a driver which controls the drive
#   no longer affects this flag.
# 
# drivers/ide/ide.c
#   2005/01/25 02:39:13+01:00 bzolnier@trik.(none) +0 -1
#   [ide] drive->nice1 fix
# 
# drivers/ide/ide-probe.c
#   2005/01/25 02:39:13+01:00 bzolnier@trik.(none) +8 -3
#   [ide] drive->nice1 fix
# 
# ChangeSet
#   2005/02/04 00:27:16+01:00 bzolnier@trik.(none) 
#   [ide] ide-tape: fix character device ->open() vs ->cleanup() race
#   
#   Similar to the same race but for the block device.
#   
#   * store pointer to struct ide_tape_obj in idetape_chrdevs[]
#   * rename idetape_chrdevs[] to idetape_devs[] and kill idetape_chrdev_t
#   * add ide_tape_chrdev_get() for getting reference to the tape
#   * store tape pointer in file->private_data and fix all users of it
#   * fix idetape_chrdev_{open,release}() to get/put reference to the tape
# 
# drivers/ide/ide-tape.c
#   2005/01/25 02:39:03+01:00 bzolnier@trik.(none) +51 -30
#   [ide] ide-tape: fix character device ->open() vs ->cleanup() race
# 
# ChangeSet
#   2005/02/03 21:47:18+01:00 bzolnier@trik.(none) 
#   [ide] fix via82cxxx resume failure
#   
#   With David Woodhouse <dwmw2@infradead.org>.
#   
#   On resume from sleep, via_set_speed() doesn't reinstate the correct
#   mode, because it thinks the drive is already configured correctly.
#   
#   Also kill redundant printk, ide_config_drive_speed() warns about errors.
# 
# drivers/ide/pci/via82cxxx.c
#   2005/02/03 21:47:05+01:00 bzolnier@trik.(none) +2 -5
#   [ide] fix via82cxxx resume failure
# 
# ChangeSet
#   2005/02/03 21:20:52+01:00 bzolnier@trik.(none) 
#   [ide] ide-scsi: add basic refcounting
#   
#   * pointers to a SCSI host and a drive are added to idescsi_scsi_t
#   * pointer to the SCSI host is stored in disk->private_data
#   * ide_scsi_{get,put}() is used to {get,put} reference to the SCSI host
# 
# drivers/scsi/ide-scsi.c
#   2005/01/21 23:41:42+01:00 bzolnier@trik.(none) +58 -11
#   [ide] ide-scsi: add basic refcounting
# 
# ChangeSet
#   2005/02/03 21:19:36+01:00 bzolnier@trik.(none) 
#   [ide] ide-tape: add basic refcounting
#   
#   Similar changes as for ide-cd.c.
# 
# drivers/ide/ide-tape.c
#   2005/01/21 23:41:25+01:00 bzolnier@trik.(none) +80 -14
#   [ide] ide-tape: add basic refcounting
# 
# ChangeSet
#   2005/02/03 21:18:37+01:00 bzolnier@trik.(none) 
#   [ide] ide-floppy: add basic refcounting
#   
#   Similar changes as for ide-cd.c.
# 
# drivers/ide/ide-floppy.c
#   2005/01/21 23:41:14+01:00 bzolnier@trik.(none) +90 -25
#   [ide] ide-floppy: add basic refcounting
# 
# ChangeSet
#   2005/02/03 21:17:26+01:00 bzolnier@trik.(none) 
#   [ide] ide-disk: add basic refcounting
#   
#   Similar changes as for ide-cd.c (except that struct ide_disk_obj is added).
# 
# drivers/ide/ide-disk.c
#   2005/01/21 23:41:03+01:00 bzolnier@trik.(none) +88 -9
#   [ide] ide-disk: add basic refcounting
# 
# ChangeSet
#   2005/02/03 21:15:21+01:00 bzolnier@trik.(none) 
#   [ide] ide-cd: add basic refcounting
#   
#   * based on reference counting in drivers/scsi/{sd,sr}.c
#   * fixes race between ->open() and ->cleanup() (ide_unregister_subdriver()
#     tests for drive->usage != 0 but there is no protection against new users)
#   * struct kref and pointer to a drive are added to struct ide_cdrom_info
#   * pointer to drive's struct ide_cdrom_info is stored in disk->private_data
#   * ide_cd_{get,put}() is used to {get,put} reference to struct ide_cdrom_info
#   * ide_cd_release() is a release method for struct ide_cdrom_info
# 
# drivers/ide/ide-cd.h
#   2005/01/21 23:40:52+01:00 bzolnier@trik.(none) +2 -0
#   [ide] ide-cd: add basic refcounting
# 
# drivers/ide/ide-cd.c
#   2005/01/21 23:40:52+01:00 bzolnier@trik.(none) +80 -19
#   [ide] ide-cd: add basic refcounting
# 
# ChangeSet
#   2005/02/03 21:13:29+01:00 bzolnier@trik.(none) 
#   [ide] make ide_generic_ioctl() take ide_drive_t * as an argument
#   
#   As a result disk->private_data can be used by device drivers now.
# 
# include/linux/ide.h
#   2005/01/21 22:30:19+01:00 bzolnier@trik.(none) +1 -1
#   [ide] make ide_generic_ioctl() take ide_drive_t * as an argument
# 
# drivers/scsi/ide-scsi.c
#   2005/01/21 22:30:19+01:00 bzolnier@trik.(none) +2 -1
#   [ide] make ide_generic_ioctl() take ide_drive_t * as an argument
# 
# drivers/ide/ide.c
#   2005/01/21 22:30:19+01:00 bzolnier@trik.(none) +1 -2
#   [ide] make ide_generic_ioctl() take ide_drive_t * as an argument
# 
# drivers/ide/ide-tape.c
#   2005/01/21 22:30:19+01:00 bzolnier@trik.(none) +1 -1
#   [ide] make ide_generic_ioctl() take ide_drive_t * as an argument
# 
# drivers/ide/ide-floppy.c
#   2005/01/21 22:30:19+01:00 bzolnier@trik.(none) +1 -1
#   [ide] make ide_generic_ioctl() take ide_drive_t * as an argument
# 
# drivers/ide/ide-disk.c
#   2005/01/21 22:30:19+01:00 bzolnier@trik.(none) +2 -1
#   [ide] make ide_generic_ioctl() take ide_drive_t * as an argument
# 
# drivers/ide/ide-cd.c
#   2005/01/21 22:30:19+01:00 bzolnier@trik.(none) +1 -1
#   [ide] make ide_generic_ioctl() take ide_drive_t * as an argument
# 
# ChangeSet
#   2005/02/03 21:08:15+01:00 bzolnier@trik.(none) 
#   [ide] kill setup_driver_defaults()
#   
#   * move default_do_request() to ide-default.c
#   * fix drivers to set ide_driver_t->{do_request,end_request,error,abort}
#   * kill setup_driver_defaults()
# 
# drivers/ide/ide.c
#   2005/01/21 22:27:18+01:00 bzolnier@trik.(none) +0 -37
#   [ide] kill setup_driver_defaults()
# 
# drivers/ide/ide-tape.c
#   2005/01/21 22:27:18+01:00 bzolnier@trik.(none) +2 -0
#   [ide] kill setup_driver_defaults()
# 
# drivers/ide/ide-io.c
#   2005/01/21 22:27:18+01:00 bzolnier@trik.(none) +4 -0
#   [ide] kill setup_driver_defaults()
# 
# drivers/ide/ide-floppy.c
#   2005/01/21 22:27:18+01:00 bzolnier@trik.(none) +2 -0
#   [ide] kill setup_driver_defaults()
# 
# drivers/ide/ide-disk.c
#   2005/01/21 22:27:18+01:00 bzolnier@trik.(none) +3 -0
#   [ide] kill setup_driver_defaults()
# 
# drivers/ide/ide-default.c
#   2005/01/21 22:27:18+01:00 bzolnier@trik.(none) +10 -0
#   [ide] kill setup_driver_defaults()
# 
# drivers/ide/ide-cd.c
#   2005/01/21 22:27:18+01:00 bzolnier@trik.(none) +3 -0
#   [ide] kill setup_driver_defaults()
# 
# ChangeSet
#   2005/02/03 21:04:06+01:00 bzolnier@trik.(none) 
#   [ide] kill ide_driver_t->capacity
#   
#   * add private /proc/ide/hd?/capacity handlers to ide-{cd,disk,floppy}.c
#   * use generic proc_ide_read_capacity() for ide-{scsi,tape}.c
#   * kill ->capacity, default_capacity() and generic_subdriver_entries[]
# 
# include/linux/ide.h
#   2005/01/21 22:23:17+01:00 bzolnier@trik.(none) +0 -1
#   [ide] kill ide_driver_t->capacity
# 
# drivers/scsi/ide-scsi.c
#   2005/01/21 22:23:17+01:00 bzolnier@trik.(none) +10 -0
#   [ide] kill ide_driver_t->capacity
# 
# drivers/ide/ide.c
#   2005/02/03 21:00:44+01:00 bzolnier@trik.(none) +1 -15
#   [ide] kill ide_driver_t->capacity
# 
# drivers/ide/ide-tape.c
#   2005/01/21 22:23:17+01:00 bzolnier@trik.(none) +1 -0
#   [ide] kill ide_driver_t->capacity
# 
# drivers/ide/ide-proc.c
#   2005/01/21 22:23:17+01:00 bzolnier@trik.(none) +3 -5
#   [ide] kill ide_driver_t->capacity
# 
# drivers/ide/ide-floppy.c
#   2005/01/21 22:23:17+01:00 bzolnier@trik.(none) +11 -1
#   [ide] kill ide_driver_t->capacity
# 
# drivers/ide/ide-disk.c
#   2005/01/21 22:23:17+01:00 bzolnier@trik.(none) +11 -1
#   [ide] kill ide_driver_t->capacity
# 
# drivers/ide/ide-cd.c
#   2005/01/21 22:23:17+01:00 bzolnier@trik.(none) +20 -1
#   [ide] kill ide_driver_t->capacity
# 
# ChangeSet
#   2005/02/03 20:44:44+01:00 bzolnier@trik.(none) 
#   Merge
# 
# include/linux/ide.h
#   2005/02/03 20:44:41+01:00 bzolnier@trik.(none) +0 -0
#   SCCS merged
# 
# drivers/ide/ide-iops.c
#   2005/02/03 20:44:41+01:00 bzolnier@trik.(none) +0 -0
#   SCCS merged
# 
# drivers/scsi/ide-scsi.c
#   2005/02/03 20:37:17+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide.c
#   2005/02/03 20:37:17+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-taskfile.c
#   2005/02/03 20:37:17+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-tape.c
#   2005/02/03 20:37:17+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-probe.c
#   2005/02/03 20:37:17+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-io.c
#   2005/02/03 20:37:17+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-floppy.c
#   2005/02/03 20:37:17+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-disk.c
#   2005/02/03 20:37:17+01:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/21 20:25:56+01:00 bzolnier@trik.(none) 
#   [ide] kill ide_driver_t->pre_reset
#   
#   Add ide_drive_t->post_reset flag and use it to signal post reset
#   condition to the ide-tape driver (the only user of ->pre_reset).
# 
# include/linux/ide.h
#   2005/01/21 20:13:35+01:00 bzolnier@trik.(none) +1 -1
#   [ide] kill ide_driver_t->pre_reset
# 
# drivers/ide/ide.c
#   2005/01/21 20:13:35+01:00 bzolnier@trik.(none) +0 -5
#   [ide] kill ide_driver_t->pre_reset
# 
# drivers/ide/ide-tape.c
#   2005/01/21 20:13:35+01:00 bzolnier@trik.(none) +5 -11
#   [ide] kill ide_driver_t->pre_reset
# 
# drivers/ide/ide-iops.c
#   2005/01/21 20:13:35+01:00 bzolnier@trik.(none) +1 -1
#   [ide] kill ide_driver_t->pre_reset
# 
# ChangeSet
#   2005/01/21 20:24:38+01:00 bzolnier@trik.(none) 
#   [ide] fix some rare ide-default vs ide-disk races
#   
#   Some rare races between ide-default and ide-disk are possible, i.e.:
#   * ide-default is used, I/O request is triggered (ie. /proc/ide/hd?/identify),
#     drive->special is cleared silently (so CHS is not initialized properly),
#     ide-disk is loaded and fails if drive uses CHS
#   * ide-disk is used, drive is resetted, ide-disk is unloaded, ide-default
#     takes control over drive and on the first I/O request silently clears
#    drive->special without restoring settings
#   
#   Fix them by moving idedisk_{special,pre_reset}() and company to IDE core.
# 
# include/linux/ide.h
#   2005/01/21 20:13:47+01:00 bzolnier@trik.(none) +0 -1
#   [ide] fix some rare ide-default vs ide-disk races
# 
# drivers/ide/ide.c
#   2005/01/21 20:13:47+01:00 bzolnier@trik.(none) +0 -10
#   [ide] fix some rare ide-default vs ide-disk races
# 
# drivers/ide/ide-taskfile.c
#   2005/01/21 20:13:47+01:00 bzolnier@trik.(none) +0 -6
#   [ide] fix some rare ide-default vs ide-disk races
# 
# drivers/ide/ide-probe.c
#   2005/01/21 20:13:47+01:00 bzolnier@trik.(none) +58 -2
#   [ide] fix some rare ide-default vs ide-disk races
# 
# drivers/ide/ide-iops.c
#   2005/01/21 20:13:47+01:00 bzolnier@trik.(none) +19 -1
#   [ide] fix some rare ide-default vs ide-disk races
# 
# drivers/ide/ide-io.c
#   2005/01/21 20:13:47+01:00 bzolnier@trik.(none) +66 -2
#   [ide] fix some rare ide-default vs ide-disk races
# 
# drivers/ide/ide-disk.c
#   2005/01/21 20:13:47+01:00 bzolnier@trik.(none) +0 -108
#   [ide] fix some rare ide-default vs ide-disk races
# 
# drivers/ide/Kconfig
#   2005/01/21 20:13:47+01:00 bzolnier@trik.(none) +0 -1
#   [ide] fix some rare ide-default vs ide-disk races
# 
# ChangeSet
#   2005/01/21 20:23:26+01:00 bzolnier@trik.(none) 
#   [ide] generic Power Management for IDE devices
#   
#   Move PM code from ide-cd.c and ide-disk.c to IDE core so:
#   * PM is supported for other ATAPI devices (floppy, tape)
#   * PM is supported even if specific driver is not loaded
# 
# include/linux/ide.h
#   2005/01/21 20:14:00+01:00 bzolnier@trik.(none) +0 -2
#   [ide] generic Power Management for IDE devices
# 
# drivers/ide/ide.c
#   2005/01/21 20:14:00+01:00 bzolnier@trik.(none) +0 -9
#   [ide] generic Power Management for IDE devices
# 
# drivers/ide/ide-io.c
#   2005/01/21 20:14:00+01:00 bzolnier@trik.(none) +89 -2
#   [ide] generic Power Management for IDE devices
# 
# drivers/ide/ide-disk.c
#   2005/01/21 20:14:00+01:00 bzolnier@trik.(none) +0 -86
#   [ide] generic Power Management for IDE devices
# 
# drivers/ide/ide-cd.c
#   2005/01/21 20:14:00+01:00 bzolnier@trik.(none) +0 -41
#   [ide] generic Power Management for IDE devices
# 
# ChangeSet
#   2005/01/21 20:21:54+01:00 bzolnier@trik.(none) 
#   [ide] fix drive->ready_stat for ATAPI
#   
#   ATAPI devices ignore DRDY bit so drive->ready_stat must be set to zero.
#   It is currently done by device drivers (including ide-default fake driver)
#   but for PMAC driver it is too late as wait_for_ready() may be called during
#   probe: probe_hwif()->pmac_ide_dma_check()->pmac_ide_{mdma,udma}_enable()->
#   ->pmac_ide_do_setfeature()->wait_for_ready().
#   
#   Fixup drive->ready_stat just after detecting ATAPI device.
# 
# drivers/scsi/ide-scsi.c
#   2005/01/21 20:14:18+01:00 bzolnier@trik.(none) +0 -1
#   [ide] fix drive->ready_stat for ATAPI
# 
# drivers/ide/ide.c
#   2005/01/21 20:14:18+01:00 bzolnier@trik.(none) +2 -0
#   [ide] fix drive->ready_stat for ATAPI
# 
# drivers/ide/ide-tape.c
#   2005/01/21 20:14:18+01:00 bzolnier@trik.(none) +0 -2
#   [ide] fix drive->ready_stat for ATAPI
# 
# drivers/ide/ide-probe.c
#   2005/01/21 20:14:18+01:00 bzolnier@trik.(none) +2 -0
#   [ide] fix drive->ready_stat for ATAPI
# 
# drivers/ide/ide-floppy.c
#   2005/01/21 20:14:18+01:00 bzolnier@trik.(none) +0 -1
#   [ide] fix drive->ready_stat for ATAPI
# 
# drivers/ide/ide-default.c
#   2005/01/21 20:14:18+01:00 bzolnier@trik.(none) +0 -7
#   [ide] fix drive->ready_stat for ATAPI
# 
# drivers/ide/ide-cd.c
#   2005/01/21 20:14:18+01:00 bzolnier@trik.(none) +0 -1
#   [ide] fix drive->ready_stat for ATAPI
# 
# ChangeSet
#   2005/01/21 20:20:25+01:00 bzolnier@trik.(none) 
#   [ide] ignore BIOS enable bits for Promise controllers
#   
#   Since there are no Promise binary drivers for 2.6.x kernels:
#   * ignore BIOS enable bits completely
#   * remove CONFIG_PDC202XX_FORCE
#   * kill IDEPCI_FLAG_FORCE_PDC hack
# 
# include/linux/ide.h
#   2005/01/21 20:14:29+01:00 bzolnier@trik.(none) +0 -1
#   [ide] ignore BIOS enable bits for Promise controllers
# 
# drivers/ide/setup-pci.c
#   2005/01/21 20:14:29+01:00 bzolnier@trik.(none) +1 -14
#   [ide] ignore BIOS enable bits for Promise controllers
# 
# drivers/ide/pci/pdc202xx_old.h
#   2005/01/21 20:14:29+01:00 bzolnier@trik.(none) +0 -17
#   [ide] ignore BIOS enable bits for Promise controllers
# 
# drivers/ide/pci/pdc202xx_new.h
#   2005/01/21 20:14:29+01:00 bzolnier@trik.(none) +0 -6
#   [ide] ignore BIOS enable bits for Promise controllers
# 
# drivers/ide/Kconfig
#   2005/01/21 20:14:29+01:00 bzolnier@trik.(none) +0 -7
#   [ide] ignore BIOS enable bits for Promise controllers
# 
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/block/ll_rw_blk.c	2005-03-30 17:28:48 -08:00
@@ -1050,7 +1050,6 @@
 	"REQ_QUIET",
 	"REQ_SPECIAL",
 	"REQ_DRIVE_CMD",
-	"REQ_DRIVE_TASK",
 	"REQ_DRIVE_TASKFILE",
 	"REQ_PREEMPT",
 	"REQ_PM_SUSPEND",
diff -Nru a/drivers/ide/Kconfig b/drivers/ide/Kconfig
--- a/drivers/ide/Kconfig	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/Kconfig	2005-03-30 17:28:48 -08:00
@@ -658,13 +658,6 @@
 config BLK_DEV_PDC202XX_NEW
 	tristate "PROMISE PDC202{68|69|70|71|75|76|77} support"
 
-# FIXME - probably wants to be one for old and for new
-config PDC202XX_FORCE
-	bool "Enable controller even if disabled by BIOS"
-	depends on BLK_DEV_PDC202XX_NEW
-	help
-	  Enable the PDC202xx controller even if it has been disabled in the BIOS setup.
-
 config BLK_DEV_SVWKS
 	tristate "ServerWorks OSB4/CSB5/CSB6 chipsets support"
 	help
diff -Nru a/drivers/ide/Makefile b/drivers/ide/Makefile
--- a/drivers/ide/Makefile	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/Makefile	2005-03-30 17:28:48 -08:00
@@ -13,8 +13,7 @@
 
 obj-$(CONFIG_BLK_DEV_IDE)		+= pci/
 
-ide-core-y += ide.o ide-default.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
-	ide-taskfile.o
+ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o
 
 ide-core-$(CONFIG_BLK_DEV_CMD640)	+= pci/cmd640.o
 
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-cd.c	2005-03-30 17:28:48 -08:00
@@ -328,7 +328,8 @@
 
 #define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref) 
 
-#define ide_cd_g(disk)	((disk)->private_data)
+#define ide_cd_g(disk) \
+	container_of((disk)->private_data, struct cdrom_info, driver)
 
 static struct cdrom_info *ide_cd_get(struct gendisk *disk)
 {
@@ -556,10 +557,13 @@
 /*
  * Initialize a ide-cd packet command request
  */
-static void cdrom_prepare_request(struct request *rq)
+static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq)
 {
+	struct cdrom_info *cd = drive->driver_data;
+
 	ide_init_drive_cmd(rq);
 	rq->flags = REQ_PC;
+	rq->rq_disk = cd->disk;
 }
 
 static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
@@ -572,7 +576,7 @@
 		sense = &info->sense_data;
 
 	/* stuff the sense request in front of our current request */
-	cdrom_prepare_request(rq);
+	cdrom_prepare_request(drive, rq);
 
 	rq->data = sense;
 	rq->cmd[0] = GPCMD_REQUEST_SENSE;
@@ -1856,7 +1860,7 @@
 static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
 {
 	struct cdrom_info *info = drive->driver_data;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g = info->disk;
 	unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
 
 	/*
@@ -2048,7 +2052,7 @@
 	struct cdrom_info *info = drive->driver_data;
 	struct cdrom_device_info *cdi = &info->devinfo;
 
-	cdrom_prepare_request(&req);
+	cdrom_prepare_request(drive, &req);
 
 	req.sense = sense;
 	req.cmd[0] = GPCMD_TEST_UNIT_READY;
@@ -2080,7 +2084,7 @@
 	if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) {
 		stat = 0;
 	} else {
-		cdrom_prepare_request(&req);
+		cdrom_prepare_request(drive, &req);
 		req.sense = sense;
 		req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
 		req.cmd[4] = lockflag ? 1 : 0;
@@ -2124,7 +2128,7 @@
 	if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag)
 		return 0;
 
-	cdrom_prepare_request(&req);
+	cdrom_prepare_request(drive, &req);
 
 	/* only tell drive to close tray if open, if it can do that */
 	if (ejectflag && !CDROM_CONFIG_FLAGS(drive)->close_tray)
@@ -2148,7 +2152,7 @@
 	int stat;
 	struct request req;
 
-	cdrom_prepare_request(&req);
+	cdrom_prepare_request(drive, &req);
 
 	req.sense = sense;
 	req.cmd[0] = GPCMD_READ_CDVD_CAPACITY;
@@ -2171,7 +2175,7 @@
 {
 	struct request req;
 
-	cdrom_prepare_request(&req);
+	cdrom_prepare_request(drive, &req);
 
 	req.sense = sense;
 	req.data =  buf;
@@ -2228,7 +2232,7 @@
 	if (stat)
 		toc->capacity = 0x1fffff;
 
-	set_capacity(drive->disk, toc->capacity * sectors_per_frame);
+	set_capacity(info->disk, toc->capacity * sectors_per_frame);
 	blk_queue_hardsect_size(drive->queue,
 				sectors_per_frame << SECTOR_BITS);
 
@@ -2266,7 +2270,7 @@
 		   If we get an error for the regular case, we assume
 		   a CDI without additional audio tracks. In this case
 		   the readable TOC is empty (CDI tracks are not included)
-		   and only holds the Leadout entry. Heiko Eißfeldt */
+		   and only holds the Leadout entry. Heiko Ei�eldt */
 		ntracks = 0;
 		stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
 					   (char *)&toc->hdr,
@@ -2348,7 +2352,7 @@
 	stat = cdrom_get_last_written(cdi, &last_written);
 	if (!stat && (last_written > toc->capacity)) {
 		toc->capacity = last_written;
-		set_capacity(drive->disk, toc->capacity * sectors_per_frame);
+		set_capacity(info->disk, toc->capacity * sectors_per_frame);
 	}
 
 	/* Remember that we've read this stuff. */
@@ -2363,7 +2367,7 @@
 {
 	struct request req;
 
-	cdrom_prepare_request(&req);
+	cdrom_prepare_request(drive, &req);
 
 	req.sense = sense;
 	req.data = buf;
@@ -2383,7 +2387,7 @@
 			      struct request_sense *sense)
 {
 	struct request req;
-	cdrom_prepare_request(&req);
+	cdrom_prepare_request(drive, &req);
 
 	req.sense = sense;
 	if (speed == 0)
@@ -2413,7 +2417,7 @@
 	struct request_sense sense;
 	struct request req;
 
-	cdrom_prepare_request(&req);
+	cdrom_prepare_request(drive, &req);
 
 	req.sense = &sense;
 	req.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
@@ -2463,7 +2467,7 @@
 	/* here we queue the commands from the uniform CD-ROM
 	   layer. the packet must be complete, as we do not
 	   touch it at all. */
-	cdrom_prepare_request(&req);
+	cdrom_prepare_request(drive, &req);
 	memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE);
 	if (cgc->sense)
 		memset(cgc->sense, 0, sizeof(struct request_sense));
@@ -2613,7 +2617,7 @@
 	struct request req;
 	int ret;
 
-	cdrom_prepare_request(&req);
+	cdrom_prepare_request(drive, &req);
 	req.flags = REQ_SPECIAL | REQ_QUIET;
 	ret = ide_do_drive_cmd(drive, &req, ide_wait);
 
@@ -2857,7 +2861,7 @@
 	if (!CDROM_CONFIG_FLAGS(drive)->mo_drive)
 		devinfo->mask |= CDC_MO_DRIVE;
 
-	devinfo->disk = drive->disk;
+	devinfo->disk = info->disk;
 	return register_cdrom(devinfo);
 }
 
@@ -3219,6 +3223,9 @@
 	 */
 	blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
 
+	if (drive->autotune == IDE_TUNE_DEFAULT ||
+	    drive->autotune == IDE_TUNE_AUTO)
+		drive->dsc_overlap = (drive->next != drive);
 #if 0
 	drive->dsc_overlap = (HWIF(drive)->no_dsc) ? 0 : 1;
 	if (HWIF(drive)->no_dsc) {
@@ -3248,18 +3255,14 @@
 	return capacity * sectors_per_frame;
 }
 
-static
-int ide_cdrom_cleanup(ide_drive_t *drive)
+static int ide_cd_remove(struct device *dev)
 {
+	ide_drive_t *drive = to_ide_device(dev);
 	struct cdrom_info *info = drive->driver_data;
 
-	if (ide_unregister_subdriver(drive)) {
-		printk(KERN_ERR "%s: %s: failed to ide_unregister_subdriver\n",
-			__FUNCTION__, drive->name);
-		return 1;
-	}
+	ide_unregister_subdriver(drive, info->driver);
 
-	del_gendisk(drive->disk);
+	del_gendisk(info->disk);
 
 	ide_cd_put(info);
 
@@ -3271,7 +3274,7 @@
 	struct cdrom_info *info = to_ide_cd(kref);
 	struct cdrom_device_info *devinfo = &info->devinfo;
 	ide_drive_t *drive = info->drive;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g = info->disk;
 
 	if (info->buffer != NULL)
 		kfree(info->buffer);
@@ -3282,14 +3285,15 @@
 	if (devinfo->handle == drive && unregister_cdrom(devinfo))
 		printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
 				"driver.\n", __FUNCTION__, drive->name);
+	drive->dsc_overlap = 0;
 	drive->driver_data = NULL;
 	blk_queue_prep_rq(drive->queue, NULL);
 	g->private_data = NULL;
-	g->fops = ide_fops;
+	put_disk(g);
 	kfree(info);
 }
 
-static int ide_cdrom_attach (ide_drive_t *drive);
+static int ide_cd_probe(struct device *);
 
 #ifdef CONFIG_PROC_FS
 static int proc_idecd_read_capacity
@@ -3312,19 +3316,20 @@
 
 static ide_driver_t ide_cdrom_driver = {
 	.owner			= THIS_MODULE,
-	.name			= "ide-cdrom",
+	.gen_driver = {
+		.name		= "ide-cdrom",
+		.bus		= &ide_bus_type,
+		.probe		= ide_cd_probe,
+		.remove		= ide_cd_remove,
+	},
 	.version		= IDECD_VERSION,
 	.media			= ide_cdrom,
-	.busy			= 0,
 	.supports_dsc_overlap	= 1,
-	.cleanup		= ide_cdrom_cleanup,
 	.do_request		= ide_do_rw_cdrom,
 	.end_request		= ide_end_request,
 	.error			= __ide_error,
 	.abort			= __ide_abort,
 	.proc			= idecd_proc,
-	.attach			= ide_cdrom_attach,
-	.drives			= LIST_HEAD_INIT(ide_cdrom_driver.drives),
 };
 
 static int idecd_open(struct inode * inode, struct file * file)
@@ -3410,10 +3415,11 @@
 module_param(ignore, charp, 0400);
 MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
 
-static int ide_cdrom_attach (ide_drive_t *drive)
+static int ide_cd_probe(struct device *dev)
 {
+	ide_drive_t *drive = to_ide_device(dev);
 	struct cdrom_info *info;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g;
 	struct request_sense sense;
 
 	if (!strstr("ide-cdrom", drive->driver_req))
@@ -3438,20 +3444,27 @@
 		printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
 		goto failed;
 	}
-	if (ide_register_subdriver(drive, &ide_cdrom_driver)) {
-		printk(KERN_ERR "%s: Failed to register the driver with ide.c\n",
-			drive->name);
-		kfree(info);
-		goto failed;
-	}
+
+	g = alloc_disk(1 << PARTN_BITS);
+	if (!g)
+		goto out_free_cd;
+
+	ide_init_disk(g, drive);
+
+	ide_register_subdriver(drive, &ide_cdrom_driver);
+
 	memset(info, 0, sizeof (struct cdrom_info));
 
 	kref_init(&info->kref);
 
 	info->drive = drive;
+	info->driver = &ide_cdrom_driver;
+	info->disk = g;
+
+	g->private_data = &info->driver;
+
 	drive->driver_data = info;
 
-	DRIVER(drive)->busy++;
 	g->minors = 1;
 	snprintf(g->devfs_name, sizeof(g->devfs_name),
 			"%s/cd", drive->devfs_name);
@@ -3459,8 +3472,7 @@
 	g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
 	if (ide_cdrom_setup(drive)) {
 		struct cdrom_device_info *devinfo = &info->devinfo;
-		DRIVER(drive)->busy--;
-		ide_unregister_subdriver(drive);
+		ide_unregister_subdriver(drive, &ide_cdrom_driver);
 		if (info->buffer != NULL)
 			kfree(info->buffer);
 		if (info->toc != NULL)
@@ -3473,27 +3485,27 @@
 		drive->driver_data = NULL;
 		goto failed;
 	}
-	DRIVER(drive)->busy--;
 
 	cdrom_read_toc(drive, &sense);
 	g->fops = &idecd_ops;
-	g->private_data = info;
 	g->flags |= GENHD_FL_REMOVABLE;
 	add_disk(g);
 	return 0;
+
+out_free_cd:
+	kfree(info);
 failed:
-	return 1;
+	return -ENODEV;
 }
 
 static void __exit ide_cdrom_exit(void)
 {
-	ide_unregister_driver(&ide_cdrom_driver);
+	driver_unregister(&ide_cdrom_driver.gen_driver);
 }
  
 static int ide_cdrom_init(void)
 {
-	ide_register_driver(&ide_cdrom_driver);
-	return 0;
+	return driver_register(&ide_cdrom_driver.gen_driver);
 }
 
 module_init(ide_cdrom_init);
diff -Nru a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
--- a/drivers/ide/ide-cd.h	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-cd.h	2005-03-30 17:28:48 -08:00
@@ -461,6 +461,8 @@
 /* Extra per-device info for cdrom drives. */
 struct cdrom_info {
 	ide_drive_t	*drive;
+	ide_driver_t	*driver;
+	struct gendisk	*disk;
 	struct kref	kref;
 
 	/* Buffer for table of contents.  NULL if we haven't allocated
diff -Nru a/drivers/ide/ide-default.c b/drivers/ide/ide-default.c
--- a/drivers/ide/ide-default.c	2005-03-30 17:28:48 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,76 +0,0 @@
-/*
- *	ide-default		-	Driver for unbound ide devices
- *
- *	This provides a clean way to bind a device to default operations
- *	by having an actual driver class that rather than special casing
- *	"no driver" all over the IDE code
- *
- *	Copyright (C) 2003, Red Hat <alan@redhat.com>
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/major.h>
-#include <linux/errno.h>
-#include <linux/genhd.h>
-#include <linux/slab.h>
-#include <linux/cdrom.h>
-#include <linux/ide.h>
-#include <linux/bitops.h>
-
-#include <asm/byteorder.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/unaligned.h>
-
-#define IDEDEFAULT_VERSION	"0.9.newide"
-/*
- *	Driver initialization.
- */
-
-static int idedefault_attach(ide_drive_t *drive);
-
-static ide_startstop_t idedefault_do_request(ide_drive_t *drive, struct request *rq, sector_t block)
-{
-	ide_end_request(drive, 0, 0);
-	return ide_stopped;
-}
-
-/*
- *	IDE subdriver functions, registered with ide.c
- */
-
-ide_driver_t idedefault_driver = {
-	.name		=	"ide-default",
-	.version	=	IDEDEFAULT_VERSION,
-	.attach		=	idedefault_attach,
-	.cleanup	=	ide_unregister_subdriver,
-	.do_request	=	idedefault_do_request,
-	.end_request	=	ide_end_request,
-	.error		=	__ide_error,
-	.abort		=	__ide_abort,
-	.drives		=	LIST_HEAD_INIT(idedefault_driver.drives)
-};
-
-static int idedefault_attach (ide_drive_t *drive)
-{
-	if (ide_register_subdriver(drive, &idedefault_driver)) {
-		printk(KERN_ERR "ide-default: %s: Failed to register the "
-			"driver with ide.c\n", drive->name);
-		return 1;
-	}
-
-	return 0;
-}
-
-MODULE_DESCRIPTION("IDE Default Driver");
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
--- a/drivers/ide/ide-disk.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-disk.c	2005-03-30 17:28:48 -08:00
@@ -73,6 +73,8 @@
 
 struct ide_disk_obj {
 	ide_drive_t	*drive;
+	ide_driver_t	*driver;
+	struct gendisk	*disk;
 	struct kref	kref;
 };
 
@@ -80,7 +82,8 @@
 
 #define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref)
 
-#define ide_disk_g(disk) ((disk)->private_data)
+#define ide_disk_g(disk) \
+	container_of((disk)->private_data, struct ide_disk_obj, driver)
 
 static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
 {
@@ -322,55 +325,31 @@
  * Queries for true maximum capacity of the drive.
  * Returns maximum LBA address (> 0) of the drive, 0 if failed.
  */
-static unsigned long idedisk_read_native_max_address(ide_drive_t *drive)
-{
-	ide_task_t args;
-	unsigned long addr = 0;
-
-	/* Create IDE/ATA command request structure */
-	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_SELECT_OFFSET]	= 0x40;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_READ_NATIVE_MAX;
-	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
-	args.handler				= &task_no_data_intr;
-	/* submit command request */
-	ide_raw_taskfile(drive, &args, NULL);
-
-	/* if OK, compute maximum address value */
-	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
-		addr = ((args.tfRegister[IDE_SELECT_OFFSET] & 0x0f) << 24)
-		     | ((args.tfRegister[  IDE_HCYL_OFFSET]       ) << 16)
-		     | ((args.tfRegister[  IDE_LCYL_OFFSET]       ) <<  8)
-		     | ((args.tfRegister[IDE_SECTOR_OFFSET]       ));
-		addr++;	/* since the return value is (maxlba - 1), we add 1 */
-	}
-	return addr;
-}
-
-static unsigned long long idedisk_read_native_max_address_ext(ide_drive_t *drive)
+static u64 idedisk_read_native_max_address(ide_drive_t *drive, unsigned int lba48)
 {
 	ide_task_t args;
+	struct ata_taskfile *tf = &args.tf;
 	unsigned long long addr = 0;
 
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(ide_task_t));
 
-	args.tfRegister[IDE_SELECT_OFFSET]	= 0x40;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_READ_NATIVE_MAX_EXT;
+	tf->device = ATA_LBA;
+	if (lba48) {
+		tf->command = WIN_READ_NATIVE_MAX_EXT;
+		tf->flags |= ATA_TFLAG_LBA48;
+	} else
+		tf->command = WIN_READ_NATIVE_MAX;
+
 	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
 	args.handler				= &task_no_data_intr;
+
         /* submit command request */
         ide_raw_taskfile(drive, &args, NULL);
 
 	/* if OK, compute maximum address value */
-	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
-		u32 high = (args.hobRegister[IDE_HCYL_OFFSET] << 16) |
-			   (args.hobRegister[IDE_LCYL_OFFSET] <<  8) |
-			    args.hobRegister[IDE_SECTOR_OFFSET];
-		u32 low  = ((args.tfRegister[IDE_HCYL_OFFSET])<<16) |
-			   ((args.tfRegister[IDE_LCYL_OFFSET])<<8) |
-			    (args.tfRegister[IDE_SECTOR_OFFSET]);
-		addr = ((__u64)high << 24) | low;
+	if ((tf->command & 1) == 0) {
+		addr = ide_tf_get_address(drive, tf);
 		addr++;	/* since the return value is (maxlba - 1), we add 1 */
 	}
 	return addr;
@@ -380,65 +359,39 @@
  * Sets maximum virtual LBA address of the drive.
  * Returns new maximum virtual LBA address (> 0) or 0 on failure.
  */
-static unsigned long idedisk_set_max_address(ide_drive_t *drive, unsigned long addr_req)
-{
-	ide_task_t args;
-	unsigned long addr_set = 0;
-	
-	addr_req--;
-	/* Create IDE/ATA command request structure */
-	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_SECTOR_OFFSET]	= ((addr_req >>  0) & 0xff);
-	args.tfRegister[IDE_LCYL_OFFSET]	= ((addr_req >>  8) & 0xff);
-	args.tfRegister[IDE_HCYL_OFFSET]	= ((addr_req >> 16) & 0xff);
-	args.tfRegister[IDE_SELECT_OFFSET]	= ((addr_req >> 24) & 0x0f) | 0x40;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SET_MAX;
-	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
-	args.handler				= &task_no_data_intr;
-	/* submit command request */
-	ide_raw_taskfile(drive, &args, NULL);
-	/* if OK, read new maximum address value */
-	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
-		addr_set = ((args.tfRegister[IDE_SELECT_OFFSET] & 0x0f) << 24)
-			 | ((args.tfRegister[  IDE_HCYL_OFFSET]       ) << 16)
-			 | ((args.tfRegister[  IDE_LCYL_OFFSET]       ) <<  8)
-			 | ((args.tfRegister[IDE_SECTOR_OFFSET]       ));
-		addr_set++;
-	}
-	return addr_set;
-}
-
-static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsigned long long addr_req)
+static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, unsigned int lba48)
 {
 	ide_task_t args;
+	struct ata_taskfile *tf = &args.tf;
 	unsigned long long addr_set = 0;
 
 	addr_req--;
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_SECTOR_OFFSET]	= ((addr_req >>  0) & 0xff);
-	args.tfRegister[IDE_LCYL_OFFSET]	= ((addr_req >>= 8) & 0xff);
-	args.tfRegister[IDE_HCYL_OFFSET]	= ((addr_req >>= 8) & 0xff);
-	args.tfRegister[IDE_SELECT_OFFSET]      = 0x40;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SET_MAX_EXT;
-	args.hobRegister[IDE_SECTOR_OFFSET]	= (addr_req >>= 8) & 0xff;
-	args.hobRegister[IDE_LCYL_OFFSET]	= (addr_req >>= 8) & 0xff;
-	args.hobRegister[IDE_HCYL_OFFSET]	= (addr_req >>= 8) & 0xff;
-	args.hobRegister[IDE_SELECT_OFFSET]	= 0x40;
-	args.hobRegister[IDE_CONTROL_OFFSET_HOB]= (drive->ctl|0x80);
+
+	tf->lbal = addr_req;
+	tf->lbam = addr_req >> 8;
+	tf->lbah = addr_req >> 16;
+	if (lba48) {
+		tf->hob_lbal = addr_req >> 24;
+		tf->hob_lbam = addr_req >> 32;
+		tf->hob_lbah = addr_req >> 40;
+		tf->device   = ATA_LBA;
+		tf->command  = WIN_SET_MAX_EXT;
+		tf->flags |= ATA_TFLAG_LBA48;
+	} else {
+		tf->device  = ((addr_req >> 24) & 0xf) | ATA_LBA;
+		tf->command = WIN_SET_MAX;
+	}
+
 	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
 	args.handler				= &task_no_data_intr;
+
 	/* submit command request */
 	ide_raw_taskfile(drive, &args, NULL);
 	/* if OK, compute maximum address value */
-	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
-		u32 high = (args.hobRegister[IDE_HCYL_OFFSET] << 16) |
-			   (args.hobRegister[IDE_LCYL_OFFSET] <<  8) |
-			    args.hobRegister[IDE_SECTOR_OFFSET];
-		u32 low  = ((args.tfRegister[IDE_HCYL_OFFSET])<<16) |
-			   ((args.tfRegister[IDE_LCYL_OFFSET])<<8) |
-			    (args.tfRegister[IDE_SECTOR_OFFSET]);
-		addr_set = ((__u64)high << 24) | low;
+	if ((tf->command & 1) == 0) {
+		addr_set = ide_tf_get_address(drive, tf);
 		addr_set++;
 	}
 	return addr_set;
@@ -476,10 +429,8 @@
 	int lba48 = idedisk_supports_lba48(drive->id);
 
 	capacity = drive->capacity64;
-	if (lba48)
-		set_max = idedisk_read_native_max_address_ext(drive);
-	else
-		set_max = idedisk_read_native_max_address(drive);
+
+	set_max = idedisk_read_native_max_address(drive, lba48);
 
 	if (set_max <= capacity)
 		return;
@@ -491,10 +442,8 @@
 			 capacity, sectors_to_MB(capacity),
 			 set_max, sectors_to_MB(set_max));
 
-	if (lba48)
-		set_max = idedisk_set_max_address_ext(drive, set_max);
-	else
-		set_max = idedisk_set_max_address(drive, set_max);
+	set_max = idedisk_set_max_address(drive, set_max, lba48);
+
 	if (set_max) {
 		drive->capacity64 = set_max;
 		printk(KERN_INFO "%s: Host Protected Area disabled.\n",
@@ -553,12 +502,15 @@
 static int smart_enable(ide_drive_t *drive)
 {
 	ide_task_t args;
+	struct ata_taskfile *tf = &args.tf;
 
 	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_FEATURE_OFFSET]	= SMART_ENABLE;
-	args.tfRegister[IDE_LCYL_OFFSET]	= SMART_LCYL_PASS;
-	args.tfRegister[IDE_HCYL_OFFSET]	= SMART_HCYL_PASS;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SMART;
+
+	tf->feature	= SMART_ENABLE;
+	tf->lbam	= SMART_LCYL_PASS;
+	tf->lbah	= SMART_HCYL_PASS;
+	tf->command	= WIN_SMART;
+
 	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
 	args.handler				= &task_no_data_intr;
 	return ide_raw_taskfile(drive, &args, NULL);
@@ -567,13 +519,16 @@
 static int get_smart_values(ide_drive_t *drive, u8 *buf)
 {
 	ide_task_t args;
+	struct ata_taskfile *tf = &args.tf;
 
 	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_FEATURE_OFFSET]	= SMART_READ_VALUES;
-	args.tfRegister[IDE_NSECTOR_OFFSET]	= 0x01;
-	args.tfRegister[IDE_LCYL_OFFSET]	= SMART_LCYL_PASS;
-	args.tfRegister[IDE_HCYL_OFFSET]	= SMART_HCYL_PASS;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SMART;
+
+	tf->feature	= SMART_READ_VALUES;
+	tf->nsect	= 1;
+	tf->lbam	= SMART_LCYL_PASS;
+	tf->lbah	= SMART_HCYL_PASS;
+	tf->command	= WIN_SMART;
+
 	args.command_type			= IDE_DRIVE_TASK_IN;
 	args.data_phase				= TASKFILE_IN;
 	args.handler				= &task_in_intr;
@@ -584,12 +539,16 @@
 static int get_smart_thresholds(ide_drive_t *drive, u8 *buf)
 {
 	ide_task_t args;
+	struct ata_taskfile *tf = &args.tf;
+
 	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_FEATURE_OFFSET]	= SMART_READ_THRESHOLDS;
-	args.tfRegister[IDE_NSECTOR_OFFSET]	= 0x01;
-	args.tfRegister[IDE_LCYL_OFFSET]	= SMART_LCYL_PASS;
-	args.tfRegister[IDE_HCYL_OFFSET]	= SMART_HCYL_PASS;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SMART;
+
+	tf->feature	= SMART_READ_THRESHOLDS;
+	tf->nsect	= 1;
+	tf->lbam	= SMART_LCYL_PASS;
+	tf->lbah	= SMART_HCYL_PASS;
+	tf->command	= WIN_SMART;
+
 	args.command_type			= IDE_DRIVE_TASK_IN;
 	args.data_phase				= TASKFILE_IN;
 	args.handler				= &task_in_intr;
@@ -690,7 +649,10 @@
 	} else if (flush_rq->errors) {
 		good_sectors = 0;
 		if (blk_barrier_preflush(rq)) {
-			sector = ide_get_error_location(drive,flush_rq->buffer);
+			ide_task_t *task = flush_rq->special;
+
+			sector = ide_tf_get_address(drive, &task->tf);
+
 			if ((sector >= rq->hard_sector) &&
 			    (sector < rq->hard_sector + rq->hard_nr_sectors))
 				good_sectors = sector - rq->hard_sector;
@@ -715,21 +677,16 @@
 static int idedisk_prepare_flush(request_queue_t *q, struct request *rq)
 {
 	ide_drive_t *drive = q->queuedata;
+	ide_task_t *task = &drive->flush_task;
 
 	if (!drive->wcache)
 		return 0;
 
-	memset(rq->cmd, 0, sizeof(rq->cmd));
-
-	if (ide_id_has_flush_cache_ext(drive->id) &&
-	    (drive->capacity64 >= (1UL << 28)))
-		rq->cmd[0] = WIN_FLUSH_CACHE_EXT;
-	else
-		rq->cmd[0] = WIN_FLUSH_CACHE;
+	ide_task_init_flush(drive, task);
 
+	rq->flags |= REQ_DRIVE_TASKFILE | REQ_SOFTBARRIER;
+	rq->special = &task;
 
-	rq->flags |= REQ_DRIVE_TASK | REQ_SOFTBARRIER;
-	rq->buffer = rq->cmd;
 	return 1;
 }
 
@@ -738,6 +695,7 @@
 {
 	ide_drive_t *drive = q->queuedata;
 	struct request *rq;
+	ide_task_t task;
 	int ret;
 
 	if (!drive->wcache)
@@ -745,7 +703,10 @@
 
 	rq = blk_get_request(q, WRITE, __GFP_WAIT);
 
-	idedisk_prepare_flush(q, rq);
+	ide_task_init_flush(drive, &task);
+
+	rq->flags |= REQ_DRIVE_TASKFILE | REQ_SOFTBARRIER;
+	rq->special = &task;
 
 	ret = blk_execute_rq(q, disk, rq);
 
@@ -753,7 +714,7 @@
 	 * if we failed and caller wants error offset, get it
 	 */
 	if (ret && error_sector)
-		*error_sector = ide_get_error_location(drive, rq->cmd);
+		*error_sector = ide_tf_get_address(drive, &task.tf);
 
 	blk_put_request(rq);
 	return ret;
@@ -790,15 +751,17 @@
 static int write_cache(ide_drive_t *drive, int arg)
 {
 	ide_task_t args;
+	struct ata_taskfile *tf = &args.tf;
 	int err;
 
 	if (!ide_id_has_flush_cache(drive->id))
 		return 1;
 
 	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_FEATURE_OFFSET]	= (arg) ?
-			SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SETFEATURES;
+
+	tf->feature = arg ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
+	tf->command = WIN_SETFEATURES;
+
 	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
 	args.handler				= &task_no_data_intr;
 
@@ -810,29 +773,17 @@
 	return 0;
 }
 
-static int do_idedisk_flushcache (ide_drive_t *drive)
+static int set_acoustic (ide_drive_t *drive, int arg)
 {
 	ide_task_t args;
+	struct ata_taskfile *tf = &args.tf;
 
 	memset(&args, 0, sizeof(ide_task_t));
-	if (ide_id_has_flush_cache_ext(drive->id))
-		args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_FLUSH_CACHE_EXT;
-	else
-		args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_FLUSH_CACHE;
-	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
-	args.handler				= &task_no_data_intr;
-	return ide_raw_taskfile(drive, &args, NULL);
-}
 
-static int set_acoustic (ide_drive_t *drive, int arg)
-{
-	ide_task_t args;
+	tf->feature	= arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM;
+	tf->nsect	= arg;
+	tf->command	= WIN_SETFEATURES;
 
-	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_FEATURE_OFFSET]	= (arg) ? SETFEATURES_EN_AAM :
-							  SETFEATURES_DIS_AAM;
-	args.tfRegister[IDE_NSECTOR_OFFSET]	= arg;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SETFEATURES;
 	args.command_type = IDE_DRIVE_TASK_NO_DATA;
 	args.handler	  = &task_no_data_intr;
 	ide_raw_taskfile(drive, &args, NULL);
@@ -1014,21 +965,27 @@
 
 static void ide_cacheflush_p(ide_drive_t *drive)
 {
+	ide_task_t task;
+
 	if (!drive->wcache || !ide_id_has_flush_cache(drive->id))
 		return;
 
-	if (do_idedisk_flushcache(drive))
+	ide_task_init_flush(drive, &task);
+
+	if (ide_raw_taskfile(drive, &task, NULL))
 		printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
 }
 
-static int idedisk_cleanup (ide_drive_t *drive)
+static int ide_disk_remove(struct device *dev)
 {
+	ide_drive_t *drive = to_ide_device(dev);
 	struct ide_disk_obj *idkp = drive->driver_data;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g = idkp->disk;
 
 	ide_cacheflush_p(drive);
-	if (ide_unregister_subdriver(drive))
-		return 1;
+
+	ide_unregister_subdriver(drive, idkp->driver);
+
 	del_gendisk(g);
 
 	ide_disk_put(idkp);
@@ -1040,16 +997,16 @@
 {
 	struct ide_disk_obj *idkp = to_ide_disk(kref);
 	ide_drive_t *drive = idkp->drive;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g = idkp->disk;
 
 	drive->driver_data = NULL;
 	drive->devfs_name[0] = '\0';
 	g->private_data = NULL;
-	g->fops = ide_fops;
+	put_disk(g);
 	kfree(idkp);
 }
 
-static int idedisk_attach(ide_drive_t *drive);
+static int ide_disk_probe(struct device *dev);
 
 static void ide_device_shutdown(struct device *dev)
 {
@@ -1079,27 +1036,23 @@
 	dev->bus->suspend(dev, PMSG_SUSPEND);
 }
 
-/*
- *      IDE subdriver functions, registered with ide.c
- */
 static ide_driver_t idedisk_driver = {
 	.owner			= THIS_MODULE,
 	.gen_driver = {
+		.name		= "ide-disk",
+		.bus		= &ide_bus_type,
+		.probe		= ide_disk_probe,
+		.remove		= ide_disk_remove,
 		.shutdown	= ide_device_shutdown,
 	},
-	.name			= "ide-disk",
 	.version		= IDEDISK_VERSION,
 	.media			= ide_disk,
-	.busy			= 0,
 	.supports_dsc_overlap	= 0,
-	.cleanup		= idedisk_cleanup,
 	.do_request		= ide_do_rw_disk,
 	.end_request		= ide_end_request,
 	.error			= __ide_error,
 	.abort			= __ide_abort,
 	.proc			= idedisk_proc,
-	.attach			= idedisk_attach,
-	.drives			= LIST_HEAD_INIT(idedisk_driver.drives),
 };
 
 static int idedisk_open(struct inode *inode, struct file *filp)
@@ -1117,7 +1070,7 @@
 	if (drive->removable && drive->usage == 1) {
 		ide_task_t args;
 		memset(&args, 0, sizeof(ide_task_t));
-		args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK;
+		args.tf.command = WIN_DOORLOCK;
 		args.command_type = IDE_DRIVE_TASK_NO_DATA;
 		args.handler	  = &task_no_data_intr;
 		check_disk_change(inode->i_bdev);
@@ -1143,7 +1096,7 @@
 	if (drive->removable && drive->usage == 1) {
 		ide_task_t args;
 		memset(&args, 0, sizeof(ide_task_t));
-		args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORUNLOCK;
+		args.tf.command = WIN_DOORUNLOCK;
 		args.command_type = IDE_DRIVE_TASK_NO_DATA;
 		args.handler	  = &task_no_data_intr;
 		if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL))
@@ -1196,10 +1149,11 @@
 
 MODULE_DESCRIPTION("ATA DISK Driver");
 
-static int idedisk_attach(ide_drive_t *drive)
+static int ide_disk_probe(struct device *dev)
 {
+	ide_drive_t *drive = to_ide_device(dev);
 	struct ide_disk_obj *idkp;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g;
 
 	/* strstr("foo", "") is non-NULL */
 	if (!strstr("ide-disk", drive->driver_req))
@@ -1213,19 +1167,26 @@
 	if (!idkp)
 		goto failed;
 
-	if (ide_register_subdriver(drive, &idedisk_driver)) {
-		printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name);
+	g = alloc_disk(1 << PARTN_BITS);
+	if (!g)
 		goto out_free_idkp;
-	}
+
+	ide_init_disk(g, drive);
+
+	ide_register_subdriver(drive, &idedisk_driver);
 
 	memset(idkp, 0, sizeof(*idkp));
 
 	kref_init(&idkp->kref);
 
 	idkp->drive = drive;
+	idkp->driver = &idedisk_driver;
+	idkp->disk = g;
+
+	g->private_data = &idkp->driver;
+
 	drive->driver_data = idkp;
 
-	DRIVER(drive)->busy++;
 	idedisk_setup(drive);
 	if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
 		printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
@@ -1233,30 +1194,30 @@
 		drive->attach = 0;
 	} else
 		drive->attach = 1;
-	DRIVER(drive)->busy--;
+
 	g->minors = 1 << PARTN_BITS;
 	strcpy(g->devfs_name, drive->devfs_name);
 	g->driverfs_dev = &drive->gendev;
 	g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
 	set_capacity(g, idedisk_capacity(drive));
 	g->fops = &idedisk_ops;
-	g->private_data = idkp;
 	add_disk(g);
 	return 0;
+
 out_free_idkp:
 	kfree(idkp);
 failed:
-	return 1;
+	return -ENODEV;
 }
 
 static void __exit idedisk_exit (void)
 {
-	ide_unregister_driver(&idedisk_driver);
+	driver_unregister(&idedisk_driver.gen_driver);
 }
 
 static int idedisk_init (void)
 {
-	return ide_register_driver(&idedisk_driver);
+	return driver_register(&idedisk_driver.gen_driver);
 }
 
 module_init(idedisk_init);
diff -Nru a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
--- a/drivers/ide/ide-dma.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-dma.c	2005-03-30 17:28:48 -08:00
@@ -176,7 +176,13 @@
 		if (!dma_stat) {
 			struct request *rq = HWGROUP(drive)->rq;
 
-			DRIVER(drive)->end_request(drive, 1, rq->nr_sectors);
+			if (rq->rq_disk) {
+				ide_driver_t *drv;
+
+				drv = *(ide_driver_t **)rq->rq_disk->private_data;;
+				drv->end_request(drive, 1, rq->nr_sectors);
+			} else
+				ide_end_request(drive, 1, rq->nr_sectors);
 			return ide_stopped;
 		}
 		printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", 
diff -Nru a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
--- a/drivers/ide/ide-floppy.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-floppy.c	2005-03-30 17:28:48 -08:00
@@ -276,6 +276,8 @@
  */
 typedef struct ide_floppy_obj {
 	ide_drive_t	*drive;
+	ide_driver_t	*driver;
+	struct gendisk	*disk;
 	struct kref	kref;
 
 	/* Current packet command */
@@ -519,7 +521,8 @@
 
 #define to_ide_floppy(obj) container_of(obj, struct ide_floppy_obj, kref)
 
-#define ide_floppy_g(disk)	((disk)->private_data)
+#define ide_floppy_g(disk) \
+	container_of((disk)->private_data, struct ide_floppy_obj, driver)
 
 static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk)
 {
@@ -680,9 +683,12 @@
  */
 static void idefloppy_queue_pc_head (ide_drive_t *drive,idefloppy_pc_t *pc,struct request *rq)
 {
+	struct ide_floppy_obj *floppy = drive->driver_data;
+
 	ide_init_drive_cmd(rq);
 	rq->buffer = (char *) pc;
 	rq->flags = REQ_SPECIAL;	//rq->cmd = IDEFLOPPY_PC_RQ;
+	rq->rq_disk = floppy->disk;
 	(void) ide_do_drive_cmd(drive, rq, ide_preempt);
 }
 
@@ -1274,7 +1280,8 @@
 	unsigned long block = (unsigned long)block_s;
 
 	debug_log(KERN_INFO "rq_status: %d, dev: %s, flags: %lx, errors: %d\n",
-			rq->rq_status, rq->rq_disk->disk_name,
+			rq->rq_status,
+			rq->rq_disk ? rq->rq_disk->disk_name ? "?",
 			rq->flags, rq->errors);
 	debug_log(KERN_INFO "sector: %ld, nr_sectors: %ld, "
 			"current_nr_sectors: %d\n", (long)rq->sector,
@@ -1329,11 +1336,13 @@
  */
 static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc)
 {
+	struct ide_floppy_obj *floppy = drive->driver_data;
 	struct request rq;
 
 	ide_init_drive_cmd (&rq);
 	rq.buffer = (char *) pc;
 	rq.flags = REQ_SPECIAL;		//	rq.cmd = IDEFLOPPY_PC_RQ;
+	rq.rq_disk = floppy->disk;
 
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
@@ -1358,7 +1367,7 @@
 	}
 	header = (idefloppy_mode_parameter_header_t *) pc.buffer;
 	floppy->wp = header->wp;
-	set_disk_ro(drive->disk, floppy->wp);
+	set_disk_ro(floppy->disk, floppy->wp);
 	page = (idefloppy_flexible_disk_page_t *) (header + 1);
 
 	page->transfer_rate = ntohs(page->transfer_rate);
@@ -1424,7 +1433,7 @@
 	drive->bios_cyl = 0;
 	drive->bios_head = drive->bios_sect = 0;
 	floppy->blocks = floppy->bs_factor = 0;
-	set_capacity(drive->disk, 0);
+	set_capacity(floppy->disk, 0);
 
 	idefloppy_create_read_capacity_cmd(&pc);
 	if (idefloppy_queue_pc_tail(drive, &pc)) {
@@ -1498,7 +1507,7 @@
 		(void) idefloppy_get_flexible_disk_page(drive);
 	}
 
-	set_capacity(drive->disk, floppy->blocks * floppy->bs_factor);
+	set_capacity(floppy->disk, floppy->blocks * floppy->bs_factor);
 	return rc;
 }
 
@@ -1856,13 +1865,13 @@
 	idefloppy_add_settings(drive);
 }
 
-static int idefloppy_cleanup (ide_drive_t *drive)
+static int ide_floppy_remove(struct device *dev)
 {
+	ide_drive_t *drive = to_ide_device(dev);
 	idefloppy_floppy_t *floppy = drive->driver_data;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g = floppy->disk;
 
-	if (ide_unregister_subdriver(drive))
-		return 1;
+	ide_unregister_subdriver(drive, floppy->driver);
 
 	del_gendisk(g);
 
@@ -1875,11 +1884,11 @@
 {
 	struct ide_floppy_obj *floppy = to_ide_floppy(kref);
 	ide_drive_t *drive = floppy->drive;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g = floppy->disk;
 
 	drive->driver_data = NULL;
 	g->private_data = NULL;
-	g->fops = ide_fops;
+	put_disk(g);
 	kfree(floppy);
 }
 
@@ -1907,26 +1916,24 @@
 
 #endif	/* CONFIG_PROC_FS */
 
-static int idefloppy_attach(ide_drive_t *drive);
+static int ide_floppy_probe(struct device *);
 
-/*
- *	IDE subdriver functions, registered with ide.c
- */
 static ide_driver_t idefloppy_driver = {
 	.owner			= THIS_MODULE,
-	.name			= "ide-floppy",
+	.gen_driver = {
+		.name		= "ide-floppy",
+		.bus		= &ide_bus_type,
+		.probe		= ide_floppy_probe,
+		.remove		= ide_floppy_remove,
+	},
 	.version		= IDEFLOPPY_VERSION,
 	.media			= ide_floppy,
-	.busy			= 0,
 	.supports_dsc_overlap	= 0,
-	.cleanup		= idefloppy_cleanup,
 	.do_request		= idefloppy_do_request,
 	.end_request		= idefloppy_do_end_request,
 	.error			= __ide_error,
 	.abort			= __ide_abort,
 	.proc			= idefloppy_proc,
-	.attach			= idefloppy_attach,
-	.drives			= LIST_HEAD_INIT(idefloppy_driver.drives),
 };
 
 static int idefloppy_open(struct inode *inode, struct file *filp)
@@ -2113,10 +2120,12 @@
 	.revalidate_disk= idefloppy_revalidate_disk
 };
 
-static int idefloppy_attach (ide_drive_t *drive)
+static int ide_floppy_probe(struct device *dev)
 {
+	ide_drive_t *drive = to_ide_device(dev);
 	idefloppy_floppy_t *floppy;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g;
+
 	if (!strstr("ide-floppy", drive->driver_req))
 		goto failed;
 	if (!drive->present)
@@ -2135,41 +2144,49 @@
 		printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name);
 		goto failed;
 	}
-	if (ide_register_subdriver(drive, &idefloppy_driver)) {
-		printk (KERN_ERR "ide-floppy: %s: Failed to register the driver with ide.c\n", drive->name);
-		kfree (floppy);
-		goto failed;
-	}
+
+	g = alloc_disk(1 << PARTN_BITS);
+	if (!g)
+		goto out_free_floppy;
+
+	ide_init_disk(g, drive);
+
+	ide_register_subdriver(drive, &idefloppy_driver);
 
 	memset(floppy, 0, sizeof(*floppy));
 
 	kref_init(&floppy->kref);
 
 	floppy->drive = drive;
+	floppy->driver = &idefloppy_driver;
+	floppy->disk = g;
+
+	g->private_data = &floppy->driver;
 
 	drive->driver_data = floppy;
 
-	DRIVER(drive)->busy++;
 	idefloppy_setup (drive, floppy);
-	DRIVER(drive)->busy--;
+
 	g->minors = 1 << PARTN_BITS;
 	g->driverfs_dev = &drive->gendev;
 	strcpy(g->devfs_name, drive->devfs_name);
 	g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
 	g->fops = &idefloppy_ops;
-	g->private_data = floppy;
 	drive->attach = 1;
 	add_disk(g);
 	return 0;
+
+out_free_floppy:
+	kfree(floppy);
 failed:
-	return 1;
+	return -ENODEV;
 }
 
 MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
 
 static void __exit idefloppy_exit (void)
 {
-	ide_unregister_driver(&idefloppy_driver);
+	driver_unregister(&idefloppy_driver.gen_driver);
 }
 
 /*
@@ -2178,8 +2195,7 @@
 static int idefloppy_init (void)
 {
 	printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
-	ide_register_driver(&idefloppy_driver);
-	return 0;
+	return driver_register(&idefloppy_driver.gen_driver);
 }
 
 module_init(idefloppy_init);
diff -Nru a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
--- a/drivers/ide/ide-io.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-io.c	2005-03-30 17:28:48 -08:00
@@ -55,6 +55,28 @@
 #include <asm/io.h>
 #include <asm/bitops.h>
 
+void ide_task_init_flush(ide_drive_t *drive, ide_task_t *task)
+{
+	struct ata_taskfile *tf = &task->tf;
+
+	memset(task, 0, sizeof(*task));
+
+	if (drive->select.b.lba)
+		tf->device = ATA_LBA;
+
+	if (ide_id_has_flush_cache_ext(drive->id) &&
+	    (drive->capacity64 >= (1UL << 28))) {
+		tf->command = WIN_FLUSH_CACHE_EXT;
+		tf->flags |= ATA_TFLAG_LBA48;
+	} else
+		tf->command = WIN_FLUSH_CACHE;
+
+	task->command_type = IDE_DRIVE_TASK_NO_DATA;
+	task->handler	   = &task_no_data_intr;
+}
+
+EXPORT_SYMBOL_GPL(ide_task_init_flush);
+
 int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate,
 		      int nr_sectors)
 {
@@ -109,12 +131,13 @@
 
 int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
 {
+	ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
 	struct request *rq;
 	unsigned long flags;
 	int ret = 1;
 
 	spin_lock_irqsave(&ide_lock, flags);
-	rq = HWGROUP(drive)->rq;
+	rq = hwgroup->rq;
 
 	if (!nr_sectors)
 		nr_sectors = rq->hard_cur_sectors;
@@ -167,6 +190,7 @@
 static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
 {
 	ide_task_t *args = rq->special;
+	struct ata_taskfile *tf = &args->tf;
 
 	memset(args, 0, sizeof(*args));
 
@@ -185,22 +209,21 @@
 			ide_complete_power_step(drive, rq, 0, 0);
 			return ide_stopped;
 		}
-		if (ide_id_has_flush_cache_ext(drive->id))
-			args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT;
-		else
-			args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;
-		args->command_type = IDE_DRIVE_TASK_NO_DATA;
-		args->handler	   = &task_no_data_intr;
+
+		ide_task_init_flush(drive, args);
+
 		return do_rw_taskfile(drive, args);
 
 	case idedisk_pm_standby:	/* Suspend step 2 (standby) */
-		args->tfRegister[IDE_COMMAND_OFFSET] = WIN_STANDBYNOW1;
+		tf->command = WIN_STANDBYNOW1;
+
 		args->command_type = IDE_DRIVE_TASK_NO_DATA;
 		args->handler	   = &task_no_data_intr;
 		return do_rw_taskfile(drive, args);
 
 	case idedisk_pm_idle:		/* Resume step 1 (idle) */
-		args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE;
+		tf->command = WIN_IDLEIMMEDIATE;
+
 		args->command_type = IDE_DRIVE_TASK_NO_DATA;
 		args->handler = task_no_data_intr;
 		return do_rw_taskfile(drive, args);
@@ -251,40 +274,29 @@
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
-/*
- * FIXME: probably move this somewhere else, name is bad too :)
- */
-u64 ide_get_error_location(ide_drive_t *drive, char *args)
+u64 ide_tf_get_address(ide_drive_t *drive, struct ata_taskfile *tf)
 {
 	u32 high, low;
-	u8 hcyl, lcyl, sect;
-	u64 sector;
 
-	high = 0;
-	hcyl = args[5];
-	lcyl = args[4];
-	sect = args[3];
-
-	if (ide_id_has_flush_cache_ext(drive->id)) {
-		low = (hcyl << 16) | (lcyl << 8) | sect;
-		HWIF(drive)->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
-		high = ide_read_24(drive);
+	if (tf->flags & ATA_TFLAG_LBA48) {
+		high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) | tf->hob_lbal;
+		low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
 	} else {
-		u8 cur = HWIF(drive)->INB(IDE_SELECT_REG);
-		if (cur & 0x40) {
-			high = cur & 0xf;
-			low = (hcyl << 16) | (lcyl << 8) | sect;
+		if (tf->device & ATA_LBA) {
+			high = tf->device & 0xf;
+			low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
 		} else {
-			low = hcyl * drive->head * drive->sect;
-			low += lcyl * drive->sect;
-			low += sect - 1;
+			high = 0;
+			low = tf->lbah * drive->head * drive->sect;
+			low += tf->lbam * drive->sect;
+			low += tf->lbal - 1;
 		}
 	}
 
-	sector = ((u64) high << 24) | low;
-	return sector;
+	return ((u64)high << 24) | low;
 }
-EXPORT_SYMBOL(ide_get_error_location);
+
+EXPORT_SYMBOL_GPL(ide_tf_get_address);
 
 /**
  *	ide_end_drive_cmd	-	end an explicit drive command
@@ -320,48 +332,37 @@
 			args[1] = err;
 			args[2] = hwif->INB(IDE_NSECTOR_REG);
 		}
-	} else if (rq->flags & REQ_DRIVE_TASK) {
-		u8 *args = (u8 *) rq->buffer;
-		if (rq->errors == 0)
-			rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-
-		if (args) {
-			args[0] = stat;
-			args[1] = err;
-			args[2] = hwif->INB(IDE_NSECTOR_REG);
-			args[3] = hwif->INB(IDE_SECTOR_REG);
-			args[4] = hwif->INB(IDE_LCYL_REG);
-			args[5] = hwif->INB(IDE_HCYL_REG);
-			args[6] = hwif->INB(IDE_SELECT_REG);
-		}
 	} else if (rq->flags & REQ_DRIVE_TASKFILE) {
 		ide_task_t *args = (ide_task_t *) rq->special;
 		if (rq->errors == 0)
 			rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
 			
 		if (args) {
-			if (args->tf_in_flags.b.data) {
-				u16 data				= hwif->INW(IDE_DATA_REG);
-				args->tfRegister[IDE_DATA_OFFSET]	= (data) & 0xFF;
-				args->hobRegister[IDE_DATA_OFFSET]	= (data >> 8) & 0xFF;
-			}
-			args->tfRegister[IDE_ERROR_OFFSET]   = err;
+			struct ata_taskfile *tf = &args->tf;
+
+			if (args->tf_in_flags.b.data)
+				args->data = hwif->INW(IDE_DATA_REG);
+
+			tf->feature	= err;
+
 			/* be sure we're looking at the low order bits */
 			hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
-			args->tfRegister[IDE_NSECTOR_OFFSET] = hwif->INB(IDE_NSECTOR_REG);
-			args->tfRegister[IDE_SECTOR_OFFSET]  = hwif->INB(IDE_SECTOR_REG);
-			args->tfRegister[IDE_LCYL_OFFSET]    = hwif->INB(IDE_LCYL_REG);
-			args->tfRegister[IDE_HCYL_OFFSET]    = hwif->INB(IDE_HCYL_REG);
-			args->tfRegister[IDE_SELECT_OFFSET]  = hwif->INB(IDE_SELECT_REG);
-			args->tfRegister[IDE_STATUS_OFFSET]  = stat;
 
-			if (drive->addressing == 1) {
+			tf->nsect	= hwif->INB(IDE_NSECTOR_REG);
+			tf->lbal	= hwif->INB(IDE_SECTOR_REG);
+			tf->lbam	= hwif->INB(IDE_LCYL_REG);
+			tf->lbah	= hwif->INB(IDE_HCYL_REG);
+			tf->device	= hwif->INB(IDE_SELECT_REG);
+			tf->command	= stat;
+
+			if (tf->flags & ATA_TFLAG_LBA48) {
 				hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
-				args->hobRegister[IDE_FEATURE_OFFSET]	= hwif->INB(IDE_FEATURE_REG);
-				args->hobRegister[IDE_NSECTOR_OFFSET]	= hwif->INB(IDE_NSECTOR_REG);
-				args->hobRegister[IDE_SECTOR_OFFSET]	= hwif->INB(IDE_SECTOR_REG);
-				args->hobRegister[IDE_LCYL_OFFSET]	= hwif->INB(IDE_LCYL_REG);
-				args->hobRegister[IDE_HCYL_OFFSET]	= hwif->INB(IDE_HCYL_REG);
+
+				tf->hob_feature	= hwif->INB(IDE_FEATURE_REG);
+				tf->hob_nsect	= hwif->INB(IDE_NSECTOR_REG);
+				tf->hob_lbal	= hwif->INB(IDE_SECTOR_REG);
+				tf->hob_lbam	= hwif->INB(IDE_LCYL_REG);
+				tf->hob_lbah	= hwif->INB(IDE_HCYL_REG);
 			}
 		}
 	} else if (blk_pm_request(rq)) {
@@ -410,6 +411,17 @@
 	}
 }
 
+static void ide_kill_rq(ide_drive_t *drive, struct request *rq)
+{
+	if (rq->rq_disk) {
+		ide_driver_t *drv;
+
+		drv = *(ide_driver_t **)rq->rq_disk->private_data;
+		drv->end_request(drive, 0, 0);
+	} else
+		ide_end_request(drive, 0, 0);
+}
+
 static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
 {
 	ide_hwif_t *hwif = drive->hwif;
@@ -444,7 +456,7 @@
 		hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
 
 	if (rq->errors >= ERROR_MAX || blk_noretry_request(rq))
-		drive->driver->end_request(drive, 0, 0);
+		ide_kill_rq(drive, rq);
 	else {
 		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
 			++rq->errors;
@@ -473,7 +485,7 @@
 		hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
 
 	if (rq->errors >= ERROR_MAX) {
-		drive->driver->end_request(drive, 0, 0);
+		ide_kill_rq(drive, rq);
 	} else {
 		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
 			++rq->errors;
@@ -519,13 +531,19 @@
 		return ide_stopped;
 
 	/* retry only "normal" I/O: */
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASKFILE)) {
 		rq->errors = 1;
 		ide_end_drive_cmd(drive, stat, err);
 		return ide_stopped;
 	}
 
-	return drive->driver->error(drive, rq, stat, err);
+	if (rq->rq_disk) {
+		ide_driver_t *drv;
+
+		drv = *(ide_driver_t **)rq->rq_disk->private_data;
+		return drv->error(drive, rq, stat, err);
+	} else
+		return __ide_error(drive, rq, stat, err);
 }
 
 EXPORT_SYMBOL_GPL(ide_error);
@@ -535,7 +553,8 @@
 	if (drive->media != ide_disk)
 		rq->errors |= ERROR_RESET;
 
-	DRIVER(drive)->end_request(drive, 0, 0);
+	ide_kill_rq(drive, rq);
+
 	return ide_stopped;
 }
 
@@ -563,13 +582,19 @@
 		return ide_stopped;
 
 	/* retry only "normal" I/O: */
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASKFILE)) {
 		rq->errors = 1;
 		ide_end_drive_cmd(drive, BUSY_STAT, 0);
 		return ide_stopped;
 	}
 
-	return drive->driver->abort(drive, rq);
+	if (rq->rq_disk) {
+		ide_driver_t *drv;
+
+		drv = *(ide_driver_t **)rq->rq_disk->private_data;
+		return drv->abort(drive, rq);
+	} else
+		return __ide_abort(drive, rq);
 }
 
 /**
@@ -622,7 +647,7 @@
 			udelay(100);
 	}
 
-	if (!OK_STAT(stat, READY_STAT, BAD_STAT) && DRIVER(drive) != NULL)
+	if (!OK_STAT(stat, READY_STAT, BAD_STAT))
 		return ide_error(drive, "drive_cmd", stat);
 		/* calls ide_end_drive_cmd */
 	ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
@@ -631,28 +656,34 @@
 
 static void ide_init_specify_cmd(ide_drive_t *drive, ide_task_t *task)
 {
-	task->tfRegister[IDE_NSECTOR_OFFSET] = drive->sect;
-	task->tfRegister[IDE_SECTOR_OFFSET]  = drive->sect;
-	task->tfRegister[IDE_LCYL_OFFSET]    = drive->cyl;
-	task->tfRegister[IDE_HCYL_OFFSET]    = drive->cyl>>8;
-	task->tfRegister[IDE_SELECT_OFFSET]  = ((drive->head-1)|drive->select.all)&0xBF;
-	task->tfRegister[IDE_COMMAND_OFFSET] = WIN_SPECIFY;
+	struct ata_taskfile *tf = &task->tf;
+
+	tf->nsect	= drive->sect;
+	tf->lbal	= drive->sect;
+	tf->lbam	= drive->cyl;
+	tf->lbah	= drive->cyl >> 8;
+	tf->device	= ((drive->head - 1) | drive->select.all) & 0xBF;
+	tf->command	= WIN_SPECIFY;
 
 	task->handler = &set_geometry_intr;
 }
 
 static void ide_init_restore_cmd(ide_drive_t *drive, ide_task_t *task)
 {
-	task->tfRegister[IDE_NSECTOR_OFFSET] = drive->sect;
-	task->tfRegister[IDE_COMMAND_OFFSET] = WIN_RESTORE;
+	struct ata_taskfile *tf = &task->tf;
+
+	tf->nsect	= drive->sect;
+	tf->command	= WIN_RESTORE;
 
 	task->handler = &recal_intr;
 }
 
 static void ide_init_setmult_cmd(ide_drive_t *drive, ide_task_t *task)
 {
-	task->tfRegister[IDE_NSECTOR_OFFSET] = drive->mult_req;
-	task->tfRegister[IDE_COMMAND_OFFSET] = WIN_SETMULT;
+	struct ata_taskfile *tf = &task->tf;
+
+	tf->nsect	= drive->mult_req;
+	tf->command	= WIN_SETMULT;
 
 	task->handler = &set_multmode_intr;
 }
@@ -785,33 +816,7 @@
 		if (args->tf_out_flags.all != 0) 
 			return flagged_taskfile(drive, args);
 		return do_rw_taskfile(drive, args);
-	} else if (rq->flags & REQ_DRIVE_TASK) {
-		u8 *args = rq->buffer;
-		u8 sel;
- 
-		if (!args)
-			goto done;
-#ifdef DEBUG
- 		printk("%s: DRIVE_TASK_CMD ", drive->name);
- 		printk("cmd=0x%02x ", args[0]);
- 		printk("fr=0x%02x ", args[1]);
- 		printk("ns=0x%02x ", args[2]);
- 		printk("sc=0x%02x ", args[3]);
- 		printk("lcyl=0x%02x ", args[4]);
- 		printk("hcyl=0x%02x ", args[5]);
- 		printk("sel=0x%02x\n", args[6]);
-#endif
- 		hwif->OUTB(args[1], IDE_FEATURE_REG);
- 		hwif->OUTB(args[3], IDE_SECTOR_REG);
- 		hwif->OUTB(args[4], IDE_LCYL_REG);
- 		hwif->OUTB(args[5], IDE_HCYL_REG);
- 		sel = (args[6] & ~0x10);
- 		if (drive->select.b.unit)
- 			sel |= 0x10;
- 		hwif->OUTB(sel, IDE_SELECT_REG);
- 		ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
- 		return ide_started;
- 	} else if (rq->flags & REQ_DRIVE_CMD) {
+	} else if (rq->flags & REQ_DRIVE_CMD) {
  		u8 *args = rq->buffer;
 
 		if (!args)
@@ -922,7 +927,9 @@
 		return startstop;
 	}
 	if (!drive->special.all) {
-		if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK))
+		ide_driver_t *drv;
+
+		if (rq->flags & REQ_DRIVE_CMD)
 			return execute_drive_cmd(drive, rq);
 		else if (rq->flags & REQ_DRIVE_TASKFILE)
 			return execute_drive_cmd(drive, rq);
@@ -937,11 +944,13 @@
 				ide_complete_pm_request(drive, rq);
 			return startstop;
 		}
-		return (DRIVER(drive)->do_request(drive, rq, block));
+
+		drv = *(ide_driver_t **)rq->rq_disk->private_data;
+		return drv->do_request(drive, rq, block);
 	}
 	return do_special(drive);
 kill_rq:
-	DRIVER(drive)->end_request(drive, 0, 0);
+	ide_kill_rq(drive, rq);
 	return ide_stopped;
 }
 
@@ -1615,8 +1624,6 @@
 
 	rq->errors = 0;
 	rq->rq_status = RQ_ACTIVE;
-
-	rq->rq_disk = drive->disk;
 
 	/*
 	 * we need to hold an extra reference to request for safe inspection
diff -Nru a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
--- a/drivers/ide/ide-iops.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-iops.c	2005-03-30 17:28:48 -08:00
@@ -645,9 +645,9 @@
 
 int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
 {
-	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
-	    (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
-	    (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
+	if (args->tf.command == WIN_SETFEATURES &&
+	    args->tf.lbal > XFER_UDMA_2 &&
+	    args->tf.feature == SETFEATURES_XFER) {
 #ifndef CONFIG_IDEDMA_IVB
 		if ((drive->id->hw_config & 0x6000) == 0) {
 #else /* !CONFIG_IDEDMA_IVB */
@@ -675,9 +675,9 @@
  */
 int set_transfer (ide_drive_t *drive, ide_task_t *args)
 {
-	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
-	    (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
-	    (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&
+	if (args->tf.command == WIN_SETFEATURES &&
+	    args->tf.lbal >= XFER_SW_DMA_0 &&
+	    args->tf.feature == SETFEATURES_XFER &&
 	    (drive->id->dma_ultra ||
 	     drive->id->dma_mword ||
 	     drive->id->dma_1word))
diff -Nru a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
--- a/drivers/ide/ide-lib.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-lib.c	2005-03-30 17:28:48 -08:00
@@ -458,7 +458,7 @@
 	spin_unlock(&ide_lock);
 	if (!rq)
 		return;
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
+	if (rq->flags & REQ_DRIVE_CMD) {
 		char *args = rq->buffer;
 		if (args) {
 			opcode = args[0];
@@ -467,8 +467,7 @@
 	} else if (rq->flags & REQ_DRIVE_TASKFILE) {
 		ide_task_t *args = rq->special;
 		if (args) {
-			task_struct_t *tf = (task_struct_t *) args->tfRegister;
-			opcode = tf->command;
+			opcode = args->tf.command;
 			found = 1;
 		}
 	}
diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
--- a/drivers/ide/ide-probe.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-probe.c	2005-03-30 17:28:48 -08:00
@@ -47,6 +47,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
+#include <linux/devfs_fs_kernel.h>
 #include <linux/spinlock.h>
 #include <linux/kmod.h>
 #include <linux/pci.h>
@@ -862,6 +863,13 @@
 				drive->autotune == IDE_TUNE_AUTO)
 				/* auto-tune PIO mode */
 				hwif->tuneproc(drive, 255);
+
+			if (drive->autotune != IDE_TUNE_DEFAULT &&
+			    drive->autotune != IDE_TUNE_AUTO)
+				continue;
+
+			drive->nice1 = 1;
+
 			/*
 			 * MAJOR HACK BARF :-/
 			 *
@@ -871,9 +879,7 @@
 			 * Move here to prevent module loading clashing.
 			 */
 	//		drive->autodma = hwif->autodma;
-			if ((hwif->ide_dma_check) &&
-				((drive->autotune == IDE_TUNE_DEFAULT) ||
-				(drive->autotune == IDE_TUNE_AUTO))) {
+			if (hwif->ide_dma_check) {
 				/*
 				 * Force DMAing for the beginning of the check.
 				 * Some chipsets appear to do interesting
@@ -913,7 +919,7 @@
 			   want them on default or a new "empty" class
 			   for hotplug reprobing ? */
 			if (drive->present) {
-				ata_attach(drive);
+				device_register(&drive->gendev);
 			}
 		}
 	}
@@ -1006,10 +1012,8 @@
 	blk_queue_max_hw_segments(q, max_sg_entries);
 	blk_queue_max_phys_segments(q, max_sg_entries);
 
-	/* assign drive and gendisk queue */
+	/* assign drive queue */
 	drive->queue = q;
-	if (drive->disk)
-		drive->disk->queue = drive->queue;
 
 	/* needs drive->queue to be set */
 	ide_toggle_bounce(drive, 1);
@@ -1209,8 +1213,6 @@
 	return 0;
 }
 
-extern ide_driver_t idedefault_driver;
-
 static struct kobject *ata_probe(dev_t dev, int *part, void *data)
 {
 	ide_hwif_t *hwif = data;
@@ -1218,56 +1220,111 @@
 	ide_drive_t *drive = &hwif->drives[unit];
 	if (!drive->present)
 		return NULL;
-	if (drive->driver == &idedefault_driver) {
-		if (drive->media == ide_disk)
-			(void) request_module("ide-disk");
-		if (drive->scsi)
-			(void) request_module("ide-scsi");
-		if (drive->media == ide_cdrom || drive->media == ide_optical)
-			(void) request_module("ide-cd");
-		if (drive->media == ide_tape)
-			(void) request_module("ide-tape");
-		if (drive->media == ide_floppy)
-			(void) request_module("ide-floppy");
-	}
-	if (drive->driver == &idedefault_driver)
-		return NULL;
+
+	if (drive->media == ide_disk)
+		request_module("ide-disk");
+	if (drive->scsi)
+		request_module("ide-scsi");
+	if (drive->media == ide_cdrom || drive->media == ide_optical)
+		request_module("ide-cd");
+	if (drive->media == ide_tape)
+		request_module("ide-tape");
+	if (drive->media == ide_floppy)
+		request_module("ide-floppy");
+
+	return NULL;
+}
+
+static struct kobject *exact_match(dev_t dev, int *part, void *data)
+{
+	struct gendisk *p = data;
 	*part &= (1 << PARTN_BITS) - 1;
-	return get_disk(drive->disk);
+	return &p->kobj;
 }
 
-static int alloc_disks(ide_hwif_t *hwif)
+static int exact_lock(dev_t dev, void *data)
 {
-	unsigned int unit;
-	struct gendisk *disks[MAX_DRIVES];
+	struct gendisk *p = data;
 
-	for (unit = 0; unit < MAX_DRIVES; unit++) {
-		disks[unit] = alloc_disk(1 << PARTN_BITS);
-		if (!disks[unit])
-			goto Enomem;
-	}
-	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		ide_drive_t *drive = &hwif->drives[unit];
-		struct gendisk *disk = disks[unit];
-		disk->major  = hwif->major;
-		disk->first_minor = unit << PARTN_BITS;
-		sprintf(disk->disk_name,"hd%c",'a'+hwif->index*MAX_DRIVES+unit);
-		disk->fops = ide_fops;
-		disk->private_data = drive;
-		drive->disk = disk;
-	}
+	if (!get_disk(p))
+		return -1;
 	return 0;
-Enomem:
-	printk(KERN_WARNING "(ide::init_gendisk) Out of memory\n");
-	while (unit--)
-		put_disk(disks[unit]);
-	return -ENOMEM;
+}
+
+void ide_register_region(struct gendisk *disk)
+{
+	blk_register_region(MKDEV(disk->major, disk->first_minor),
+			    disk->minors, NULL, exact_match, exact_lock, disk);
+}
+
+EXPORT_SYMBOL_GPL(ide_register_region);
+
+void ide_unregister_region(struct gendisk *disk)
+{
+	blk_unregister_region(MKDEV(disk->major, disk->first_minor),
+			      disk->minors);
+}
+
+EXPORT_SYMBOL_GPL(ide_unregister_region);
+
+void ide_init_disk(struct gendisk *disk, ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	unsigned int unit = (drive->select.all >> 4) & 1;
+
+	disk->major = hwif->major;
+	disk->first_minor = unit << PARTN_BITS;
+	sprintf(disk->disk_name, "hd%c", 'a' + hwif->index * MAX_DRIVES + unit);
+	disk->queue = drive->queue;
+}
+
+EXPORT_SYMBOL_GPL(ide_init_disk);
+
+static void ide_remove_drive_from_hwgroup(ide_drive_t *drive)
+{
+	ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
+
+	if (drive == drive->next) {
+		/* special case: last drive from hwgroup. */
+		BUG_ON(hwgroup->drive != drive);
+		hwgroup->drive = NULL;
+	} else {
+		ide_drive_t *walk;
+
+		walk = hwgroup->drive;
+		while (walk->next != drive)
+			walk = walk->next;
+		walk->next = drive->next;
+		if (hwgroup->drive == drive) {
+			hwgroup->drive = drive->next;
+			hwgroup->hwif = hwgroup->drive->hwif;
+		}
+	}
+	BUG_ON(hwgroup->drive == drive);
 }
 
 static void drive_release_dev (struct device *dev)
 {
 	ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
 
+	spin_lock_irq(&ide_lock);
+	if (drive->devfs_name[0] != '\0') {
+		devfs_remove(drive->devfs_name);
+		drive->devfs_name[0] = '\0';
+	}
+	ide_remove_drive_from_hwgroup(drive);
+	if (drive->id != NULL) {
+		kfree(drive->id);
+		drive->id = NULL;
+	}
+	drive->present = 0;
+	/* Messed up locking ... */
+	spin_unlock_irq(&ide_lock);
+	blk_cleanup_queue(drive->queue);
+	spin_lock_irq(&ide_lock);
+	drive->queue = NULL;
+	spin_unlock_irq(&ide_lock);
+
 	up(&drive->gendev_rel_sem);
 }
 
@@ -1291,7 +1348,6 @@
 		drive->gendev.driver_data = drive;
 		drive->gendev.release = drive_release_dev;
 		if (drive->present) {
-			device_register(&drive->gendev);
 			sprintf(drive->devfs_name, "ide/host%d/bus%d/target%d/lun%d",
 				(hwif->channel && hwif->mate) ?
 				hwif->mate->index : hwif->index,
@@ -1304,7 +1360,7 @@
 
 static int hwif_init(ide_hwif_t *hwif)
 {
-	int old_irq, unit;
+	int old_irq;
 
 	/* Return success if no device is connected */
 	if (!hwif->present)
@@ -1340,9 +1396,6 @@
 		printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
 		goto out;
 	}
-
-	if (alloc_disks(hwif) < 0)
-		goto out;
 	
 	if (init_irq(hwif) == 0)
 		goto done;
@@ -1355,12 +1408,12 @@
 	if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) {
 		printk("%s: Disabled unable to get IRQ %d.\n",
 			hwif->name, old_irq);
-		goto out_disks;
+		goto out;
 	}
 	if (init_irq(hwif)) {
 		printk("%s: probed IRQ %d and default IRQ %d failed.\n",
 			hwif->name, old_irq, hwif->irq);
-		goto out_disks;
+		goto out;
 	}
 	printk("%s: probed IRQ %d failed, using default.\n",
 		hwif->name, hwif->irq);
@@ -1370,12 +1423,6 @@
 	hwif->present = 1;	/* success */
 	return 1;
 
-out_disks:
-	for (unit = 0; unit < MAX_DRIVES; unit++) {
-		struct gendisk *disk = hwif->drives[unit].disk;
-		hwif->drives[unit].disk = NULL;
-		put_disk(disk);
-	}
 out:
 	unregister_blkdev(hwif->major, hwif->name);
 	return 0;
@@ -1406,7 +1453,7 @@
 				hwif->chipset = ide_generic;
 			for (unit = 0; unit < MAX_DRIVES; ++unit)
 				if (hwif->drives[unit].present)
-					ata_attach(&hwif->drives[unit]);
+					device_register(&hwif->drives[unit].gendev);
 		}
 	}
 	return 0;
diff -Nru a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
--- a/drivers/ide/ide-proc.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-proc.c	2005-03-30 17:28:48 -08:00
@@ -107,8 +107,6 @@
 	if (drive) {
 		unsigned short *val = (unsigned short *) page;
 
-		BUG_ON(!drive->driver);
-
 		err = taskfile_lib_get_identify(drive, page);
 		if (!err) {
 			char *out = ((char *)page) + (SECTOR_WORDS * 4);
@@ -309,14 +307,41 @@
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
 	ide_drive_t	*drive = (ide_drive_t *) data;
-	ide_driver_t	*driver = drive->driver;
+	struct device	*dev = &drive->gendev;
+	ide_driver_t	*ide_drv;
 	int		len;
 
-	len = sprintf(page, "%s version %s\n",
-			driver->name, driver->version);
+	down_read(&dev->bus->subsys.rwsem);
+	if (dev->driver) {
+		ide_drv = container_of(dev->driver, ide_driver_t, gen_driver);
+		len = sprintf(page, "%s version %s\n",
+				dev->driver->name, ide_drv->version);
+	} else
+		len = sprintf(page, "ide-default version 0.9.newide\n");
+	up_read(&dev->bus->subsys.rwsem);
 	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
+static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
+{
+	struct device *dev = &drive->gendev;
+	int ret = 1;
+
+	down_write(&dev->bus->subsys.rwsem);
+	device_release_driver(dev);
+	/* FIXME: device can still be in use by previous driver */
+	strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));
+	device_attach(dev);
+	drive->driver_req[0] = 0;
+	if (dev->driver == NULL)
+		device_attach(dev);
+	if (dev->driver && !strcmp(dev->driver->name, driver))
+		ret = 0;
+	up_write(&dev->bus->subsys.rwsem);
+
+	return ret;
+}
+
 static int proc_ide_write_driver
 	(struct file *file, const char __user *buffer, unsigned long count, void *data)
 {
@@ -421,10 +446,7 @@
 
 static void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_driver_t *driver = drive->driver;
-
 	if (drive->proc) {
-		ide_remove_proc_entries(drive->proc, driver->proc);
 		ide_remove_proc_entries(drive->proc, generic_drive_entries);
 		remove_proc_entry(drive->name, proc_ide_root);
 		remove_proc_entry(drive->name, hwif->proc);
@@ -490,16 +512,32 @@
 	}
 }
 
-extern struct seq_operations ide_drivers_op;
+static int proc_print_driver(struct device_driver *drv, void *data)
+{
+	ide_driver_t *ide_drv = container_of(drv, ide_driver_t, gen_driver);
+	struct seq_file *s = data;
+
+	seq_printf(s, "%s version %s\n", drv->name, ide_drv->version);
+
+	return 0;
+}
+
+static int ide_drivers_show(struct seq_file *s, void *p)
+{
+	bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver);
+	return 0;
+}
+
 static int ide_drivers_open(struct inode *inode, struct file *file)
 {
-	return seq_open(file, &ide_drivers_op);
+	return single_open(file, &ide_drivers_show, NULL);
 }
+
 static struct file_operations ide_drivers_operations = {
 	.open		= ide_drivers_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
-	.release	= seq_release,
+	.release	= single_release,
 };
 
 void proc_ide_create(void)
diff -Nru a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
--- a/drivers/ide/ide-tape.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-tape.c	2005-03-30 17:28:48 -08:00
@@ -783,6 +783,8 @@
  */
 typedef struct ide_tape_obj {
 	ide_drive_t	*drive;
+	ide_driver_t	*driver;
+	struct gendisk	*disk;
 	struct kref	kref;
 
 	/*
@@ -1013,7 +1015,8 @@
 
 #define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref)
 
-#define ide_tape_g(disk)	((disk)->private_data)
+#define ide_tape_g(disk) \
+	container_of((disk)->private_data, struct ide_tape_obj, driver)
 
 static struct ide_tape_obj *ide_tape_get(struct gendisk *disk)
 {
@@ -1543,6 +1546,7 @@
 	}
 #endif /* IDETAPE_DEBUG_BUGS */	
 
+	rq->rq_disk = tape->disk;
 	rq->buffer = NULL;
 	rq->special = (void *)stage->bh;
 	tape->active_data_request = rq;
@@ -1795,8 +1799,11 @@
  */
 static void idetape_queue_pc_head (ide_drive_t *drive, idetape_pc_t *pc,struct request *rq)
 {
+	struct ide_tape_obj *tape = drive->driver_data;
+
 	idetape_init_rq(rq, REQ_IDETAPE_PC1);
 	rq->buffer = (char *) pc;
+	rq->rq_disk = tape->disk;
 	(void) ide_do_drive_cmd(drive, rq, ide_preempt);
 }
 
@@ -2852,10 +2859,12 @@
  */
 static int __idetape_queue_pc_tail (ide_drive_t *drive, idetape_pc_t *pc)
 {
+	struct ide_tape_obj *tape = drive->driver_data;
 	struct request rq;
 
 	idetape_init_rq(&rq, REQ_IDETAPE_PC1);
 	rq.buffer = (char *) pc;
+	rq.rq_disk = tape->disk;
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
@@ -3079,6 +3088,7 @@
 #endif /* IDETAPE_DEBUG_BUGS */	
 
 	idetape_init_rq(&rq, cmd);
+	rq.rq_disk = tape->disk;
 	rq.special = (void *)bh;
 	rq.sector = tape->first_frame_position;
 	rq.nr_sectors = rq.current_nr_sectors = blocks;
@@ -4671,21 +4681,14 @@
 	idetape_add_settings(drive);
 }
 
-static int idetape_cleanup (ide_drive_t *drive)
+static int ide_tape_remove(struct device *dev)
 {
+	ide_drive_t *drive = to_ide_device(dev);
 	idetape_tape_t *tape = drive->driver_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&ide_lock, flags);
-	if (test_bit(IDETAPE_BUSY, &tape->flags) || drive->usage ||
-	    tape->first_stage != NULL || tape->merge_stage_size) {
-		spin_unlock_irqrestore(&ide_lock, flags);
-		return 1;
-	}
+	ide_unregister_subdriver(drive, tape->driver);
 
-	spin_unlock_irqrestore(&ide_lock, flags);
-	DRIVER(drive)->busy = 0;
-	(void) ide_unregister_subdriver(drive);
+	ide_unregister_region(tape->disk);
 
 	ide_tape_put(tape);
 
@@ -4696,15 +4699,18 @@
 {
 	struct ide_tape_obj *tape = to_ide_tape(kref);
 	ide_drive_t *drive = tape->drive;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g = tape->disk;
+
+	BUG_ON(tape->first_stage != NULL || tape->merge_stage_size);
 
+	drive->dsc_overlap = 0;
 	drive->driver_data = NULL;
 	devfs_remove("%s/mt", drive->devfs_name);
 	devfs_remove("%s/mtn", drive->devfs_name);
 	devfs_unregister_tape(g->number);
 	idetape_devs[tape->minor] = NULL;
 	g->private_data = NULL;
-	g->fops = ide_fops;
+	put_disk(g);
 	kfree(tape);
 }
 
@@ -4734,26 +4740,24 @@
 
 #endif
 
-static int idetape_attach(ide_drive_t *drive);
+static int ide_tape_probe(struct device *);
 
-/*
- *	IDE subdriver functions, registered with ide.c
- */
 static ide_driver_t idetape_driver = {
 	.owner			= THIS_MODULE,
-	.name			= "ide-tape",
+	.gen_driver = {
+		.name		= "ide-tape",
+		.bus		= &ide_bus_type,
+		.probe		= ide_tape_probe,
+		.remove		= ide_tape_remove,
+	},
 	.version		= IDETAPE_VERSION,
 	.media			= ide_tape,
-	.busy			= 1,
 	.supports_dsc_overlap 	= 1,
-	.cleanup		= idetape_cleanup,
 	.do_request		= idetape_do_request,
 	.end_request		= idetape_end_request,
 	.error			= __ide_error,
 	.abort			= __ide_abort,
 	.proc			= idetape_proc,
-	.attach			= idetape_attach,
-	.drives			= LIST_HEAD_INIT(idetape_driver.drives),
 };
 
 /*
@@ -4816,10 +4820,11 @@
 	.ioctl		= idetape_ioctl,
 };
 
-static int idetape_attach (ide_drive_t *drive)
+static int ide_tape_probe(struct device *dev)
 {
+	ide_drive_t *drive = to_ide_device(dev);
 	idetape_tape_t *tape;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g;
 	int minor;
 
 	if (!strstr("ide-tape", drive->driver_req))
@@ -4845,17 +4850,24 @@
 		printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name);
 		goto failed;
 	}
-	if (ide_register_subdriver(drive, &idetape_driver)) {
-		printk(KERN_ERR "ide-tape: %s: Failed to register the driver with ide.c\n", drive->name);
-		kfree(tape);
-		goto failed;
-	}
+
+	g = alloc_disk(1 << PARTN_BITS);
+	if (!g)
+		goto out_free_tape;
+
+	ide_init_disk(g, drive);
+
+	ide_register_subdriver(drive, &idetape_driver);
 
 	memset(tape, 0, sizeof(*tape));
 
 	kref_init(&tape->kref);
 
 	tape->drive = drive;
+	tape->driver = &idetape_driver;
+	tape->disk = g;
+
+	g->private_data = &tape->driver;
 
 	drive->driver_data = tape;
 
@@ -4876,11 +4888,14 @@
 
 	g->number = devfs_register_tape(drive->devfs_name);
 	g->fops = &idetape_block_ops;
-	g->private_data = tape;
+	ide_register_region(g);
 
 	return 0;
+
+out_free_tape:
+	kfree(tape);
 failed:
-	return 1;
+	return -ENODEV;
 }
 
 MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver");
@@ -4888,7 +4903,7 @@
 
 static void __exit idetape_exit (void)
 {
-	ide_unregister_driver(&idetape_driver);
+	driver_unregister(&idetape_driver.gen_driver);
 	unregister_chrdev(IDETAPE_MAJOR, "ht");
 }
 
@@ -4901,8 +4916,7 @@
 		printk(KERN_ERR "ide-tape: Failed to register character device interface\n");
 		return -EBUSY;
 	}
-	ide_register_driver(&idetape_driver);
-	return 0;
+	return driver_register(&idetape_driver.gen_driver);
 }
 
 module_init(idetape_init);
diff -Nru a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
--- a/drivers/ide/ide-taskfile.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide-taskfile.c	2005-03-30 17:28:48 -08:00
@@ -84,12 +84,16 @@
 int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
 {
 	ide_task_t args;
+	struct ata_taskfile *tf = &args.tf;
+
 	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_NSECTOR_OFFSET]	= 0x01;
+
+	tf->nsect = 1;
 	if (drive->media == ide_disk)
-		args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_IDENTIFY;
+		tf->command = WIN_IDENTIFY;
 	else
-		args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_PIDENTIFY;
+		tf->command = WIN_PIDENTIFY;
+
 	args.command_type = IDE_DRIVE_TASK_IN;
 	args.data_phase   = TASKFILE_IN;
 	args.handler	  = &task_in_intr;
@@ -99,9 +103,8 @@
 ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
-	task_struct_t *taskfile	= (task_struct_t *) task->tfRegister;
-	hob_struct_t *hobfile	= (hob_struct_t *) task->hobRegister;
-	u8 HIHI			= (drive->addressing == 1) ? 0xE0 : 0xEF;
+	struct ata_taskfile *tf = &task->tf;
+	u8 HIHI			= (tf->flags & ATA_TFLAG_LBA48) ? 0xE0 : 0xEF;
 
 	/* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
 	if (IDE_CONTROL_REG) {
@@ -110,36 +113,36 @@
 	}
 	SELECT_MASK(drive, 0);
 
-	if (drive->addressing == 1) {
-		hwif->OUTB(hobfile->feature, IDE_FEATURE_REG);
-		hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG);
-		hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG);
-		hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG);
-		hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG);
+	if (tf->flags & ATA_TFLAG_LBA48) {
+		hwif->OUTB(tf->hob_feature, IDE_FEATURE_REG);
+		hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG);
+		hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG);
+		hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG);
+		hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG);
 	}
 
-	hwif->OUTB(taskfile->feature, IDE_FEATURE_REG);
-	hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG);
-	hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG);
-	hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG);
-	hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);
+	hwif->OUTB(tf->feature, IDE_FEATURE_REG);
+	hwif->OUTB(tf->nsect, IDE_NSECTOR_REG);
+	hwif->OUTB(tf->lbal, IDE_SECTOR_REG);
+	hwif->OUTB(tf->lbam, IDE_LCYL_REG);
+	hwif->OUTB(tf->lbah, IDE_HCYL_REG);
 
-	hwif->OUTB((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
+	hwif->OUTB((tf->device & HIHI) | (drive->select.all & 0xBF), IDE_SELECT_REG);
 
 	if (task->handler != NULL) {
 		if (task->prehandler != NULL) {
-			hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG);
+			hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG);
 			ndelay(400);	/* FIXME */
 			return task->prehandler(drive, task->rq);
 		}
-		ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL);
+		ide_execute_command(drive, tf->command, task->handler, WAIT_WORSTCASE, NULL);
 		return ide_started;
 	}
 
 	if (!drive->using_dma)
 		return ide_stopped;
 
-	switch (taskfile->command) {
+	switch (tf->command) {
 		case WIN_WRITEDMA_ONCE:
 		case WIN_WRITEDMA:
 		case WIN_WRITEDMA_EXT:
@@ -148,7 +151,7 @@
 		case WIN_READDMA_EXT:
 		case WIN_IDENTIFY_DMA:
 			if (!hwif->dma_setup(drive)) {
-				hwif->dma_exec_cmd(drive, taskfile->command);
+				hwif->dma_exec_cmd(drive, tf->command);
 				hwif->dma_start(drive);
 				return ide_started;
 			}
@@ -315,9 +318,18 @@
 static inline void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
 				     unsigned int write)
 {
+	u8 saved_io_32bit = drive->io_32bit;
+
 	if (rq->bio)	/* fs request */
 		rq->errors = 0;
 
+	if (rq->flags & REQ_DRIVE_TASKFILE) {
+		ide_task_t *task = rq->special;
+
+		if (task->tf.flags & ATA_TFLAG_IO_16BIT)
+			drive->io_32bit = 0;
+	}
+
 	switch (drive->hwif->data_phase) {
 	case TASKFILE_MULTI_IN:
 	case TASKFILE_MULTI_OUT:
@@ -327,6 +339,8 @@
 		ide_pio_sector(drive, write);
 		break;
 	}
+
+	drive->io_32bit = saved_io_32bit;
 }
 
 static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
@@ -354,8 +368,12 @@
 			break;
 		}
 
-		if (sectors > 0)
-			drive->driver->end_request(drive, 1, sectors);
+		if (sectors > 0) {
+			ide_driver_t *drv;
+
+			drv = *(ide_driver_t **)rq->rq_disk->private_data;
+			drv->end_request(drive, 1, sectors);
+		}
 	}
 	return ide_error(drive, s, stat);
 }
@@ -371,7 +389,8 @@
 			return;
 		}
 	}
-	drive->driver->end_request(drive, 1, rq->hard_nr_sectors);
+
+	ide_end_request(drive, 1, rq->hard_nr_sectors);
 }
 
 /*
@@ -477,7 +496,7 @@
 	 */
 	if (args->command_type != IDE_DRIVE_TASK_NO_DATA) {
 		if (data_size == 0)
-			rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET];
+			rq.nr_sectors = (args->tf.hob_nsect << 8) | args->tf.nsect;
 		else
 			rq.nr_sectors = data_size / SECTOR_SIZE;
 
@@ -509,15 +528,13 @@
 {
 	ide_task_request_t	*req_task;
 	ide_task_t		args;
+	struct ata_taskfile *tf = &args.tf;
 	u8 *outbuf		= NULL;
 	u8 *inbuf		= NULL;
-	task_ioreg_t *argsptr	= args.tfRegister;
-	task_ioreg_t *hobsptr	= args.hobRegister;
 	int err			= 0;
 	int tasksize		= sizeof(struct ide_task_request_s);
 	int taskin		= 0;
 	int taskout		= 0;
-	u8 io_32bit		= drive->io_32bit;
 	char __user *buf = (char __user *)arg;
 
 //	printk("IDE Taskfile ...\n");
@@ -562,15 +579,35 @@
 	}
 
 	memset(&args, 0, sizeof(ide_task_t));
-	memcpy(argsptr, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
-	memcpy(hobsptr, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE);
+
+	args.data = req_task->io_ports[0] | (req_task->hob_ports[0] << 8);
+
+	tf->hob_feature	= req_task->hob_ports[1];
+	tf->hob_nsect	= req_task->hob_ports[2];
+	tf->hob_lbal	= req_task->hob_ports[3];
+	tf->hob_lbam	= req_task->hob_ports[4];
+	tf->hob_lbah	= req_task->hob_ports[5];
+
+	tf->feature	= req_task->io_ports[1];
+	tf->nsect	= req_task->io_ports[2];
+	tf->lbal	= req_task->io_ports[3];
+	tf->lbam	= req_task->io_ports[4];
+	tf->lbah	= req_task->io_ports[5];
+	tf->device	= req_task->io_ports[6];
+	tf->command	= req_task->io_ports[7];
 
 	args.tf_in_flags  = req_task->in_flags;
 	args.tf_out_flags = req_task->out_flags;
 	args.data_phase   = req_task->data_phase;
 	args.command_type = req_task->req_cmd;
 
-	drive->io_32bit = 0;
+	tf->flags = ATA_TFLAG_IO_16BIT;
+	if (drive->addressing == 1)
+		tf->flags |= ATA_TFLAG_LBA48;
+
+	if (drive->select.b.lba)
+		tf->device |= ATA_LBA;
+
 	switch(req_task->data_phase) {
 		case TASKFILE_OUT_DMAQ:
 		case TASKFILE_OUT_DMA:
@@ -618,8 +655,23 @@
 			goto abort;
 	}
 
-	memcpy(req_task->io_ports, &(args.tfRegister), HDIO_DRIVE_TASK_HDR_SIZE);
-	memcpy(req_task->hob_ports, &(args.hobRegister), HDIO_DRIVE_HOB_HDR_SIZE);
+	req_task->io_ports[0]	= args.data;
+	req_task->hob_ports[0]	= args.data << 8;
+
+	req_task->hob_ports[1] = tf->hob_feature;
+	req_task->hob_ports[2] = tf->hob_nsect;
+	req_task->hob_ports[3] = tf->hob_lbal;
+	req_task->hob_ports[4] = tf->hob_lbam;
+	req_task->hob_ports[5] = tf->hob_lbah;
+
+	req_task->io_ports[1] = tf->feature;
+	req_task->io_ports[2] = tf->nsect;
+	req_task->io_ports[3] = tf->lbal;
+	req_task->io_ports[4] = tf->lbam;
+	req_task->io_ports[5] = tf->lbah;
+	req_task->io_ports[6] = tf->device;
+	req_task->io_ports[7] = tf->command;
+
 	req_task->in_flags  = args.tf_in_flags;
 	req_task->out_flags = args.tf_out_flags;
 
@@ -650,8 +702,6 @@
 
 //	printk("IDE Taskfile ioctl ended. rc = %i\n", err);
 
-	drive->io_32bit = io_32bit;
-
 	return err;
 }
 
@@ -682,6 +732,7 @@
 	u8 xfer_rate = 0;
 	int argsize = 4;
 	ide_task_t tfargs;
+	struct ata_taskfile *tf = &tfargs.tf;
 
 	if (NULL == (void *) arg) {
 		struct request rq;
@@ -693,13 +744,10 @@
 		return -EFAULT;
 
 	memset(&tfargs, 0, sizeof(ide_task_t));
-	tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2];
-	tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3];
-	tfargs.tfRegister[IDE_SECTOR_OFFSET]  = args[1];
-	tfargs.tfRegister[IDE_LCYL_OFFSET]    = 0x00;
-	tfargs.tfRegister[IDE_HCYL_OFFSET]    = 0x00;
-	tfargs.tfRegister[IDE_SELECT_OFFSET]  = 0x00;
-	tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0];
+	tf->feature	= args[2];
+	tf->nsect	= args[3];
+	tf->lbal	= args[1];
+	tf->command	= args[0];
 
 	if (args[3]) {
 		argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
@@ -729,30 +777,42 @@
 	return err;
 }
 
-static int ide_wait_cmd_task(ide_drive_t *drive, u8 *buf)
-{
-	struct request rq;
-
-	ide_init_drive_cmd(&rq);
-	rq.flags = REQ_DRIVE_TASK;
-	rq.buffer = buf;
-	return ide_do_drive_cmd(drive, &rq, ide_wait);
-}
-
-/*
- * FIXME : this needs to map into at taskfile. <andre@linux-ide.org>
- */
-int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
+int ide_task_ioctl(ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 {
 	void __user *p = (void __user *)arg;
-	int err = 0;
-	u8 args[7], *argbuf = args;
-	int argsize = 7;
+	int err;
+	u8 args[7];
+	ide_task_t task;
+	struct ata_taskfile *tf = &task.tf;
 
 	if (copy_from_user(args, p, 7))
 		return -EFAULT;
-	err = ide_wait_cmd_task(drive, argbuf);
-	if (copy_to_user(p, argbuf, argsize))
+
+	memset(&task, 0, sizeof(task));
+
+	tf->command	= args[0];
+	tf->feature	= args[1];
+	tf->nsect	= args[2];
+	tf->lbal	= args[3];
+	tf->lbam	= args[4];
+	tf->lbah	= args[5];
+	tf->device	= args[6];
+
+	task.command_type = IDE_DRIVE_TASK_NO_DATA;
+	task.data_phase = TASKFILE_NO_DATA;
+	task.handler = &task_no_data_intr;
+
+	err = ide_diag_taskfile(drive, &task, 0, NULL);
+
+	args[0] = tf->command;
+	args[1] = tf->feature;
+	args[2] = tf->nsect;
+	args[3] = tf->lbal;
+	args[4] = tf->lbam;
+	args[5] = tf->lbah;
+	args[6] = tf->device;
+
+	if (copy_to_user(p, args, 7))
 		err = -EFAULT;
 	return err;
 }
@@ -765,8 +825,7 @@
 ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
-	task_struct_t *taskfile	= (task_struct_t *) task->tfRegister;
-	hob_struct_t *hobfile	= (hob_struct_t *) task->hobRegister;
+	struct ata_taskfile *tf = &task->tf;
 #if DEBUG_TASKFILE
 	u8 status;
 #endif
@@ -815,34 +874,32 @@
 	}
 #endif
 
-	if (task->tf_out_flags.b.data) {
-		u16 data =  taskfile->data + (hobfile->data << 8);
-		hwif->OUTW(data, IDE_DATA_REG);
-	}
+	if (task->tf_out_flags.b.data)
+		hwif->OUTW(task->data, IDE_DATA_REG);
 
 	/* (ks) send hob registers first */
 	if (task->tf_out_flags.b.nsector_hob)
-		hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG);
+		hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG);
 	if (task->tf_out_flags.b.sector_hob)
-		hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG);
+		hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG);
 	if (task->tf_out_flags.b.lcyl_hob)
-		hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG);
+		hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG);
 	if (task->tf_out_flags.b.hcyl_hob)
-		hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG);
+		hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG);
 
 	/* (ks) Send now the standard registers */
 	if (task->tf_out_flags.b.error_feature)
-		hwif->OUTB(taskfile->feature, IDE_FEATURE_REG);
+		hwif->OUTB(tf->feature, IDE_FEATURE_REG);
 	/* refers to number of sectors to transfer */
 	if (task->tf_out_flags.b.nsector)
-		hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG);
+		hwif->OUTB(tf->nsect, IDE_NSECTOR_REG);
 	/* refers to sector offset or start sector */
 	if (task->tf_out_flags.b.sector)
-		hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG);
+		hwif->OUTB(tf->lbal, IDE_SECTOR_REG);
 	if (task->tf_out_flags.b.lcyl)
-		hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG);
+		hwif->OUTB(tf->lbam, IDE_LCYL_REG);
 	if (task->tf_out_flags.b.hcyl)
-		hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);
+		hwif->OUTB(tf->lbah, IDE_HCYL_REG);
 
         /*
 	 * (ks) In the flagged taskfile approch, we will use all specified
@@ -850,7 +907,7 @@
 	 * select bit (master/slave) in the drive_head register. We must make
 	 * sure that the desired drive is selected.
 	 */
-	hwif->OUTB(taskfile->device_head | drive->select.all, IDE_SELECT_REG);
+	hwif->OUTB(tf->device | (drive->select.all & 0xBF), IDE_SELECT_REG);
 	switch(task->data_phase) {
 
    	        case TASKFILE_OUT_DMAQ:
@@ -858,7 +915,7 @@
 		case TASKFILE_IN_DMAQ:
 		case TASKFILE_IN_DMA:
 			hwif->dma_setup(drive);
-			hwif->dma_exec_cmd(drive, taskfile->command);
+			hwif->dma_exec_cmd(drive, tf->command);
 			hwif->dma_start(drive);
 			break;
 
@@ -868,11 +925,11 @@
 
 			/* Issue the command */
 			if (task->prehandler) {
-				hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG);
+				hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG);
 				ndelay(400);	/* FIXME */
 				return task->prehandler(drive, task->rq);
 			}
-			ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL);
+			ide_execute_command(drive, tf->command, task->handler, WAIT_WORSTCASE, NULL);
 	}
 
 	return ide_started;
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/ide.c	2005-03-30 17:28:48 -08:00
@@ -196,8 +196,6 @@
 
 EXPORT_SYMBOL(ide_hwifs);
 
-extern ide_driver_t idedefault_driver;
-
 /*
  * Do not even *think* about calling this!
  */
@@ -245,7 +243,6 @@
 		drive->max_failures		= IDE_DEFAULT_MAX_FAILURES;
 		drive->using_dma		= 0;
 		drive->is_flash			= 0;
-		drive->driver			= &idedefault_driver;
 		drive->vdma			= 0;
 		INIT_LIST_HEAD(&drive->list);
 		sema_init(&drive->gendev_rel_sem, 0);
@@ -359,59 +356,6 @@
 	return system_bus_speed;
 }
 
-static int ide_open (struct inode * inode, struct file * filp)
-{
-	return -ENXIO;
-}
-
-/*
- *	drives_lock protects the list of drives, drivers_lock the
- *	list of drivers.  Currently nobody takes both at once.
- */
-
-static DEFINE_SPINLOCK(drives_lock);
-static DEFINE_SPINLOCK(drivers_lock);
-static LIST_HEAD(drivers);
-
-/* Iterator for the driver list. */
-
-static void *m_start(struct seq_file *m, loff_t *pos)
-{
-	struct list_head *p;
-	loff_t l = *pos;
-	spin_lock(&drivers_lock);
-	list_for_each(p, &drivers)
-		if (!l--)
-			return list_entry(p, ide_driver_t, drivers);
-	return NULL;
-}
-
-static void *m_next(struct seq_file *m, void *v, loff_t *pos)
-{
-	struct list_head *p = ((ide_driver_t *)v)->drivers.next;
-	(*pos)++;
-	return p==&drivers ? NULL : list_entry(p, ide_driver_t, drivers);
-}
-
-static void m_stop(struct seq_file *m, void *v)
-{
-	spin_unlock(&drivers_lock);
-}
-
-static int show_driver(struct seq_file *m, void *v)
-{
-	ide_driver_t *driver = v;
-	seq_printf(m, "%s version %s\n", driver->name, driver->version);
-	return 0;
-}
-
-struct seq_operations ide_drivers_op = {
-	.start	= m_start,
-	.next	= m_next,
-	.stop	= m_stop,
-	.show	= show_driver
-};
-
 #ifdef CONFIG_PROC_FS
 struct proc_dir_entry *proc_ide_root;
 #endif
@@ -636,7 +580,7 @@
 	ide_hwif_t *hwif, *g;
 	static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */
 	ide_hwgroup_t *hwgroup;
-	int irq_count = 0, unit, i;
+	int irq_count = 0, unit;
 
 	BUG_ON(index >= MAX_HWIFS);
 
@@ -649,23 +593,22 @@
 		goto abort;
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		drive = &hwif->drives[unit];
-		if (!drive->present)
+		if (!drive->present) {
+			if (drive->devfs_name[0] != '\0') {
+				devfs_remove(drive->devfs_name);
+				drive->devfs_name[0] = '\0';
+			}
 			continue;
-		if (drive->usage || DRIVER(drive)->busy)
-			goto abort;
-		drive->dead = 1;
+		}
+		spin_unlock_irq(&ide_lock);
+		device_unregister(&drive->gendev);
+		down(&drive->gendev_rel_sem);
+		spin_lock_irq(&ide_lock);
 	}
 	hwif->present = 0;
 
 	spin_unlock_irq(&ide_lock);
 
-	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		drive = &hwif->drives[unit];
-		if (!drive->present)
-			continue;
-		DRIVER(drive)->cleanup(drive);
-	}
-
 	destroy_proc_ide_interface(hwif);
 
 	hwgroup = hwif->hwgroup;
@@ -693,44 +636,6 @@
 	 * Remove us from the hwgroup, and free
 	 * the hwgroup if we were the only member
 	 */
-	for (i = 0; i < MAX_DRIVES; ++i) {
-		drive = &hwif->drives[i];
-		if (drive->devfs_name[0] != '\0') {
-			devfs_remove(drive->devfs_name);
-			drive->devfs_name[0] = '\0';
-		}
-		if (!drive->present)
-			continue;
-		if (drive == drive->next) {
-			/* special case: last drive from hwgroup. */
-			BUG_ON(hwgroup->drive != drive);
-			hwgroup->drive = NULL;
-		} else {
-			ide_drive_t *walk;
-
-			walk = hwgroup->drive;
-			while (walk->next != drive)
-				walk = walk->next;
-			walk->next = drive->next;
-			if (hwgroup->drive == drive) {
-				hwgroup->drive = drive->next;
-				hwgroup->hwif = HWIF(hwgroup->drive);
-			}
-		}
-		BUG_ON(hwgroup->drive == drive);
-		if (drive->id != NULL) {
-			kfree(drive->id);
-			drive->id = NULL;
-		}
-		drive->present = 0;
-		/* Messed up locking ... */
-		spin_unlock_irq(&ide_lock);
-		blk_cleanup_queue(drive->queue);
-		device_unregister(&drive->gendev);
-		down(&drive->gendev_rel_sem);
-		spin_lock_irq(&ide_lock);
-		drive->queue = NULL;
-	}
 	if (hwif->next == hwif) {
 		BUG_ON(hwgroup->hwif != hwif);
 		kfree(hwgroup);
@@ -763,11 +668,6 @@
 	 * Remove us from the kernel's knowledge
 	 */
 	blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS);
-	for (i = 0; i < MAX_DRIVES; i++) {
-		struct gendisk *disk = hwif->drives[i].disk;
-		hwif->drives[i].disk = NULL;
-		put_disk(disk);
-	}
 	kfree(hwif->sg_table);
 	unregister_blkdev(hwif->major, hwif->name);
 	spin_lock_irq(&ide_lock);
@@ -931,7 +831,7 @@
 DECLARE_MUTEX(ide_setting_sem);
 
 /**
- *	ide_add_setting	-	add an ide setting option
+ *	__ide_add_setting	-	add an ide setting option
  *	@drive: drive to use
  *	@name: setting name
  *	@rw: true if the function is read write
@@ -944,6 +844,7 @@
  *	@div_factor: divison scale
  *	@data: private data field
  *	@set: setting
+ *	@auto_remove: setting auto removal flag
  *
  *	Removes the setting named from the device if it is present.
  *	The function takes the settings_lock to protect against 
@@ -955,8 +856,8 @@
  *	a driver is attached we assume the driver settings are auto
  *	remove.
  */
- 
-int ide_add_setting (ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
+
+static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set, int auto_remove)
 {
 	ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL;
 
@@ -981,7 +882,7 @@
 	setting->set = set;
 	
 	setting->next = *p;
-	if (drive->driver != &idedefault_driver)
+	if (auto_remove)
 		setting->auto_remove = 1;
 	*p = setting;
 	up(&ide_setting_sem);
@@ -993,6 +894,11 @@
 	return -1;
 }
 
+int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
+{
+	return __ide_add_setting(drive, name, rw, read_ioctl, write_ioctl, data_type, min, max, mul_factor, div_factor, data, set, 1);
+}
+
 EXPORT_SYMBOL(ide_add_setting);
 
 /**
@@ -1282,17 +1188,17 @@
 void ide_add_generic_settings (ide_drive_t *drive)
 {
 /*
- *			drive	setting name		read/write access				read ioctl		write ioctl		data type	min	max				mul_factor	div_factor	data pointer			set function
+ *			  drive		setting name		read/write access				read ioctl		write ioctl		data type	min	max				mul_factor	div_factor	data pointer			set function
  */
-	ide_add_setting(drive,	"io_32bit",		drive->no_io_32bit ? SETTING_READ : SETTING_RW,	HDIO_GET_32BIT,		HDIO_SET_32BIT,		TYPE_BYTE,	0,	1 + (SUPPORT_VLB_SYNC << 1),	1,		1,		&drive->io_32bit,		set_io_32bit);
-	ide_add_setting(drive,	"keepsettings",		SETTING_RW,					HDIO_GET_KEEPSETTINGS,	HDIO_SET_KEEPSETTINGS,	TYPE_BYTE,	0,	1,				1,		1,		&drive->keep_settings,		NULL);
-	ide_add_setting(drive,	"nice1",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	1,				1,		1,		&drive->nice1,			NULL);
-	ide_add_setting(drive,	"pio_mode",		SETTING_WRITE,					-1,			HDIO_SET_PIO_MODE,	TYPE_BYTE,	0,	255,				1,		1,		NULL,				set_pio_mode);
-	ide_add_setting(drive,	"unmaskirq",		drive->no_unmask ? SETTING_READ : SETTING_RW,	HDIO_GET_UNMASKINTR,	HDIO_SET_UNMASKINTR,	TYPE_BYTE,	0,	1,				1,		1,		&drive->unmask,			NULL);
-	ide_add_setting(drive,	"using_dma",		SETTING_RW,					HDIO_GET_DMA,		HDIO_SET_DMA,		TYPE_BYTE,	0,	1,				1,		1,		&drive->using_dma,		set_using_dma);
-	ide_add_setting(drive,	"init_speed",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	70,				1,		1,		&drive->init_speed,		NULL);
-	ide_add_setting(drive,	"current_speed",	SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	70,				1,		1,		&drive->current_speed,		set_xfer_rate);
-	ide_add_setting(drive,	"number",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	3,				1,		1,		&drive->dn,			NULL);
+	__ide_add_setting(drive,	"io_32bit",		drive->no_io_32bit ? SETTING_READ : SETTING_RW,	HDIO_GET_32BIT,		HDIO_SET_32BIT,		TYPE_BYTE,	0,	1 + (SUPPORT_VLB_SYNC << 1),	1,		1,		&drive->io_32bit,		set_io_32bit,	0);
+	__ide_add_setting(drive,	"keepsettings",		SETTING_RW,					HDIO_GET_KEEPSETTINGS,	HDIO_SET_KEEPSETTINGS,	TYPE_BYTE,	0,	1,				1,		1,		&drive->keep_settings,		NULL,		0);
+	__ide_add_setting(drive,	"nice1",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	1,				1,		1,		&drive->nice1,			NULL,		0);
+	__ide_add_setting(drive,	"pio_mode",		SETTING_WRITE,					-1,			HDIO_SET_PIO_MODE,	TYPE_BYTE,	0,	255,				1,		1,		NULL,				set_pio_mode,	0);
+	__ide_add_setting(drive,	"unmaskirq",		drive->no_unmask ? SETTING_READ : SETTING_RW,	HDIO_GET_UNMASKINTR,	HDIO_SET_UNMASKINTR,	TYPE_BYTE,	0,	1,				1,		1,		&drive->unmask,			NULL,		0);
+	__ide_add_setting(drive,	"using_dma",		SETTING_RW,					HDIO_GET_DMA,		HDIO_SET_DMA,		TYPE_BYTE,	0,	1,				1,		1,		&drive->using_dma,		set_using_dma,	0);
+	__ide_add_setting(drive,	"init_speed",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	70,				1,		1,		&drive->init_speed,		NULL,		0);
+	__ide_add_setting(drive,	"current_speed",	SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	70,				1,		1,		&drive->current_speed,		set_xfer_rate,	0);
+	__ide_add_setting(drive,	"number",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	3,				1,		1,		&drive->dn,			NULL,		0);
 }
 
 /**
@@ -1309,73 +1215,6 @@
 
 EXPORT_SYMBOL(system_bus_clock);
 
-/*
- *	Locking is badly broken here - since way back.  That sucker is
- * root-only, but that's not an excuse...  The real question is what
- * exclusion rules do we want here.
- */
-int ide_replace_subdriver (ide_drive_t *drive, const char *driver)
-{
-	if (!drive->present || drive->usage || drive->dead)
-		goto abort;
-	if (DRIVER(drive)->cleanup(drive))
-		goto abort;
-	strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));
-	if (ata_attach(drive)) {
-		spin_lock(&drives_lock);
-		list_del_init(&drive->list);
-		spin_unlock(&drives_lock);
-		drive->driver_req[0] = 0;
-		ata_attach(drive);
-	} else {
-		drive->driver_req[0] = 0;
-	}
-	if (DRIVER(drive)!= &idedefault_driver && !strcmp(DRIVER(drive)->name, driver))
-		return 0;
-abort:
-	return 1;
-}
-
-/**
- *	ata_attach		-	attach an ATA/ATAPI device
- *	@drive: drive to attach
- *
- *	Takes a drive that is as yet not assigned to any midlayer IDE
- *	driver (or is assigned to the default driver) and figures out
- *	which driver would like to own it. If nobody claims the drive
- *	then it is automatically attached to the default driver used for
- *	unclaimed objects.
- *
- *	A return of zero indicates attachment to a driver, of one
- *	attachment to the default driver.
- *
- *	Takes drivers_lock.
- */
-
-int ata_attach(ide_drive_t *drive)
-{
-	struct list_head *p;
-	spin_lock(&drivers_lock);
-	list_for_each(p, &drivers) {
-		ide_driver_t *driver = list_entry(p, ide_driver_t, drivers);
-		if (!try_module_get(driver->owner))
-			continue;
-		spin_unlock(&drivers_lock);
-		if (driver->attach(drive) == 0) {
-			module_put(driver->owner);
-			drive->gendev.driver = &driver->gen_driver;
-			return 0;
-		}
-		spin_lock(&drivers_lock);
-		module_put(driver->owner);
-	}
-	drive->gendev.driver = &idedefault_driver.gen_driver;
-	spin_unlock(&drivers_lock);
-	if(idedefault_driver.attach(drive) != 0)
-		panic("ide: default attach failed");
-	return 1;
-}
-
 static int generic_ide_suspend(struct device *dev, pm_message_t state)
 {
 	ide_drive_t *drive = dev->driver_data;
@@ -1418,6 +1257,7 @@
 			unsigned int cmd, unsigned long arg)
 {
 	ide_settings_t *setting;
+	ide_driver_t *drv;
 	int err = 0;
 	void __user *p = (void __user *)arg;
 
@@ -1517,7 +1357,8 @@
 			if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1))))
 				return -EPERM;
 			drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1;
-			if (drive->dsc_overlap && !DRIVER(drive)->supports_dsc_overlap) {
+			drv = *(ide_driver_t **)bdev->bd_disk->private_data;
+			if (drive->dsc_overlap && !drv->supports_dsc_overlap) {
 				drive->dsc_overlap = 0;
 				return -EPERM;
 			}
@@ -2016,35 +1857,11 @@
 #endif
 }
 
-int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver)
+void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver)
 {
-	unsigned long flags;
-
-	BUG_ON(!drive->driver);
-
-	spin_lock_irqsave(&ide_lock, flags);
-	if (!drive->present || drive->driver != &idedefault_driver ||
-	    drive->usage || drive->dead) {
-		spin_unlock_irqrestore(&ide_lock, flags);
-		return 1;
-	}
-	drive->driver = driver;
-	spin_unlock_irqrestore(&ide_lock, flags);
-	spin_lock(&drives_lock);
-	list_add_tail(&drive->list, &driver->drives);
-	spin_unlock(&drives_lock);
-//	printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name);
-	if ((drive->autotune == IDE_TUNE_DEFAULT) ||
-		(drive->autotune == IDE_TUNE_AUTO)) {
-		/* DMA timings and setup moved to ide-probe.c */
-		drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap);
-		drive->nice1 = 1;
-	}
 #ifdef CONFIG_PROC_FS
-	if (drive->driver != &idedefault_driver)
-		ide_add_proc_entries(drive->proc, driver->proc, drive);
+	ide_add_proc_entries(drive->proc, driver->proc, drive);
 #endif
-	return 0;
 }
 
 EXPORT_SYMBOL(ide_register_subdriver);
@@ -2052,142 +1869,50 @@
 /**
  *	ide_unregister_subdriver	-	disconnect drive from driver
  *	@drive: drive to unplug
+ *	@driver: driver
  *
  *	Disconnect a drive from the driver it was attached to and then
  *	clean up the various proc files and other objects attached to it.
  *
- *	Takes ide_setting_sem, ide_lock and drives_lock.
+ *	Takes ide_setting_sem and ide_lock.
  *	Caller must hold none of the locks.
- *
- *	No locking versus subdriver unload because we are moving to the
- *	default driver anyway. Wants double checking.
  */
 
-int ide_unregister_subdriver (ide_drive_t *drive)
+void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver)
 {
 	unsigned long flags;
 	
 	down(&ide_setting_sem);
 	spin_lock_irqsave(&ide_lock, flags);
-	if (drive->usage || drive->driver == &idedefault_driver || DRIVER(drive)->busy) {
-		spin_unlock_irqrestore(&ide_lock, flags);
-		up(&ide_setting_sem);
-		return 1;
-	}
 #ifdef CONFIG_PROC_FS
-	ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc);
+	ide_remove_proc_entries(drive->proc, driver->proc);
 #endif
 	auto_remove_settings(drive);
-	drive->driver = &idedefault_driver;
 	spin_unlock_irqrestore(&ide_lock, flags);
 	up(&ide_setting_sem);
-	spin_lock(&drives_lock);
-	list_del_init(&drive->list);
-	spin_unlock(&drives_lock);
-	/* drive will be added to &idedefault_driver->drives in ata_attach() */
-	return 0;
 }
 
 EXPORT_SYMBOL(ide_unregister_subdriver);
 
-static int ide_drive_remove(struct device * dev)
-{
-	ide_drive_t * drive = container_of(dev,ide_drive_t,gendev);
-	DRIVER(drive)->cleanup(drive);
-	return 0;
-}
-
-/**
- *	ide_register_driver	-	register IDE device driver
- *	@driver: the IDE device driver
- *
- *	Register a new device driver and then scan the devices
- *	on the IDE bus in case any should be attached to the
- *	driver we have just registered.  If so attach them.
- *
- *	Takes drivers_lock and drives_lock.
- */
-
-int ide_register_driver(ide_driver_t *driver)
-{
-	struct list_head list;
-	struct list_head *list_loop;
-	struct list_head *tmp_storage;
-
-	spin_lock(&drivers_lock);
-	list_add(&driver->drivers, &drivers);
-	spin_unlock(&drivers_lock);
-
-	INIT_LIST_HEAD(&list);
-	spin_lock(&drives_lock);
-	list_splice_init(&idedefault_driver.drives, &list);
-	spin_unlock(&drives_lock);
-
-	list_for_each_safe(list_loop, tmp_storage, &list) {
-		ide_drive_t *drive = container_of(list_loop, ide_drive_t, list);
-		list_del_init(&drive->list);
-		if (drive->present)
-			ata_attach(drive);
-	}
-	driver->gen_driver.name = (char *) driver->name;
-	driver->gen_driver.bus = &ide_bus_type;
-	driver->gen_driver.remove = ide_drive_remove;
-	return driver_register(&driver->gen_driver);
-}
-
-EXPORT_SYMBOL(ide_register_driver);
-
-/**
- *	ide_unregister_driver	-	unregister IDE device driver
- *	@driver: the IDE device driver
- *
- *	Called when a driver module is being unloaded. We reattach any
- *	devices to whatever driver claims them next (typically the default
- *	driver).
- *
- *	Takes drivers_lock and called functions will take ide_setting_sem.
- */
-
-void ide_unregister_driver(ide_driver_t *driver)
-{
-	ide_drive_t *drive;
-
-	spin_lock(&drivers_lock);
-	list_del(&driver->drivers);
-	spin_unlock(&drivers_lock);
-
-	driver_unregister(&driver->gen_driver);
-
-	while(!list_empty(&driver->drives)) {
-		drive = list_entry(driver->drives.next, ide_drive_t, list);
-		if (driver->cleanup(drive)) {
-			printk(KERN_ERR "%s: cleanup_module() called while still busy\n", drive->name);
-			BUG();
-		}
-		ata_attach(drive);
-	}
-}
-
-EXPORT_SYMBOL(ide_unregister_driver);
-
-struct block_device_operations ide_fops[] = {{
-	.owner		= THIS_MODULE,
-	.open		= ide_open,
-}};
-
-EXPORT_SYMBOL(ide_fops);
-
 /*
  * Probe module
  */
 
 EXPORT_SYMBOL(ide_lock);
 
+static int ide_bus_match(struct device *dev, struct device_driver *drv)
+{
+	return 1;
+}
+
 struct bus_type ide_bus_type = {
 	.name		= "ide",
+	.match		= ide_bus_match,
 	.suspend	= generic_ide_suspend,
 	.resume		= generic_ide_resume,
 };
+
+EXPORT_SYMBOL_GPL(ide_bus_type);
 
 /*
  * This is gets invoked once during initialization, to set *everything* up
diff -Nru a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
--- a/drivers/ide/pci/pdc202xx_new.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/pci/pdc202xx_new.c	2005-03-30 17:28:48 -08:00
@@ -420,9 +420,6 @@
 		.init_hwif	= init_hwif_pdc202new,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
 		.bootable	= OFF_BOARD,
 	},{	/* 3 */
 		.name		= "PDC20271",
@@ -447,9 +444,6 @@
 		.init_hwif	= init_hwif_pdc202new,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
 		.bootable	= OFF_BOARD,
 	},{	/* 6 */
 		.name		= "PDC20277",
diff -Nru a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
--- a/drivers/ide/pci/pdc202xx_old.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/pci/pdc202xx_old.c	2005-03-30 17:28:48 -08:00
@@ -786,9 +786,6 @@
 		.init_dma	= init_dma_pdc202xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
 		.bootable	= OFF_BOARD,
 		.extra		= 16,
 	},{	/* 1 */
@@ -799,12 +796,8 @@
 		.init_dma	= init_dma_pdc202xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
 		.bootable	= OFF_BOARD,
 		.extra		= 48,
-		.flags		= IDEPCI_FLAG_FORCE_PDC,
 	},{	/* 2 */
 		.name		= "PDC20263",
 		.init_setup	= init_setup_pdc202ata4,
@@ -813,9 +806,6 @@
 		.init_dma	= init_dma_pdc202xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
 		.bootable	= OFF_BOARD,
 		.extra		= 48,
 	},{	/* 3 */
@@ -826,12 +816,8 @@
 		.init_dma	= init_dma_pdc202xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
 		.bootable	= OFF_BOARD,
 		.extra		= 48,
-		.flags		= IDEPCI_FLAG_FORCE_PDC,
 	},{	/* 4 */
 		.name		= "PDC20267",
 		.init_setup	= init_setup_pdc202xx,
@@ -840,9 +826,6 @@
 		.init_dma	= init_dma_pdc202xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
 		.bootable	= OFF_BOARD,
 		.extra		= 48,
 	}
diff -Nru a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
--- a/drivers/ide/pci/via82cxxx.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/pci/via82cxxx.c	2005-03-30 17:28:48 -08:00
@@ -79,6 +79,7 @@
 	u8 rev_max;
 	u16 flags;
 } via_isa_bridges[] = {
+	{ "vt6410",	PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
@@ -332,11 +333,8 @@
 	struct ide_timing t, p;
 	unsigned int T, UT;
 
-	if (speed != XFER_PIO_SLOW && speed != drive->current_speed)
-		if (ide_config_drive_speed(drive, speed))
-			printk(KERN_WARNING "ide%d: Drive %d didn't "
-				"accept speed setting. Oh, well.\n",
-				drive->dn >> 1, drive->dn & 1);
+	if (speed != XFER_PIO_SLOW)
+		ide_config_drive_speed(drive, speed);
 
 	T = 1000000000 / via_clock;
 
@@ -619,24 +617,35 @@
 	hwif->drives[1].autodma = hwif->autodma;
 }
 
-static ide_pci_device_t via82cxxx_chipset __devinitdata = {
-	.name		= "VP_IDE",
-	.init_chipset	= init_chipset_via82cxxx,
-	.init_hwif	= init_hwif_via82cxxx,
-	.channels	= 2,
-	.autodma	= NOAUTODMA,
-	.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
-	.bootable	= ON_BOARD,
+static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "VP_IDE",
+		.init_chipset	= init_chipset_via82cxxx,
+		.init_hwif	= init_hwif_via82cxxx,
+		.channels	= 2,
+		.autodma	= NOAUTODMA,
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+		.bootable	= ON_BOARD
+	},{	/* 1 */
+		.name		= "VP_IDE",
+		.init_chipset	= init_chipset_via82cxxx,
+		.init_hwif	= init_hwif_via82cxxx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+		.bootable	= ON_BOARD,
+	}
 };
 
 static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	return ide_setup_pci_device(dev, &via82cxxx_chipset);
+	return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
 }
 
 static struct pci_device_id via_pci_tbl[] = {
 	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, via_pci_tbl);
diff -Nru a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
--- a/drivers/ide/setup-pci.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/ide/setup-pci.c	2005-03-30 17:28:48 -08:00
@@ -579,7 +579,6 @@
 	int port;
 	int at_least_one_hwif_enabled = 0;
 	ide_hwif_t *hwif, *mate = NULL;
-	static int secondpdc = 0;
 	u8 tmp;
 
 	index->all = 0xf0f0;
@@ -590,22 +589,10 @@
 	 
 	for (port = 0; port <= 1; ++port) {
 		ide_pci_enablebit_t *e = &(d->enablebits[port]);
-	
-		/* 
-		 * If this is a Promise FakeRaid controller,
-		 * the 2nd controller will be marked as 
-		 * disabled while it is actually there and enabled
-		 * by the bios for raid purposes. 
-		 * Skip the normal "is it enabled" test for those.
-		 */
-		if ((d->flags & IDEPCI_FLAG_FORCE_PDC) &&
-		    (secondpdc++==1) && (port==1))
-			goto controller_ok;
-			
+
 		if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
 		    (tmp & e->mask) != e->val))
 			continue;	/* port not enabled */
-controller_ok:
 
 		if (d->channels	<= port)
 			break;
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c	2005-03-30 17:28:48 -08:00
+++ b/drivers/scsi/ide-scsi.c	2005-03-30 17:28:48 -08:00
@@ -98,6 +98,8 @@
 
 typedef struct ide_scsi_obj {
 	ide_drive_t		*drive;
+	ide_driver_t		*driver;
+	struct gendisk		*disk;
 	struct Scsi_Host	*host;
 
 	idescsi_pc_t *pc;			/* Current packet command */
@@ -108,7 +110,8 @@
 
 static DECLARE_MUTEX(idescsi_ref_sem);
 
-#define ide_scsi_g(disk)	((disk)->private_data)
+#define ide_scsi_g(disk) \
+	container_of((disk)->private_data, struct ide_scsi_obj, driver)
 
 static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk)
 {
@@ -323,9 +326,12 @@
 		printk ("ide-scsi: %s: queue cmd = ", drive->name);
 		hexdump(pc->c, 6);
 	}
+	rq->rq_disk = scsi->disk;
 	return ide_do_drive_cmd(drive, rq, ide_preempt);
 }
 
+static int idescsi_end_request(ide_drive_t *, int, int);
+
 static ide_startstop_t
 idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
 {
@@ -334,7 +340,9 @@
 		HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
 
 	rq->errors++;
-	DRIVER(drive)->end_request(drive, 0, 0);
+
+	idescsi_end_request(drive, 0, 0);
+
 	return ide_stopped;
 }
 
@@ -346,7 +354,9 @@
 			((idescsi_pc_t *) rq->special)->scsi_cmd->serial_number);
 #endif
 	rq->errors |= ERROR_MAX;
-	DRIVER(drive)->end_request(drive, 0, 0);
+
+	idescsi_end_request(drive, 0, 0);
+
 	return ide_stopped;
 }
 
@@ -703,7 +713,6 @@
  */
 static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
 {
-	DRIVER(drive)->busy++;
 	if (drive->id && (drive->id->config & 0x0060) == 0x20)
 		set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
 	set_bit(IDESCSI_TRANSFORM, &scsi->transform);
@@ -712,28 +721,32 @@
 	set_bit(IDESCSI_LOG_CMD, &scsi->log);
 #endif /* IDESCSI_DEBUG_LOG */
 	idescsi_add_settings(drive);
-	DRIVER(drive)->busy--;
 }
 
-static int idescsi_cleanup (ide_drive_t *drive)
+static int ide_scsi_remove(struct device *dev)
 {
+	ide_drive_t *drive = to_ide_device(dev);
 	struct Scsi_Host *scsihost = drive->driver_data;
-	struct gendisk *g = drive->disk;
+	struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);
+	struct gendisk *g = scsi->disk;
 
-	if (ide_unregister_subdriver(drive))
-		return 1;
+	ide_unregister_subdriver(drive, scsi->driver);
+
+	ide_unregister_region(g);
 
+	/* FIXME: drive->driver_data shouldn't be used */
 	drive->driver_data = NULL;
+	/* FIXME: add driver's private struct gendisk */
 	g->private_data = NULL;
-	g->fops = ide_fops;
+	put_disk(g);
 
 	scsi_remove_host(scsihost);
-	ide_scsi_put(scsihost_to_idescsi(scsihost));
+	ide_scsi_put(scsi);
 
 	return 0;
 }
 
-static int idescsi_attach(ide_drive_t *drive);
+static int ide_scsi_probe(struct device *);
 
 #ifdef CONFIG_PROC_FS
 static ide_proc_entry_t idescsi_proc[] = {
@@ -744,24 +757,22 @@
 # define idescsi_proc	NULL
 #endif
 
-/*
- *	IDE subdriver functions, registered with ide.c
- */
 static ide_driver_t idescsi_driver = {
 	.owner			= THIS_MODULE,
-	.name			= "ide-scsi",
+	.gen_driver = {
+		.name		= "ide-scsi",
+		.bus		= &ide_bus_type,
+		.probe		= ide_scsi_probe,
+		.remove		= ide_scsi_remove,
+	},
 	.version		= IDESCSI_VERSION,
 	.media			= ide_scsi,
-	.busy			= 0,
 	.supports_dsc_overlap	= 0,
 	.proc			= idescsi_proc,
-	.attach			= idescsi_attach,
-	.cleanup		= idescsi_cleanup,
 	.do_request		= idescsi_do_request,
 	.end_request		= idescsi_end_request,
 	.error                  = idescsi_atapi_error,
 	.abort                  = idescsi_atapi_abort,
-	.drives			= LIST_HEAD_INIT(idescsi_driver.drives),
 };
 
 static int idescsi_ide_open(struct inode *inode, struct file *filp)
@@ -808,8 +819,6 @@
 	.ioctl		= idescsi_ide_ioctl,
 };
 
-static int idescsi_attach(ide_drive_t *drive);
-
 static int idescsi_slave_configure(struct scsi_device * sdp)
 {
 	/* Configure detected device */
@@ -910,6 +919,7 @@
 	rq->special = (char *) pc;
 	rq->flags = REQ_SPECIAL;
 	spin_unlock_irq(host->host_lock);
+	rq->rq_disk = scsi->disk;
 	(void) ide_do_drive_cmd (drive, rq, ide_end);
 	spin_lock_irq(host->host_lock);
 	return 0;
@@ -1081,13 +1091,14 @@
 	.proc_name		= "ide-scsi",
 };
 
-static int idescsi_attach(ide_drive_t *drive)
+static int ide_scsi_probe(struct device *dev)
 {
+	ide_drive_t *drive = to_ide_device(dev);
 	idescsi_scsi_t *idescsi;
 	struct Scsi_Host *host;
-	struct gendisk *g = drive->disk;
+	struct gendisk *g;
 	static int warned;
-	int err;
+	int err = -ENODEV;
 
 	if (!warned && drive->media == ide_cdrom) {
 		printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n");
@@ -1095,10 +1106,19 @@
 	}
 
 	if (!strstr("ide-scsi", drive->driver_req) ||
-	    !drive->present ||
-	    drive->media == ide_disk ||
-	    !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
-		return 1;
+	    drive->media == ide_disk || !drive->present)
+		goto out;
+
+	err = -ENOMEM;
+	host = scsi_host_alloc(&idescsi_template, sizeof(idescsi_scsi_t));
+	if (!host)
+		goto out;
+
+	g = alloc_disk(1 << PARTN_BITS);
+	if (!g)
+		goto out_host_put;
+
+	ide_init_disk(g, drive);
 
 	host->max_id = 1;
 
@@ -1114,33 +1134,41 @@
 	drive->driver_data = host;
 	idescsi = scsihost_to_idescsi(host);
 	idescsi->drive = drive;
+	idescsi->driver = &idescsi_driver;
 	idescsi->host = host;
-	err = ide_register_subdriver(drive, &idescsi_driver);
+	idescsi->disk = g;
+	g->private_data = &idescsi->driver;
+	ide_register_subdriver(drive, &idescsi_driver);
+	err = 0;
 	if (!err) {
 		idescsi_setup (drive, idescsi);
 		g->fops = &idescsi_ops;
-		g->private_data = idescsi;
+		ide_register_region(g);
 		err = scsi_add_host(host, &drive->gendev);
 		if (!err) {
 			scsi_scan_host(host);
 			return 0;
 		}
 		/* fall through on error */
-		ide_unregister_subdriver(drive);
+		ide_unregister_region(g);
+		ide_unregister_subdriver(drive, &idescsi_driver);
 	}
 
+	put_disk(g);
+out_host_put:
 	scsi_host_put(host);
+out:
 	return err;
 }
 
 static int __init init_idescsi_module(void)
 {
-	return ide_register_driver(&idescsi_driver);
+	return driver_register(&idescsi_driver.gen_driver);
 }
 
 static void __exit exit_idescsi_module(void)
 {
-	ide_unregister_driver(&idescsi_driver);
+	driver_unregister(&idescsi_driver.gen_driver);
 }
 
 module_init(init_idescsi_module);
diff -Nru a/include/linux/ata.h b/include/linux/ata.h
--- a/include/linux/ata.h	2005-03-30 17:28:48 -08:00
+++ b/include/linux/ata.h	2005-03-30 17:28:48 -08:00
@@ -174,6 +174,7 @@
 	ATA_TFLAG_ISADDR	= (1 << 1), /* enable r/w to nsect/lba regs */
 	ATA_TFLAG_DEVICE	= (1 << 2), /* enable r/w to device reg */
 	ATA_TFLAG_WRITE		= (1 << 3), /* data dir: host->dev==1 (write) */
+	ATA_TFLAG_IO_16BIT	= (1 << 4), /* force 16bit pio */
 };
 
 enum ata_tf_protocols {
@@ -212,15 +213,16 @@
 	u8			hob_lbam;
 	u8			hob_lbah;
 
-	u8			feature;
+	u8			feature;	/* error on read */
 	u8			nsect;
-	u8			lbal;
-	u8			lbam;
-	u8			lbah;
+	u8			lbal;		/* sector in CHS */
+	u8			lbam;		/* low cylinder in CHS */
+	u8			lbah;		/* high cylinder in CHS */
 
-	u8			device;
+	u8			device;		/* select */
 
 	u8			command;	/* IO operation */
+						/* status on read */
 };
 
 #define ata_id_is_ata(id)	(((id)[0] & (1 << 15)) == 0)
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	2005-03-30 17:28:48 -08:00
+++ b/include/linux/blkdev.h	2005-03-30 17:28:48 -08:00
@@ -211,7 +211,6 @@
 	__REQ_QUIET,		/* don't worry about errors */
 	__REQ_SPECIAL,		/* driver suplied command */
 	__REQ_DRIVE_CMD,
-	__REQ_DRIVE_TASK,
 	__REQ_DRIVE_TASKFILE,
 	__REQ_PREEMPT,		/* set for "ide_preempt" requests */
 	__REQ_PM_SUSPEND,	/* suspend request */
@@ -239,7 +238,6 @@
 #define REQ_QUIET	(1 << __REQ_QUIET)
 #define REQ_SPECIAL	(1 << __REQ_SPECIAL)
 #define REQ_DRIVE_CMD	(1 << __REQ_DRIVE_CMD)
-#define REQ_DRIVE_TASK	(1 << __REQ_DRIVE_TASK)
 #define REQ_DRIVE_TASKFILE	(1 << __REQ_DRIVE_TASKFILE)
 #define REQ_PREEMPT	(1 << __REQ_PREEMPT)
 #define REQ_PM_SUSPEND	(1 << __REQ_PM_SUSPEND)
diff -Nru a/include/linux/hdreg.h b/include/linux/hdreg.h
--- a/include/linux/hdreg.h	2005-03-30 17:28:48 -08:00
+++ b/include/linux/hdreg.h	2005-03-30 17:28:48 -08:00
@@ -113,7 +113,7 @@
 
 typedef struct ide_task_request_s {
 	task_ioreg_t	io_ports[8];
-	task_ioreg_t	hob_ports[8];
+	task_ioreg_t	hob_ports[8]; /* bytes 6 and 7 are unused */
 	ide_reg_valid_t	out_flags;
 	ide_reg_valid_t	in_flags;
 	int		data_phase;
@@ -135,6 +135,7 @@
 	task_ioreg_t sector_count;
 };
 
+#ifndef __KERNEL__
 typedef struct hd_drive_task_hdr {
 	task_ioreg_t data;
 	task_ioreg_t feature;
@@ -156,6 +157,7 @@
 	task_ioreg_t device_head;
 	task_ioreg_t control;
 } hob_struct_t;
+#endif
 
 #define TASKFILE_INVALID		0x7fff
 #define TASKFILE_48			0x8000
diff -Nru a/include/linux/ide.h b/include/linux/ide.h
--- a/include/linux/ide.h	2005-03-30 17:28:48 -08:00
+++ b/include/linux/ide.h	2005-03-30 17:28:48 -08:00
@@ -110,8 +110,6 @@
 #define IDE_FEATURE_OFFSET	IDE_ERROR_OFFSET
 #define IDE_COMMAND_OFFSET	IDE_STATUS_OFFSET
 
-#define IDE_CONTROL_OFFSET_HOB	(7)
-
 #define IDE_DATA_REG		(HWIF(drive)->io_ports[IDE_DATA_OFFSET])
 #define IDE_ERROR_REG		(HWIF(drive)->io_ports[IDE_ERROR_OFFSET])
 #define IDE_NSECTOR_REG		(HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET])
@@ -653,6 +651,21 @@
 	ide_started,	/* a drive operation was started, handler was set */
 } ide_startstop_t;
 
+struct ide_drive_s;
+
+typedef struct ide_task_s {
+	struct ata_taskfile	tf;
+	u16			data;
+	ide_reg_valid_t		tf_out_flags;
+	ide_reg_valid_t		tf_in_flags;
+	int			data_phase;
+	int			command_type;
+	ide_startstop_t		(*prehandler)(struct ide_drive_s *, struct request *rq);
+	ide_startstop_t		(*handler)(struct ide_drive_s *);
+	struct request		*rq;		/* copy of request */
+	void			*special;	/* valid_t generally */
+} ide_task_t;
+
 struct ide_driver_s;
 struct ide_settings_s;
 
@@ -664,7 +677,6 @@
 
 	struct request		*rq;	/* current request */
 	struct ide_drive_s 	*next;	/* circular list of hwgroup drives */
-	struct ide_driver_s	*driver;/* (ide_driver_t *) */
 	void		*driver_data;	/* extra driver data */
 	struct hd_driveid	*id;	/* drive model identification info */
 	struct proc_dir_entry *proc;	/* /proc/ide/ directory entry */
@@ -756,9 +768,12 @@
 	struct list_head list;
 	struct device	gendev;
 	struct semaphore gendev_rel_sem;	/* to deal with device release() */
-	struct gendisk *disk;
+
+	ide_task_t	flush_task;	/* task used for flushing */
 } ide_drive_t;
 
+#define to_ide_device(dev)container_of(dev, ide_drive_t, gendev)
+
 #define IDE_CHIPSET_PCI_MASK	\
     ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
 #define IDE_CHIPSET_IS_PCI(c)	((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
@@ -951,8 +966,6 @@
 	struct request *rq;
 		/* failsafe timer */
 	struct timer_list timer;
-		/* local copy of current write rq */
-	struct request wrq;
 		/* timeout value during long polls */
 	unsigned long poll_timeout;
 		/* queried upon timeouts */
@@ -1087,28 +1100,20 @@
  */
 typedef struct ide_driver_s {
 	struct module			*owner;
-	const char			*name;
 	const char			*version;
 	u8				media;
-	unsigned busy			: 1;
 	unsigned supports_dsc_overlap	: 1;
-	int		(*cleanup)(ide_drive_t *);
 	ide_startstop_t	(*do_request)(ide_drive_t *, struct request *, sector_t);
 	int		(*end_request)(ide_drive_t *, int, int);
 	ide_startstop_t	(*error)(ide_drive_t *, struct request *rq, u8, u8);
 	ide_startstop_t	(*abort)(ide_drive_t *, struct request *rq);
 	int		(*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
 	ide_proc_entry_t	*proc;
-	int		(*attach)(ide_drive_t *);
 	void		(*ata_prebuilder)(ide_drive_t *);
 	void		(*atapi_prebuilder)(ide_drive_t *);
 	struct device_driver	gen_driver;
-	struct list_head drives;
-	struct list_head drivers;
 } ide_driver_t;
 
-#define DRIVER(drive)		((drive)->driver)
-
 int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsigned, unsigned long);
 
 /*
@@ -1192,10 +1197,9 @@
  */
 extern void ide_init_drive_cmd (struct request *rq);
 
-/*
- * this function returns error location sector offset in case of a write error
- */
-extern u64 ide_get_error_location(ide_drive_t *, char *);
+void ide_task_init_flush(ide_drive_t *, ide_task_t *);
+
+u64 ide_tf_get_address(ide_drive_t *, struct ata_taskfile *);
 
 /*
  * "action" parameter type for ide_do_drive_cmd() below.
@@ -1252,25 +1256,6 @@
  */
 extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *);
 
-typedef struct ide_task_s {
-/*
- *	struct hd_drive_task_hdr	tf;
- *	task_struct_t		tf;
- *	struct hd_drive_hob_hdr		hobf;
- *	hob_struct_t		hobf;
- */
-	task_ioreg_t		tfRegister[8];
-	task_ioreg_t		hobRegister[8];
-	ide_reg_valid_t		tf_out_flags;
-	ide_reg_valid_t		tf_in_flags;
-	int			data_phase;
-	int			command_type;
-	ide_pre_handler_t	*prehandler;
-	ide_handler_t		*handler;
-	struct request		*rq;		/* copy of request */
-	void			*special;	/* valid_t generally */
-} ide_task_t;
-
 extern u32 ide_read_24(ide_drive_t *);
 
 extern void SELECT_DRIVE(ide_drive_t *);
@@ -1327,9 +1312,7 @@
 extern void do_ide_request(request_queue_t *);
 extern void ide_init_subdrivers(void);
 
-extern struct block_device_operations ide_fops[];
-
-extern int ata_attach(ide_drive_t *);
+void ide_init_disk(struct gendisk *, ide_drive_t *);
 
 extern int ideprobe_init(void);
 
@@ -1343,11 +1326,8 @@
 extern void default_hwif_mmiops(ide_hwif_t *);
 extern void default_hwif_transport(ide_hwif_t *);
 
-int ide_register_driver(ide_driver_t *driver);
-void ide_unregister_driver(ide_driver_t *driver);
-int ide_register_subdriver(ide_drive_t *, ide_driver_t *);
-int ide_unregister_subdriver (ide_drive_t *drive);
-int ide_replace_subdriver(ide_drive_t *drive, const char *driver);
+void ide_register_subdriver(ide_drive_t *, ide_driver_t *);
+void ide_unregister_subdriver(ide_drive_t *, ide_driver_t *);
 
 #define ON_BOARD		1
 #define NEVER_BOARD		0
@@ -1371,7 +1351,6 @@
 enum {
 	/* Uses ISA control ports not PCI ones. */
 	IDEPCI_FLAG_ISA_PORTS		= (1 << 0),
-	IDEPCI_FLAG_FORCE_PDC		= (1 << 1),
 };
 
 typedef struct ide_pci_device_s {
@@ -1441,6 +1420,9 @@
 extern int ide_hwif_request_regions(ide_hwif_t *hwif);
 extern void ide_hwif_release_regions(ide_hwif_t* hwif);
 extern void ide_unregister (unsigned int index);
+
+void ide_register_region(struct gendisk *);
+void ide_unregister_region(struct gendisk *);
 
 void ide_undecoded_slave(ide_hwif_t *);
 
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	2005-03-30 17:28:48 -08:00
+++ b/include/linux/pci_ids.h	2005-03-30 17:28:48 -08:00
@@ -1388,6 +1388,7 @@
 #define PCI_DEVICE_ID_VIA_8703_51_0	0x3148
 #define PCI_DEVICE_ID_VIA_8237_SATA	0x3149
 #define PCI_DEVICE_ID_VIA_XN266		0x3156
+#define PCI_DEVICE_ID_VIA_6410		0x3164
 #define PCI_DEVICE_ID_VIA_8754C_0	0x3168
 #define PCI_DEVICE_ID_VIA_8235		0x3177
 #define PCI_DEVICE_ID_VIA_P4N333	0x3178