2010-03-22 18:18:04 pata_pcmcia CompactFLASH load error
Doug Bailey (UNITED STATES)
Message: 87593
I am running the 2009R1.1-RC4 tag distro on a BF537 based board. Configured on
this board is a pcmcia slot used for interfacing a compactflash drive. I am
using the blackfin pcmcia adapter and the pata_pcmcia driver with ATA SFF
support for the device drivers. I am building these devices as loadable modules.
I have a situation where occasionally the compact flash card is not
recognized by the pata_pcmcia driver.when the driver is loading. I have tracked
the problem to after the soft reset performed by the ata_sff_softreset function.
(It writes an 0xe to the device control register). After the reset is
complete, the taskfile error register is read by ata_sff_dev_classify. If the
function reads an error, the drive is not recognized.
The occurrence of the above error sequence is relatively rare. However, once an error is
detected, it stays on the CF device until a power cycle. Even strobing the
reset line to the device for > 200 mS will not clear the error. After the power
cycle, the compact flash comes up and does not report any error.
The errors are not always consistent. I have seen 0x93 and 0xd2 reported in the error
register.
Is there a way to clear the error reported by the error task file register? Is
there something I am missing in the load sequence?
Thanks,
Doug Bailey
QuoteReplyEditDelete
2010-03-22 23:08:34 Re: pata_pcmcia CompactFLASH load error
Sonic Zhang (CHINA)
Message: 87598
Please following the instruction in docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:bfin_cf_pcmcia
and use blackfin specific cf pcmcia driver instead.
QuoteReplyEditDelete
2010-03-23 10:02:22 Re: pata_pcmcia CompactFLASH load error
Doug Bailey (UNITED STATES)
Message: 87619
Is there any advantage in using the old IDE driver over the libata based driver? Any anecdotal evidence that one is superior to the other?
QuoteReplyEditDelete
2010-03-23 15:22:02 Re: pata_pcmcia CompactFLASH load error
Mike Frysinger (UNITED STATES)
Message: 87626
the old ide driver has been punted while the libata one is supported going forward ...
QuoteReplyEditDelete
2010-03-24 15:03:40 Re: pata_pcmcia CompactFLASH load error
Doug Bailey (UNITED STATES)
Message: 87674
This indicates that I need to use the pata_pcmcia driver that uses the libata
library. This means that I need to overcome the problem where my drive is
sometimes not detected.
This issue manifests itself in the with ata_sff_softreset function in libata-sff.c
and its use of ata_sff_dev_classify to determine the type of device that it is interfacing.
After perfroming a soft reset, the ata_sff_dev_classify function reads the error
register (offset 1) of the taskfile registers. It uses this value as a
qualifier to filter out return values indicating non ATA drive types. I am
missing something here as I do not see where in the ATAPI spec it indicates that
the error register has any diagnostic value to be used for this purpose.
Further, the ATAPI spec indicates that the ERR bit in the status register
(offset 7) should be checked to indicate if the error register contents are
meaningful. Yet, the ata_sff_dev_classify simply uses the error register contents
looking for a signature that I have not seen decribed.
Can anyone point me to a reference in the ATAPI spec that details the motivation
behind the ata_sff_dev_classify function's logic?
---------- The functions in question -------------------
int ata_sff_softreset(struct ata_link *link, unsigned int *classes,
unsigned long deadline)
{
struct ata_port *ap = link->ap;
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
unsigned int devmask = 0;
int rc;
u8 err;
DPRINTK("ENTER\n");
/* determine if device 0/1 are present */
if (ata_devchk(ap, 0))
devmask |= (1 << 0);
if (slave_possible && ata_devchk(ap, 1))
devmask |= (1 << 1);
/* select device 0 again */
ap->ops->sff_dev_select(ap, 0);
/* issue bus reset */
DPRINTK("about to softreset, devmask=%x\n", devmask);
rc = ata_bus_softreset(ap, devmask, deadline);
/* if link is occupied, -ENODEV too is an error */
if (rc && (rc != -ENODEV || sata_scr_valid(link))) {
ata_link_printk(link, KERN_ERR, "SRST failed (errno=%d)\n", rc);
return rc;
}
/* determine by signature whether we have ATA or ATAPI devices */
classes[0] = ata_sff_dev_classify(&link->device[0],
devmask & (1 << 0), &err);
if (slave_possible && err != 0x81)
classes[1] = ata_sff_dev_classify(&link->device[1],
devmask & (1 << 1), &err);
DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
return 0;
}
EXPORT_SYMBOL_GPL(ata_sff_softreset);
unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
u8 *r_err)
{
struct ata_port *ap = dev->link->ap;
struct ata_taskfile tf;
unsigned int class;
u8 err;
ap->ops->sff_dev_select(ap, dev->devno);
memset(&tf, 0, sizeof(tf));
ap->ops->sff_tf_read(ap, &tf);
err = tf.feature;
if (r_err)
*r_err = err;
/* see if device passed diags: continue and warn later */
if (err == 0)
/* diagnostic fail : do nothing _YET_ */
dev->horkage |= ATA_HORKAGE_DIAGNOSTIC;
else if (err == 1)
/* do nothing */ ;
else if ((dev->devno == 0) && (err == 0x81))
/* do nothing */ ;
else
return ATA_DEV_NONE;
/* determine if device is ATA or ATAPI */
class = ata_dev_classify(&tf);
if (class == ATA_DEV_UNKNOWN) {
/* If the device failed diagnostic, it's likely to
* have reported incorrect device signature too.
* Assume ATA device if the device seems present but
* device signature is invalid with diagnostic
* failure.
*/
if (present && (dev->horkage & ATA_HORKAGE_DIAGNOSTIC))
class = ATA_DEV_ATA;
else
class = ATA_DEV_NONE;
} else if ((class == ATA_DEV_ATA) &&
(ap->ops->sff_check_status(ap) == 0))
class = ATA_DEV_NONE;
return class;
}
EXPORT_SYMBOL_GPL(ata_sff_dev_classify);