Commit 8182d7a3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'ata-6.6-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata

Pull ata fixes from Damien Le Moal:

 - Three fixes for the pata_parport driver to address a typo in the
   code, a missing operation implementation and port reset handling in
   the presence of slave devices (Ondrej)

 - Fix handling of ATAPI devices reset with the fit3 protocol driver of
   the pata_parport driver (Ondrej)

 - A follow up fix for the recent suspend/resume corrections to avoid
   attempting rescanning on resume the scsi device associated with an
   ata disk when the request queue of the scsi device is still suspended
   (in addition to not doing the rescan if the scsi device itself is
   still suspended) (me)

* tag 'ata-6.6-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata:
  scsi: Do not rescan devices with a suspended queue
  ata: pata_parport: fit3: implement IDE command set registers
  ata: pata_parport: add custom version of wait_after_reset
  ata: pata_parport: implement set_devctl
  ata: pata_parport: fix pata_parport_devchk
parents bab19d1b 626b13f0
......@@ -9,11 +9,6 @@
*
* The TD-2000 and certain older devices use a different protocol.
* Try the fit2 protocol module with them.
*
* NB: The FIT adapters do not appear to support the control
* registers. So, we map ALT_STATUS to STATUS and NO-OP writes
* to the device control register - this means that IDE reset
* will not work on these devices.
*/
#include <linux/module.h>
......@@ -37,8 +32,7 @@
static void fit3_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
if (cont == 1)
return;
regr += cont << 3;
switch (pi->mode) {
case 0:
......@@ -59,11 +53,7 @@ static int fit3_read_regr(struct pi_adapter *pi, int cont, int regr)
{
int a, b;
if (cont) {
if (regr != 6)
return 0xff;
regr = 7;
}
regr += cont << 3;
switch (pi->mode) {
case 0:
......
......@@ -51,6 +51,13 @@ static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
ata_sff_pause(ap);
}
static void pata_parport_set_devctl(struct ata_port *ap, u8 ctl)
{
struct pi_adapter *pi = ap->host->private_data;
pi->proto->write_regr(pi, 1, 6, ctl);
}
static bool pata_parport_devchk(struct ata_port *ap, unsigned int device)
{
struct pi_adapter *pi = ap->host->private_data;
......@@ -64,7 +71,7 @@ static bool pata_parport_devchk(struct ata_port *ap, unsigned int device)
pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0xaa);
pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0x55);
pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 055);
pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
......@@ -73,6 +80,72 @@ static bool pata_parport_devchk(struct ata_port *ap, unsigned int device)
return (nsect == 0x55) && (lbal == 0xaa);
}
static int pata_parport_wait_after_reset(struct ata_link *link,
unsigned int devmask,
unsigned long deadline)
{
struct ata_port *ap = link->ap;
struct pi_adapter *pi = ap->host->private_data;
unsigned int dev0 = devmask & (1 << 0);
unsigned int dev1 = devmask & (1 << 1);
int rc, ret = 0;
ata_msleep(ap, ATA_WAIT_AFTER_RESET);
/* always check readiness of the master device */
rc = ata_sff_wait_ready(link, deadline);
if (rc) {
/*
* some adapters return bogus values if master device is not
* present, so don't abort now if a slave device is present
*/
if (!dev1)
return rc;
ret = -ENODEV;
}
/*
* if device 1 was found in ata_devchk, wait for register
* access briefly, then wait for BSY to clear.
*/
if (dev1) {
int i;
pata_parport_dev_select(ap, 1);
/*
* Wait for register access. Some ATAPI devices fail
* to set nsect/lbal after reset, so don't waste too
* much time on it. We're gonna wait for !BSY anyway.
*/
for (i = 0; i < 2; i++) {
u8 nsect, lbal;
nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
if (nsect == 1 && lbal == 1)
break;
/* give drive a breather */
ata_msleep(ap, 50);
}
rc = ata_sff_wait_ready(link, deadline);
if (rc) {
if (rc != -ENODEV)
return rc;
ret = rc;
}
}
pata_parport_dev_select(ap, 0);
if (dev1)
pata_parport_dev_select(ap, 1);
if (dev0)
pata_parport_dev_select(ap, 0);
return ret;
}
static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
unsigned long deadline)
{
......@@ -87,7 +160,7 @@ static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
ap->last_ctl = ap->ctl;
/* wait the port to become ready */
return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
return pata_parport_wait_after_reset(&ap->link, devmask, deadline);
}
static int pata_parport_softreset(struct ata_link *link, unsigned int *classes,
......@@ -252,6 +325,7 @@ static struct ata_port_operations pata_parport_port_ops = {
.hardreset = NULL,
.sff_dev_select = pata_parport_dev_select,
.sff_set_devctl = pata_parport_set_devctl,
.sff_check_status = pata_parport_check_status,
.sff_check_altstatus = pata_parport_check_altstatus,
.sff_tf_load = pata_parport_tf_load,
......
......@@ -1627,12 +1627,13 @@ int scsi_rescan_device(struct scsi_device *sdev)
device_lock(dev);
/*
* Bail out if the device is not running. Otherwise, the rescan may
* block waiting for commands to be executed, with us holding the
* device lock. This can result in a potential deadlock in the power
* management core code when system resume is on-going.
* Bail out if the device or its queue are not running. Otherwise,
* the rescan may block waiting for commands to be executed, with us
* holding the device lock. This can result in a potential deadlock
* in the power management core code when system resume is on-going.
*/
if (sdev->sdev_state != SDEV_RUNNING) {
if (sdev->sdev_state != SDEV_RUNNING ||
blk_queue_pm_only(sdev->request_queue)) {
ret = -EWOULDBLOCK;
goto unlock;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment