2005-04-17 02:20:36 +04:00
/*
2008-02-02 01:09:33 +03:00
* Copyright ( C ) 1994 - 1998 Linus Torvalds & authors ( see below )
* Copyright ( C ) 1998 - 2002 Linux ATA Development
* Andre Hedrick < andre @ linux - ide . org >
2008-11-02 23:40:08 +03:00
* Copyright ( C ) 2003 Red Hat
2008-02-02 01:09:33 +03:00
* Copyright ( C ) 2003 - 2005 , 2007 Bartlomiej Zolnierkiewicz
2005-04-17 02:20:36 +04:00
*/
/*
* Mostly written by Mark Lord < mlord @ pobox . com >
* and Gadi Oxman < gadio @ netvision . net . il >
* and Andre Hedrick < andre @ linux - ide . org >
*
* This is the IDE / ATA disk driver , as evolved from hd . c and ide . c .
*/
# include <linux/types.h>
# include <linux/string.h>
# include <linux/kernel.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/delay.h>
2006-03-23 14:00:45 +03:00
# include <linux/mutex.h>
2006-03-31 14:31:16 +04:00
# include <linux/leds.h>
2005-04-17 02:20:36 +04:00
# include <linux/ide.h>
# include <asm/byteorder.h>
# include <asm/irq.h>
# include <asm/uaccess.h>
# include <asm/io.h>
# include <asm/div64.h>
2008-10-13 23:39:45 +04:00
# include "ide-disk.h"
2005-04-17 02:20:36 +04:00
2008-01-26 00:17:16 +03:00
static const u8 ide_rw_cmds [ ] = {
2008-10-11 00:39:21 +04:00
ATA_CMD_READ_MULTI ,
ATA_CMD_WRITE_MULTI ,
ATA_CMD_READ_MULTI_EXT ,
ATA_CMD_WRITE_MULTI_EXT ,
ATA_CMD_PIO_READ ,
ATA_CMD_PIO_WRITE ,
ATA_CMD_PIO_READ_EXT ,
ATA_CMD_PIO_WRITE_EXT ,
ATA_CMD_READ ,
ATA_CMD_WRITE ,
ATA_CMD_READ_EXT ,
ATA_CMD_WRITE_EXT ,
2008-01-26 00:17:16 +03:00
} ;
2009-03-27 14:46:37 +03:00
static void ide_tf_set_cmd ( ide_drive_t * drive , struct ide_cmd * cmd , u8 dma )
2008-01-26 00:17:16 +03:00
{
u8 index , lba48 , write ;
2009-03-27 14:46:37 +03:00
lba48 = ( cmd - > tf_flags & IDE_TFLAG_LBA48 ) ? 2 : 0 ;
write = ( cmd - > tf_flags & IDE_TFLAG_WRITE ) ? 1 : 0 ;
2008-01-26 00:17:16 +03:00
2009-03-27 14:46:39 +03:00
if ( dma ) {
cmd - > protocol = ATA_PROT_DMA ;
2008-07-23 21:55:55 +04:00
index = 8 ;
2009-03-27 14:46:39 +03:00
} else {
cmd - > protocol = ATA_PROT_PIO ;
if ( drive - > mult_count ) {
cmd - > tf_flags | = IDE_TFLAG_MULTI_PIO ;
index = 0 ;
} else
index = 4 ;
}
2008-01-26 00:17:16 +03:00
2009-03-27 14:46:37 +03:00
cmd - > tf . command = ide_rw_cmds [ index + lba48 + write ] ;
2008-01-26 00:17:16 +03:00
}
2005-04-17 02:20:36 +04:00
/*
* __ide_do_rw_disk ( ) issues READ and WRITE commands to a disk ,
* using LBA if supported , or CHS otherwise , to address sectors .
*/
2008-04-26 19:36:37 +04:00
static ide_startstop_t __ide_do_rw_disk ( ide_drive_t * drive , struct request * rq ,
sector_t block )
2005-04-17 02:20:36 +04:00
{
2009-01-06 19:20:52 +03:00
ide_hwif_t * hwif = drive - > hwif ;
2009-05-07 17:24:40 +04:00
u16 nsectors = ( u16 ) blk_rq_sectors ( rq ) ;
2008-10-13 23:39:36 +04:00
u8 lba48 = ! ! ( drive - > dev_flags & IDE_DFLAG_LBA48 ) ;
u8 dma = ! ! ( drive - > dev_flags & IDE_DFLAG_USING_DMA ) ;
2009-03-27 14:46:37 +03:00
struct ide_cmd cmd ;
struct ide_taskfile * tf = & cmd . tf ;
2008-01-26 00:17:16 +03:00
ide_startstop_t rc ;
2005-04-17 02:20:36 +04:00
2007-10-19 02:30:07 +04:00
if ( ( hwif - > host_flags & IDE_HFLAG_NO_LBA48_DMA ) & & lba48 & & dma ) {
2009-05-07 17:24:40 +04:00
if ( block + blk_rq_sectors ( rq ) > 1ULL < < 28 )
2005-04-17 02:20:36 +04:00
dma = 0 ;
else
lba48 = 0 ;
}
2009-03-27 14:46:37 +03:00
memset ( & cmd , 0 , sizeof ( cmd ) ) ;
2009-04-08 16:13:01 +04:00
cmd . valid . out . tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE ;
cmd . valid . in . tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE ;
2008-01-26 00:17:06 +03:00
2008-10-13 23:39:38 +04:00
if ( drive - > dev_flags & IDE_DFLAG_LBA ) {
2005-04-17 02:20:36 +04:00
if ( lba48 ) {
2006-02-07 23:58:33 +03:00
pr_debug ( " %s: LBA=0x%012llx \n " , drive - > name ,
( unsigned long long ) block ) ;
2005-04-17 02:20:36 +04:00
2008-01-26 00:17:12 +03:00
tf - > nsect = nsectors & 0xff ;
2008-01-26 00:17:06 +03:00
tf - > lbal = ( u8 ) block ;
tf - > lbam = ( u8 ) ( block > > 8 ) ;
tf - > lbah = ( u8 ) ( block > > 16 ) ;
2009-04-08 16:13:02 +04:00
tf - > device = ATA_LBA ;
tf = & cmd . hob ;
tf - > nsect = ( nsectors > > 8 ) & 0xff ;
tf - > lbal = ( u8 ) ( block > > 24 ) ;
if ( sizeof ( block ) ! = 4 ) {
tf - > lbam = ( u8 ) ( ( u64 ) block > > 32 ) ;
tf - > lbah = ( u8 ) ( ( u64 ) block > > 40 ) ;
}
2008-01-26 22:13:03 +03:00
2009-04-08 16:13:01 +04:00
cmd . valid . out . hob = IDE_VALID_OUT_HOB ;
cmd . valid . in . hob = IDE_VALID_IN_HOB ;
cmd . tf_flags | = IDE_TFLAG_LBA48 ;
2005-04-17 02:20:36 +04:00
} else {
2008-01-26 00:17:12 +03:00
tf - > nsect = nsectors & 0xff ;
2008-01-26 00:17:06 +03:00
tf - > lbal = block ;
tf - > lbam = block > > = 8 ;
tf - > lbah = block > > = 8 ;
2009-04-08 16:13:02 +04:00
tf - > device = ( ( block > > 8 ) & 0xf ) | ATA_LBA ;
2005-04-17 02:20:36 +04:00
}
} else {
2008-04-26 19:36:37 +04:00
unsigned int sect , head , cyl , track ;
2005-04-17 02:20:36 +04:00
track = ( int ) block / drive - > sect ;
sect = ( int ) block % drive - > sect + 1 ;
head = track % drive - > head ;
cyl = track / drive - > head ;
pr_debug ( " %s: CHS=%u/%u/%u \n " , drive - > name , cyl , head , sect ) ;
2008-01-26 00:17:12 +03:00
tf - > nsect = nsectors & 0xff ;
2008-01-26 00:17:06 +03:00
tf - > lbal = sect ;
tf - > lbam = cyl ;
tf - > lbah = cyl > > 8 ;
tf - > device = head ;
2005-04-17 02:20:36 +04:00
}
2009-03-27 14:46:38 +03:00
cmd . tf_flags | = IDE_TFLAG_FS ;
2008-01-26 00:17:16 +03:00
if ( rq_data_dir ( rq ) )
2009-03-27 14:46:37 +03:00
cmd . tf_flags | = IDE_TFLAG_WRITE ;
2008-01-26 00:17:16 +03:00
2009-03-27 14:46:37 +03:00
ide_tf_set_cmd ( drive , & cmd , dma ) ;
cmd . rq = rq ;
2008-01-26 00:17:16 +03:00
2009-03-27 14:46:46 +03:00
if ( dma = = 0 ) {
2009-03-27 14:46:47 +03:00
ide_init_sg_cmd ( & cmd , nsectors < < 9 ) ;
2009-03-27 14:46:46 +03:00
ide_map_sg ( drive , & cmd ) ;
}
2009-03-27 14:46:37 +03:00
rc = do_rw_taskfile ( drive , & cmd ) ;
2008-01-26 00:17:06 +03:00
2008-01-26 00:17:16 +03:00
if ( rc = = ide_stopped & & dma ) {
2005-04-17 02:20:36 +04:00
/* fallback to PIO */
2009-03-27 14:46:37 +03:00
cmd . tf_flags | = IDE_TFLAG_DMA_PIO_FALLBACK ;
ide_tf_set_cmd ( drive , & cmd , 0 ) ;
2009-03-27 14:46:47 +03:00
ide_init_sg_cmd ( & cmd , nsectors < < 9 ) ;
2009-03-27 14:46:37 +03:00
rc = do_rw_taskfile ( drive , & cmd ) ;
2005-04-17 02:20:36 +04:00
}
2008-01-26 00:17:16 +03:00
return rc ;
2005-04-17 02:20:36 +04:00
}
/*
* 268435455 = = 137439 MB or 28 bit limit
* 320173056 = = 163929 MB or 48 bit addressing
* 1073741822 = = 549756 MB or 48 bit addressing fake drive
*/
2008-10-17 20:09:14 +04:00
static ide_startstop_t ide_do_rw_disk ( ide_drive_t * drive , struct request * rq ,
sector_t block )
2005-04-17 02:20:36 +04:00
{
2009-01-06 19:20:52 +03:00
ide_hwif_t * hwif = drive - > hwif ;
2005-04-17 02:20:36 +04:00
2008-10-13 23:39:36 +04:00
BUG_ON ( drive - > dev_flags & IDE_DFLAG_BLOCKED ) ;
2009-06-16 00:16:10 +04:00
BUG_ON ( ! blk_fs_request ( rq ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-31 14:31:16 +04:00
ledtrig_ide_activity ( ) ;
2009-05-07 17:24:40 +04:00
pr_debug ( " %s: %sing: block=%llu, sectors=%u, buffer=0x%08lx \n " ,
2005-04-17 02:20:36 +04:00
drive - > name , rq_data_dir ( rq ) = = READ ? " read " : " writ " ,
2009-05-07 17:24:40 +04:00
( unsigned long long ) block , blk_rq_sectors ( rq ) ,
2006-02-07 23:58:33 +03:00
( unsigned long ) rq - > buffer ) ;
2005-04-17 02:20:36 +04:00
if ( hwif - > rw_disk )
hwif - > rw_disk ( drive , rq ) ;
return __ide_do_rw_disk ( drive , rq , block ) ;
}
/*
* Queries for true maximum capacity of the drive .
* Returns maximum LBA address ( > 0 ) of the drive , 0 if failed .
*/
2008-01-26 00:17:06 +03:00
static u64 idedisk_read_native_max_address ( ide_drive_t * drive , int lba48 )
2005-04-17 02:20:36 +04:00
{
2009-03-27 14:46:37 +03:00
struct ide_cmd cmd ;
struct ide_taskfile * tf = & cmd . tf ;
2008-01-26 00:17:06 +03:00
u64 addr = 0 ;
2005-04-17 02:20:36 +04:00
2009-03-27 14:46:37 +03:00
memset ( & cmd , 0 , sizeof ( cmd ) ) ;
2008-01-26 00:17:06 +03:00
if ( lba48 )
2008-10-11 00:39:21 +04:00
tf - > command = ATA_CMD_READ_NATIVE_MAX_EXT ;
2008-01-26 00:17:06 +03:00
else
2008-10-11 00:39:21 +04:00
tf - > command = ATA_CMD_READ_NATIVE_MAX ;
2008-01-26 00:17:06 +03:00
tf - > device = ATA_LBA ;
2009-03-27 14:46:37 +03:00
2009-04-08 16:13:01 +04:00
cmd . valid . out . tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE ;
cmd . valid . in . tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE ;
if ( lba48 ) {
cmd . valid . out . hob = IDE_VALID_OUT_HOB ;
cmd . valid . in . hob = IDE_VALID_IN_HOB ;
cmd . tf_flags = IDE_TFLAG_LBA48 ;
}
2009-03-27 14:46:37 +03:00
ide_no_data_taskfile ( drive , & cmd ) ;
2005-04-17 02:20:36 +04:00
/* if OK, compute maximum address value */
2009-03-31 22:15:29 +04:00
if ( ! ( tf - > status & ATA_ERR ) )
2009-04-08 16:13:02 +04:00
addr = ide_get_lba_addr ( & cmd , lba48 ) + 1 ;
2008-01-26 00:17:06 +03:00
2005-04-17 02:20:36 +04:00
return addr ;
}
/*
* Sets maximum virtual LBA address of the drive .
* Returns new maximum virtual LBA address ( > 0 ) or 0 on failure .
*/
2008-01-26 00:17:06 +03:00
static u64 idedisk_set_max_address ( ide_drive_t * drive , u64 addr_req , int lba48 )
2005-04-17 02:20:36 +04:00
{
2009-03-27 14:46:37 +03:00
struct ide_cmd cmd ;
struct ide_taskfile * tf = & cmd . tf ;
2008-01-26 00:17:06 +03:00
u64 addr_set = 0 ;
2005-04-17 02:20:36 +04:00
addr_req - - ;
2009-03-27 14:46:37 +03:00
memset ( & cmd , 0 , sizeof ( cmd ) ) ;
2008-01-26 00:17:06 +03:00
tf - > lbal = ( addr_req > > 0 ) & 0xff ;
tf - > lbam = ( addr_req > > = 8 ) & 0xff ;
tf - > lbah = ( addr_req > > = 8 ) & 0xff ;
2008-01-26 00:17:06 +03:00
if ( lba48 ) {
2009-04-08 16:13:02 +04:00
cmd . hob . lbal = ( addr_req > > = 8 ) & 0xff ;
cmd . hob . lbam = ( addr_req > > = 8 ) & 0xff ;
cmd . hob . lbah = ( addr_req > > = 8 ) & 0xff ;
2008-10-11 00:39:21 +04:00
tf - > command = ATA_CMD_SET_MAX_EXT ;
2008-01-26 00:17:06 +03:00
} else {
tf - > device = ( addr_req > > = 8 ) & 0x0f ;
2008-10-11 00:39:21 +04:00
tf - > command = ATA_CMD_SET_MAX ;
2008-01-26 00:17:06 +03:00
}
tf - > device | = ATA_LBA ;
2009-03-27 14:46:37 +03:00
2009-04-08 16:13:01 +04:00
cmd . valid . out . tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE ;
cmd . valid . in . tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE ;
if ( lba48 ) {
cmd . valid . out . hob = IDE_VALID_OUT_HOB ;
cmd . valid . in . hob = IDE_VALID_IN_HOB ;
cmd . tf_flags = IDE_TFLAG_LBA48 ;
}
2009-03-27 14:46:37 +03:00
ide_no_data_taskfile ( drive , & cmd ) ;
2005-04-17 02:20:36 +04:00
/* if OK, compute maximum address value */
2009-03-31 22:15:29 +04:00
if ( ! ( tf - > status & ATA_ERR ) )
2009-04-08 16:13:02 +04:00
addr_set = ide_get_lba_addr ( & cmd , lba48 ) + 1 ;
2008-01-26 00:17:06 +03:00
2005-04-17 02:20:36 +04:00
return addr_set ;
}
static unsigned long long sectors_to_MB ( unsigned long long n )
{
n < < = 9 ; /* make it bytes */
do_div ( n , 1000000 ) ; /* make it MB */
return n ;
}
2007-08-21 00:42:57 +04:00
/*
* Some disks report total number of sectors instead of
* maximum sector address . We list them here .
*/
static const struct drive_list_entry hpa_list [ ] = {
{ " ST340823A " , NULL } ,
2007-09-17 14:35:30 +04:00
{ " ST320413A " , NULL } ,
2008-02-19 03:41:25 +03:00
{ " ST310211A " , NULL } ,
2007-08-21 00:42:57 +04:00
{ NULL , NULL }
} ;
2009-06-07 15:52:52 +04:00
static u64 ide_disk_hpa_get_native_capacity ( ide_drive_t * drive , int lba48 )
2005-04-17 02:20:36 +04:00
{
2009-06-07 15:52:52 +04:00
u64 capacity , set_max ;
2005-04-17 02:20:36 +04:00
capacity = drive - > capacity64 ;
2009-06-07 15:52:52 +04:00
set_max = idedisk_read_native_max_address ( drive , lba48 ) ;
2005-04-17 02:20:36 +04:00
2007-08-21 00:42:57 +04:00
if ( ide_in_drive_list ( drive - > id , hpa_list ) ) {
/*
* Since we are inclusive wrt to firmware revisions do this
* extra check and apply the workaround only when needed .
*/
if ( set_max = = capacity + 1 )
set_max - - ;
}
2009-06-07 15:52:52 +04:00
return set_max ;
}
static u64 ide_disk_hpa_set_capacity ( ide_drive_t * drive , u64 set_max , int lba48 )
{
set_max = idedisk_set_max_address ( drive , set_max , lba48 ) ;
if ( set_max )
drive - > capacity64 = set_max ;
return set_max ;
}
static void idedisk_check_hpa ( ide_drive_t * drive )
{
u64 capacity , set_max ;
int lba48 = ata_id_lba48_enabled ( drive - > id ) ;
capacity = drive - > capacity64 ;
set_max = ide_disk_hpa_get_native_capacity ( drive , lba48 ) ;
2005-04-17 02:20:36 +04:00
if ( set_max < = capacity )
return ;
2009-06-07 15:52:52 +04:00
drive - > probed_capacity = set_max ;
2005-04-17 02:20:36 +04:00
printk ( KERN_INFO " %s: Host Protected Area detected. \n "
" \t current capacity is %llu sectors (%llu MB) \n "
" \t native capacity is %llu sectors (%llu MB) \n " ,
drive - > name ,
capacity , sectors_to_MB ( capacity ) ,
set_max , sectors_to_MB ( set_max ) ) ;
2009-06-07 15:52:52 +04:00
if ( ( drive - > dev_flags & IDE_DFLAG_NOHPA ) = = 0 )
return ;
2008-01-26 00:17:06 +03:00
2009-06-07 15:52:52 +04:00
set_max = ide_disk_hpa_set_capacity ( drive , set_max , lba48 ) ;
if ( set_max )
2005-04-17 02:20:36 +04:00
printk ( KERN_INFO " %s: Host Protected Area disabled. \n " ,
drive - > name ) ;
}
2008-10-17 20:09:14 +04:00
static int ide_disk_get_capacity ( ide_drive_t * drive )
2005-04-17 02:20:36 +04:00
{
2008-10-11 00:39:19 +04:00
u16 * id = drive - > id ;
2008-10-13 23:39:38 +04:00
int lba ;
2005-04-17 02:20:36 +04:00
2008-10-11 00:39:30 +04:00
if ( ata_id_lba48_enabled ( id ) ) {
2005-04-17 02:20:36 +04:00
/* drive speaks 48-bit LBA */
2008-10-13 23:39:38 +04:00
lba = 1 ;
2008-10-11 00:39:19 +04:00
drive - > capacity64 = ata_id_u64 ( id , ATA_ID_LBA_CAPACITY_2 ) ;
2008-10-11 00:39:31 +04:00
} else if ( ata_id_has_lba ( id ) & & ata_id_is_lba_capacity_ok ( id ) ) {
2005-04-17 02:20:36 +04:00
/* drive speaks 28-bit LBA */
2008-10-13 23:39:38 +04:00
lba = 1 ;
2008-10-11 00:39:19 +04:00
drive - > capacity64 = ata_id_u32 ( id , ATA_ID_LBA_CAPACITY ) ;
2005-04-17 02:20:36 +04:00
} else {
/* drive speaks boring old 28-bit CHS */
2008-10-13 23:39:38 +04:00
lba = 0 ;
2005-04-17 02:20:36 +04:00
drive - > capacity64 = drive - > cyl * drive - > head * drive - > sect ;
}
2008-10-13 23:39:38 +04:00
2009-06-07 15:52:52 +04:00
drive - > probed_capacity = drive - > capacity64 ;
2008-10-13 23:39:38 +04:00
if ( lba ) {
drive - > dev_flags | = IDE_DFLAG_LBA ;
/*
* If this device supports the Host Protected Area feature set ,
* then we may need to change our opinion about its capacity .
*/
if ( ata_id_hpa_enabled ( id ) )
idedisk_check_hpa ( drive ) ;
}
2008-10-17 20:09:09 +04:00
/* limit drive capacity to 137GB if LBA48 cannot be used */
if ( ( drive - > dev_flags & IDE_DFLAG_LBA48 ) = = 0 & &
drive - > capacity64 > 1ULL < < 28 ) {
printk ( KERN_WARNING " %s: cannot use LBA48 - full capacity "
" %llu sectors (%llu MB) \n " ,
drive - > name , ( unsigned long long ) drive - > capacity64 ,
sectors_to_MB ( drive - > capacity64 ) ) ;
2009-06-07 15:52:52 +04:00
drive - > probed_capacity = drive - > capacity64 = 1ULL < < 28 ;
2008-10-17 20:09:09 +04:00
}
if ( ( drive - > hwif - > host_flags & IDE_HFLAG_NO_LBA48_DMA ) & &
( drive - > dev_flags & IDE_DFLAG_LBA48 ) ) {
if ( drive - > capacity64 > 1ULL < < 28 ) {
printk ( KERN_INFO " %s: cannot use LBA48 DMA - PIO mode "
" will be used for accessing sectors "
" > %u \n " , drive - > name , 1 < < 28 ) ;
} else
drive - > dev_flags & = ~ IDE_DFLAG_LBA48 ;
}
2008-10-17 20:09:14 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2009-06-07 15:52:52 +04:00
static u64 ide_disk_set_capacity ( ide_drive_t * drive , u64 capacity )
{
u64 set = min ( capacity , drive - > probed_capacity ) ;
u16 * id = drive - > id ;
int lba48 = ata_id_lba48_enabled ( id ) ;
if ( ( drive - > dev_flags & IDE_DFLAG_LBA ) = = 0 | |
ata_id_hpa_enabled ( id ) = = 0 )
goto out ;
/*
* according to the spec the SET MAX ADDRESS command shall be
* immediately preceded by a READ NATIVE MAX ADDRESS command
*/
capacity = ide_disk_hpa_get_native_capacity ( drive , lba48 ) ;
if ( capacity = = 0 )
goto out ;
set = ide_disk_hpa_set_capacity ( drive , set , lba48 ) ;
2009-06-07 15:52:52 +04:00
if ( set ) {
/* needed for ->resume to disable HPA */
drive - > dev_flags | = IDE_DFLAG_NOHPA ;
2009-06-07 15:52:52 +04:00
return set ;
2009-06-07 15:52:52 +04:00
}
2009-06-07 15:52:52 +04:00
out :
return drive - > capacity64 ;
}
2007-07-24 11:28:11 +04:00
static void idedisk_prepare_flush ( struct request_queue * q , struct request * rq )
2005-04-17 02:20:36 +04:00
{
ide_drive_t * drive = q - > queuedata ;
2009-03-27 14:46:37 +03:00
struct ide_cmd * cmd = kmalloc ( sizeof ( * cmd ) , GFP_ATOMIC ) ;
2005-04-17 02:20:36 +04:00
2008-02-11 02:32:14 +03:00
/* FIXME: map struct ide_taskfile on rq->cmd[] */
2009-03-27 14:46:37 +03:00
BUG_ON ( cmd = = NULL ) ;
2008-02-11 02:32:14 +03:00
2009-03-27 14:46:37 +03:00
memset ( cmd , 0 , sizeof ( * cmd ) ) ;
2008-10-11 00:39:31 +04:00
if ( ata_id_flush_ext_enabled ( drive - > id ) & &
2005-04-17 02:20:36 +04:00
( drive - > capacity64 > = ( 1UL < < 28 ) ) )
2009-03-27 14:46:37 +03:00
cmd - > tf . command = ATA_CMD_FLUSH_EXT ;
2005-04-17 02:20:36 +04:00
else
2009-03-27 14:46:37 +03:00
cmd - > tf . command = ATA_CMD_FLUSH ;
2009-04-08 16:13:01 +04:00
cmd - > valid . out . tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE ;
cmd - > tf_flags = IDE_TFLAG_DYN ;
2009-03-27 14:46:39 +03:00
cmd - > protocol = ATA_PROT_NODATA ;
2005-04-17 02:20:36 +04:00
2008-01-26 00:17:10 +03:00
rq - > cmd_type = REQ_TYPE_ATA_TASKFILE ;
2009-03-27 14:46:37 +03:00
rq - > special = cmd ;
2009-07-16 10:32:52 +04:00
cmd - > rq = rq ;
2005-04-17 02:20:36 +04:00
}
ide: /proc/ide/hd*/settings rework
* Add struct ide_devset, S_* flags, *DEVSET() & ide*_devset_*() macros.
* Add 'const struct ide_devset **settings' to ide_driver_t.
* Use 'const struct ide_devset **settings' in ide_drive_t instead of
'struct ide_settings_s *settings'. Then convert core code and device
drivers to use struct ide_devset and co.:
- device settings are no longer allocated dynamically for each device
but instead there is an unique struct ide_devset instance per setting
- device driver keeps the pointer to the table of pointers to its
settings in ide_driver_t.settings
- generic settings are kept in ide_generic_setting[]
- ide_proc_[un]register_driver(), ide_find_setting_by_name(),
ide_{read,write}_setting() and proc_ide_{read,write}_settings()
are updated accordingly
- ide*_add_settings() are removed
* Remove no longer used __ide_add_setting(), ide_add_setting(),
__ide_remove_setting() and auto_remove_settings().
* Remove no longer used TYPE_*, SETTING_*, ide_procset_t
and ide_settings_t.
* ->keep_settings, ->using_dma, ->unmask, ->noflush, ->dsc_overlap,
->nice1, ->addressing, ->wcache and ->nowerr ide_drive_t fields
can now be bitfield flags.
While at it:
* Rename ide_find_setting_by_name() to ide_find_setting().
* Rename write_wcache() to set_wcache().
There should be no functional changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2008-10-11 00:39:28 +04:00
ide_devset_get ( multcount , mult_count ) ;
2005-04-17 02:20:36 +04:00
/*
* This is tightly woven into the driver - > do_special can not touch .
* DON ' T do it again until a total personality rewrite is committed .
*/
static int set_multcount ( ide_drive_t * drive , int arg )
{
2008-07-15 23:21:43 +04:00
struct request * rq ;
int error ;
2005-04-17 02:20:36 +04:00
2008-10-11 00:39:19 +04:00
if ( arg < 0 | | arg > ( drive - > id [ ATA_ID_MAX_MULTSECT ] & 0xff ) )
2007-05-10 02:01:10 +04:00
return - EINVAL ;
2009-05-17 21:12:21 +04:00
if ( drive - > special_flags & IDE_SFLAG_SET_MULTMODE )
2005-04-17 02:20:36 +04:00
return - EBUSY ;
2008-01-26 22:13:12 +03:00
2008-07-15 23:21:43 +04:00
rq = blk_get_request ( drive - > queue , READ , __GFP_WAIT ) ;
rq - > cmd_type = REQ_TYPE_ATA_TASKFILE ;
2008-01-26 22:13:12 +03:00
2005-04-17 02:20:36 +04:00
drive - > mult_req = arg ;
2009-05-17 21:12:21 +04:00
drive - > special_flags | = IDE_SFLAG_SET_MULTMODE ;
2008-07-15 23:21:43 +04:00
error = blk_execute_rq ( drive - > queue , NULL , rq , 0 ) ;
blk_put_request ( rq ) ;
2008-04-26 19:36:37 +04:00
2005-04-17 02:20:36 +04:00
return ( drive - > mult_count = = arg ) ? 0 : - EIO ;
}
2008-10-13 23:39:36 +04:00
ide_devset_get_flag ( nowerr , IDE_DFLAG_NOWERR ) ;
ide: /proc/ide/hd*/settings rework
* Add struct ide_devset, S_* flags, *DEVSET() & ide*_devset_*() macros.
* Add 'const struct ide_devset **settings' to ide_driver_t.
* Use 'const struct ide_devset **settings' in ide_drive_t instead of
'struct ide_settings_s *settings'. Then convert core code and device
drivers to use struct ide_devset and co.:
- device settings are no longer allocated dynamically for each device
but instead there is an unique struct ide_devset instance per setting
- device driver keeps the pointer to the table of pointers to its
settings in ide_driver_t.settings
- generic settings are kept in ide_generic_setting[]
- ide_proc_[un]register_driver(), ide_find_setting_by_name(),
ide_{read,write}_setting() and proc_ide_{read,write}_settings()
are updated accordingly
- ide*_add_settings() are removed
* Remove no longer used __ide_add_setting(), ide_add_setting(),
__ide_remove_setting() and auto_remove_settings().
* Remove no longer used TYPE_*, SETTING_*, ide_procset_t
and ide_settings_t.
* ->keep_settings, ->using_dma, ->unmask, ->noflush, ->dsc_overlap,
->nice1, ->addressing, ->wcache and ->nowerr ide_drive_t fields
can now be bitfield flags.
While at it:
* Rename ide_find_setting_by_name() to ide_find_setting().
* Rename write_wcache() to set_wcache().
There should be no functional changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2008-10-11 00:39:28 +04:00
2005-04-17 02:20:36 +04:00
static int set_nowerr ( ide_drive_t * drive , int arg )
{
2007-05-10 02:01:10 +04:00
if ( arg < 0 | | arg > 1 )
return - EINVAL ;
2008-10-13 23:39:36 +04:00
if ( arg )
drive - > dev_flags | = IDE_DFLAG_NOWERR ;
else
drive - > dev_flags & = ~ IDE_DFLAG_NOWERR ;
2005-04-17 02:20:36 +04:00
drive - > bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT ;
2008-10-13 23:39:36 +04:00
2005-04-17 02:20:36 +04:00
return 0 ;
}
2008-10-13 23:39:36 +04:00
static int ide_do_setfeature ( ide_drive_t * drive , u8 feature , u8 nsect )
{
2009-03-27 14:46:37 +03:00
struct ide_cmd cmd ;
2008-10-13 23:39:36 +04:00
2009-03-27 14:46:37 +03:00
memset ( & cmd , 0 , sizeof ( cmd ) ) ;
cmd . tf . feature = feature ;
cmd . tf . nsect = nsect ;
cmd . tf . command = ATA_CMD_SET_FEATURES ;
2009-04-08 16:13:01 +04:00
cmd . valid . out . tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE ;
cmd . valid . in . tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE ;
2008-10-13 23:39:36 +04:00
2009-03-27 14:46:37 +03:00
return ide_no_data_taskfile ( drive , & cmd ) ;
2008-10-13 23:39:36 +04:00
}
2006-01-06 11:57:31 +03:00
static void update_ordered ( ide_drive_t * drive )
{
2008-10-11 00:39:19 +04:00
u16 * id = drive - > id ;
2006-01-06 11:57:31 +03:00
unsigned ordered = QUEUE_ORDERED_NONE ;
prepare_flush_fn * prep_fn = NULL ;
2008-10-13 23:39:36 +04:00
if ( drive - > dev_flags & IDE_DFLAG_WCACHE ) {
2006-01-06 11:57:31 +03:00
unsigned long long capacity ;
int barrier ;
/*
* We must avoid issuing commands a drive does not
* understand or we may crash it . We check flush cache
* is supported . We also check we have the LBA48 flush
* cache if the drive capacity is too large . By this
* time we have trimmed the drive capacity if LBA48 is
* not available so we don ' t need to recheck that .
*/
2008-10-17 20:09:12 +04:00
capacity = ide_gd_capacity ( drive ) ;
2008-10-13 23:39:36 +04:00
barrier = ata_id_flush_enabled ( id ) & &
( drive - > dev_flags & IDE_DFLAG_NOFLUSH ) = = 0 & &
( ( drive - > dev_flags & IDE_DFLAG_LBA48 ) = = 0 | |
capacity < = ( 1ULL < < 28 ) | |
2008-10-11 00:39:31 +04:00
ata_id_flush_ext_enabled ( id ) ) ;
2006-01-06 11:57:31 +03:00
printk ( KERN_INFO " %s: cache flushes %ssupported \n " ,
2006-02-03 14:04:57 +03:00
drive - > name , barrier ? " " : " not " ) ;
2006-01-06 11:57:31 +03:00
if ( barrier ) {
ordered = QUEUE_ORDERED_DRAIN_FLUSH ;
prep_fn = idedisk_prepare_flush ;
}
} else
ordered = QUEUE_ORDERED_DRAIN ;
blk_queue_ordered ( drive - > queue , ordered , prep_fn ) ;
}
2008-10-13 23:39:36 +04:00
ide_devset_get_flag ( wcache , IDE_DFLAG_WCACHE ) ;
ide: /proc/ide/hd*/settings rework
* Add struct ide_devset, S_* flags, *DEVSET() & ide*_devset_*() macros.
* Add 'const struct ide_devset **settings' to ide_driver_t.
* Use 'const struct ide_devset **settings' in ide_drive_t instead of
'struct ide_settings_s *settings'. Then convert core code and device
drivers to use struct ide_devset and co.:
- device settings are no longer allocated dynamically for each device
but instead there is an unique struct ide_devset instance per setting
- device driver keeps the pointer to the table of pointers to its
settings in ide_driver_t.settings
- generic settings are kept in ide_generic_setting[]
- ide_proc_[un]register_driver(), ide_find_setting_by_name(),
ide_{read,write}_setting() and proc_ide_{read,write}_settings()
are updated accordingly
- ide*_add_settings() are removed
* Remove no longer used __ide_add_setting(), ide_add_setting(),
__ide_remove_setting() and auto_remove_settings().
* Remove no longer used TYPE_*, SETTING_*, ide_procset_t
and ide_settings_t.
* ->keep_settings, ->using_dma, ->unmask, ->noflush, ->dsc_overlap,
->nice1, ->addressing, ->wcache and ->nowerr ide_drive_t fields
can now be bitfield flags.
While at it:
* Rename ide_find_setting_by_name() to ide_find_setting().
* Rename write_wcache() to set_wcache().
There should be no functional changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2008-10-11 00:39:28 +04:00
static int set_wcache ( ide_drive_t * drive , int arg )
2005-04-17 02:20:36 +04:00
{
2006-01-06 11:57:31 +03:00
int err = 1 ;
2005-04-17 02:20:36 +04:00
2007-05-10 02:01:10 +04:00
if ( arg < 0 | | arg > 1 )
return - EINVAL ;
2008-10-11 00:39:30 +04:00
if ( ata_id_flush_enabled ( drive - > id ) ) {
2008-10-13 23:39:36 +04:00
err = ide_do_setfeature ( drive ,
arg ? SETFEATURES_WC_ON : SETFEATURES_WC_OFF , 0 ) ;
2008-10-13 23:39:36 +04:00
if ( err = = 0 ) {
if ( arg )
drive - > dev_flags | = IDE_DFLAG_WCACHE ;
else
drive - > dev_flags & = ~ IDE_DFLAG_WCACHE ;
}
2006-01-06 11:57:31 +03:00
}
2005-04-17 02:20:36 +04:00
2006-01-06 11:57:31 +03:00
update_ordered ( drive ) ;
2005-04-17 02:20:36 +04:00
2006-01-06 11:57:31 +03:00
return err ;
2005-04-17 02:20:36 +04:00
}
2008-04-26 19:36:37 +04:00
static int do_idedisk_flushcache ( ide_drive_t * drive )
2005-04-17 02:20:36 +04:00
{
2009-03-27 14:46:37 +03:00
struct ide_cmd cmd ;
2005-04-17 02:20:36 +04:00
2009-03-27 14:46:37 +03:00
memset ( & cmd , 0 , sizeof ( cmd ) ) ;
2008-10-11 00:39:31 +04:00
if ( ata_id_flush_ext_enabled ( drive - > id ) )
2009-03-27 14:46:37 +03:00
cmd . tf . command = ATA_CMD_FLUSH_EXT ;
2005-04-17 02:20:36 +04:00
else
2009-03-27 14:46:37 +03:00
cmd . tf . command = ATA_CMD_FLUSH ;
2009-04-08 16:13:01 +04:00
cmd . valid . out . tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE ;
cmd . valid . in . tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE ;
2009-03-27 14:46:37 +03:00
return ide_no_data_taskfile ( drive , & cmd ) ;
2005-04-17 02:20:36 +04:00
}
ide: /proc/ide/hd*/settings rework
* Add struct ide_devset, S_* flags, *DEVSET() & ide*_devset_*() macros.
* Add 'const struct ide_devset **settings' to ide_driver_t.
* Use 'const struct ide_devset **settings' in ide_drive_t instead of
'struct ide_settings_s *settings'. Then convert core code and device
drivers to use struct ide_devset and co.:
- device settings are no longer allocated dynamically for each device
but instead there is an unique struct ide_devset instance per setting
- device driver keeps the pointer to the table of pointers to its
settings in ide_driver_t.settings
- generic settings are kept in ide_generic_setting[]
- ide_proc_[un]register_driver(), ide_find_setting_by_name(),
ide_{read,write}_setting() and proc_ide_{read,write}_settings()
are updated accordingly
- ide*_add_settings() are removed
* Remove no longer used __ide_add_setting(), ide_add_setting(),
__ide_remove_setting() and auto_remove_settings().
* Remove no longer used TYPE_*, SETTING_*, ide_procset_t
and ide_settings_t.
* ->keep_settings, ->using_dma, ->unmask, ->noflush, ->dsc_overlap,
->nice1, ->addressing, ->wcache and ->nowerr ide_drive_t fields
can now be bitfield flags.
While at it:
* Rename ide_find_setting_by_name() to ide_find_setting().
* Rename write_wcache() to set_wcache().
There should be no functional changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2008-10-11 00:39:28 +04:00
ide_devset_get ( acoustic , acoustic ) ;
2008-04-26 19:36:37 +04:00
static int set_acoustic ( ide_drive_t * drive , int arg )
2005-04-17 02:20:36 +04:00
{
2007-05-10 02:01:10 +04:00
if ( arg < 0 | | arg > 254 )
return - EINVAL ;
2008-10-13 23:39:36 +04:00
ide_do_setfeature ( drive ,
arg ? SETFEATURES_AAM_ON : SETFEATURES_AAM_OFF , arg ) ;
2005-04-17 02:20:36 +04:00
drive - > acoustic = arg ;
2008-10-13 23:39:36 +04:00
2005-04-17 02:20:36 +04:00
return 0 ;
}
2008-10-13 23:39:36 +04:00
ide_devset_get_flag ( addressing , IDE_DFLAG_LBA48 ) ;
ide: /proc/ide/hd*/settings rework
* Add struct ide_devset, S_* flags, *DEVSET() & ide*_devset_*() macros.
* Add 'const struct ide_devset **settings' to ide_driver_t.
* Use 'const struct ide_devset **settings' in ide_drive_t instead of
'struct ide_settings_s *settings'. Then convert core code and device
drivers to use struct ide_devset and co.:
- device settings are no longer allocated dynamically for each device
but instead there is an unique struct ide_devset instance per setting
- device driver keeps the pointer to the table of pointers to its
settings in ide_driver_t.settings
- generic settings are kept in ide_generic_setting[]
- ide_proc_[un]register_driver(), ide_find_setting_by_name(),
ide_{read,write}_setting() and proc_ide_{read,write}_settings()
are updated accordingly
- ide*_add_settings() are removed
* Remove no longer used __ide_add_setting(), ide_add_setting(),
__ide_remove_setting() and auto_remove_settings().
* Remove no longer used TYPE_*, SETTING_*, ide_procset_t
and ide_settings_t.
* ->keep_settings, ->using_dma, ->unmask, ->noflush, ->dsc_overlap,
->nice1, ->addressing, ->wcache and ->nowerr ide_drive_t fields
can now be bitfield flags.
While at it:
* Rename ide_find_setting_by_name() to ide_find_setting().
* Rename write_wcache() to set_wcache().
There should be no functional changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2008-10-11 00:39:28 +04:00
2005-04-17 02:20:36 +04:00
/*
* drive - > addressing :
* 0 : 28 - bit
* 1 : 48 - bit
* 2 : 48 - bit capable doing 28 - bit
*/
2008-10-11 00:39:33 +04:00
static int set_addressing ( ide_drive_t * drive , int arg )
2005-04-17 02:20:36 +04:00
{
2007-05-10 02:01:10 +04:00
if ( arg < 0 | | arg > 2 )
return - EINVAL ;
2008-10-13 23:39:36 +04:00
if ( arg & & ( ( drive - > hwif - > host_flags & IDE_HFLAG_NO_LBA48 ) | |
ata_id_lba48_enabled ( drive - > id ) = = 0 ) )
2008-04-26 19:36:37 +04:00
return - EIO ;
2008-10-11 00:39:30 +04:00
2008-10-13 23:39:36 +04:00
if ( arg = = 2 )
arg = 0 ;
2008-10-13 23:39:36 +04:00
if ( arg )
drive - > dev_flags | = IDE_DFLAG_LBA48 ;
else
drive - > dev_flags & = ~ IDE_DFLAG_LBA48 ;
2008-10-11 00:39:30 +04:00
2005-04-17 02:20:36 +04:00
return 0 ;
}
2008-10-13 23:39:45 +04:00
ide_ext_devset_rw ( acoustic , acoustic ) ;
ide_ext_devset_rw ( address , addressing ) ;
ide_ext_devset_rw ( multcount , multcount ) ;
ide_ext_devset_rw ( wcache , wcache ) ;
2008-10-11 00:39:40 +04:00
2008-10-13 23:39:45 +04:00
ide_ext_devset_rw_sync ( nowerr , nowerr ) ;
2008-10-11 00:39:40 +04:00
2008-10-17 20:09:14 +04:00
static int ide_disk_check ( ide_drive_t * drive , const char * s )
{
return 1 ;
}
static void ide_disk_setup ( ide_drive_t * drive )
2005-04-17 02:20:36 +04:00
{
2008-10-11 00:39:27 +04:00
struct ide_disk_obj * idkp = drive - > driver_data ;
2008-10-24 01:22:09 +04:00
struct request_queue * q = drive - > queue ;
2007-10-19 02:30:07 +04:00
ide_hwif_t * hwif = drive - > hwif ;
2008-10-11 00:39:19 +04:00
u16 * id = drive - > id ;
char * m = ( char * ) & id [ ATA_ID_PROD ] ;
2005-04-17 02:20:36 +04:00
unsigned long long capacity ;
2008-10-11 00:39:27 +04:00
ide_proc_register_driver ( drive , idkp - > driver ) ;
2005-04-17 02:20:36 +04:00
2008-10-13 23:39:36 +04:00
if ( ( drive - > dev_flags & IDE_DFLAG_ID_READ ) = = 0 )
2005-04-17 02:20:36 +04:00
return ;
2008-10-13 23:39:36 +04:00
if ( drive - > dev_flags & IDE_DFLAG_REMOVABLE ) {
2005-04-17 02:20:36 +04:00
/*
2008-04-26 19:36:37 +04:00
* Removable disks ( eg . SYQUEST ) ; ignore ' WD ' drives
2005-04-17 02:20:36 +04:00
*/
2008-10-11 00:39:19 +04:00
if ( m [ 0 ] ! = ' W ' | | m [ 1 ] ! = ' D ' )
2008-10-13 23:39:36 +04:00
drive - > dev_flags | = IDE_DFLAG_DOORLOCKING ;
2005-04-17 02:20:36 +04:00
}
2008-10-11 00:39:33 +04:00
( void ) set_addressing ( drive , 1 ) ;
2005-04-17 02:20:36 +04:00
2008-10-13 23:39:36 +04:00
if ( drive - > dev_flags & IDE_DFLAG_LBA48 ) {
2005-04-17 02:20:36 +04:00
int max_s = 2048 ;
if ( max_s > hwif - > rqsize )
max_s = hwif - > rqsize ;
2010-02-26 08:20:38 +03:00
blk_queue_max_hw_sectors ( q , max_s ) ;
2005-04-17 02:20:36 +04:00
}
2008-04-26 19:36:37 +04:00
printk ( KERN_INFO " %s: max request size: %dKiB \n " , drive - > name ,
2009-05-23 10:23:16 +04:00
queue_max_sectors ( q ) / 2 ) ;
2008-10-24 01:22:09 +04:00
2009-01-14 21:19:03 +03:00
if ( ata_id_is_ssd ( id ) )
2008-10-24 01:22:09 +04:00
queue_flag_set_unlocked ( QUEUE_FLAG_NONROT , q ) ;
2005-04-17 02:20:36 +04:00
/* calculate drive capacity, and select LBA if possible */
2008-10-17 20:09:14 +04:00
ide_disk_get_capacity ( drive ) ;
2005-04-17 02:20:36 +04:00
/*
* if possible , give fdisk access to more of the drive ,
* by correcting bios_cyls :
*/
2008-10-17 20:09:12 +04:00
capacity = ide_gd_capacity ( drive ) ;
2008-04-26 19:36:37 +04:00
2008-10-13 23:39:36 +04:00
if ( ( drive - > dev_flags & IDE_DFLAG_FORCED_GEOM ) = = 0 ) {
2008-10-11 00:39:30 +04:00
if ( ata_id_lba48_enabled ( drive - > id ) ) {
2005-04-17 02:20:36 +04:00
/* compatibility */
drive - > bios_sect = 63 ;
drive - > bios_head = 255 ;
}
if ( drive - > bios_sect & & drive - > bios_head ) {
unsigned int cap0 = capacity ; /* truncate to 32 bits */
unsigned int cylsz , cyl ;
if ( cap0 ! = capacity )
drive - > bios_cyl = 65535 ;
else {
cylsz = drive - > bios_sect * drive - > bios_head ;
cyl = cap0 / cylsz ;
if ( cyl > 65535 )
cyl = 65535 ;
if ( cyl > drive - > bios_cyl )
drive - > bios_cyl = cyl ;
}
}
}
printk ( KERN_INFO " %s: %llu sectors (%llu MB) " ,
drive - > name , capacity , sectors_to_MB ( capacity ) ) ;
/* Only print cache size when it was specified */
2008-10-11 00:39:19 +04:00
if ( id [ ATA_ID_BUF_SIZE ] )
printk ( KERN_CONT " w/%dKiB Cache " , id [ ATA_ID_BUF_SIZE ] / 2 ) ;
2005-04-17 02:20:36 +04:00
2007-12-13 01:31:58 +03:00
printk ( KERN_CONT " , CHS=%d/%d/%d \n " ,
drive - > bios_cyl , drive - > bios_head , drive - > bios_sect ) ;
2005-04-17 02:20:36 +04:00
/* write cache enabled? */
2008-10-11 00:39:20 +04:00
if ( ( id [ ATA_ID_CSFO ] & 1 ) | | ata_id_wcache_enabled ( id ) )
2008-10-13 23:39:36 +04:00
drive - > dev_flags | = IDE_DFLAG_WCACHE ;
2005-04-17 02:20:36 +04:00
ide: /proc/ide/hd*/settings rework
* Add struct ide_devset, S_* flags, *DEVSET() & ide*_devset_*() macros.
* Add 'const struct ide_devset **settings' to ide_driver_t.
* Use 'const struct ide_devset **settings' in ide_drive_t instead of
'struct ide_settings_s *settings'. Then convert core code and device
drivers to use struct ide_devset and co.:
- device settings are no longer allocated dynamically for each device
but instead there is an unique struct ide_devset instance per setting
- device driver keeps the pointer to the table of pointers to its
settings in ide_driver_t.settings
- generic settings are kept in ide_generic_setting[]
- ide_proc_[un]register_driver(), ide_find_setting_by_name(),
ide_{read,write}_setting() and proc_ide_{read,write}_settings()
are updated accordingly
- ide*_add_settings() are removed
* Remove no longer used __ide_add_setting(), ide_add_setting(),
__ide_remove_setting() and auto_remove_settings().
* Remove no longer used TYPE_*, SETTING_*, ide_procset_t
and ide_settings_t.
* ->keep_settings, ->using_dma, ->unmask, ->noflush, ->dsc_overlap,
->nice1, ->addressing, ->wcache and ->nowerr ide_drive_t fields
can now be bitfield flags.
While at it:
* Rename ide_find_setting_by_name() to ide_find_setting().
* Rename write_wcache() to set_wcache().
There should be no functional changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2008-10-11 00:39:28 +04:00
set_wcache ( drive , 1 ) ;
2008-10-17 20:09:10 +04:00
if ( ( drive - > dev_flags & IDE_DFLAG_LBA ) = = 0 & &
( drive - > head = = 0 | | drive - > head > 16 ) ) {
printk ( KERN_ERR " %s: invalid geometry: %d physical heads? \n " ,
drive - > name , drive - > head ) ;
drive - > dev_flags & = ~ IDE_DFLAG_ATTACH ;
} else
drive - > dev_flags | = IDE_DFLAG_ATTACH ;
2005-04-17 02:20:36 +04:00
}
2008-10-17 20:09:14 +04:00
static void ide_disk_flush ( ide_drive_t * drive )
2005-04-17 02:20:36 +04:00
{
2008-10-13 23:39:36 +04:00
if ( ata_id_flush_enabled ( drive - > id ) = = 0 | |
( drive - > dev_flags & IDE_DFLAG_WCACHE ) = = 0 )
2005-04-17 02:20:36 +04:00
return ;
if ( do_idedisk_flushcache ( drive ) )
printk ( KERN_INFO " %s: wcache flush failed! \n " , drive - > name ) ;
}
2008-10-17 20:09:14 +04:00
static int ide_disk_init_media ( ide_drive_t * drive , struct gendisk * disk )
{
return 0 ;
}
static int ide_disk_set_doorlock ( ide_drive_t * drive , struct gendisk * disk ,
int on )
2008-01-26 22:12:59 +03:00
{
2009-03-27 14:46:37 +03:00
struct ide_cmd cmd ;
2008-10-17 20:09:10 +04:00
int ret ;
if ( ( drive - > dev_flags & IDE_DFLAG_DOORLOCKING ) = = 0 )
return 0 ;
2008-01-26 22:12:59 +03:00
2009-03-27 14:46:37 +03:00
memset ( & cmd , 0 , sizeof ( cmd ) ) ;
cmd . tf . command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK ;
2009-04-08 16:13:01 +04:00
cmd . valid . out . tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE ;
cmd . valid . in . tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE ;
2008-01-26 22:12:59 +03:00
2009-03-27 14:46:37 +03:00
ret = ide_no_data_taskfile ( drive , & cmd ) ;
2008-10-17 20:09:10 +04:00
if ( ret )
drive - > dev_flags & = ~ IDE_DFLAG_DOORLOCKING ;
return ret ;
2008-01-26 22:12:59 +03:00
}
2008-10-17 20:09:14 +04:00
const struct ide_disk_ops ide_ata_disk_ops = {
. check = ide_disk_check ,
2009-06-07 15:52:52 +04:00
. set_capacity = ide_disk_set_capacity ,
2008-10-17 20:09:14 +04:00
. get_capacity = ide_disk_get_capacity ,
. setup = ide_disk_setup ,
. flush = ide_disk_flush ,
. init_media = ide_disk_init_media ,
. set_doorlock = ide_disk_set_doorlock ,
. do_request = ide_do_rw_disk ,
. ioctl = ide_disk_ioctl ,
} ;