2006-08-30 02:12:40 +04:00
/*
* ata - it821x . c - IT821x PATA for new ATA layer
* ( C ) 2005 Red Hat Inc
* Alan Cox < alan @ redhat . com >
*
* based upon
*
* it821x . c
2006-08-31 08:03:49 +04:00
*
2006-08-30 02:12:40 +04:00
* linux / drivers / ide / pci / it821x . c Version 0.09 December 2004
*
* Copyright ( C ) 2004 Red Hat < alan @ redhat . com >
*
* May be copied or modified under the terms of the GNU General Public License
* Based in part on the ITE vendor provided SCSI driver .
*
* Documentation available from
* http : //www.ite.com.tw/pc/IT8212F_V04.pdf
* Some other documents are NDA .
*
* The ITE8212 isn ' t exactly a standard IDE controller . It has two
* modes . In pass through mode then it is an IDE controller . In its smart
* mode its actually quite a capable hardware raid controller disguised
* as an IDE controller . Smart mode only understands DMA read / write and
* identify , none of the fancier commands apply . The IT8211 is identical
* in other respects but lacks the raid mode .
*
* Errata :
* o Rev 0x10 also requires master / slave hold the same DMA timings and
* cannot do ATAPI MWDMA .
* o The identify data for raid volumes lacks CHS info ( technically ok )
* but also fails to set the LBA28 and other bits . We fix these in
* the IDE probe quirk code .
* o If you write LBA48 sized I / O ' s ( ie > 256 sector ) in smart mode
* raid then the controller firmware dies
* o Smart mode without RAID doesn ' t clear all the necessary identify
* bits to reduce the command set to the one used
*
* This has a few impacts on the driver
* - In pass through mode we do all the work you would expect
* - In smart mode the clocking set up is done by the controller generally
* but we must watch the other limits and filter .
* - There are a few extra vendor commands that actually talk to the
* controller but only work PIO with no IRQ .
*
* Vendor areas of the identify block in smart mode are used for the
* timing and policy set up . Each HDD in raid mode also has a serial
* block on the disk . The hardware extra commands are get / set chip status ,
* rebuild , get rebuild status .
*
* In Linux the driver supports pass through mode as if the device was
* just another IDE controller . If the smart mode is running then
* volumes are managed by the controller firmware and each IDE " disk "
* is a raid volume . Even more cute - the controller can do automated
* hotplug and rebuild .
*
* The pass through controller itself is a little demented . It has a
* flaw that it has a single set of PIO / MWDMA timings per channel so
* non UDMA devices restrict each others performance . It also has a
* single clock source per channel so mixed UDMA100 / 133 performance
* isn ' t perfect and we have to pick a clock . Thankfully none of this
* matters in smart mode . ATAPI DMA is not currently supported .
*
* It seems the smart mode is a win for RAID1 / RAID10 but otherwise not .
*
* TODO
* - ATAPI and other speed filtering
* - Command filter in smart mode
* - RAID configuration ioctls
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/pci.h>
# include <linux/init.h>
# include <linux/blkdev.h>
# include <linux/delay.h>
# include <scsi/scsi_host.h>
# include <linux/libata.h>
# define DRV_NAME "pata_it821x"
2006-11-27 19:14:36 +03:00
# define DRV_VERSION "0.3.3"
2006-08-30 02:12:40 +04:00
struct it821x_dev
{
unsigned int smart : 1 , /* Are we in smart raid mode */
timing10 : 1 ; /* Rev 0x10 */
u8 clock_mode ; /* 0, ATA_50 or ATA_66 */
u8 want [ 2 ] [ 2 ] ; /* Mode/Pri log for master slave */
/* We need these for switching the clock when DMA goes on/off
The high byte is the 66 Mhz timing */
u16 pio [ 2 ] ; /* Cached PIO values */
u16 mwdma [ 2 ] ; /* Cached MWDMA values */
u16 udma [ 2 ] ; /* Cached UDMA values (per drive) */
u16 last_device ; /* Master or slave loaded ? */
} ;
# define ATA_66 0
# define ATA_50 1
# define ATA_ANY 2
# define UDMA_OFF 0
# define MWDMA_OFF 0
/*
* We allow users to force the card into non raid mode without
* flashing the alternative BIOS . This is also neccessary right now
* for embedded platforms that cannot run a PC BIOS but are using this
* device .
*/
static int it8212_noraid ;
/**
* it821x_pre_reset - probe
* @ ap : ATA port
*
* Set the cable type
*/
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
static int it821x_pre_reset ( struct ata_port * ap )
{
ap - > cbl = ATA_CBL_PATA80 ;
return ata_std_prereset ( ap ) ;
}
/**
* it821x_error_handler - probe / reset
* @ ap : ATA port
*
* Set the cable type and trigger a probe
*/
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
static void it821x_error_handler ( struct ata_port * ap )
{
return ata_bmdma_drive_eh ( ap , it821x_pre_reset , ata_std_softreset , NULL , ata_std_postreset ) ;
}
/**
* it821x_program - program the PIO / MWDMA registers
* @ ap : ATA port
* @ adev : Device to program
* @ timing : Timing value ( 66 Mhz in top 8 bits , 50 in the low 8 )
*
* Program the PIO / MWDMA timing for this channel according to the
* current clock . These share the same register so are managed by
* the DMA start / stop sequence as with the old driver .
*/
static void it821x_program ( struct ata_port * ap , struct ata_device * adev , u16 timing )
{
struct pci_dev * pdev = to_pci_dev ( ap - > host - > dev ) ;
struct it821x_dev * itdev = ap - > private_data ;
int channel = ap - > port_no ;
u8 conf ;
/* Program PIO/MWDMA timing bits */
if ( itdev - > clock_mode = = ATA_66 )
conf = timing > > 8 ;
else
conf = timing & 0xFF ;
pci_write_config_byte ( pdev , 0x54 + 4 * channel , conf ) ;
}
/**
* it821x_program_udma - program the UDMA registers
* @ ap : ATA port
* @ adev : ATA device to update
* @ timing : Timing bits . Top 8 are for 66 Mhz bottom for 50 Mhz
*
* Program the UDMA timing for this drive according to the
* current clock . Handles the dual clocks and also knows about
* the errata on the 0x10 revision . The UDMA errata is partly handled
* here and partly in start_dma .
*/
static void it821x_program_udma ( struct ata_port * ap , struct ata_device * adev , u16 timing )
{
struct it821x_dev * itdev = ap - > private_data ;
struct pci_dev * pdev = to_pci_dev ( ap - > host - > dev ) ;
int channel = ap - > port_no ;
int unit = adev - > devno ;
u8 conf ;
/* Program UDMA timing bits */
if ( itdev - > clock_mode = = ATA_66 )
conf = timing > > 8 ;
else
conf = timing & 0xFF ;
if ( itdev - > timing10 = = 0 )
pci_write_config_byte ( pdev , 0x56 + 4 * channel + unit , conf ) ;
else {
/* Early revision must be programmed for both together */
pci_write_config_byte ( pdev , 0x56 + 4 * channel , conf ) ;
pci_write_config_byte ( pdev , 0x56 + 4 * channel + 1 , conf ) ;
}
}
/**
* it821x_clock_strategy
* @ ap : ATA interface
* @ adev : ATA device being updated
*
* Select between the 50 and 66 Mhz base clocks to get the best
* results for this interface .
*/
static void it821x_clock_strategy ( struct ata_port * ap , struct ata_device * adev )
{
struct pci_dev * pdev = to_pci_dev ( ap - > host - > dev ) ;
struct it821x_dev * itdev = ap - > private_data ;
u8 unit = adev - > devno ;
struct ata_device * pair = ata_dev_pair ( adev ) ;
int clock , altclock ;
u8 v ;
int sel = 0 ;
/* Look for the most wanted clocking */
if ( itdev - > want [ 0 ] [ 0 ] > itdev - > want [ 1 ] [ 0 ] ) {
clock = itdev - > want [ 0 ] [ 1 ] ;
altclock = itdev - > want [ 1 ] [ 1 ] ;
} else {
clock = itdev - > want [ 1 ] [ 1 ] ;
altclock = itdev - > want [ 0 ] [ 1 ] ;
}
/* Master doesn't care does the slave ? */
if ( clock = = ATA_ANY )
clock = altclock ;
/* Nobody cares - keep the same clock */
if ( clock = = ATA_ANY )
return ;
/* No change */
if ( clock = = itdev - > clock_mode )
return ;
/* Load this into the controller */
if ( clock = = ATA_66 )
itdev - > clock_mode = ATA_66 ;
else {
itdev - > clock_mode = ATA_50 ;
sel = 1 ;
}
pci_read_config_byte ( pdev , 0x50 , & v ) ;
v & = ~ ( 1 < < ( 1 + ap - > port_no ) ) ;
v | = sel < < ( 1 + ap - > port_no ) ;
pci_write_config_byte ( pdev , 0x50 , v ) ;
/*
* Reprogram the UDMA / PIO of the pair drive for the switch
* MWDMA will be dealt with by the dma switcher
*/
if ( pair & & itdev - > udma [ 1 - unit ] ! = UDMA_OFF ) {
it821x_program_udma ( ap , pair , itdev - > udma [ 1 - unit ] ) ;
it821x_program ( ap , pair , itdev - > pio [ 1 - unit ] ) ;
}
/*
* Reprogram the UDMA / PIO of our drive for the switch .
* MWDMA will be dealt with by the dma switcher
*/
if ( itdev - > udma [ unit ] ! = UDMA_OFF ) {
it821x_program_udma ( ap , adev , itdev - > udma [ unit ] ) ;
it821x_program ( ap , adev , itdev - > pio [ unit ] ) ;
}
}
/**
* it821x_passthru_set_piomode - set PIO mode data
* @ ap : ATA interface
* @ adev : ATA device
*
* Configure for PIO mode . This is complicated as the register is
* shared by PIO and MWDMA and for both channels .
*/
static void it821x_passthru_set_piomode ( struct ata_port * ap , struct ata_device * adev )
{
/* Spec says 89 ref driver uses 88 */
static const u16 pio [ ] = { 0xAA88 , 0xA382 , 0xA181 , 0x3332 , 0x3121 } ;
static const u8 pio_want [ ] = { ATA_66 , ATA_66 , ATA_66 , ATA_66 , ATA_ANY } ;
struct it821x_dev * itdev = ap - > private_data ;
int unit = adev - > devno ;
int mode_wanted = adev - > pio_mode - XFER_PIO_0 ;
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
/* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
itdev - > want [ unit ] [ 1 ] = pio_want [ mode_wanted ] ;
itdev - > want [ unit ] [ 0 ] = 1 ; /* PIO is lowest priority */
itdev - > pio [ unit ] = pio [ mode_wanted ] ;
it821x_clock_strategy ( ap , adev ) ;
it821x_program ( ap , adev , itdev - > pio [ unit ] ) ;
}
/**
* it821x_passthru_set_dmamode - set initial DMA mode data
* @ ap : ATA interface
* @ adev : ATA device
*
* Set up the DMA modes . The actions taken depend heavily on the mode
2006-08-31 08:03:49 +04:00
* to use . If UDMA is used as is hopefully the usual case then the
2006-08-30 02:12:40 +04:00
* timing register is private and we need only consider the clock . If
* we are using MWDMA then we have to manage the setting ourself as
* we switch devices and mode .
*/
static void it821x_passthru_set_dmamode ( struct ata_port * ap , struct ata_device * adev )
{
static const u16 dma [ ] = { 0x8866 , 0x3222 , 0x3121 } ;
static const u8 mwdma_want [ ] = { ATA_ANY , ATA_66 , ATA_ANY } ;
static const u16 udma [ ] = { 0x4433 , 0x4231 , 0x3121 , 0x2121 , 0x1111 , 0x2211 , 0x1111 } ;
static const u8 udma_want [ ] = { ATA_ANY , ATA_50 , ATA_ANY , ATA_66 , ATA_66 , ATA_50 , ATA_66 } ;
struct pci_dev * pdev = to_pci_dev ( ap - > host - > dev ) ;
struct it821x_dev * itdev = ap - > private_data ;
int channel = ap - > port_no ;
int unit = adev - > devno ;
u8 conf ;
if ( adev - > dma_mode > = XFER_UDMA_0 ) {
int mode_wanted = adev - > dma_mode - XFER_UDMA_0 ;
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
itdev - > want [ unit ] [ 1 ] = udma_want [ mode_wanted ] ;
itdev - > want [ unit ] [ 0 ] = 3 ; /* UDMA is high priority */
itdev - > mwdma [ unit ] = MWDMA_OFF ;
itdev - > udma [ unit ] = udma [ mode_wanted ] ;
if ( mode_wanted > = 5 )
itdev - > udma [ unit ] | = 0x8080 ; /* UDMA 5/6 select on */
/* UDMA on. Again revision 0x10 must do the pair */
pci_read_config_byte ( pdev , 0x50 , & conf ) ;
if ( itdev - > timing10 )
conf & = channel ? 0x9F : 0xE7 ;
else
conf & = ~ ( 1 < < ( 3 + 2 * channel + unit ) ) ;
pci_write_config_byte ( pdev , 0x50 , conf ) ;
it821x_clock_strategy ( ap , adev ) ;
it821x_program_udma ( ap , adev , itdev - > udma [ unit ] ) ;
} else {
int mode_wanted = adev - > dma_mode - XFER_MW_DMA_0 ;
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
itdev - > want [ unit ] [ 1 ] = mwdma_want [ mode_wanted ] ;
itdev - > want [ unit ] [ 0 ] = 2 ; /* MWDMA is low priority */
itdev - > mwdma [ unit ] = dma [ mode_wanted ] ;
itdev - > udma [ unit ] = UDMA_OFF ;
/* UDMA bits off - Revision 0x10 do them in pairs */
pci_read_config_byte ( pdev , 0x50 , & conf ) ;
if ( itdev - > timing10 )
conf | = channel ? 0x60 : 0x18 ;
else
conf | = 1 < < ( 3 + 2 * channel + unit ) ;
pci_write_config_byte ( pdev , 0x50 , conf ) ;
it821x_clock_strategy ( ap , adev ) ;
}
}
/**
* it821x_passthru_dma_start - DMA start callback
* @ qc : Command in progress
*
* Usually drivers set the DMA timing at the point the set_dmamode call
2006-08-31 08:03:49 +04:00
* is made . IT821x however requires we load new timings on the
2006-08-30 02:12:40 +04:00
* transitions in some cases .
*/
static void it821x_passthru_bmdma_start ( struct ata_queued_cmd * qc )
{
struct ata_port * ap = qc - > ap ;
struct ata_device * adev = qc - > dev ;
struct it821x_dev * itdev = ap - > private_data ;
int unit = adev - > devno ;
if ( itdev - > mwdma [ unit ] ! = MWDMA_OFF )
it821x_program ( ap , adev , itdev - > mwdma [ unit ] ) ;
else if ( itdev - > udma [ unit ] ! = UDMA_OFF & & itdev - > timing10 )
it821x_program_udma ( ap , adev , itdev - > udma [ unit ] ) ;
ata_bmdma_start ( qc ) ;
}
/**
* it821x_passthru_dma_stop - DMA stop callback
* @ qc : ATA command
*
* We loaded new timings in dma_start , as a result we need to restore
* the PIO timings in dma_stop so that the next command issue gets the
* right clock values .
*/
static void it821x_passthru_bmdma_stop ( struct ata_queued_cmd * qc )
{
struct ata_port * ap = qc - > ap ;
struct ata_device * adev = qc - > dev ;
struct it821x_dev * itdev = ap - > private_data ;
int unit = adev - > devno ;
ata_bmdma_stop ( qc ) ;
if ( itdev - > mwdma [ unit ] ! = MWDMA_OFF )
it821x_program ( ap , adev , itdev - > pio [ unit ] ) ;
}
/**
* it821x_passthru_dev_select - Select master / slave
* @ ap : ATA port
* @ device : Device number ( not pointer )
*
* Device selection hook . If neccessary perform clock switching
*/
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
static void it821x_passthru_dev_select ( struct ata_port * ap ,
unsigned int device )
{
struct it821x_dev * itdev = ap - > private_data ;
if ( itdev & & device ! = itdev - > last_device ) {
struct ata_device * adev = & ap - > device [ device ] ;
it821x_program ( ap , adev , itdev - > pio [ adev - > devno ] ) ;
itdev - > last_device = device ;
}
ata_std_dev_select ( ap , device ) ;
}
/**
* it821x_smart_qc_issue_prot - wrap qc issue prot
* @ qc : command
*
* Wrap the command issue sequence for the IT821x . We need to
* perform out own device selection timing loads before the
* usual happenings kick off
*/
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
static unsigned int it821x_smart_qc_issue_prot ( struct ata_queued_cmd * qc )
{
switch ( qc - > tf . command )
{
/* Commands the firmware supports */
case ATA_CMD_READ :
case ATA_CMD_READ_EXT :
case ATA_CMD_WRITE :
case ATA_CMD_WRITE_EXT :
case ATA_CMD_PIO_READ :
case ATA_CMD_PIO_READ_EXT :
case ATA_CMD_PIO_WRITE :
case ATA_CMD_PIO_WRITE_EXT :
case ATA_CMD_READ_MULTI :
case ATA_CMD_READ_MULTI_EXT :
case ATA_CMD_WRITE_MULTI :
case ATA_CMD_WRITE_MULTI_EXT :
case ATA_CMD_ID_ATA :
/* Arguably should just no-op this one */
case ATA_CMD_SET_FEATURES :
return ata_qc_issue_prot ( qc ) ;
}
printk ( KERN_DEBUG " it821x: can't process command 0x%02X \n " , qc - > tf . command ) ;
return AC_ERR_INVALID ;
}
/**
* it821x_passthru_qc_issue_prot - wrap qc issue prot
* @ qc : command
*
* Wrap the command issue sequence for the IT821x . We need to
* perform out own device selection timing loads before the
* usual happenings kick off
*/
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
static unsigned int it821x_passthru_qc_issue_prot ( struct ata_queued_cmd * qc )
{
it821x_passthru_dev_select ( qc - > ap , qc - > dev - > devno ) ;
return ata_qc_issue_prot ( qc ) ;
}
/**
* it821x_smart_set_mode - mode setting
* @ ap : interface to set up
2007-01-24 14:47:07 +03:00
* @ unused : device that failed ( error only )
2006-08-30 02:12:40 +04:00
*
* Use a non standard set_mode function . We don ' t want to be tuned .
* The BIOS configured everything . Our job is not to fiddle . We
* read the dma enabled bits from the PCI configuration of the device
2006-08-31 08:03:49 +04:00
* and respect them .
2006-08-30 02:12:40 +04:00
*/
2006-08-31 08:03:49 +04:00
2007-01-24 14:47:07 +03:00
static int it821x_smart_set_mode ( struct ata_port * ap , struct ata_device * * unused )
2006-08-30 02:12:40 +04:00
{
int dma_enabled = 0 ;
int i ;
/* Bits 5 and 6 indicate if DMA is active on master/slave */
/* It is possible that BMDMA isn't allocated */
if ( ap - > ioaddr . bmdma_addr )
2007-02-01 09:06:36 +03:00
dma_enabled = ioread8 ( ap - > ioaddr . bmdma_addr + ATA_DMA_CMD ) ;
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
for ( i = 0 ; i < ATA_MAX_DEVICES ; i + + ) {
struct ata_device * dev = & ap - > device [ i ] ;
if ( ata_dev_enabled ( dev ) ) {
/* We don't really care */
dev - > pio_mode = XFER_PIO_0 ;
dev - > dma_mode = XFER_MW_DMA_0 ;
2006-08-31 08:03:49 +04:00
/* We do need the right mode information for DMA or PIO
2006-08-30 02:12:40 +04:00
and this comes from the current configuration flags */
if ( dma_enabled & ( 1 < < ( 5 + i ) ) ) {
dev - > xfer_mode = XFER_MW_DMA_0 ;
dev - > xfer_shift = ATA_SHIFT_MWDMA ;
dev - > flags & = ~ ATA_DFLAG_PIO ;
} else {
dev - > xfer_mode = XFER_PIO_0 ;
dev - > xfer_shift = ATA_SHIFT_PIO ;
dev - > flags | = ATA_DFLAG_PIO ;
}
}
}
2007-01-24 14:47:07 +03:00
return 0 ;
2006-08-30 02:12:40 +04:00
}
/**
* it821x_dev_config - Called each device identify
* @ ap : ATA port
* @ adev : Device that has just been identified
*
* Perform the initial setup needed for each device that is chip
* special . In our case we need to lock the sector count to avoid
* blowing the brains out of the firmware with large LBA48 requests
*
* FIXME : When FUA appears we need to block FUA too . And SMART and
* basically we need to filter commands for this chip .
*/
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
static void it821x_dev_config ( struct ata_port * ap , struct ata_device * adev )
{
2007-01-02 14:19:40 +03:00
unsigned char model_num [ ATA_ID_PROD_LEN + 1 ] ;
2006-08-30 02:12:40 +04:00
2007-01-02 14:19:40 +03:00
ata_id_c_string ( adev - > id , model_num , ATA_ID_PROD , sizeof ( model_num ) ) ;
2006-08-30 02:12:40 +04:00
if ( adev - > max_sectors > 255 )
adev - > max_sectors = 255 ;
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
if ( strstr ( model_num , " Integrated Technology Express " ) ) {
/* RAID mode */
printk ( KERN_INFO " IT821x %sRAID%d volume " ,
adev - > id [ 147 ] ? " Bootable " : " " ,
adev - > id [ 129 ] ) ;
if ( adev - > id [ 129 ] ! = 1 )
printk ( " (%dK stripe) " , adev - > id [ 146 ] ) ;
printk ( " . \n " ) ;
}
}
/**
* it821x_check_atapi_dma - ATAPI DMA handler
* @ qc : Command we are about to issue
*
* Decide if this ATAPI command can be issued by DMA on this
* controller . Return 0 if it can be .
*/
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
static int it821x_check_atapi_dma ( struct ata_queued_cmd * qc )
{
struct ata_port * ap = qc - > ap ;
struct it821x_dev * itdev = ap - > private_data ;
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
/* No ATAPI DMA in smart mode */
if ( itdev - > smart )
return - EOPNOTSUPP ;
/* No ATAPI DMA on rev 10 */
if ( itdev - > timing10 )
return - EOPNOTSUPP ;
/* Cool */
return 0 ;
}
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
/**
* it821x_port_start - port setup
* @ ap : ATA port being set up
*
* The it821x needs to maintain private data structures and also to
* use the standard PCI interface which lacks support for this
2006-08-31 08:03:49 +04:00
* functionality . We instead set up the private data on the port
2006-08-30 02:12:40 +04:00
* start hook , and tear it down on port stop
*/
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
static int it821x_port_start ( struct ata_port * ap )
{
struct pci_dev * pdev = to_pci_dev ( ap - > host - > dev ) ;
struct it821x_dev * itdev ;
u8 conf ;
int ret = ata_port_start ( ap ) ;
if ( ret < 0 )
return ret ;
2006-08-31 08:03:49 +04:00
2007-01-20 10:00:28 +03:00
itdev = devm_kzalloc ( & pdev - > dev , sizeof ( struct it821x_dev ) , GFP_KERNEL ) ;
if ( itdev = = NULL )
2006-08-30 02:12:40 +04:00
return - ENOMEM ;
2007-01-20 10:00:28 +03:00
ap - > private_data = itdev ;
2006-08-30 02:12:40 +04:00
pci_read_config_byte ( pdev , 0x50 , & conf ) ;
if ( conf & 1 ) {
itdev - > smart = 1 ;
/* Long I/O's although allowed in LBA48 space cause the
onboard firmware to enter the twighlight zone */
/* No ATAPI DMA in this mode either */
}
/* Pull the current clocks from 0x50 */
if ( conf & ( 1 < < ( 1 + ap - > port_no ) ) )
itdev - > clock_mode = ATA_50 ;
else
itdev - > clock_mode = ATA_66 ;
itdev - > want [ 0 ] [ 1 ] = ATA_ANY ;
itdev - > want [ 1 ] [ 1 ] = ATA_ANY ;
itdev - > last_device = - 1 ;
pci_read_config_byte ( pdev , PCI_REVISION_ID , & conf ) ;
if ( conf = = 0x10 ) {
itdev - > timing10 = 1 ;
/* Need to disable ATAPI DMA for this case */
if ( ! itdev - > smart )
printk ( KERN_WARNING DRV_NAME " : Revision 0x10, workarounds activated. \n " ) ;
}
return 0 ;
}
static struct scsi_host_template it821x_sht = {
. module = THIS_MODULE ,
. name = DRV_NAME ,
. ioctl = ata_scsi_ioctl ,
. queuecommand = ata_scsi_queuecmd ,
. can_queue = ATA_DEF_QUEUE ,
. this_id = ATA_SHT_THIS_ID ,
. sg_tablesize = LIBATA_MAX_PRD ,
. cmd_per_lun = ATA_SHT_CMD_PER_LUN ,
. emulated = ATA_SHT_EMULATED ,
. use_clustering = ATA_SHT_USE_CLUSTERING ,
. proc_name = DRV_NAME ,
. dma_boundary = ATA_DMA_BOUNDARY ,
. slave_configure = ata_scsi_slave_config ,
2006-11-29 05:26:47 +03:00
. slave_destroy = ata_scsi_slave_destroy ,
2006-08-30 02:12:40 +04:00
. bios_param = ata_std_bios_param ,
2006-11-27 19:14:36 +03:00
. resume = ata_scsi_device_resume ,
. suspend = ata_scsi_device_suspend ,
2006-08-30 02:12:40 +04:00
} ;
static struct ata_port_operations it821x_smart_port_ops = {
. set_mode = it821x_smart_set_mode ,
. port_disable = ata_port_disable ,
. tf_load = ata_tf_load ,
. tf_read = ata_tf_read ,
. mode_filter = ata_pci_default_filter ,
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
. check_status = ata_check_status ,
. check_atapi_dma = it821x_check_atapi_dma ,
. exec_command = ata_exec_command ,
. dev_select = ata_std_dev_select ,
. dev_config = it821x_dev_config ,
. freeze = ata_bmdma_freeze ,
. thaw = ata_bmdma_thaw ,
. error_handler = it821x_error_handler ,
. post_internal_cmd = ata_bmdma_post_internal_cmd ,
. bmdma_setup = ata_bmdma_setup ,
. bmdma_start = ata_bmdma_start ,
. bmdma_stop = ata_bmdma_stop ,
. bmdma_status = ata_bmdma_status ,
. qc_prep = ata_qc_prep ,
. qc_issue = it821x_smart_qc_issue_prot ,
2006-09-27 13:41:13 +04:00
2007-02-01 09:06:36 +03:00
. data_xfer = ata_data_xfer ,
2006-08-30 02:12:40 +04:00
. irq_handler = ata_interrupt ,
. irq_clear = ata_bmdma_irq_clear ,
2007-01-26 10:27:58 +03:00
. irq_on = ata_irq_on ,
. irq_ack = ata_irq_ack ,
2006-08-30 02:12:40 +04:00
. port_start = it821x_port_start ,
2006-08-31 08:03:49 +04:00
} ;
2006-08-30 02:12:40 +04:00
static struct ata_port_operations it821x_passthru_port_ops = {
. port_disable = ata_port_disable ,
. set_piomode = it821x_passthru_set_piomode ,
. set_dmamode = it821x_passthru_set_dmamode ,
. mode_filter = ata_pci_default_filter ,
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
. tf_load = ata_tf_load ,
. tf_read = ata_tf_read ,
. check_status = ata_check_status ,
. exec_command = ata_exec_command ,
. check_atapi_dma = it821x_check_atapi_dma ,
. dev_select = it821x_passthru_dev_select ,
. freeze = ata_bmdma_freeze ,
. thaw = ata_bmdma_thaw ,
. error_handler = it821x_error_handler ,
. post_internal_cmd = ata_bmdma_post_internal_cmd ,
. bmdma_setup = ata_bmdma_setup ,
. bmdma_start = it821x_passthru_bmdma_start ,
. bmdma_stop = it821x_passthru_bmdma_stop ,
. bmdma_status = ata_bmdma_status ,
. qc_prep = ata_qc_prep ,
. qc_issue = it821x_passthru_qc_issue_prot ,
2006-09-27 13:41:13 +04:00
2007-02-01 09:06:36 +03:00
. data_xfer = ata_data_xfer ,
2006-08-30 02:12:40 +04:00
. irq_clear = ata_bmdma_irq_clear ,
. irq_handler = ata_interrupt ,
2007-01-26 10:27:58 +03:00
. irq_on = ata_irq_on ,
. irq_ack = ata_irq_ack ,
2006-08-30 02:12:40 +04:00
. port_start = it821x_port_start ,
2006-08-31 08:03:49 +04:00
} ;
2006-08-30 02:12:40 +04:00
static void __devinit it821x_disable_raid ( struct pci_dev * pdev )
{
/* Reset local CPU, and set BIOS not ready */
pci_write_config_byte ( pdev , 0x5E , 0x01 ) ;
/* Set to bypass mode, and reset PCI bus */
pci_write_config_byte ( pdev , 0x50 , 0x00 ) ;
pci_write_config_word ( pdev , PCI_COMMAND ,
PCI_COMMAND_PARITY | PCI_COMMAND_IO |
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER ) ;
pci_write_config_word ( pdev , 0x40 , 0xA0F3 ) ;
pci_write_config_dword ( pdev , 0x4C , 0x02040204 ) ;
pci_write_config_byte ( pdev , 0x42 , 0x36 ) ;
pci_write_config_byte ( pdev , PCI_LATENCY_TIMER , 0x20 ) ;
}
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
static int it821x_init_one ( struct pci_dev * pdev , const struct pci_device_id * id )
{
u8 conf ;
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
static struct ata_port_info info_smart = {
. sht = & it821x_sht ,
. flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST ,
. pio_mask = 0x1f ,
. mwdma_mask = 0x07 ,
. port_ops = & it821x_smart_port_ops
} ;
static struct ata_port_info info_passthru = {
. sht = & it821x_sht ,
. flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST ,
. pio_mask = 0x1f ,
. mwdma_mask = 0x07 ,
. udma_mask = 0x7f ,
. port_ops = & it821x_passthru_port_ops
} ;
static struct ata_port_info * port_info [ 2 ] ;
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
static char * mode [ 2 ] = { " pass through " , " smart " } ;
/* Force the card into bypass mode if so requested */
if ( it8212_noraid ) {
printk ( KERN_INFO DRV_NAME " : forcing bypass mode. \n " ) ;
it821x_disable_raid ( pdev ) ;
}
pci_read_config_byte ( pdev , 0x50 , & conf ) ;
conf & = 1 ;
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
printk ( KERN_INFO DRV_NAME " : controller in %s mode. \n " , mode [ conf ] ) ;
if ( conf = = 0 )
port_info [ 0 ] = port_info [ 1 ] = & info_passthru ;
else
port_info [ 0 ] = port_info [ 1 ] = & info_smart ;
2006-08-31 08:03:49 +04:00
2006-08-30 02:12:40 +04:00
return ata_pci_init_one ( pdev , port_info , 2 ) ;
}
2006-11-27 19:14:36 +03:00
static int it821x_reinit_one ( struct pci_dev * pdev )
{
/* Resume - turn raid back off if need be */
if ( it8212_noraid )
it821x_disable_raid ( pdev ) ;
return ata_pci_device_resume ( pdev ) ;
}
2006-09-29 04:21:59 +04:00
static const struct pci_device_id it821x [ ] = {
{ PCI_VDEVICE ( ITE , PCI_DEVICE_ID_ITE_8211 ) , } ,
{ PCI_VDEVICE ( ITE , PCI_DEVICE_ID_ITE_8212 ) , } ,
{ } ,
2006-08-30 02:12:40 +04:00
} ;
static struct pci_driver it821x_pci_driver = {
2006-09-29 04:21:59 +04:00
. name = DRV_NAME ,
2006-08-30 02:12:40 +04:00
. id_table = it821x ,
. probe = it821x_init_one ,
2006-11-27 19:14:36 +03:00
. remove = ata_pci_remove_one ,
. suspend = ata_pci_device_suspend ,
. resume = it821x_reinit_one ,
2006-08-30 02:12:40 +04:00
} ;
static int __init it821x_init ( void )
{
return pci_register_driver ( & it821x_pci_driver ) ;
}
static void __exit it821x_exit ( void )
{
pci_unregister_driver ( & it821x_pci_driver ) ;
}
MODULE_AUTHOR ( " Alan Cox " ) ;
MODULE_DESCRIPTION ( " low-level driver for the IT8211/IT8212 IDE RAID controller " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_DEVICE_TABLE ( pci , it821x ) ;
MODULE_VERSION ( DRV_VERSION ) ;
module_param_named ( noraid , it8212_noraid , int , S_IRUGO ) ;
MODULE_PARM_DESC ( it8212_noraid , " Force card into bypass mode " ) ;
module_init ( it821x_init ) ;
module_exit ( it821x_exit ) ;