hpt374 support
PATCH 1/1 hpt374 support
Martin,
I've been carrying this diff for a month or two, learning more than I ever wanted to about IDE each time a new kernel comes out ;)
It is Andre's work, offered for 2.5 with his permission. It adds HPT374 support to hpt366.c.
It works for me [unlike hptraid..c and ataraid.c :(].
It has a problem with my 80 gigabyte Seagates - in UDMA133 mode, writes are inexplicably slow. I manually set UDMA100 and it flies.
drivers/ide/hpt366.c renamed from drivers/ide/hpt366.c~hpt374 +392 -75
@@ -40,6 +40,8 @@* Reset the hpt366 on error, reset on dma * Fix disabling Fast Interrupt hpt366. * Mike Waychison <[email protected]> +* +* 02 May 2002 - HPT374 support (Andre Hedrick <[email protected]>) */ #include <linux/config.h>
@@ -164,9 +166,8 @@ struct chipset_bus_clock_list_entry {* PIO. * 31 FIFO enable. */ -struct chipset_bus_clock_list_entry forty_base [] = { - - {XFER_UDMA_4 ,0x900fd943 }, +struct chipset_bus_clock_list_entry forty_base_hpt366[] = { + {XFER_UDMA_4 ,0x900fd943 }, {XFER_UDMA_3 ,0x900ad943 }, {XFER_UDMA_2 ,0x900bd943 }, {XFER_UDMA_1 ,0x9008d943 },
@@ -184,8 +185,7 @@ struct chipset_bus_clock_list_entry fort { 0, 0x0120d9d9 } }; -struct chipset_bus_clock_list_entry thirty_three_base [] = { - +struct chipset_bus_clock_list_entry thirty_three_base_hpt366[] = { {XFER_UDMA_4 ,0x90c9a731 }, {XFER_UDMA_3 ,0x90cfa731 }, {XFER_UDMA_2 ,0x90caa731 },
@@ -204,7 +204,7 @@ struct chipset_bus_clock_list_entry thir { 0, 0x0120a7a7 } }; -struct chipset_bus_clock_list_entry twenty_five_base [] = { +struct chipset_bus_clock_list_entry twenty_five_base_hpt366[] = { {XFER_UDMA_4 ,0x90c98521 }, {XFER_UDMA_3 ,0x90cf8521 },
@@ -329,6 +329,144 @@ struct chipset_bus_clock_list_entry fift { 0, 0x0ac1f48a } }; +struct chipset_bus_clock_list_entry thirty_three_base_hpt372[] = { + {XFER_UDMA_6 ,0x1c81dc62 }, + {XFER_UDMA_5 ,0x1c6ddc62 }, + {XFER_UDMA_4 ,0x1c8ddc62 }, + {XFER_UDMA_3 ,0x1c8edc62 },/* checkme */ + {XFER_UDMA_2 ,0x1c91dc62 }, + {XFER_UDMA_1 ,0x1c9adc62 },/* checkme */ + {XFER_UDMA_0 ,0x1c82dc62 },/* checkme */ + + {XFER_MW_DMA_2 ,0x2c829262 }, + {XFER_MW_DMA_1 ,0x2c829266 },/* checkme */ + {XFER_MW_DMA_0 ,0x2c82922e },/* checkme */ + + {XFER_PIO_4 ,0x0c829c62 }, + {XFER_PIO_3 ,0x0c829c84 }, + {XFER_PIO_2 ,0x0c829ca6 }, + {XFER_PIO_1 ,0x0d029d26 }, + {XFER_PIO_0 ,0x0d029d5e }, + {0 ,0x0d029d5e } +}; + +struct chipset_bus_clock_list_entry fifty_base_hpt372[] = { + {XFER_UDMA_5 ,0x12848242 }, + {XFER_UDMA_4 ,0x12ac8242 }, + {XFER_UDMA_3 ,0x128c8242 }, + {XFER_UDMA_2 ,0x120c8242 }, + {XFER_UDMA_1 ,0x12148254 }, + {XFER_UDMA_0 ,0x121882ea }, + + {XFER_MW_DMA_2 ,0x22808242 }, + {XFER_MW_DMA_1 ,0x22808254 }, + {XFER_MW_DMA_0 ,0x228082ea }, + + {XFER_PIO_4 ,0x0a81f442 }, + {XFER_PIO_3 ,0x0a81f443 }, + {XFER_PIO_2 ,0x0a81f454 }, + {XFER_PIO_1 ,0x0ac1f465 }, + {XFER_PIO_0 ,0x0ac1f48a }, + {0 ,0x0a81f443 } +}; + +struct chipset_bus_clock_list_entry sixty_six_base_hpt372[] = { + {XFER_UDMA_6 ,0x1c869c62 }, + {XFER_UDMA_5 ,0x1cae9c62 }, + {XFER_UDMA_4 ,0x1c8a9c62 }, + {XFER_UDMA_3 ,0x1c8e9c62 }, + {XFER_UDMA_2 ,0x1c929c62 }, + {XFER_UDMA_1 ,0x1c9a9c62 }, + {XFER_UDMA_0 ,0x1c829c62 }, + + {XFER_MW_DMA_2 ,0x2c829c62 }, + {XFER_MW_DMA_1 ,0x2c829c66 }, + {XFER_MW_DMA_0 ,0x2c829d2e }, + + {XFER_PIO_4 ,0x0c829c62 }, + {XFER_PIO_3 ,0x0c829c84 }, + {XFER_PIO_2 ,0x0c829ca6 }, + {XFER_PIO_1 ,0x0d029d26 }, + {XFER_PIO_0 ,0x0d029d5e }, + {0 ,0x0d029d26 } +}; + +struct chipset_bus_clock_list_entry thirty_three_base_hpt374[] = { + {XFER_UDMA_6 ,0x12808242 }, + {XFER_UDMA_5 ,0x12848242 }, + {XFER_UDMA_4 ,0x12ac8242 }, + {XFER_UDMA_3 ,0x128c8242 }, + {XFER_UDMA_2 ,0x120c8242 }, + {XFER_UDMA_1 ,0x12148254 }, + {XFER_UDMA_0 ,0x121882ea }, + + {XFER_MW_DMA_2 ,0x22808242 }, + {XFER_MW_DMA_1 ,0x22808254 }, + {XFER_MW_DMA_0 ,0x228082ea }, + + {XFER_PIO_4 ,0x0a81f442 }, + {XFER_PIO_3 ,0x0a81f443 }, + {XFER_PIO_2 ,0x0a81f454 }, + {XFER_PIO_1 ,0x0ac1f465 }, + {XFER_PIO_0 ,0x0ac1f48a }, + {0 ,0x06814e93 } +}; + +#if 0 +struct chipset_bus_clock_list_entry fifty_base_hpt374[] = { + {XFER_UDMA_6 , }, + {XFER_UDMA_5 , }, + {XFER_UDMA_4 , }, + {XFER_UDMA_3 , }, + {XFER_UDMA_2 , }, + {XFER_UDMA_1 , }, + {XFER_UDMA_0 , }, + {XFER_MW_DMA_2 , }, + {XFER_MW_DMA_1 , }, + {XFER_MW_DMA_0 , }, + {XFER_PIO_4 , }, + {XFER_PIO_3 , }, + {XFER_PIO_2 , }, + {XFER_PIO_1 , }, + {XFER_PIO_0 , }, + {0 , } +}; +#endif +#if 0 +struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = { + {XFER_UDMA_6 ,0x12406231 },/* checkme */ + {XFER_UDMA_5 ,0x12446231 }, + 0x14846231 + {XFER_UDMA_4 ,0x16814ea7 }, + 0x14886231 + {XFER_UDMA_3 ,0x16814ea7 }, + 0x148c6231 + {XFER_UDMA_2 ,0x16814ea7 }, + 0x148c6231 + {XFER_UDMA_1 ,0x16814ea7 }, + 0x14906231 + {XFER_UDMA_0 ,0x16814ea7 }, + 0x14986231 + {XFER_MW_DMA_2 ,0x16814ea7 }, + 0x26514e21 + {XFER_MW_DMA_1 ,0x16814ea7 }, + 0x26514e97 + {XFER_MW_DMA_0 ,0x16814ea7 }, + 0x26514e97 + {XFER_PIO_4 ,0x06814ea7 }, + 0x06514e21 + {XFER_PIO_3 ,0x06814ea7 }, + 0x06514e22 + {XFER_PIO_2 ,0x06814ea7 }, + 0x06514e33 + {XFER_PIO_1 ,0x06814ea7 }, + 0x06914e43 + {XFER_PIO_0 ,0x06814ea7 }, + 0x06914e57 + {0 ,0x06814ea7 } +}; +#endif +#define HPT366_DEBUG_DRIVE_INFO 0#define HPT370_ALLOW_ATA100_5 1#define HPT366_ALLOW_ATA66_4 1
@@ -345,6 +483,10 @@ static int n_hpt_devs;static unsigned int pci_rev_check_hpt3xx (struct pci_dev *dev);static unsigned int pci_rev2_check_hpt3xx (struct pci_dev *dev); +static unsigned int pci_rev3_check_hpt3xx (struct pci_dev *dev); +static unsigned int pci_rev5_check_hpt3xx (struct pci_dev *dev); +static unsigned int pci_rev7_check_hpt3xx (struct pci_dev *dev); +byte hpt366_proc =0 ;byte hpt363_shared_irq;byte hpt363_shared_pin;
@@ -357,11 +499,13 @@ extern int (*hpt366_display_info)(char *static int hpt366_get_info (char *buffer,char **addr,off_t offset,int count) {char *p = buffer; -char *chipset_nums[] = {"366" ,"366" ,"368" ,"370" ,"370A" }; +char *chipset_nums[] = {"366" ,"366" ,"368" , +"370" ,"370A" ,"372" , +"??" ,"374" };int i; p +=sprintf (p,"\n " -"HighPoint HPT366/368/370\n" ); +"HighPoint HPT366/368/370/372/374\n" );for (i =0 ; i < n_hpt_devs; i++) {struct pci_dev *dev = hpt_devs[i];unsigned short iobase = dev->resource[4 ].start;
@@ -386,7 +530,7 @@ static int hpt366_get_info (char *buffer (c0 &0x80 ) ?"no" :"yes" , (c1 & 0x80) ? "no" : "yes"); -if (pci_rev_check_hpt3xx (dev)) { +if (pci_rev3_check_hpt3xx (dev)) {u8 cbl; cbl =inb_p (iobase +0x7b );outb_p (cbl |1 , iobase +0x7b );
@@ -435,6 +579,10 @@ static int hpt366_get_info (char *buffer }#endif /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */ +/* +* fixme: it really needs to be a switch. +*/ +static unsigned int pci_rev_check_hpt3xx (struct pci_dev *dev) {unsigned int class_rev;
@@ -451,6 +599,30 @@ static unsigned int pci_rev2_check_hpt3xreturn ((int ) (class_rev >0x01 ) ?1 :0 ); } +static unsigned int pci_rev3_check_hpt3xx (struct pci_dev *dev) +{ +unsigned int class_rev; +pci_read_config_dword (dev,PCI_CLASS_REVISION , &class_rev); + class_rev &=0xff ; +return ((int ) (class_rev >0x02 ) ?1 :0 ); +} + +static unsigned int pci_rev5_check_hpt3xx (struct pci_dev *dev) +{ +unsigned int class_rev; +pci_read_config_dword (dev,PCI_CLASS_REVISION , &class_rev); + class_rev &=0xff ; +return ((int ) (class_rev >0x04 ) ?1 :0 ); +} + +static unsigned int pci_rev7_check_hpt3xx (struct pci_dev *dev) +{ +unsigned int class_rev; +pci_read_config_dword (dev,PCI_CLASS_REVISION , &class_rev); + class_rev &=0xff ; +return ((int ) (class_rev >0x06 ) ?1 :0 ); +} +static int check_in_drive_lists (ide_drive_t *drive,const char **list) {struct hd_driveid *id = drive->id;
@@ -482,6 +654,7 @@ static unsigned int pci_bus_clock_list (static void hpt366_tune_chipset (ide_drive_t *drive,byte speed) { +struct pci_dev *dev = drive->channel->pci_dev;byte regtime = (drive->select.b.unit &0x01 ) ?0x44 :0x40 ;byte regfast = (drive->channel->unit) ?0x55 :0x51 ;/*
@@ -495,30 +668,13 @@ static void hpt366_tune_chipset (ide_dri/* * Disable the "fast interrupt" prediction. */ -pci_read_config_byte (drive->channel->pci_dev, regfast, &drive_fast); +pci_read_config_byte (dev, regfast, &drive_fast);if (drive_fast &0x02 ) -pci_write_config_byte (drive->channel->pci_dev, regfast, drive_fast & ~0x20 ); +pci_write_config_byte (dev, regfast, drive_fast & ~0x20 ); -pci_read_config_dword (drive->channel->pci_dev, regtime, ®1); -/* detect bus speed by looking at control reg timing: */ -switch ((reg1 >>8 ) &7 ) { -case 5 : - reg2 =pci_bus_clock_list (speed, forty_base); -break ; -case 9 : - reg2 =pci_bus_clock_list (speed, twenty_five_base); -break ; -default : -case 7 : - reg2 =pci_bus_clock_list (speed, thirty_three_base); -break ; - } -#if 0 -/* this is a nice idea ... */ - list_conf =pci_bus_clock_list (speed, - (struct chipset_bus_clock_list_entry *) - dev->sysdata); -#endif +pci_read_config_dword (dev, regtime, ®1); + reg2 =pci_bus_clock_list (speed, + (struct chipset_bus_clock_list_entry *) dev->sysdata);/* * Disable on-chip PIO FIFO/buffer (to avoid problems handling I/O errors later) */
@@ -529,7 +685,12 @@ static void hpt366_tune_chipset (ide_dri } reg2 &= ~0x80000000 ; -pci_write_config_dword (drive->channel->pci_dev, regtime, reg2); +pci_write_config_dword (dev, regtime, reg2); +} + +static void hpt368_tune_chipset (ide_drive_t *drive,byte speed) +{ +hpt366_tune_chipset (drive, speed); }static void hpt370_tune_chipset (ide_drive_t *drive,byte speed)
@@ -575,6 +736,39 @@ static void hpt370_tune_chipset (ide_dripci_write_config_dword (dev, drive_pci, list_conf); } +static void hpt372_tune_chipset (ide_drive_t *drive,byte speed) +{ +byte regfast = (drive->channel->unit) ?0x55 :0x51 ; +unsigned int list_conf =0 ; +unsigned int drive_conf =0 ; +unsigned int conf_mask = (speed >=XFER_MW_DMA_0 ) ?0xc0000000 :0x30070000 ; +byte drive_pci =0x40 + (drive->dn *4 ); +byte drive_fast =0 ; +struct pci_dev *dev = drive->channel->pci_dev; + +/* +* Disable the "fast interrupt" prediction. +* don't holdoff on interrupts. (== 0x01 despite what the docs say) +*/ +pci_read_config_byte (dev, regfast, &drive_fast); + drive_fast &= ~0x07 ; +pci_write_config_byte (drive->channel->pci_dev, regfast, drive_fast); + + list_conf =pci_bus_clock_list (speed, + (struct chipset_bus_clock_list_entry *) + dev->sysdata); +pci_read_config_dword (dev, drive_pci, &drive_conf); + list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); +if (speed <XFER_MW_DMA_0 ) + list_conf &= ~0x80000000 ;/* Disable on-chip PIO FIFO/buffer */ +pci_write_config_dword (dev, drive_pci, list_conf); +} + +static void hpt374_tune_chipset (ide_drive_t *drive,byte speed) +{ +hpt372_tune_chipset (drive, speed); +} +static int hpt3xx_tune_chipset (ide_drive_t *drive,byte speed) {if ((drive->type !=ATA_DISK ) && (speed <XFER_SW_DMA_0 ))
@@ -583,9 +777,15 @@ static int hpt3xx_tune_chipset (ide_drivif (!drive->init_speed) drive->init_speed = speed; -if (pci_rev_check_hpt3xx (drive->channel->pci_dev)) { +if (pci_rev7_check_hpt3xx (drive->channel->pci_dev)) { +hpt374_tune_chipset (drive, speed); + }else if (pci_rev5_check_hpt3xx (drive->channel->pci_dev)) { +hpt372_tune_chipset (drive, speed); + }else if (pci_rev3_check_hpt3xx (drive->channel->pci_dev)) {hpt370_tune_chipset (drive, speed); - }else { + }else if (pci_rev2_check_hpt3xx (drive->channel->pci_dev)) { +hpt368_tune_chipset (drive, speed); + }else {hpt366_tune_chipset (drive, speed); } drive->current_speed = speed;
@@ -662,13 +862,21 @@ static int config_chipset_for_dma (ide_dbyte ultra66 =eighty_ninty_three (drive);int rval; +config_chipset_for_pio (drive); + drive->init_speed =0 ; +if ((drive->type !=ATA_DISK ) && (speed <XFER_SW_DMA_0 ))return ((int ) ide_dma_off_quietly); -if ((id->dma_ultra &0x0020 ) && +if ((id->dma_ultra &0x0040 ) && + (pci_rev5_check_hpt3xx (drive->channel->pci_dev)) && + (ultra66)) { + speed =XFER_UDMA_6 ; + }else if ((id->dma_ultra &0x0020 ) && (!check_in_drive_lists (drive, bad_ata100_5)) && (HPT370_ALLOW_ATA100_5 ) && (pci_rev_check_hpt3xx (drive->channel->pci_dev)) && + (pci_rev3_check_hpt3xx (drive->channel->pci_dev)) && (ultra66)) { speed =XFER_UDMA_5 ; } else if ((id->dma_ultra & 0x0010) &&
@@ -701,7 +909,8 @@ static int config_chipset_for_dma (ide_d (void )hpt3xx_tune_chipset (drive, speed); - rval = (int )( ((id->dma_ultra >>11 ) &7 ) ? ide_dma_on : + rval = (int )( ((id->dma_ultra >>14 ) &3 ) ? ide_dma_on : + ((id->dma_ultra >>11 ) &7 ) ? ide_dma_on : ((id->dma_ultra >>8 ) &7 ) ? ide_dma_on : ((id->dma_mword >>8 ) &7 ) ? ide_dma_on : ide_dma_off_quietly);
@@ -724,12 +933,14 @@ void hpt3xx_intrproc (ide_drive_t *drivevoid hpt3xx_maskproc (ide_drive_t *drive,int mask) { +struct pci_dev *dev = drive->channel->pci_dev; +if (drive->quirk_list) { -if (pci_rev_check_hpt3xx (drive->channel->pci_dev)) { +if (pci_rev3_check_hpt3xx (dev)) {byte reg5a =0 ; -pci_read_config_byte (drive->channel->pci_dev,0x5a , ®5a); +pci_read_config_byte (dev,0x5a , ®5a);if (((reg5a &0x10 ) >>4 ) != mask) -pci_write_config_byte (drive->channel->pci_dev,0x5a , mask ? (reg5a |0x10 ) : (reg5a & ~0x10 )); +pci_write_config_byte (dev,0x5a , mask ? (reg5a |0x10 ) : (reg5a & ~0x10 )); }else {if (mask) {disable_irq (drive->channel->irq);
@@ -756,7 +967,7 @@ static int config_drive_xfer_rate (ide_d } dma_func = ide_dma_off_quietly;if (id->field_valid &4 ) { -if (id->dma_ultra &0x002F ) { +if (id->dma_ultra &0x007F ) {/* Force if Capable UltraDMA */ dma_func =config_chipset_for_dma (drive); if ((id->field_valid & 2) &&
@@ -885,6 +1096,43 @@ int hpt370_dmaproc(ide_dma_action_t func }return ide_dmaproc (func, drive, rq);/* use standard DMA stuff */ } + +int hpt374_dmaproc (ide_dma_action_t func,ide_drive_t *drive,struct request *rq) +{ +struct pci_dev *dev = drive->channel->pci_dev; +struct ata_channel *hwif = drive->channel; +unsigned long dma_base = hwif->dma_base; +byte mscreg = hwif->unit ?0x54 :0x50 ; +// byte reginfo = hwif->unit ? 0x56 : 0x52; +byte dma_stat; + +switch (func) { +case ide_dma_check: +return config_drive_xfer_rate (drive); +case ide_dma_test_irq:/* returns 1 if dma irq issued, 0 otherwise */ + dma_stat =inb (dma_base+2 ); +#if 0 /* do not set unless you know what you are doing */ +if (dma_stat &4 ) { +byte stat =GET_STAT (); +outb (dma_base+2 , dma_stat &0xE4 ); + } +#endif +/* return 1 if INTR asserted */ +return (dma_stat &4 ) ==4 ; +case ide_dma_end: + { +byte bwsr_mask = hwif->unit ?0x02 :0x01 ; +byte bwsr_stat, msc_stat; +pci_read_config_byte (dev,0x6a , &bwsr_stat); +pci_read_config_byte (dev, mscreg, &msc_stat); +if ((bwsr_stat & bwsr_mask) == bwsr_mask) +pci_write_config_byte (dev, mscreg, msc_stat|0x30 ); + } +default : +break ; + } +return ide_dmaproc (func, drive, rq);/* use standard DMA stuff */ +}#endif /* CONFIG_BLK_DEV_IDEDMA */ /*
@@ -1004,7 +1252,7 @@ static int hpt370_busproc(ide_drive_t *return 0 ; } -static void __init init_hpt370 (struct pci_dev *dev) +static void __init init_hpt37x (struct pci_dev *dev) {int adjust, i;u16 freq;
@@ -1025,18 +1273,44 @@ static void __init init_hpt370(struct pc freq &=0x1FF ;if (freq <0x9c ) { pll =F_LOW_PCI_33 ; - dev->sysdata = (void *) thirty_three_base_hpt370; -printk ("HPT370: using 33MHz PCI clock\n" ); +if (pci_rev7_check_hpt3xx (dev)) { + dev->sysdata = (void *) thirty_three_base_hpt374; + }else if (pci_rev5_check_hpt3xx (dev)) { + dev->sysdata = (void *) thirty_three_base_hpt372; + }else if (dev->device ==PCI_DEVICE_ID_TTI_HPT372 ) { + dev->sysdata = (void *) thirty_three_base_hpt372; + }else { + dev->sysdata = (void *) thirty_three_base_hpt370; + } +printk ("HPT37X: using 33MHz PCI clock\n" ); }else if (freq <0xb0 ) { pll =F_LOW_PCI_40 ; }else if (freq <0xc8 ) { pll =F_LOW_PCI_50 ; - dev->sysdata = (void *) fifty_base_hpt370; -printk ("HPT370: using 50MHz PCI clock\n" ); +if (pci_rev7_check_hpt3xx (dev)) { +// dev->sysdata = (void *) fifty_base_hpt374; +BUG (); + }else if (pci_rev5_check_hpt3xx (dev)) { + dev->sysdata = (void *) fifty_base_hpt372; + }else if (dev->device ==PCI_DEVICE_ID_TTI_HPT372 ) { + dev->sysdata = (void *) fifty_base_hpt372; + }else { + dev->sysdata = (void *) fifty_base_hpt370; + } +printk ("HPT37X: using 50MHz PCI clock\n" ); }else { pll =F_LOW_PCI_66 ; - dev->sysdata = (void *) sixty_six_base_hpt370; -printk ("HPT370: using 66MHz PCI clock\n" ); +if (pci_rev7_check_hpt3xx (dev)) { +// dev->sysdata = (void *) sixty_six_base_hpt374; +BUG (); + }else if (pci_rev5_check_hpt3xx (dev)) { + dev->sysdata = (void *) sixty_six_base_hpt372; + }else if (dev->device ==PCI_DEVICE_ID_TTI_HPT372 ) { + dev->sysdata = (void *) sixty_six_base_hpt372; + }else { + dev->sysdata = (void *) sixty_six_base_hpt370; + } +printk ("HPT37X: using 66MHz PCI clock\n" ); }/*
@@ -1047,7 +1321,7 @@ static void __init init_hpt370(struct pc* on PRST/SRST when the HPT state engine gets reset. */ if (dev->sysdata) - goto init_hpt370_done; + goto init_hpt37X_done;/* * adjust PLL based upon PCI clock, enable it, and wait for
@@ -1074,9 +1348,18 @@ static void __init init_hpt370(struct pcpci_write_config_dword (dev,0x5c , pll & ~0x100 );pci_write_config_byte (dev,0x5b ,0x21 ); - dev->sysdata = (void *) fifty_base_hpt370; -printk ("HPT370: using 50MHz internal PLL\n" ); - goto init_hpt370_done; +if (pci_rev7_check_hpt3xx (dev)) { +// dev->sysdata = (void *) fifty_base_hpt374; +BUG (); + }else if (pci_rev5_check_hpt3xx (dev)) { + dev->sysdata = (void *) fifty_base_hpt372; + }else if (dev->device ==PCI_DEVICE_ID_TTI_HPT372 ) { + dev->sysdata = (void *) fifty_base_hpt372; + }else { + dev->sysdata = (void *) fifty_base_hpt370; + } +printk ("HPT37X: using 50MHz internal PLL\n" ); + goto init_hpt37X_done; } } pll_recal:
@@ -1086,13 +1369,41 @@ pll_recal: pll += (adjust >>1 ); } -init_hpt370_done: +init_hpt37X_done:/* reset state engine */ pci_write_config_byte (dev,0x50 ,0x37 );pci_write_config_byte (dev,0x54 ,0x37 );udelay (100 ); } +static void __init init_hpt366 (struct pci_dev *dev) +{ +unsigned int reg1 =0 ; +byte drive_fast =0 ; + +/* +* Disable the "fast interrupt" prediction. +*/ +pci_read_config_byte (dev,0x51 , &drive_fast); +if (drive_fast &0x80 ) +pci_write_config_byte (dev,0x51 , drive_fast & ~0x80 ); +pci_read_config_dword (dev,0x40 , ®1); + +/* detect bus speed by looking at control reg timing: */ +switch ((reg1 >>8 ) &7 ) { +case 5 : + dev->sysdata = (void *) forty_base_hpt366; +break ; +case 9 : + dev->sysdata = (void *) twenty_five_base_hpt366; +break ; +case 7 : +default : + dev->sysdata = (void *) thirty_three_base_hpt366; +break ; + } +} +unsigned int __init pci_init_hpt366 (struct pci_dev *dev) {byte test =0 ;
@@ -1116,8 +1427,10 @@ unsigned int __init pci_init_hpt366(struif (test !=0x08 )pci_write_config_byte (dev,PCI_MAX_LAT ,0x08 ); -if (pci_rev_check_hpt3xx (dev)) -init_hpt370 (dev); +if (pci_rev3_check_hpt3xx (dev)) +init_hpt37x (dev); +else +init_hpt366 (dev);if (n_hpt_devs <HPT366_MAX_DEVS ) hpt_devs[n_hpt_devs++] = dev;
@@ -1148,8 +1461,6 @@ unsigned int __init ata66_hpt366(structvoid __init ide_init_hpt366 (struct ata_channel *hwif) { -int hpt_rev; - hwif->tuneproc = &hpt3xx_tune_drive; hwif->speedproc = &hpt3xx_tune_chipset; hwif->quirkproc = &hpt3xx_quirkproc;
@@ -1162,32 +1473,38 @@ void __init ide_init_hpt366(struct ata_c hwif->serialized = hwif->mate->serialized =1 ;#endif - hpt_rev =pci_rev_check_hpt3xx (hwif->pci_dev); -if (hpt_rev) { -/* set up ioctl for power status. note: power affects both -* drives on each channel */ - hwif->busproc = &hpt370_busproc; - } - -if (pci_rev2_check_hpt3xx (hwif->pci_dev)) { -/* do nothing now but will split device types */ - hwif->resetproc = &hpt3xx_reset; -/* -* don't do until we can parse out the cobalt box argh ... -* hwif->busproc = &hpt3xx_tristate; -*/ - } -#ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { -if (hpt_rev) { +if (pci_rev3_check_hpt3xx (hwif->pci_dev)) {byte reg5ah =0 ;pci_read_config_byte (hwif->pci_dev,0x5a , ®5ah);if (reg5ah &0x10 )/* interrupt force enable */ pci_write_config_byte (hwif->pci_dev,0x5a , reg5ah & ~0x10 ); - hwif->udma = hpt370_dmaproc; +/* +* set up ioctl for power status. +* note: power affects both +* drives on each channel +*/ + hwif->resetproc = &hpt3xx_reset; + hwif->busproc = &hpt370_busproc; + +if (pci_rev7_check_hpt3xx (hwif->pci_dev)) { + hwif->udma = &hpt374_dmaproc; + }else if (pci_rev5_check_hpt3xx (hwif->pci_dev)) { + hwif->udma = &hpt374_dmaproc; + }else if (hwif->pci_dev->device ==PCI_DEVICE_ID_TTI_HPT372 ) { + hwif->udma = &hpt374_dmaproc; + }else if (pci_rev3_check_hpt3xx (hwif->pci_dev)) { + hwif->udma = &hpt370_dmaproc; + } + }else if (pci_rev2_check_hpt3xx (hwif->pci_dev)) { +// hwif->resetproc = &hpt3xx_reset; +// hwif->busproc = &hpt3xx_tristate; + hwif->udma = &hpt366_dmaproc; }else { - hwif->udma = hpt366_dmaproc; +// hwif->resetproc = &hpt3xx_reset; +// hwif->busproc = &hpt3xx_tristate; + hwif->udma = &hpt366_dmaproc; }if (!noautodma) hwif->autodma =1 ;
include/linux/pci_ids.h renamed from include/linux/pci_ids.h~hpt374 +2 -0
@@ -932,6 +932,8 @@#define PCI_VENDOR_ID_TTI 0x1103#define PCI_DEVICE_ID_TTI_HPT343 0x0003#define PCI_DEVICE_ID_TTI_HPT366 0x0004 +#define PCI_DEVICE_ID_TTI_HPT372 0x0005 +#define PCI_DEVICE_ID_TTI_HPT374 0x0008#define PCI_VENDOR_ID_VIA 0x1106#define PCI_DEVICE_ID_VIA_8363_0 0x0305
drivers/ide/ide-pci.c renamed from drivers/ide/ide-pci.c~hpt374 +52 -2
84 lines not on this page · raw message
-
Hi Andrew,
could you add something like the following patch to make it better visible to users which chipsets are supported (I'm not sure whether the two lines I suggest in drivers/ide/Config.help are correct but I hope you understand the idea)?
ide/Config.in renamed from ide/Config.in.old +1 -1
@@ -63,7 +63,7 @@ dep_bool ' Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X $CONFIG_BLK_DEV_IDEDMA_PCI dep_mbool ' HPT34X AUTODMA support (EXPERMENTAL)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_EXPERIMENTAL - dep_bool ' HPT366 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI + dep_bool ' HPT36X/37X chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Intel and Efar (SMsC) chipset support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI if [ "$CONFIG_BLK_DEV_PIIX" = "y" ]; then dep_bool ' Use UDMA133 even on ICH2, ICH3 and CICH chips (EXPERIMENTAL)' CONFIG_BLK_DEV_PIIX_TRY133 $CONFIG_EXPERIMENTAL
ide/Config.help renamed from ide/Config.help.old +2 -0
@@ -388,6 +388,8 @@ HPT366 is an Ultra DMA chipset for ATA-66. HPT368 is an Ultra DMA chipset for ATA-66 RAID Based. HPT370 is an Ultra DMA chipset for ATA-100. + HPT372 is an Ultra DMA chipset for ATA-100. + HPT374 is an Ultra DMA chipset for ATA-100. This driver adds up to 4 more EIDE devices sharing a single interrupt.
TIA
Adrian
Signature · 3 lines
You only think this is a free country. Like the US the UK spends a lot of time explaining its a free country because its a police state. Alan Cox