libata-dev-2.6: pdc2027x PLL input clock detection fix, etc.
cover libata-dev-2.6: pdc2027x PLL input clock detection fix, etc.
Hi Jeff,
pdc2027x PLL input clock detection fix, etc. for your review.
Desc:
- Patch 1/4 and 2/4 are minor fixes.
- Patch 3/4 move the PLL counter reading code to a separate function.
- Patch 4/4 fix the PLL input clock detection problem.
Albert
PATCH 1/4 libata-dev-2.6: pdc2027x add ata_scsi_ioctl
Hi Jeff,
Change:
pdc2027x: add ata_scsi_ioctl.
Attached please find the patch 1/4 against the libata-dev-2.6 tree for your review. Thanks.
Albert
drivers/scsi/pata_pdc2027x.c +3 -1
@@ -29,7 +29,7 @@#include <asm/io.h> #define DRV_NAME "pata_pdc2027x" -#define DRV_VERSION "0.57" +#define DRV_VERSION "0.58"#undef PDC_DEBUG#ifdef PDC_DEBUG
@@ -115,6 +115,7 @@static Scsi_Host_Template pdc2027x_sht = { .module =THIS_MODULE , .name =DRV_NAME , + .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, .eh_strategy_handler = ata_scsi_error, .can_queue =ATA_DEF_QUEUE ,
@@ -450,6 +451,7 @@if (cmd->request_bufflen %256 ) rc =1 ; +PDPRINTK ("request_bufflen %d, rc %d\n" , cmd->request_bufflen, rc);return rc; }
Re: [PATCH 1/4] libata-dev-2.6: pdc2027x add ata_scsi_ioctl
applied patches 1-4
PATCH 2/4 libata-dev-2.6: pdc2027x change comments
In reply to Albert LeeHi Jeff,
Change:
pdc2027x: change comments, indent, etc.
Attached please find the patch 2/4 against the libata-dev-2.6 tree for your review. Thanks.
Albert
drivers/scsi/pata_pdc2027x.c +15 -16
@@ -29,11 +29,11 @@#include <asm/io.h> #define DRV_NAME "pata_pdc2027x" -#define DRV_VERSION "0.58" +#define DRV_VERSION "0.59"#undef PDC_DEBUG#ifdef PDC_DEBUG -#define PDPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__, ## args) +#define PDPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)#else #define PDPRINTK(fmt, args...)#endif
@@ -217,8 +217,8 @@MODULE_DEVICE_TABLE (pci, pdc2027x_pci_tbl);/** -* pdc_get_indexed_reg - Set pdc202xx extended register -* @ap: Port to which the extended register is set +* pdc_get_indexed_reg - Get pdc202xx extended register +* @ap: Port to get the extended register * @index: index of the extended register */ static u8 pdc_get_indexed_reg (struct ata_port *ap,u8 index)
@@ -232,8 +232,8 @@return tmp8; }/** -* pdc_set_indexed_reg - Read pdc202xx extended register -* @ap: Port to which the extended register is read +* pdc_set_indexed_reg - Set pdc202xx extended register +* @ap: Port to set the extended register * @index: index of the extended register */ static void pdc_set_indexed_reg (struct ata_port *ap,u8 index,u8 value)
@@ -322,7 +322,7 @@PDPRINTK ("adev->pio_mode[%X]\n" , adev->pio_mode);/* Sanity check */ -if (pio >4 ) { +if (pio >4 ) { printk(KERN_ERR DRV_NAME ": Unknown pio mode [%d] ignored\n", pio);return ;
@@ -357,7 +357,7 @@u8 adj = (drive_dn%2 ) ?0x08 :0x00 ;u8 tmp8; -if ((dma_mode >=XFER_UDMA_0 ) && +if ((dma_mode >=XFER_UDMA_0 ) && (dma_mode <=XFER_UDMA_6 )) {/* Set the UDMA timing registers with value table for 133MHz */ unsigned int udma_mode = dma_mode &0x07 ;
@@ -380,7 +380,7 @@PDPRINTK ("Set to udma mode[%u] \n" , udma_mode); - }else if ((dma_mode >=XFER_MW_DMA_0 ) && + }else if ((dma_mode >=XFER_MW_DMA_0 ) && (dma_mode <=XFER_MW_DMA_2 )) {/* Set the MDMA timing registers with value table for 133MHz */ unsigned int mdma_mode = dma_mode &0x07 ;
@@ -451,7 +451,6 @@if (cmd->request_bufflen %256 ) rc =1 ; -PDPRINTK ("request_bufflen %d, rc %d\n" , cmd->request_bufflen, rc);return rc; }
@@ -496,16 +495,16 @@* Calculate the ratio of F, R and OD * POUT = (F + 2) / (( R + 2) * NO) */ -if (ratio <8600L ) {// 8.6x +if (ratio <8600L ) {/* 8.6x */ /* Using NO = 0x01, R = 0x0D */ R =0x0d ; - }else if (ratio <12900L ) {// 12.9x + }else if (ratio <12900L ) {/* 12.9x */ /* Using NO = 0x01, R = 0x08 */ R =0x08 ; - }else if (ratio <16100L ) {// 16.1x + }else if (ratio <16100L ) {/* 16.1x */ /* Using NO = 0x01, R = 0x06 */ R =0x06 ; - }else if (ratio <64000L ) {// 64x + }else if (ratio <64000L ) {/* 64x */ R =0x00 ; }else {/* Invalid ratio */
@@ -639,7 +638,7 @@*/ pll_clock =pdc_detect_pll_input_clock (pe); -if (pll_clock <0 )/* counter overflow? Try again. */ +if (pll_clock <0 )/* counter overflow? Try again. */ pll_clock =pdc_detect_pll_input_clock (pe); printk(KERN_INFO DRV_NAME ": PLL input clock %ld kHz\n", pll_clock/1000);
@@ -727,7 +726,7 @@//pci_enable_intx(pdev); /* initialize adapter */ -if (pdc_hardware_init (pdev, probe_ent, board_idx) !=0 ) +if (pdc_hardware_init (pdev, probe_ent, board_idx) !=0 ) goto err_out_free_ent;ata_device_add (probe_ent);
PATCH 3/4 libata-dev-2.6: pdc2027x move the PLL counter reading code
In reply to Albert LeeHi Jeff,
Change:
pdc2027x: move the PLL counter reading code to a separate function.
Attached please find the patch 3/4 against the libata-dev-2.6 tree for your review. Thanks.
Albert
drivers/scsi/pata_pdc2027x.c +30 -31
@@ -455,6 +455,33 @@ }/** +* pdc_read_counter - Read the ctr counter +* @probe_ent: for the port address +*/ + +static unsigned long pdc_read_counter (struct ata_probe_ent *probe_ent) +{ +u8 ctr0, ctr1, ctr2, ctr3; +unsigned long counter; + +outb (0x20 , probe_ent->port[0 ].bmdma_addr +0x01 ); + ctr0 =inb (probe_ent->port[0 ].bmdma_addr +0x03 ); +outb (0x21 , probe_ent->port[0 ].bmdma_addr +0x01 ); + ctr1 =inb (probe_ent->port[0 ].bmdma_addr +0x03 ); +outb (0x20 , probe_ent->port[1 ].bmdma_addr +0x01 ); + ctr2 =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); +outb (0x21 , probe_ent->port[1 ].bmdma_addr +0x01 ); + ctr3 =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); + + counter = (ctr3 <<23 ) | (ctr2 <<15 ) | (ctr1 <<8 ) | ctr0; + +PDPRINTK ("ctr0[%X] ctr1[%X] ctr2[%X] ctr3[%X]\n" , + ctr0, ctr1, ctr2, ctr3); + +return counter; +} + +/** * adjust_pll - Adjust the PLL input clock in Hz. * * @pdc_controller: controller specific information
@@ -550,6 +577,7 @@return ; } +/** * detect_pll_input_clock - Detect the PLL input clock in Hz. * @probe_ent: for the port address
@@ -559,28 +587,11 @@static long pdc_detect_pll_input_clock (struct ata_probe_ent *probe_ent) {u8 scr1; -unsigned long ctr0; -unsigned long ctr1; -unsigned long ctr2 =0 ; -unsigned long ctr3 =0 ; -unsigned long start_count, end_count;long pll_clock;/* Read current counter value */ -outb (0x20 , probe_ent->port[0 ].bmdma_addr +0x01 ); - ctr0 =inb (probe_ent->port[0 ].bmdma_addr +0x03 ); -outb (0x21 , probe_ent->port[0 ].bmdma_addr +0x01 ); - ctr1 =inb (probe_ent->port[0 ].bmdma_addr +0x03 ); - -outb (0x20 , probe_ent->port[1 ].bmdma_addr +0x01 ); - ctr2 =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); -outb (0x21 , probe_ent->port[1 ].bmdma_addr +0x01 ); - ctr3 =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); - - start_count = (ctr3 <<23 ) | (ctr2 <<15 ) | (ctr1 <<8 ) | ctr0; - -PDPRINTK ("ctr0[%lX] ctr1[%lX] ctr2 [%lX] ctr3 [%lX]\n" , ctr0, ctr1, ctr2, ctr3); + start_count =pdc_read_counter (probe_ent);/* Start the test mode */ outb (0x01 , probe_ent->port[0 ].bmdma_addr +0x01 );
@@ -592,19 +603,7 @@udelay (1000 );/* Read the counter values again */ -outb (0x20 , probe_ent->port[0 ].bmdma_addr +0x01 ); - ctr0 =inb (probe_ent->port[0 ].bmdma_addr +0x03 ); -outb (0x21 , probe_ent->port[0 ].bmdma_addr +0x01 ); - ctr1 =inb (probe_ent->port[0 ].bmdma_addr +0x03 ); - -outb (0x20 , probe_ent->port[1 ].bmdma_addr +0x01 ); - ctr2 =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); -outb (0x21 , probe_ent->port[1 ].bmdma_addr +0x01 ); - ctr3 =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); - - end_count = (ctr3 <<23 ) | (ctr2 <<15 ) | (ctr1 <<8 ) | ctr0; - -PDPRINTK ("ctr0[%lX] ctr1[%lX] ctr2 [%lX] ctr3 [%lX]\n" , ctr0, ctr1, ctr2, ctr3); + end_count =pdc_read_counter (probe_ent);/* Stop the test mode */ outb (0x01 , probe_ent->port[0 ].bmdma_addr +0x01 );
Hi Jeff,
Desc:
pdc2027x: fix the PLL input clock detection problem:
Sometimes the pdc2027x driver reads incorrect value from the counter and initialize the hardware with incorrect clock rate.
Root Cause:
- The PLL input clock counter on the pdc2027x is a 30-bit deceasing counter. The driver reads the decreasing counter byte by byte and assemsble back the whole 30-bit counter when detecting the PLL input clock rate on the fly.
- The driver reads the counter from LSB then MSB, byte by byte. For example, for 7D030093, the driver read 93, 00, 03 and 7D, piece by piece. (This is pdc2027x hardware limitation.)
- The counter is running when the driver reads it.
Ex. When 7D030093 decreasing to 7D027FFF, sometimes the driver will read 7D020093. That is, when the driver read LSB, LSB 0093 is quite close to zero. Later when the driver read MSB, MSB is already changed from 7D03 to 7D02. => The driver assembles the wrong bytes and gets 7D020093.
Changes:
- Verify whether the driver is reading while the MSB bits of the counter is changing. If yes, reread the counter. (Incorrect LSB bits only affect the result by less than 5% under 100ms delay time and can be ignored.)
- Change the delay time from 1ms to 100ms. This can make the detected clock rate more accurate. The extra time spent on rereading the counter is less than 1% compared to 100ms.
Attached please find the patch 4/4 against the libata-dev-2.6 tree for your review. Thanks.
Albert
drivers/scsi/pata_pdc2027x.c +29 -4
@@ -29,7 +29,7 @@#include <asm/io.h> #define DRV_NAME "pata_pdc2027x" -#define DRV_VERSION "0.59" +#define DRV_VERSION "0.60"#undef PDC_DEBUG#ifdef PDC_DEBUG
@@ -463,7 +463,10 @@ {u8 ctr0, ctr1, ctr2, ctr3;unsigned long counter; +u8 ctr0v, ctr1v, ctr2v, ctr3v; +int retry =1 ; +retry:outb (0x20 , probe_ent->port[0 ].bmdma_addr +0x01 ); ctr0 =inb (probe_ent->port[0 ].bmdma_addr +0x03 );outb (0x21 , probe_ent->port[0 ].bmdma_addr +0x01 );
@@ -473,10 +476,32 @@outb (0x21 , probe_ent->port[1 ].bmdma_addr +0x01 ); ctr3 =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); +/* Read the counter values again for verification */ +outb (0x20 , probe_ent->port[0 ].bmdma_addr +0x01 ); + ctr0v =inb (probe_ent->port[0 ].bmdma_addr +0x03 ); +outb (0x21 , probe_ent->port[0 ].bmdma_addr +0x01 ); + ctr1v =inb (probe_ent->port[0 ].bmdma_addr +0x03 ); +outb (0x20 , probe_ent->port[1 ].bmdma_addr +0x01 ); + ctr2v =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); +outb (0x21 , probe_ent->port[1 ].bmdma_addr +0x01 ); + ctr3v =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); + counter = (ctr3 <<23 ) | (ctr2 <<15 ) | (ctr1 <<8 ) | ctr0;PDPRINTK ("ctr0[%X] ctr1[%X] ctr2[%X] ctr3[%X]\n" , ctr0, ctr1, ctr2, ctr3); +PDPRINTK ("ctr0[%X] ctr1[%X] ctr2[%X] ctr3[%X]\n" , + ctr0v, ctr1v, ctr2v, ctr3v); + +/* +* The 30-bit decreasing counter are read by 4 pieces. +* Incorrect value may be read when ctr2 and ctr3 are changing. +*/ +if (retry && !(ctr3 == ctr3v && ctr2 == ctr2v && ctr1 >= ctr1v)) { + retry--; +PDPRINTK ("rereading counter\n" ); + goto retry; + }return counter; }
@@ -599,8 +624,8 @@PDPRINTK ("scr1[%X]\n" , scr1);outb (scr1 |0x40 , probe_ent->port[0 ].bmdma_addr +0x03 ); -/* Let the counter run for 1000 us. */ -udelay (1000 ); +/* Let the counter run for 100 ms. */ +mdelay (100 );/* Read the counter values again */ end_count =pdc_read_counter (probe_ent);
@@ -612,7 +637,7 @@outb (scr1 &0xBF , probe_ent->port[0 ].bmdma_addr +0x03 );/* calculate the input clock in Hz */ - pll_clock = (long ) ((start_count - end_count) *1000 ); + pll_clock = (long ) ((start_count - end_count) *10 );PDPRINTK ("start[%lu] end[%lu] \n" , start_count, end_count);PDPRINTK ("PLL input clock[%ld]Hz\n" , pll_clock);
PATCH 4/4 libata-dev-2.6: pdc2027x PLL input clock detection fix
In reply to Albert LeeHi Jeff,
Desc:
pdc2027x: fix the PLL input clock detection problem:
Sometimes the pdc2027x driver reads incorrect value from the counter and initialize the hardware with incorrect clock rate.
Root Cause:
- The PLL input clock counter on the pdc2027x is a 30-bit deceasing counter. The driver reads the decreasing counter byte by byte and assemsble back the whole 30-bit counter when detecting the PLL input clock rate on the fly.
- The driver reads the counter from LSB then MSB, byte by byte. For example, for 7D030093, the driver read 93, 00, 03 and 7D, piece by piece. (This is pdc2027x hardware limitation.)
- The counter is running when the driver reads it.
Ex. When 7D030093 decreasing to 7D027FFF, sometimes the driver will read 7D020093. That is, when the driver read LSB, LSB 0093 is quite close to zero. Later when the driver read MSB, MSB is already changed from 7D03 to 7D02. => The driver assembles the wrong bytes and gets 7D020093.
Changes:
- Verify whether the driver is reading while the MSB bits of the counter is changing. If yes, reread the counter. (Incorrect LSB bits only affect the result by less than 5% under 100ms delay time and can be ignored.)
- Change the delay time from 1ms to 100ms. This can make the detected clock rate more accurate. The extra time spent on rereading the counter is less than 1% compared to 100ms.
Attached please find the patch 4/4 against the libata-dev-2.6 tree for your review. Thanks.
Albert
drivers/scsi/pata_pdc2027x.c +29 -4
@@ -29,7 +29,7 @@#include <asm/io.h> #define DRV_NAME "pata_pdc2027x" -#define DRV_VERSION "0.59" +#define DRV_VERSION "0.60"#undef PDC_DEBUG#ifdef PDC_DEBUG
@@ -463,7 +463,10 @@ {u8 ctr0, ctr1, ctr2, ctr3;unsigned long counter; +u8 ctr0v, ctr1v, ctr2v, ctr3v; +int retry =1 ; +retry:outb (0x20 , probe_ent->port[0 ].bmdma_addr +0x01 ); ctr0 =inb (probe_ent->port[0 ].bmdma_addr +0x03 );outb (0x21 , probe_ent->port[0 ].bmdma_addr +0x01 );
@@ -473,10 +476,32 @@outb (0x21 , probe_ent->port[1 ].bmdma_addr +0x01 ); ctr3 =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); +/* Read the counter values again for verification */ +outb (0x20 , probe_ent->port[0 ].bmdma_addr +0x01 ); + ctr0v =inb (probe_ent->port[0 ].bmdma_addr +0x03 ); +outb (0x21 , probe_ent->port[0 ].bmdma_addr +0x01 ); + ctr1v =inb (probe_ent->port[0 ].bmdma_addr +0x03 ); +outb (0x20 , probe_ent->port[1 ].bmdma_addr +0x01 ); + ctr2v =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); +outb (0x21 , probe_ent->port[1 ].bmdma_addr +0x01 ); + ctr3v =inb (probe_ent->port[1 ].bmdma_addr +0x03 ); + counter = (ctr3 <<23 ) | (ctr2 <<15 ) | (ctr1 <<8 ) | ctr0;PDPRINTK ("ctr0[%X] ctr1[%X] ctr2[%X] ctr3[%X]\n" , ctr0, ctr1, ctr2, ctr3); +PDPRINTK ("ctr0[%X] ctr1[%X] ctr2[%X] ctr3[%X]\n" , + ctr0v, ctr1v, ctr2v, ctr3v); + +/* +* The 30-bit decreasing counter are read by 4 pieces. +* Incorrect value may be read when ctr2 and ctr3 are changing. +*/ +if (retry && !(ctr3 == ctr3v && ctr2 == ctr2v && ctr1 >= ctr1v)) { + retry--; +PDPRINTK ("rereading counter\n" ); + goto retry; + }return counter; }
@@ -599,8 +624,8 @@PDPRINTK ("scr1[%X]\n" , scr1);outb (scr1 |0x40 , probe_ent->port[0 ].bmdma_addr +0x03 ); -/* Let the counter run for 1000 us. */ -udelay (1000 ); +/* Let the counter run for 100 ms. */ +mdelay (100 );/* Read the counter values again */ end_count =pdc_read_counter (probe_ent);
@@ -612,7 +637,7 @@outb (scr1 &0xBF , probe_ent->port[0 ].bmdma_addr +0x03 );/* calculate the input clock in Hz */ - pll_clock = (long ) ((start_count - end_count) *1000 ); + pll_clock = (long ) ((start_count - end_count) *10 );PDPRINTK ("start[%lu] end[%lu] \n" , start_count, end_count);PDPRINTK ("PLL input clock[%ld]Hz\n" , pll_clock);
Re: [PATCH 2.6.12-rc2 0/2] libata: add reporting of atapi errors
In reply to Albert LeeHello Jeff,
Simple ATAPI error reporting for your review.
Description:
Patch 1/2 is a simple fix to add a missing read of the error register when the task file is read. Patch 2/2 reads the error register if there is an error on a ATAPI device and builds a simple SCSI sense block.
73 Eric [email protected]
PATCH 1/1 libata-dev-2.6: pdc2027x ATAPI DMA fix
In reply to Albert LeeJeff,
pdc2027x: pdc2027x ATAPI DMA fix.
The previous (request_bufflen % 256) ATAPI DMA rule still fails and causes timeout in some case.
Changes:
- Only turn on pdc2027x ATAPI DMA for READ/WRITE and (request_bufflen % 1024 == 0) for safty.
Attached please find the patch against the libata-dev-2.6 tree for your review. Thanks.
Albert
drivers/scsi/pata_pdc2027x.c +20 -5
@@ -29,7 +29,7 @@#include <asm/io.h> #define DRV_NAME "pata_pdc2027x" -#define DRV_VERSION "0.60" +#define DRV_VERSION "0.61"#undef PDC_DEBUG#ifdef PDC_DEBUG
@@ -445,11 +445,26 @@static int pdc2027x_check_atapi_dma (struct ata_queued_cmd *qc) {struct scsi_cmnd *cmd = qc->scsicmd; -int rc =0 ; +u8 *scsicmd = cmd->cmnd; +int rc =1 ;/* atapi dma off by default */ -/* pdc2027x can only do ATAPI DMA for specific buffer size */ -if (cmd->request_bufflen %256 ) - rc =1 ; +switch (scsicmd[0 ]) { +case READ_6 : +case READ_10 : +case READ_12 : +case READ_16 : + +case WRITE_6 : +case WRITE_10 : +case WRITE_12 : +case WRITE_16 : +/* pdc2027x can only do ATAPI DMA for specific buffer size */ +if (cmd->request_bufflen %1024 ==0 ) + rc =0 ; +break ; +default : + ; + }return rc; }
Re: [PATCH 1/1] libata-dev-2.6: pdc2027x ATAPI DMA fix
Hi Jeff,
Revised pdc2027x: pdc2027x ATAPI DMA fix.
(Please ignore the previous patch.)
Problem:
The previous (request_bufflen % 256) ATAPI DMA rule still fails and causes timeout in some case.
Changes:
- Only turn on pdc2027x ATAPI DMA for READ/WRITE.
The additional (request_bufflen % 1024 == 0) check in the previous patch is not necessary. Since most ATAPI devices has 512 bytes or 2048 bytes sector size, it should be safe for ATAPI DMA. Thanks Jens for the advice.
Attached please find the revised patch against the libata-dev-2.6 tree for your review. Thanks.
Albert
drivers/scsi/pata_pdc2027x.c renamed from drivers/scsi/pata_pdc2027x.c.ori +18 -5
@@ -29,7 +29,7 @@#include <asm/io.h> #define DRV_NAME "pata_pdc2027x" -#define DRV_VERSION "0.60" +#define DRV_VERSION "0.61"#undef PDC_DEBUG#ifdef PDC_DEBUG
@@ -445,11 +445,24 @@static int pdc2027x_check_atapi_dma (struct ata_queued_cmd *qc) {struct scsi_cmnd *cmd = qc->scsicmd; -int rc =0 ; +u8 *scsicmd = cmd->cmnd; +int rc =1 ;/* atapi dma off by default */ -/* pdc2027x can only do ATAPI DMA for specific buffer size */ -if (cmd->request_bufflen %256 ) - rc =1 ; +switch (scsicmd[0 ]) { +case READ_6 : +case READ_10 : +case READ_12 : +case READ_16 : + +case WRITE_6 : +case WRITE_10 : +case WRITE_12 : +case WRITE_16 : + rc =0 ; +break ; +default : + ; + }return rc; }
PATCH 1/1 libata-dev-2.6: pdc2027x yet another PLL fix
Hi Jeff,
Yet another pdc2027x PLL fix.
Problem:
The mdelay(100) does not delay exactly 100 ms on power5 machines
with the CPU micro-partitioning feature turned on.
Changes:
- Change the "unsigned long" counter data type to "long". (Since the counter value is only 30-bit, "long" should be enough.)
- Add do_gettimeofday() to measure the elapsed time.
Patch tested OK on power4, power5 and x86 machines. (According to the document, do_gettimeofday() works on most platforms except some old M68K machines. There are no PCI slots on those machines, using do_gettimeofday() seems to be safe here.)
Attached please find the patch against the libata-dev-2.6 tree for your review. Thanks.
Albert
drivers/scsi/pata_pdc2027x.c +11 -6
@@ -29,7 +29,7 @@#include <asm/io.h> #define DRV_NAME "pata_pdc2027x" -#define DRV_VERSION "0.61" +#define DRV_VERSION "0.62"#undef PDC_DEBUG#ifdef PDC_DEBUG
@@ -472,10 +472,10 @@* @probe_ent: for the port address */ -static unsigned long pdc_read_counter (struct ata_probe_ent *probe_ent) +static long pdc_read_counter (struct ata_probe_ent *probe_ent) {u8 ctr0, ctr1, ctr2, ctr3; -unsigned long counter; +long counter;u8 ctr0v, ctr1v, ctr2v, ctr3v;int retry =1 ;
@@ -625,11 +625,13 @@static long pdc_detect_pll_input_clock (struct ata_probe_ent *probe_ent) {u8 scr1; -unsigned long start_count, end_count; -long pll_clock; +long start_count, end_count; +struct timeval start_time, end_time; +long pll_clock, usec_elapsed;/* Read current counter value */ start_count =pdc_read_counter (probe_ent); +do_gettimeofday (&start_time);/* Start the test mode */ outb (0x01 , probe_ent->port[0 ].bmdma_addr +0x01 );
@@ -642,6 +644,7 @@/* Read the counter values again */ end_count =pdc_read_counter (probe_ent); +do_gettimeofday (&end_time);/* Stop the test mode */ outb (0x01 , probe_ent->port[0 ].bmdma_addr +0x01 );
@@ -650,7 +653,9 @@outb (scr1 &0xBF , probe_ent->port[0 ].bmdma_addr +0x03 );/* calculate the input clock in Hz */ - pll_clock = (long ) ((start_count - end_count) *10 ); + usec_elapsed = (end_time.tv_sec - start_time.tv_sec) *1000000 + + (end_time.tv_usec - start_time.tv_usec); + pll_clock = (start_count - end_count) /100 * (100000000 / usec_elapsed);PDPRINTK ("start[%lu] end[%lu] \n" , start_count, end_count);PDPRINTK ("PLL input clock[%ld]Hz\n" , pll_clock);