[libata] ensure ->tf_read() hook reads Status and Error registers
We want ->tf_read() to get a complete snapshot of all taskfile registers, without requiring the callers to manually call ata_chk_status() and ata_chk_err() themselves. This also fixes a minor bug in sata_vsc where the lower bits of the feature register were incorrectly placed in the HOB (high order bits) portion of struct ata_taskfile.
This commit is contained in:
parent
9dfb7808fb
commit
ac19bff25b
5 changed files with 36 additions and 14 deletions
|
@ -370,6 +370,8 @@ static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
{
|
{
|
||||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||||
|
|
||||||
|
tf->command = ata_check_status(ap);
|
||||||
|
tf->feature = ata_chk_err(ap);
|
||||||
tf->nsect = inb(ioaddr->nsect_addr);
|
tf->nsect = inb(ioaddr->nsect_addr);
|
||||||
tf->lbal = inb(ioaddr->lbal_addr);
|
tf->lbal = inb(ioaddr->lbal_addr);
|
||||||
tf->lbam = inb(ioaddr->lbam_addr);
|
tf->lbam = inb(ioaddr->lbam_addr);
|
||||||
|
@ -402,6 +404,8 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
{
|
{
|
||||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||||
|
|
||||||
|
tf->command = ata_check_status(ap);
|
||||||
|
tf->feature = ata_chk_err(ap);
|
||||||
tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
|
tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
|
||||||
tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
|
tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
|
||||||
tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
|
tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
|
||||||
|
|
|
@ -490,7 +490,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
|
||||||
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
|
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
|
||||||
|
|
||||||
/* check main status, clearing INTRQ */
|
/* check main status, clearing INTRQ */
|
||||||
u8 status = ata_chk_status(ap);
|
u8 status = ata_check_status(ap);
|
||||||
if ((status & ATA_BUSY))
|
if ((status & ATA_BUSY))
|
||||||
continue;
|
continue;
|
||||||
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
|
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
|
||||||
|
|
|
@ -433,7 +433,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
|
||||||
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
|
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
|
||||||
|
|
||||||
/* check main status, clearing INTRQ */
|
/* check main status, clearing INTRQ */
|
||||||
u8 status = ata_chk_status(ap);
|
u8 status = ata_check_status(ap);
|
||||||
if ((status & ATA_BUSY))
|
if ((status & ATA_BUSY))
|
||||||
continue;
|
continue;
|
||||||
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
|
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
|
||||||
|
|
|
@ -84,6 +84,8 @@
|
||||||
/* Port stride */
|
/* Port stride */
|
||||||
#define K2_SATA_PORT_OFFSET 0x100
|
#define K2_SATA_PORT_OFFSET 0x100
|
||||||
|
|
||||||
|
static u8 k2_stat_check_status(struct ata_port *ap);
|
||||||
|
|
||||||
|
|
||||||
static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
|
static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
|
||||||
{
|
{
|
||||||
|
@ -136,16 +138,24 @@ static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
|
||||||
static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
{
|
{
|
||||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||||
u16 nsect, lbal, lbam, lbah;
|
u16 nsect, lbal, lbam, lbah, feature;
|
||||||
|
|
||||||
nsect = tf->nsect = readw(ioaddr->nsect_addr);
|
tf->command = k2_stat_check_status(ap);
|
||||||
lbal = tf->lbal = readw(ioaddr->lbal_addr);
|
|
||||||
lbam = tf->lbam = readw(ioaddr->lbam_addr);
|
|
||||||
lbah = tf->lbah = readw(ioaddr->lbah_addr);
|
|
||||||
tf->device = readw(ioaddr->device_addr);
|
tf->device = readw(ioaddr->device_addr);
|
||||||
|
feature = readw(ioaddr->error_addr);
|
||||||
|
nsect = readw(ioaddr->nsect_addr);
|
||||||
|
lbal = readw(ioaddr->lbal_addr);
|
||||||
|
lbam = readw(ioaddr->lbam_addr);
|
||||||
|
lbah = readw(ioaddr->lbah_addr);
|
||||||
|
|
||||||
|
tf->feature = feature;
|
||||||
|
tf->nsect = nsect;
|
||||||
|
tf->lbal = lbal;
|
||||||
|
tf->lbam = lbam;
|
||||||
|
tf->lbah = lbah;
|
||||||
|
|
||||||
if (tf->flags & ATA_TFLAG_LBA48) {
|
if (tf->flags & ATA_TFLAG_LBA48) {
|
||||||
tf->hob_feature = readw(ioaddr->error_addr) >> 8;
|
tf->hob_feature = feature >> 8;
|
||||||
tf->hob_nsect = nsect >> 8;
|
tf->hob_nsect = nsect >> 8;
|
||||||
tf->hob_lbal = lbal >> 8;
|
tf->hob_lbal = lbal >> 8;
|
||||||
tf->hob_lbam = lbam >> 8;
|
tf->hob_lbam = lbam >> 8;
|
||||||
|
|
|
@ -153,16 +153,24 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
|
||||||
static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||||
{
|
{
|
||||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||||
u16 nsect, lbal, lbam, lbah;
|
u16 nsect, lbal, lbam, lbah, feature;
|
||||||
|
|
||||||
nsect = tf->nsect = readw(ioaddr->nsect_addr);
|
tf->command = ata_check_status(ap);
|
||||||
lbal = tf->lbal = readw(ioaddr->lbal_addr);
|
|
||||||
lbam = tf->lbam = readw(ioaddr->lbam_addr);
|
|
||||||
lbah = tf->lbah = readw(ioaddr->lbah_addr);
|
|
||||||
tf->device = readw(ioaddr->device_addr);
|
tf->device = readw(ioaddr->device_addr);
|
||||||
|
feature = readw(ioaddr->error_addr);
|
||||||
|
nsect = readw(ioaddr->nsect_addr);
|
||||||
|
lbal = readw(ioaddr->lbal_addr);
|
||||||
|
lbam = readw(ioaddr->lbam_addr);
|
||||||
|
lbah = readw(ioaddr->lbah_addr);
|
||||||
|
|
||||||
|
tf->feature = feature;
|
||||||
|
tf->nsect = nsect;
|
||||||
|
tf->lbal = lbal;
|
||||||
|
tf->lbam = lbam;
|
||||||
|
tf->lbah = lbah;
|
||||||
|
|
||||||
if (tf->flags & ATA_TFLAG_LBA48) {
|
if (tf->flags & ATA_TFLAG_LBA48) {
|
||||||
tf->hob_feature = readb(ioaddr->error_addr);
|
tf->hob_feature = feature >> 8;
|
||||||
tf->hob_nsect = nsect >> 8;
|
tf->hob_nsect = nsect >> 8;
|
||||||
tf->hob_lbal = lbal >> 8;
|
tf->hob_lbal = lbal >> 8;
|
||||||
tf->hob_lbam = lbam >> 8;
|
tf->hob_lbam = lbam >> 8;
|
||||||
|
|
Loading…
Reference in a new issue