[PATCH, RFC] sata_qstor: convert to new EH

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Convert sata_qstor to new EH.

---

Hello, Mark.

Does this conversion make sense?  I don't have access to qstor
controller or the doc, so this is done mostly by guessing.  I'm
curious about...

* qs_reset_channel_logic() resets the silicon but nothing else.  ie.
  it makes the controller forget about previous state and ready for
  new command but doesn't reset ATA bus, right?  If so, I think it
  would be better to move pp->state = qs_state_idle into that
  function.

* Is there better way to implement freeze/thaw other than the standard
  BMDMA way (ATA_NIEN)?

* Would ata_std_softreset() work on this controller?

* What do you think about freezing the port if pp->state != idle on
  entry to EH instead of forcing it to mmio?  Doing so would keep EH
  from mangling with the controller until the controller is reset,
  which will restore pp->state to idle.

Thanks.

diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index 98ddc25..aafabd1 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -118,14 +118,14 @@ static irqreturn_t qs_intr (int irq, voi
 static int qs_port_start(struct ata_port *ap);
 static void qs_host_stop(struct ata_host_set *host_set);
 static void qs_port_stop(struct ata_port *ap);
-static void qs_phy_reset(struct ata_port *ap);
 static void qs_qc_prep(struct ata_queued_cmd *qc);
 static unsigned int qs_qc_issue(struct ata_queued_cmd *qc);
 static int qs_check_atapi_dma(struct ata_queued_cmd *qc);
 static void qs_bmdma_stop(struct ata_queued_cmd *qc);
 static u8 qs_bmdma_status(struct ata_port *ap);
 static void qs_irq_clear(struct ata_port *ap);
-static void qs_eng_timeout(struct ata_port *ap);
+static void qs_error_handler(struct ata_port *ap);
+static void qs_post_internal_cmd(struct ata_queued_cmd *qc);
 
 static struct scsi_host_template qs_ata_sht = {
 	.module			= THIS_MODULE,
@@ -154,11 +154,13 @@ static const struct ata_port_operations 
 	.check_atapi_dma	= qs_check_atapi_dma,
 	.exec_command		= ata_exec_command,
 	.dev_select		= ata_std_dev_select,
-	.phy_reset		= qs_phy_reset,
 	.qc_prep		= qs_qc_prep,
 	.qc_issue		= qs_qc_issue,
 	.data_xfer		= ata_mmio_data_xfer,
-	.eng_timeout		= qs_eng_timeout,
+	.freeze			= ata_bmdma_freeze,
+	.thaw			= ata_bmdma_thaw,
+	.error_handler		= qs_error_handler,
+	.post_internal_cmd	= qs_post_internal_cmd,
 	.irq_handler		= qs_intr,
 	.irq_clear		= qs_irq_clear,
 	.scr_read		= qs_scr_read,
@@ -175,8 +177,6 @@ static const struct ata_port_info qs_por
 	{
 		.sht		= &qs_ata_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_SATA_RESET |
-				  //FIXME ATA_FLAG_SRST |
 				  ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
 		.pio_mask	= 0x10, /* pio4 */
 		.udma_mask	= 0x7f, /* udma0-6 */
@@ -235,23 +235,51 @@ static inline void qs_reset_channel_logi
 	qs_enter_reg_mode(ap);
 }
 
-static void qs_phy_reset(struct ata_port *ap)
+static int qs_softreset(struct ata_port *ap, unsigned int *class)
 {
 	struct qs_port_priv *pp = ap->private_data;
 
 	pp->state = qs_state_idle;
 	qs_reset_channel_logic(ap);
-	sata_phy_reset(ap);
+
+	return ata_std_softreset(ap, class);
+}
+
+static int qs_hardreset(struct ata_port *ap, unsigned int *class)
+{
+	struct qs_port_priv *pp = ap->private_data;
+
+	pp->state = qs_state_idle;
+	qs_reset_channel_logic(ap);
+
+	return sata_std_hardreset(ap, class);
 }
 
-static void qs_eng_timeout(struct ata_port *ap)
+static void qs_error_handler(struct ata_port *ap)
 {
 	struct qs_port_priv *pp = ap->private_data;
 
 	if (pp->state != qs_state_idle) /* healthy paranoia */
 		pp->state = qs_state_mmio;
-	qs_reset_channel_logic(ap);
-	ata_eng_timeout(ap);
+
+	if (!(ap->flags & ATA_FLAG_FROZEN)) {
+		pp->state = qs_state_idle;
+		qs_reset_channel_logic(ap);
+	}
+
+	ata_do_eh(ap, ata_std_prereset, qs_softreset, qs_hardreset,
+		  ata_std_postreset);
+}
+
+static void qs_post_internal_cmd(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct qs_port_priv *pp = ap->private_data;
+
+	if (qc->err_mask) {
+		pp->state = qs_state_idle;
+		qs_reset_channel_logic(ap);
+	}
 }
 
 static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg)
-
: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux