Re: [PATCH][INCOMPLETE] sata_nv: merge ADMA support

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

 



On Fri, Mar 17, 2006 at 07:56:53PM -0500, Jeff Garzik wrote:
> Could I get you to diff against the attached version?

Certainly.

I took the opportunity to modify my source file to fix a pair of typos in
the pci_device_id changes, and make cosmetic changes by switching to enums
rather than #defines, removing unnecessary braces around single statements,
and fixing whitespace.  That reduced the noise considerably, and made the
NV_ADMA_CTL_READ_NON_COHERENT difference manifest.

	-Bill

--- sata_nv.c.garzik	2006-03-18 01:50:18.518554000 -0500
+++ sata_nv.c	2006-03-18 02:53:18.000000000 -0500
@@ -29,6 +29,38 @@
  *  NV-specific details such as register offsets, SATA phy location,
  *  hotplug info, etc.
  *
+ *  0.11
+ *     - Added support for ADMA.  Disabled by default.  Use the module
+ *       option adma=on to enable it for supported chipsets.
+ *
+ *  0.10
+ *     - Fixed spurious interrupts issue seen with the Maxtor 6H500F0 500GB
+ *       drive.  Also made the check_hotplug() callbacks return whether there
+ *       was a hotplug interrupt or not.  This was not the source of the
+ *       spurious interrupts, but is the right thing to do anyway.
+ *
+ *  0.09
+ *     - Fixed bug introduced by 0.08's MCP51 and MCP55 support.
+ *
+ *  0.08
+ *     - Added support for MCP51 and MCP55.
+ *
+ *  0.07
+ *     - Added support for RAID class code.
+ *
+ *  0.06
+ *     - Added generic SATA support by using a pci_device_id that filters on
+ *       the IDE storage class code.
+ *
+ *  0.03
+ *     - Fixed a bug where the hotplug handlers for non-CK804/MCP04 were using
+ *       mmio_base, which is only set for the CK804/MCP04 case.
+ *
+ *  0.02
+ *     - Added support for CK804 SATA controller.
+ *
+ *  0.01
+ *     - Initial revision.
  */
 
 #include <linux/config.h>
@@ -47,7 +79,7 @@
 //#define DEBUG
 
 #define DRV_NAME			"sata_nv"
-#define DRV_VERSION			"0.8"
+#define DRV_VERSION			"0.11-alpha"
 
 enum {
 	NV_PORTS			= 2,
@@ -148,7 +180,7 @@ enum {
 	NV_ADMA_CTL_CHANNEL_RESET	= (1 << 5),
 	NV_ADMA_CTL_GO			= (1 << 7),
 	NV_ADMA_CTL_AIEN		= (1 << 8),
-	NV_ADMA_CTL_READ_NON_COHERENT	= (1 << 11),
+	NV_ADMA_CTL_READ_NON_COHERENT	= (2 << 11),
 	NV_ADMA_CTL_WRITE_NON_COHERENT	= (1 << 12),
 
 	// CPB response flag bits
@@ -186,6 +218,10 @@ enum {
 	NV_ADMA_PORT_REGISTER_MODE	= (1 << 0),
 };
 
+#ifndef min
+#define min(x,y) ((x) < (y) ? x : y)
+#endif
+
 struct nv_adma_prd {
 	u64			addr;
 	u32			len;
@@ -237,18 +273,23 @@ static irqreturn_t nv_interrupt (int irq
 static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static void nv_host_stop (struct ata_host_set *host_set);
+static int nv_port_start(struct ata_port *ap);
+static void nv_port_stop(struct ata_port *ap);
 static int nv_adma_port_start(struct ata_port *ap);
 static void nv_adma_port_stop(struct ata_port *ap);
+static void nv_irq_clear(struct ata_port *ap);
 static void nv_adma_irq_clear(struct ata_port *ap);
 static void nv_enable_hotplug(struct ata_probe_ent *probe_ent);
 static void nv_disable_hotplug(struct ata_host_set *host_set);
-static void nv_check_hotplug(struct ata_host_set *host_set);
+static int nv_check_hotplug(struct ata_host_set *host_set);
 static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent);
 static void nv_disable_hotplug_ck804(struct ata_host_set *host_set);
-static void nv_check_hotplug_ck804(struct ata_host_set *host_set);
+static int nv_check_hotplug_ck804(struct ata_host_set *host_set);
 static void nv_enable_hotplug_adma(struct ata_probe_ent *probe_ent);
 static void nv_disable_hotplug_adma(struct ata_host_set *host_set);
-static void nv_check_hotplug_adma(struct ata_host_set *host_set);
+static int nv_check_hotplug_adma(struct ata_host_set *host_set);
+static void nv_qc_prep(struct ata_queued_cmd *qc);
+static int nv_qc_issue(struct ata_queued_cmd *qc);
 static int nv_adma_qc_issue(struct ata_queued_cmd *qc);
 static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
 static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, u16 *cpb);
@@ -256,8 +297,11 @@ static void nv_adma_fill_sg(struct ata_q
 static void nv_adma_fill_aprd(struct ata_queued_cmd *qc, struct scatterlist *sg, int idx, struct nv_adma_prd *aprd);
 static void nv_adma_register_mode(struct ata_port *ap);
 static void nv_adma_mode(struct ata_port *ap);
+static u8 nv_bmdma_status(struct ata_port *ap);
 static u8 nv_adma_bmdma_status(struct ata_port *ap);
+static void nv_bmdma_stop(struct ata_queued_cmd *qc);
 static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc);
+static void nv_eng_timeout(struct ata_port *ap);
 static void nv_adma_eng_timeout(struct ata_port *ap);
 #ifdef DEBUG
 static void nv_adma_dump_cpb(struct nv_adma_cpb *cpb);
@@ -267,40 +311,40 @@ static void nv_adma_dump_port(struct ata
 static void nv_adma_dump_iomem(void __iomem *m, int len);
 #endif
 
+
+static int adma_enabled;
+
 enum nv_host_type
 {
-	GENERIC,
-	NFORCE2,
-	NFORCE3,
-	CK804,
-	MCP51,
-	MCP55,
-	ADMA
+	GENERIC = 0x0,
+	NFORCE  = 0x1,
+	CK804   = 0x2,
+	ADMA    = 0x4
 };
 
 static const struct pci_device_id nv_pci_tbl[] = {
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE2 },
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE3 },
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE3 },
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADMA },
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 | ADMA },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADMA },
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 | ADMA },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADMA },
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 | ADMA },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADMA },
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 | ADMA },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP51 },
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP51 },
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP55 },
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP55 },
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
 		PCI_ANY_ID, PCI_ANY_ID,
 		PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
@@ -317,7 +361,7 @@ struct nv_host_desc
 	enum nv_host_type	host_type;
 	void			(*enable_hotplug)(struct ata_probe_ent *probe_ent);
 	void			(*disable_hotplug)(struct ata_host_set *host_set);
-	void			(*check_hotplug)(struct ata_host_set *host_set);
+	int			(*check_hotplug)(struct ata_host_set *host_set);
 
 };
 static struct nv_host_desc nv_device_tbl[] = {
@@ -328,13 +372,7 @@ static struct nv_host_desc nv_device_tbl
 		.check_hotplug	= NULL,
 	},
 	{
-		.host_type	= NFORCE2,
-		.enable_hotplug	= nv_enable_hotplug,
-		.disable_hotplug= nv_disable_hotplug,
-		.check_hotplug	= nv_check_hotplug,
-	},
-	{
-		.host_type	= NFORCE3,
+		.host_type	= NFORCE,
 		.enable_hotplug	= nv_enable_hotplug,
 		.disable_hotplug= nv_disable_hotplug,
 		.check_hotplug	= nv_check_hotplug,
@@ -344,16 +382,6 @@ static struct nv_host_desc nv_device_tbl
 		.disable_hotplug= nv_disable_hotplug_ck804,
 		.check_hotplug	= nv_check_hotplug_ck804,
 	},
-	{	.host_type	= MCP51,
-		.enable_hotplug	= nv_enable_hotplug,
-		.disable_hotplug= nv_disable_hotplug,
-		.check_hotplug	= nv_check_hotplug,
-	},
-	{	.host_type	= MCP55,
-		.enable_hotplug	= nv_enable_hotplug,
-		.disable_hotplug= nv_disable_hotplug,
-		.check_hotplug	= nv_check_hotplug,
-	},
 	{	.host_type	= ADMA,
 		.enable_hotplug	= nv_enable_hotplug_adma,
 		.disable_hotplug= nv_disable_hotplug_adma,
@@ -393,25 +421,6 @@ static struct scsi_host_template nv_sht 
 	.bios_param		= ata_std_bios_param,
 };
 
-static struct scsi_host_template nv_adma_sht = {
-	.module			= THIS_MODULE,
-	.name			= DRV_NAME,
-	.ioctl			= ata_scsi_ioctl,
-	.queuecommand		= ata_scsi_queuecmd,
-	.eh_strategy_handler	= ata_scsi_error,
-	.can_queue		= ATA_DEF_QUEUE,
-	.this_id		= ATA_SHT_THIS_ID,
-	.sg_tablesize		= NV_ADMA_SGTBL_LEN,
-	.max_sectors		= ATA_MAX_SECTORS,
-	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
-	.emulated		= ATA_SHT_EMULATED,
-	.use_clustering		= ATA_SHT_USE_CLUSTERING,
-	.proc_name		= DRV_NAME,
-	.dma_boundary		= ATA_DMA_BOUNDARY,
-	.slave_configure	= ata_scsi_slave_config,
-	.bios_param		= ata_std_bios_param,
-};
-
 static const struct ata_port_operations nv_ops = {
 	.port_disable		= ata_port_disable,
 	.tf_load		= ata_tf_load,
@@ -422,41 +431,17 @@ static const struct ata_port_operations 
 	.phy_reset		= sata_phy_reset,
 	.bmdma_setup		= ata_bmdma_setup,
 	.bmdma_start		= ata_bmdma_start,
-	.bmdma_stop		= ata_bmdma_stop,
-	.bmdma_status		= ata_bmdma_status,
-	.qc_prep		= ata_qc_prep,
-	.qc_issue		= ata_qc_issue_prot,
-	.eng_timeout		= ata_eng_timeout,
-	.irq_handler		= nv_interrupt,
-	.irq_clear		= ata_bmdma_irq_clear,
-	.scr_read		= nv_scr_read,
-	.scr_write		= nv_scr_write,
-	.port_start		= ata_port_start,
-	.port_stop		= ata_port_stop,
-	.host_stop		= nv_host_stop,
-};
-
-static const struct ata_port_operations nv_adma_ops = {
-	.port_disable		= ata_port_disable,
-	.tf_load		= ata_tf_load,
-	.tf_read		= ata_tf_read,
-	.exec_command		= ata_exec_command,
-	.check_status		= ata_check_status,
-	.dev_select		= ata_std_dev_select,
-	.phy_reset		= sata_phy_reset,
-	.bmdma_setup		= ata_bmdma_setup,
-	.bmdma_start		= ata_bmdma_start,
-	.bmdma_stop		= nv_adma_bmdma_stop,
-	.bmdma_status		= nv_adma_bmdma_status,
-	.qc_prep		= nv_adma_qc_prep,
-	.qc_issue		= nv_adma_qc_issue,
-	.eng_timeout		= nv_adma_eng_timeout,
+	.bmdma_stop		= nv_bmdma_stop,
+	.bmdma_status		= nv_bmdma_status,
+	.qc_prep		= nv_qc_prep,
+	.qc_issue		= nv_qc_issue,
+	.eng_timeout		= nv_eng_timeout,
 	.irq_handler		= nv_interrupt,
-	.irq_clear		= nv_adma_irq_clear,
+	.irq_clear		= nv_irq_clear,
 	.scr_read		= nv_scr_read,
 	.scr_write		= nv_scr_write,
-	.port_start		= nv_adma_port_start,
-	.port_stop		= nv_adma_port_stop,
+	.port_start		= nv_port_start,
+	.port_stop		= nv_port_stop,
 	.host_stop		= nv_host_stop,
 };
 
@@ -646,19 +631,6 @@ static struct ata_port_info nv_port_info
 	.port_ops	= &nv_ops,
 };
 
-static struct ata_port_info nv_adma_port_info = {
-	.sht		= &nv_adma_sht,
-	.host_flags	= ATA_FLAG_SATA |
-			  /* ATA_FLAG_SATA_RESET | */
-			  ATA_FLAG_SRST |
-			  ATA_FLAG_MMIO |
-			  ATA_FLAG_NO_LEGACY,
-	.pio_mask	= NV_PIO_MASK,
-	.mwdma_mask	= NV_MWDMA_MASK,
-	.udma_mask	= NV_UDMA_MASK,
-	.port_ops	= &nv_adma_ops,
-};
-
 MODULE_AUTHOR("NVIDIA");
 MODULE_DESCRIPTION("low-level driver for NVIDIA nForce SATA controller");
 MODULE_LICENSE("GPL");
@@ -687,19 +659,53 @@ static inline void nv_disable_adma_space
 	pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
 }
 
+static void nv_irq_clear(struct ata_port *ap)
+{
+	struct ata_host_set *host_set = ap->host_set;
+	struct nv_host *host = host_set->private_data;
+
+	if (host->host_desc->host_type == ADMA)
+		nv_adma_irq_clear(ap);
+	else
+		ata_bmdma_irq_clear(ap);
+}
+
 static void nv_adma_irq_clear(struct ata_port *ap)
 {
-	/* TODO */
+	/* FIXME: TODO  */
+}
+
+static u8 nv_bmdma_status(struct ata_port *ap)
+{
+	struct ata_host_set *host_set = ap->host_set;
+	struct nv_host *host = host_set->private_data;
+
+	if (host->host_desc->host_type == ADMA)
+		return nv_adma_bmdma_status(ap);
+	else
+		return ata_bmdma_status(ap);
 }
 
 static u8 nv_adma_bmdma_status(struct ata_port *ap)
 {
+	// FIXME: This is no different than ata_bmdma_status for PIO
 	return inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
 }
 
+static void nv_bmdma_stop(struct ata_queued_cmd *qc)
+{
+	struct ata_host_set *host_set = qc->ap->host_set;
+	struct nv_host *host = host_set->private_data;
+
+	if (host->host_desc->host_type == ADMA)
+		nv_adma_bmdma_stop(qc);
+	else
+		ata_bmdma_stop(qc);
+}
+
 static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc)
 {
-	/* TODO */
+	/* FIXME: TODO */
 }
 
 static irqreturn_t nv_interrupt (int irq, void *dev_instance,
@@ -715,16 +721,18 @@ static irqreturn_t nv_interrupt (int irq
 
 	for (i = 0; i < host_set->n_ports; i++) {
 		struct ata_port *ap = host_set->ports[i];
-		struct nv_adma_port_priv *pp = ap->private_data;
 
 		if (ap &&
 		    !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) {
-			void __iomem *mmio = nv_adma_ctl_block(ap);
 			struct ata_queued_cmd *qc;
 
-			// read notifiers
-			pp->notifier = readl(mmio + NV_ADMA_NOTIFIER);
-			pp->notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
+			if (host->host_desc->host_type == ADMA) {
+				struct nv_adma_port_priv *pp = ap->private_data;
+				void __iomem *mmio = nv_adma_ctl_block(ap);
+				// read notifiers
+				pp->notifier = readl(mmio + NV_ADMA_NOTIFIER);
+				pp->notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
+			}
 				
 			qc = ata_qc_from_tag(ap, ap->active_tag);
 			if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
@@ -732,16 +740,21 @@ static irqreturn_t nv_interrupt (int irq
 					handled += nv_adma_host_intr(ap, qc);
 				else
 					handled += ata_host_intr(ap, qc);
+			} else {
+				// No request pending?  Clear interrupt status
+				// anyway, in case there's one pending.
+				ap->ops->check_status(ap);
 			}
 		}
 
 	}
 
 	if (host->host_desc->check_hotplug)
-		host->host_desc->check_hotplug(host_set);
+		// FIXME: do something with the return value
+		(void) host->host_desc->check_hotplug(host_set);
 
 	// clear notifier
-	if (handled) {
+	if (handled && host->host_desc->host_type == ADMA) {
 		for (i = 0; i < host_set->n_ports; i++) {
 			struct ata_port *ap = host_set->ports[i];
 			struct nv_adma_port_priv *pp = ap->private_data;
@@ -811,6 +824,28 @@ static void nv_host_stop (struct ata_hos
 		pci_iounmap(pdev, host_set->mmio_base);
 }
 
+static int nv_port_start(struct ata_port *ap)
+{
+	struct ata_host_set *host_set = ap->host_set;
+	struct nv_host *host = host_set->private_data;
+
+	if (host->host_desc->host_type == ADMA)
+		return nv_adma_port_start(ap);
+	else
+		return ata_port_start(ap);
+}
+
+static void nv_port_stop(struct ata_port *ap)
+{
+	struct ata_host_set *host_set = ap->host_set;
+	struct nv_host *host = host_set->private_data;
+
+	if (host->host_desc->host_type == ADMA)
+		nv_adma_port_stop(ap);
+	else
+		ata_port_stop(ap);
+}
+
 static int nv_adma_port_start(struct ata_port *ap)
 {
 	struct device *dev = ap->host_set->dev;
@@ -975,6 +1010,17 @@ static int nv_adma_host_init(struct ata_
 	return 0;
 }
 
+static struct nv_host_desc *nv_find_host_desc(unsigned int host_type)
+{
+	int i;
+
+	for (i = 0 ; i < (sizeof nv_device_tbl)/(sizeof nv_device_tbl[0]); i++)
+		if (nv_device_tbl[i].host_type == host_type)
+			return &nv_device_tbl[i];
+	return NULL;
+}
+
+
 static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	static int printed_version = 0;
@@ -1017,18 +1063,23 @@ static int nv_init_one (struct pci_dev *
 
 	rc = -ENOMEM;
 
-	host_desc = &nv_device_tbl[ent->driver_data];
+	ppi = &nv_port_info;
+
+	if (adma_enabled && (ent->driver_data & ADMA))
+		host_desc = nv_find_host_desc(ADMA);
+	else
+		host_desc = nv_find_host_desc(ent->driver_data & ~ADMA);
 
-	/* select ADMA or legacy PCI IDE BMDMA controller operation */
 	if (host_desc->host_type == ADMA) {
+		// ADMA overrides
+		ppi->host_flags                |= ATA_FLAG_MMIO | ATA_FLAG_SATA_RESET;
 #ifdef NV_ADMA_NCQ
 		ppi->host_flags		       |= ATA_FLAG_NCQ;
-		ppi->sht->can_queue		= NV_ADMA_CAN_QUEUE;
 #endif
-
-		ppi = &nv_adma_port_info;
-	} else
-		ppi = &nv_port_info;
+		ppi->sht->can_queue		= NV_ADMA_CAN_QUEUE;
+		ppi->sht->sg_tablesize		= NV_ADMA_SGTBL_LEN;
+//		ppi->port_ops->irq_handler	= nv_adma_interrupt;
+	}
 	
 	probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
 	if (!probe_ent)
@@ -1072,7 +1123,7 @@ static int nv_init_one (struct pci_dev *
 
 	pci_set_master(pdev);
 
-	if (ent->driver_data == ADMA) {
+	if (host_desc->host_type == ADMA) {
 		rc = nv_adma_host_init(probe_ent);
 		if (rc)
 			goto err_out_iounmap;
@@ -1106,6 +1157,17 @@ err_out:
 	return rc;
 }
 
+static void nv_eng_timeout(struct ata_port *ap)
+{
+	struct ata_host_set *host_set = ap->host_set;
+	struct nv_host *host = host_set->private_data;
+
+	if (host->host_desc->host_type == ADMA)
+		nv_adma_eng_timeout(ap);
+	else
+		ata_eng_timeout(ap);
+}
+
 static void nv_adma_eng_timeout(struct ata_port *ap)
 {
 	struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
@@ -1149,6 +1211,17 @@ out:
 	DPRINTK("EXIT\n");
 }
 
+static void nv_qc_prep(struct ata_queued_cmd *qc)
+{
+	struct ata_host_set *host_set = qc->ap->host_set;
+	struct nv_host *host = host_set->private_data;
+
+	if (host->host_desc->host_type == ADMA)
+		nv_adma_qc_prep(qc);
+	else
+		ata_qc_prep(qc);
+}
+
 static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
 {
 	struct nv_adma_port_priv *pp = qc->ap->private_data;
@@ -1259,6 +1332,17 @@ static void nv_adma_mode(struct ata_port
 	pp->flags &= ~NV_ADMA_PORT_REGISTER_MODE;
 }
 
+static int nv_qc_issue(struct ata_queued_cmd *qc)
+{
+	struct ata_host_set *host_set = qc->ap->host_set;
+	struct nv_host *host = host_set->private_data;
+
+	if (host->host_desc->host_type == ADMA)
+		return nv_adma_qc_issue(qc);
+	else
+		return ata_qc_issue_prot(qc);
+}
+
 static int nv_adma_qc_issue(struct ata_queued_cmd *qc)
 {
 #if 0
@@ -1281,9 +1365,8 @@ static int nv_adma_qc_issue(struct ata_q
 	nv_adma_dump_cpb(&pp->cpb[qc->tag]);
 	if (qc->n_elem > 5) {
 		int i;
-		for (i = 0; i < qc->n_elem - 5; i++) {
+		for (i = 0; i < qc->n_elem - 5; i++)
 			nv_adma_dump_aprd(&pp->aprd[i]);
-		}
 	}
 #endif
 
@@ -1323,7 +1406,7 @@ static void nv_disable_hotplug(struct at
 	outb(intr_mask, host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE);
 }
 
-static void nv_check_hotplug(struct ata_host_set *host_set)
+static int nv_check_hotplug(struct ata_host_set *host_set)
 {
 	u8 intr_status;
 
@@ -1348,7 +1431,9 @@ static void nv_check_hotplug(struct ata_
 		if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
 			printk(KERN_WARNING "nv_sata: "
 				"Secondary device removed\n");
+		return 1;
 	}
+	return 0;
 }
 
 static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent)
@@ -1380,7 +1465,7 @@ static void nv_disable_hotplug_ck804(str
 	nv_disable_adma_space(pdev);
 }
 
-static void nv_check_hotplug_ck804(struct ata_host_set *host_set)
+static int nv_check_hotplug_ck804(struct ata_host_set *host_set)
 {
 	u8 intr_status;
 
@@ -1405,7 +1490,9 @@ static void nv_check_hotplug_ck804(struc
 		if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
 			printk(KERN_WARNING "nv_sata: "
 				"Secondary device removed\n");
+		return 1;
 	}
+	return 0;
 }
 
 static void nv_enable_hotplug_adma(struct ata_probe_ent *probe_ent)
@@ -1439,10 +1526,11 @@ static void nv_disable_hotplug_adma(stru
 	}
 }
 
-static void nv_check_hotplug_adma(struct ata_host_set *host_set)
+static int nv_check_hotplug_adma(struct ata_host_set *host_set)
 {
 	unsigned int i;
 	u16 adma_status;
+	int hotplugged = 0;
 
 	for (i = 0; i < host_set->n_ports; i++) {
 		void __iomem *mmio = __nv_adma_ctl_block(host_set->mmio_base, i);
@@ -1451,13 +1539,16 @@ static void nv_check_hotplug_adma(struct
 			printk(KERN_WARNING "nv_sata: "
 			       "port %d device added\n", i);
 			writew(NV_ADMA_STAT_HOTPLUG, mmio + NV_ADMA_STAT);
+			hotplugged = 1;
 		}
 		if (adma_status & NV_ADMA_STAT_HOTUNPLUG) {
 			printk(KERN_WARNING "nv_sata: "
 			       "port %d device removed\n", i);
 			writew(NV_ADMA_STAT_HOTUNPLUG, mmio + NV_ADMA_STAT);
+			hotplugged = 1;
 		}
 	}
+	return hotplugged;
 }
 
 static int __init nv_init(void)
@@ -1472,6 +1563,9 @@ static void __exit nv_exit(void)
 
 module_init(nv_init);
 module_exit(nv_exit);
+module_param_named(adma, adma_enabled, bool, 0);
+MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: false)");
+
 
 #ifdef DEBUG
 static void nv_adma_dump_aprd(struct nv_adma_prd *aprd)
@@ -1525,13 +1619,11 @@ static void nv_adma_dump_cpb(struct nv_a
 	printk("tag:          0x%02x\n", cpb->tag);
 	printk("next_cpb_idx: 0x%02x\n", cpb->next_cpb_idx);
 	printk("tf:\n");
-	for (i=0; i<12; i++) {
+	for (i=0; i<12; i++)
 		nv_adma_dump_cpb_tf(cpb->tf[i]);
-	}
 	printk("aprd:\n");
-	for (i=0; i<5; i++) {
+	for (i=0; i<5; i++)
 		nv_adma_dump_aprd(&cpb->aprd[i]);
-	}
 	printk("next_aprd:    0x%016llx\n", cpb->next_aprd);
 }
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux