2009-03-25 01:22:47 +03:00
# include <linux/kernel.h>
2011-07-17 23:33:58 +04:00
# include <linux/export.h>
2009-03-25 01:22:47 +03:00
# include <linux/ide.h>
# include <linux/delay.h>
static ide_startstop_t ide_ata_error ( ide_drive_t * drive , struct request * rq ,
u8 stat , u8 err )
{
ide_hwif_t * hwif = drive - > hwif ;
if ( ( stat & ATA_BUSY ) | |
( ( stat & ATA_DF ) & & ( drive - > dev_flags & IDE_DFLAG_NOWERR ) = = 0 ) ) {
/* other bits are useless when BUSY */
2017-04-20 17:03:01 +03:00
scsi_req ( rq ) - > result | = ERROR_RESET ;
2009-03-25 01:22:47 +03:00
} else if ( stat & ATA_ERR ) {
/* err has different meaning on cdrom and tape */
if ( err = = ATA_ABORTED ) {
if ( ( drive - > dev_flags & IDE_DFLAG_LBA ) & &
/* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
hwif - > tp_ops - > read_status ( hwif ) = = ATA_CMD_INIT_DEV_PARAMS )
return ide_stopped ;
} else if ( ( err & BAD_CRC ) = = BAD_CRC ) {
/* UDMA crc error, just retry the operation */
drive - > crc_count + + ;
} else if ( err & ( ATA_BBK | ATA_UNC ) ) {
/* retries won't help these */
2017-04-20 17:03:01 +03:00
scsi_req ( rq ) - > result = ERROR_MAX ;
2009-03-25 01:22:47 +03:00
} else if ( err & ATA_TRK0NF ) {
/* help it find track zero */
2017-04-20 17:03:01 +03:00
scsi_req ( rq ) - > result | = ERROR_RECAL ;
2009-03-25 01:22:47 +03:00
}
}
if ( ( stat & ATA_DRQ ) & & rq_data_dir ( rq ) = = READ & &
( hwif - > host_flags & IDE_HFLAG_ERROR_STOPS_FIFO ) = = 0 ) {
int nsect = drive - > mult_count ? drive - > mult_count : 1 ;
ide_pad_transfer ( drive , READ , nsect * SECTOR_SIZE ) ;
}
2017-04-20 17:03:01 +03:00
if ( scsi_req ( rq ) - > result > = ERROR_MAX | | blk_noretry_request ( rq ) ) {
2009-03-25 01:22:47 +03:00
ide_kill_rq ( drive , rq ) ;
return ide_stopped ;
}
if ( hwif - > tp_ops - > read_status ( hwif ) & ( ATA_BUSY | ATA_DRQ ) )
2017-04-20 17:03:01 +03:00
scsi_req ( rq ) - > result | = ERROR_RESET ;
2009-03-25 01:22:47 +03:00
2017-04-20 17:03:01 +03:00
if ( ( scsi_req ( rq ) - > result & ERROR_RESET ) = = ERROR_RESET ) {
+ + scsi_req ( rq ) - > result ;
2009-03-25 01:22:47 +03:00
return ide_do_reset ( drive ) ;
}
2017-04-20 17:03:01 +03:00
if ( ( scsi_req ( rq ) - > result & ERROR_RECAL ) = = ERROR_RECAL )
2009-05-17 21:12:21 +04:00
drive - > special_flags | = IDE_SFLAG_RECALIBRATE ;
2009-03-25 01:22:47 +03:00
2017-04-20 17:03:01 +03:00
+ + scsi_req ( rq ) - > result ;
2009-03-25 01:22:47 +03:00
return ide_stopped ;
}
static ide_startstop_t ide_atapi_error ( ide_drive_t * drive , struct request * rq ,
u8 stat , u8 err )
{
ide_hwif_t * hwif = drive - > hwif ;
if ( ( stat & ATA_BUSY ) | |
( ( stat & ATA_DF ) & & ( drive - > dev_flags & IDE_DFLAG_NOWERR ) = = 0 ) ) {
/* other bits are useless when BUSY */
2017-04-20 17:03:01 +03:00
scsi_req ( rq ) - > result | = ERROR_RESET ;
2009-03-25 01:22:47 +03:00
} else {
/* add decoding error stuff */
}
if ( hwif - > tp_ops - > read_status ( hwif ) & ( ATA_BUSY | ATA_DRQ ) )
/* force an abort */
hwif - > tp_ops - > exec_command ( hwif , ATA_CMD_IDLEIMMEDIATE ) ;
2017-04-20 17:03:01 +03:00
if ( scsi_req ( rq ) - > result > = ERROR_MAX ) {
2009-03-25 01:22:47 +03:00
ide_kill_rq ( drive , rq ) ;
} else {
2017-04-20 17:03:01 +03:00
if ( ( scsi_req ( rq ) - > result & ERROR_RESET ) = = ERROR_RESET ) {
+ + scsi_req ( rq ) - > result ;
2009-03-25 01:22:47 +03:00
return ide_do_reset ( drive ) ;
}
2017-04-20 17:03:01 +03:00
+ + scsi_req ( rq ) - > result ;
2009-03-25 01:22:47 +03:00
}
return ide_stopped ;
}
static ide_startstop_t __ide_error ( ide_drive_t * drive , struct request * rq ,
u8 stat , u8 err )
{
if ( drive - > media = = ide_disk )
return ide_ata_error ( drive , rq , stat , err ) ;
return ide_atapi_error ( drive , rq , stat , err ) ;
}
/**
* ide_error - handle an error on the IDE
* @ drive : drive the error occurred on
* @ msg : message to report
* @ stat : status bits
*
* ide_error ( ) takes action based on the error returned by the drive .
* For normal I / O that may well include retries . We deal with
* both new - style ( taskfile ) and old style command handling here .
* In the case of taskfile command handling there is work left to
* do
*/
ide_startstop_t ide_error ( ide_drive_t * drive , const char * msg , u8 stat )
{
struct request * rq ;
u8 err ;
err = ide_dump_status ( drive , msg , stat ) ;
rq = drive - > hwif - > rq ;
if ( rq = = NULL )
return ide_stopped ;
/* retry only "normal" I/O: */
2017-01-31 18:57:31 +03:00
if ( blk_rq_is_passthrough ( rq ) ) {
2017-01-31 18:57:30 +03:00
if ( ata_taskfile_request ( rq ) ) {
2009-03-27 14:46:37 +03:00
struct ide_cmd * cmd = rq - > special ;
2009-03-27 14:46:31 +03:00
2009-03-27 14:46:37 +03:00
if ( cmd )
ide_complete_cmd ( drive , cmd , stat , err ) ;
2015-04-17 23:37:20 +03:00
} else if ( ata_pm_request ( rq ) ) {
2017-04-20 17:03:01 +03:00
scsi_req ( rq ) - > result = 1 ;
2009-03-27 14:46:31 +03:00
ide_complete_pm_rq ( drive , rq ) ;
return ide_stopped ;
}
2017-04-20 17:03:01 +03:00
scsi_req ( rq ) - > result = err ;
2017-06-03 10:38:04 +03:00
ide_complete_rq ( drive , err ? BLK_STS_IOERR : BLK_STS_OK , blk_rq_bytes ( rq ) ) ;
2009-03-25 01:22:47 +03:00
return ide_stopped ;
}
return __ide_error ( drive , rq , stat , err ) ;
}
EXPORT_SYMBOL_GPL ( ide_error ) ;
2017-06-03 10:38:04 +03:00
static inline void ide_complete_drive_reset ( ide_drive_t * drive , blk_status_t err )
2009-03-25 01:22:47 +03:00
{
struct request * rq = drive - > hwif - > rq ;
2017-01-31 18:57:30 +03:00
if ( rq & & ata_misc_request ( rq ) & &
2017-01-27 11:46:29 +03:00
scsi_req ( rq ) - > cmd [ 0 ] = = REQ_DRIVE_RESET ) {
2017-04-20 17:03:01 +03:00
if ( err < = 0 & & scsi_req ( rq ) - > result = = 0 )
scsi_req ( rq ) - > result = - EIO ;
2017-06-03 10:38:04 +03:00
ide_complete_rq ( drive , err , blk_rq_bytes ( rq ) ) ;
2009-03-27 14:46:43 +03:00
}
2009-03-25 01:22:47 +03:00
}
/* needed below */
static ide_startstop_t do_reset1 ( ide_drive_t * , int ) ;
/*
* atapi_reset_pollfunc ( ) gets invoked to poll the interface for completion
* every 50 ms during an atapi drive reset operation . If the drive has not yet
* responded , and we have not yet hit our maximum waiting time , then the timer
* is restarted for another 50 ms .
*/
static ide_startstop_t atapi_reset_pollfunc ( ide_drive_t * drive )
{
ide_hwif_t * hwif = drive - > hwif ;
2009-03-31 22:15:33 +04:00
const struct ide_tp_ops * tp_ops = hwif - > tp_ops ;
2009-03-25 01:22:47 +03:00
u8 stat ;
2009-03-31 22:15:33 +04:00
tp_ops - > dev_select ( drive ) ;
2009-03-25 01:22:47 +03:00
udelay ( 10 ) ;
2009-03-31 22:15:33 +04:00
stat = tp_ops - > read_status ( hwif ) ;
2009-03-25 01:22:47 +03:00
if ( OK_STAT ( stat , 0 , ATA_BUSY ) )
printk ( KERN_INFO " %s: ATAPI reset complete \n " , drive - > name ) ;
else {
if ( time_before ( jiffies , hwif - > poll_timeout ) ) {
2009-03-27 14:46:46 +03:00
ide_set_handler ( drive , & atapi_reset_pollfunc , HZ / 20 ) ;
2009-03-25 01:22:47 +03:00
/* continue polling */
return ide_started ;
}
/* end of polling */
hwif - > polling = 0 ;
printk ( KERN_ERR " %s: ATAPI reset timed-out, status=0x%02x \n " ,
drive - > name , stat ) ;
/* do it the old fashioned way */
return do_reset1 ( drive , 1 ) ;
}
/* done polling */
hwif - > polling = 0 ;
2017-06-03 10:38:04 +03:00
ide_complete_drive_reset ( drive , BLK_STS_OK ) ;
2009-03-25 01:22:47 +03:00
return ide_stopped ;
}
static void ide_reset_report_error ( ide_hwif_t * hwif , u8 err )
{
static const char * err_master_vals [ ] =
{ NULL , " passed " , " formatter device error " ,
" sector buffer error " , " ECC circuitry error " ,
" controlling MPU error " } ;
u8 err_master = err & 0x7f ;
printk ( KERN_ERR " %s: reset: master: " , hwif - > name ) ;
if ( err_master & & err_master < 6 )
printk ( KERN_CONT " %s " , err_master_vals [ err_master ] ) ;
else
printk ( KERN_CONT " error (0x%02x?) " , err ) ;
if ( err & 0x80 )
printk ( KERN_CONT " ; slave: failed " ) ;
printk ( KERN_CONT " \n " ) ;
}
/*
* reset_pollfunc ( ) gets invoked to poll the interface for completion every 50 ms
* during an ide reset operation . If the drives have not yet responded ,
* and we have not yet hit our maximum waiting time , then the timer is restarted
* for another 50 ms .
*/
static ide_startstop_t reset_pollfunc ( ide_drive_t * drive )
{
ide_hwif_t * hwif = drive - > hwif ;
const struct ide_port_ops * port_ops = hwif - > port_ops ;
u8 tmp ;
2017-06-03 10:38:04 +03:00
blk_status_t err = BLK_STS_OK ;
2009-03-25 01:22:47 +03:00
if ( port_ops & & port_ops - > reset_poll ) {
err = port_ops - > reset_poll ( drive ) ;
if ( err ) {
printk ( KERN_ERR " %s: host reset_poll failure for %s. \n " ,
hwif - > name , drive - > name ) ;
goto out ;
}
}
tmp = hwif - > tp_ops - > read_status ( hwif ) ;
if ( ! OK_STAT ( tmp , 0 , ATA_BUSY ) ) {
if ( time_before ( jiffies , hwif - > poll_timeout ) ) {
2009-03-27 14:46:46 +03:00
ide_set_handler ( drive , & reset_pollfunc , HZ / 20 ) ;
2009-03-25 01:22:47 +03:00
/* continue polling */
return ide_started ;
}
printk ( KERN_ERR " %s: reset timed-out, status=0x%02x \n " ,
hwif - > name , tmp ) ;
drive - > failures + + ;
2017-06-03 10:38:04 +03:00
err = BLK_STS_IOERR ;
2009-03-25 01:22:47 +03:00
} else {
tmp = ide_read_error ( drive ) ;
if ( tmp = = 1 ) {
printk ( KERN_INFO " %s: reset: success \n " , hwif - > name ) ;
drive - > failures = 0 ;
} else {
ide_reset_report_error ( hwif , tmp ) ;
drive - > failures + + ;
2017-06-03 10:38:04 +03:00
err = BLK_STS_IOERR ;
2009-03-25 01:22:47 +03:00
}
}
out :
hwif - > polling = 0 ; /* done polling */
ide_complete_drive_reset ( drive , err ) ;
return ide_stopped ;
}
static void ide_disk_pre_reset ( ide_drive_t * drive )
{
int legacy = ( drive - > id [ ATA_ID_CFS_ENABLE_2 ] & 0x0400 ) ? 0 : 1 ;
2009-05-17 21:12:21 +04:00
drive - > special_flags =
legacy ? ( IDE_SFLAG_SET_GEOMETRY | IDE_SFLAG_RECALIBRATE ) : 0 ;
2009-03-25 01:22:47 +03:00
drive - > mult_count = 0 ;
drive - > dev_flags & = ~ IDE_DFLAG_PARKED ;
if ( ( drive - > dev_flags & IDE_DFLAG_KEEP_SETTINGS ) = = 0 & &
( drive - > dev_flags & IDE_DFLAG_USING_DMA ) = = 0 )
drive - > mult_req = 0 ;
if ( drive - > mult_req ! = drive - > mult_count )
2009-05-17 21:12:21 +04:00
drive - > special_flags | = IDE_SFLAG_SET_MULTMODE ;
2009-03-25 01:22:47 +03:00
}
static void pre_reset ( ide_drive_t * drive )
{
const struct ide_port_ops * port_ops = drive - > hwif - > port_ops ;
if ( drive - > media = = ide_disk )
ide_disk_pre_reset ( drive ) ;
else
drive - > dev_flags | = IDE_DFLAG_POST_RESET ;
if ( drive - > dev_flags & IDE_DFLAG_USING_DMA ) {
if ( drive - > crc_count )
ide_check_dma_crc ( drive ) ;
else
ide_dma_off ( drive ) ;
}
if ( ( drive - > dev_flags & IDE_DFLAG_KEEP_SETTINGS ) = = 0 ) {
if ( ( drive - > dev_flags & IDE_DFLAG_USING_DMA ) = = 0 ) {
drive - > dev_flags & = ~ IDE_DFLAG_UNMASK ;
drive - > io_32bit = 0 ;
}
return ;
}
if ( port_ops & & port_ops - > pre_reset )
port_ops - > pre_reset ( drive ) ;
if ( drive - > current_speed ! = 0xff )
drive - > desired_speed = drive - > current_speed ;
drive - > current_speed = 0xff ;
}
/*
* do_reset1 ( ) attempts to recover a confused drive by resetting it .
* Unfortunately , resetting a disk drive actually resets all devices on
* the same interface , so it can really be thought of as resetting the
* interface rather than resetting the drive .
*
* ATAPI devices have their own reset mechanism which allows them to be
* individually reset without clobbering other devices on the same interface .
*
* Unfortunately , the IDE interface does not generate an interrupt to let
* us know when the reset operation has finished , so we must poll for this .
* Equally poor , though , is the fact that this may a very long time to complete ,
* ( up to 30 seconds worstcase ) . So , instead of busy - waiting here for it ,
* we set a timer to poll at 50 ms intervals .
*/
static ide_startstop_t do_reset1 ( ide_drive_t * drive , int do_not_try_atapi )
{
ide_hwif_t * hwif = drive - > hwif ;
struct ide_io_ports * io_ports = & hwif - > io_ports ;
const struct ide_tp_ops * tp_ops = hwif - > tp_ops ;
const struct ide_port_ops * port_ops ;
ide_drive_t * tdrive ;
unsigned long flags , timeout ;
int i ;
DEFINE_WAIT ( wait ) ;
spin_lock_irqsave ( & hwif - > lock , flags ) ;
/* We must not reset with running handlers */
BUG_ON ( hwif - > handler ! = NULL ) ;
/* For an ATAPI device, first try an ATAPI SRST. */
if ( drive - > media ! = ide_disk & & ! do_not_try_atapi ) {
pre_reset ( drive ) ;
2009-03-31 22:15:33 +04:00
tp_ops - > dev_select ( drive ) ;
2009-03-25 01:22:47 +03:00
udelay ( 20 ) ;
tp_ops - > exec_command ( hwif , ATA_CMD_DEV_RESET ) ;
ndelay ( 400 ) ;
hwif - > poll_timeout = jiffies + WAIT_WORSTCASE ;
hwif - > polling = 1 ;
2009-03-27 14:46:46 +03:00
__ide_set_handler ( drive , & atapi_reset_pollfunc , HZ / 20 ) ;
2009-03-25 01:22:47 +03:00
spin_unlock_irqrestore ( & hwif - > lock , flags ) ;
return ide_started ;
}
/* We must not disturb devices in the IDE_DFLAG_PARKED state. */
do {
unsigned long now ;
prepare_to_wait ( & ide_park_wq , & wait , TASK_UNINTERRUPTIBLE ) ;
timeout = jiffies ;
ide_port_for_each_present_dev ( i , tdrive , hwif ) {
if ( ( tdrive - > dev_flags & IDE_DFLAG_PARKED ) & &
time_after ( tdrive - > sleep , timeout ) )
timeout = tdrive - > sleep ;
}
now = jiffies ;
if ( time_before_eq ( timeout , now ) )
break ;
spin_unlock_irqrestore ( & hwif - > lock , flags ) ;
timeout = schedule_timeout_uninterruptible ( timeout - now ) ;
spin_lock_irqsave ( & hwif - > lock , flags ) ;
} while ( timeout ) ;
finish_wait ( & ide_park_wq , & wait ) ;
/*
* First , reset any device state data we were maintaining
* for any of the drives on this interface .
*/
ide_port_for_each_dev ( i , tdrive , hwif )
pre_reset ( tdrive ) ;
if ( io_ports - > ctl_addr = = 0 ) {
spin_unlock_irqrestore ( & hwif - > lock , flags ) ;
2017-06-03 10:38:04 +03:00
ide_complete_drive_reset ( drive , BLK_STS_IOERR ) ;
2009-03-25 01:22:47 +03:00
return ide_stopped ;
}
/*
* Note that we also set nIEN while resetting the device ,
* to mask unwanted interrupts from the interface during the reset .
* However , due to the design of PC hardware , this will cause an
* immediate interrupt due to the edge transition it produces .
* This single interrupt gives us a " fast poll " for drives that
* recover from reset very quickly , saving us the first 50 ms wait time .
*/
/* set SRST and nIEN */
2009-03-31 22:15:30 +04:00
tp_ops - > write_devctl ( hwif , ATA_SRST | ATA_NIEN | ATA_DEVCTL_OBS ) ;
2009-03-25 01:22:47 +03:00
/* more than enough time */
udelay ( 10 ) ;
/* clear SRST, leave nIEN (unless device is on the quirk list) */
2009-06-07 17:37:10 +04:00
tp_ops - > write_devctl ( hwif ,
( ( drive - > dev_flags & IDE_DFLAG_NIEN_QUIRK ) ? 0 : ATA_NIEN ) |
ATA_DEVCTL_OBS ) ;
2009-03-25 01:22:47 +03:00
/* more than enough time */
udelay ( 10 ) ;
hwif - > poll_timeout = jiffies + WAIT_WORSTCASE ;
hwif - > polling = 1 ;
2009-03-27 14:46:46 +03:00
__ide_set_handler ( drive , & reset_pollfunc , HZ / 20 ) ;
2009-03-25 01:22:47 +03:00
/*
* Some weird controller like resetting themselves to a strange
* state when the disks are reset this way . At least , the Winbond
* 553 documentation says that
*/
port_ops = hwif - > port_ops ;
if ( port_ops & & port_ops - > resetproc )
port_ops - > resetproc ( drive ) ;
spin_unlock_irqrestore ( & hwif - > lock , flags ) ;
return ide_started ;
}
/*
* ide_do_reset ( ) is the entry point to the drive / interface reset code .
*/
ide_startstop_t ide_do_reset ( ide_drive_t * drive )
{
return do_reset1 ( drive , 0 ) ;
}
EXPORT_SYMBOL ( ide_do_reset ) ;