Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c1eb90a authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik
Browse files

sata_nv: reinstate nv_hardreset() for non generic controllers



Commit 2fd673ec which tried to remove
hardreset for generic accidentally removed it for all flavors as all
others were inheriting from nv_generic_ops.  This patch reinstates
nv_hardreset() and puts it into nv_common_ops which all flavors
inherit from.  nv_generic_ops now inherits from nv_common_ops and
overrides .hardreset to ATA_OP_NULL.

While at it, explain why nv_hardreset and ATA_OP_NULL override are
necessary.

Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 6ef190cc
Loading
Loading
Loading
Loading
+40 −6
Original line number Original line Diff line number Diff line
@@ -309,6 +309,8 @@ static void nv_nf2_freeze(struct ata_port *ap);
static void nv_nf2_thaw(struct ata_port *ap);
static void nv_nf2_thaw(struct ata_port *ap);
static void nv_ck804_freeze(struct ata_port *ap);
static void nv_ck804_freeze(struct ata_port *ap);
static void nv_ck804_thaw(struct ata_port *ap);
static void nv_ck804_thaw(struct ata_port *ap);
static int nv_hardreset(struct ata_link *link, unsigned int *class,
			unsigned long deadline);
static int nv_adma_slave_config(struct scsi_device *sdev);
static int nv_adma_slave_config(struct scsi_device *sdev);
static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
@@ -403,28 +405,45 @@ static struct scsi_host_template nv_swncq_sht = {
	.slave_configure	= nv_swncq_slave_config,
	.slave_configure	= nv_swncq_slave_config,
};
};


static struct ata_port_operations nv_generic_ops = {
/* OSDL bz3352 reports that some nv controllers can't determine device
 * signature reliably and nv_hardreset is implemented to work around
 * the problem.  This was reported on nf3 and it's unclear whether any
 * other controllers are affected.  However, the workaround has been
 * applied to all variants and there isn't much to gain by trying to
 * find out exactly which ones are affected at this point especially
 * because NV has moved over to ahci for newer controllers.
 */
static struct ata_port_operations nv_common_ops = {
	.inherits		= &ata_bmdma_port_ops,
	.inherits		= &ata_bmdma_port_ops,
	.hardreset		= ATA_OP_NULL,
	.hardreset		= nv_hardreset,
	.scr_read		= nv_scr_read,
	.scr_read		= nv_scr_read,
	.scr_write		= nv_scr_write,
	.scr_write		= nv_scr_write,
};
};


/* OSDL bz11195 reports that link doesn't come online after hardreset
 * on generic nv's and there have been several other similar reports
 * on linux-ide.  Disable hardreset for generic nv's.
 */
static struct ata_port_operations nv_generic_ops = {
	.inherits		= &nv_common_ops,
	.hardreset		= ATA_OP_NULL,
};

static struct ata_port_operations nv_nf2_ops = {
static struct ata_port_operations nv_nf2_ops = {
	.inherits		= &nv_generic_ops,
	.inherits		= &nv_common_ops,
	.freeze			= nv_nf2_freeze,
	.freeze			= nv_nf2_freeze,
	.thaw			= nv_nf2_thaw,
	.thaw			= nv_nf2_thaw,
};
};


static struct ata_port_operations nv_ck804_ops = {
static struct ata_port_operations nv_ck804_ops = {
	.inherits		= &nv_generic_ops,
	.inherits		= &nv_common_ops,
	.freeze			= nv_ck804_freeze,
	.freeze			= nv_ck804_freeze,
	.thaw			= nv_ck804_thaw,
	.thaw			= nv_ck804_thaw,
	.host_stop		= nv_ck804_host_stop,
	.host_stop		= nv_ck804_host_stop,
};
};


static struct ata_port_operations nv_adma_ops = {
static struct ata_port_operations nv_adma_ops = {
	.inherits		= &nv_generic_ops,
	.inherits		= &nv_common_ops,


	.check_atapi_dma	= nv_adma_check_atapi_dma,
	.check_atapi_dma	= nv_adma_check_atapi_dma,
	.sff_tf_read		= nv_adma_tf_read,
	.sff_tf_read		= nv_adma_tf_read,
@@ -448,7 +467,7 @@ static struct ata_port_operations nv_adma_ops = {
};
};


static struct ata_port_operations nv_swncq_ops = {
static struct ata_port_operations nv_swncq_ops = {
	.inherits		= &nv_generic_ops,
	.inherits		= &nv_common_ops,


	.qc_defer		= ata_std_qc_defer,
	.qc_defer		= ata_std_qc_defer,
	.qc_prep		= nv_swncq_qc_prep,
	.qc_prep		= nv_swncq_qc_prep,
@@ -1586,6 +1605,21 @@ static void nv_mcp55_thaw(struct ata_port *ap)
	ata_sff_thaw(ap);
	ata_sff_thaw(ap);
}
}


static int nv_hardreset(struct ata_link *link, unsigned int *class,
			unsigned long deadline)
{
	int rc;

	/* SATA hardreset fails to retrieve proper device signature on
	 * some controllers.  Request follow up SRST.  For more info,
	 * see http://bugzilla.kernel.org/show_bug.cgi?id=3352
	 */
	rc = sata_sff_hardreset(link, class, deadline);
	if (rc)
		return rc;
	return -EAGAIN;
}

static void nv_adma_error_handler(struct ata_port *ap)
static void nv_adma_error_handler(struct ata_port *ap)
{
{
	struct nv_adma_port_priv *pp = ap->private_data;
	struct nv_adma_port_priv *pp = ap->private_data;