From 9b358e305c1d783c8a4ebf00344e95deb9e38f3d Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Fri, 19 May 2006 16:21:03 -0400 Subject: [PATCH] sata_mv: prevent unnecessary double-resets The mv_err_intr() function is invoked from the driver's interrupt handler, as well as from the timeout function. This patch prevents it from triggering a one-after-the-other double reset of the controller when invoked from the timeout function. This also adds a check for a timeout race condition that has been observed to occur with this driver in earlier kernels. This should not be needed, in theory, but in practice it has caught bugs. Maybe nuke it at a later date. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/scsi/sata_mv.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index d5fdcb9a8842..87f26cd60fae 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -1291,6 +1291,7 @@ static u8 mv_get_crpb_status(struct ata_port *ap) /** * mv_err_intr - Handle error interrupts on the port * @ap: ATA channel to manipulate + * @reset_allowed: bool: 0 == don't trigger from reset here * * In most cases, just clear the interrupt and move on. However, * some cases require an eDMA reset, which is done right before @@ -1301,7 +1302,7 @@ static u8 mv_get_crpb_status(struct ata_port *ap) * LOCKING: * Inherited from caller. */ -static void mv_err_intr(struct ata_port *ap) +static void mv_err_intr(struct ata_port *ap, int reset_allowed) { void __iomem *port_mmio = mv_ap_base(ap); u32 edma_err_cause, serr = 0; @@ -1323,9 +1324,8 @@ static void mv_err_intr(struct ata_port *ap) writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); /* check for fatal here and recover if needed */ - if (EDMA_ERR_FATAL & edma_err_cause) { + if (reset_allowed && (EDMA_ERR_FATAL & edma_err_cause)) mv_stop_and_reset(ap); - } } /** @@ -1406,7 +1406,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, shift++; /* skip bit 8 in the HC Main IRQ reg */ } if ((PORT0_ERR << shift) & relevant) { - mv_err_intr(ap); + mv_err_intr(ap, 1); err_mask |= AC_ERR_OTHER; handled = 1; } @@ -2031,11 +2031,14 @@ static void mv_eng_timeout(struct ata_port *ap) ap->host_set->mmio_base, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd); - mv_err_intr(ap); + mv_err_intr(ap, 0); mv_stop_and_reset(ap); - qc->err_mask |= AC_ERR_TIMEOUT; - ata_eh_qc_complete(qc); + WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); + if (qc->flags & ATA_QCFLAG_ACTIVE) { + qc->err_mask |= AC_ERR_TIMEOUT; + ata_eh_qc_complete(qc); + } } /** -- cgit v1.2.3 From 615ab95342f6245026d8974b9724f7ea57d9a184 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Fri, 19 May 2006 16:24:56 -0400 Subject: [PATCH] sata_mv: deal with interrupt coalescing interrupts In some systems, it is possible that the BIOS may have enabled interrupt coalescing for the Marvell controllers which support it. This patch adds code to detect/ack interrupts from the chip's coalescing (combing) logic. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/scsi/sata_mv.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 87f26cd60fae..3ed2f333d5a9 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -50,6 +50,12 @@ enum { MV_PCI_REG_BASE = 0, MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */ + MV_IRQ_COAL_CAUSE = (MV_IRQ_COAL_REG_BASE + 0x08), + MV_IRQ_COAL_CAUSE_LO = (MV_IRQ_COAL_REG_BASE + 0x88), + MV_IRQ_COAL_CAUSE_HI = (MV_IRQ_COAL_REG_BASE + 0x8c), + MV_IRQ_COAL_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xcc), + MV_IRQ_COAL_TIME_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xd0), + MV_SATAHC0_REG_BASE = 0x20000, MV_FLASH_CTL = 0x1046c, MV_GPIO_PORT_CTL = 0x104f0, @@ -1448,6 +1454,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, struct ata_host_set *host_set = dev_instance; unsigned int hc, handled = 0, n_hcs; void __iomem *mmio = host_set->mmio_base; + struct mv_host_priv *hpriv; u32 irq_stat; irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS); @@ -1469,6 +1476,17 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, handled++; } } + + hpriv = host_set->private_data; + if (IS_60XX(hpriv)) { + /* deal with the interrupt coalescing bits */ + if (irq_stat & (TRAN_LO_DONE | TRAN_HI_DONE | PORTS_0_7_COAL_DONE)) { + writelfl(0, mmio + MV_IRQ_COAL_CAUSE_LO); + writelfl(0, mmio + MV_IRQ_COAL_CAUSE_HI); + writelfl(0, mmio + MV_IRQ_COAL_CAUSE); + } + } + if (PCI_ERR & irq_stat) { printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n", readl(mmio + PCI_IRQ_CAUSE_OFS)); -- cgit v1.2.3 From eb46d684600ac145501805a294c94675e82eab2e Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Fri, 19 May 2006 16:29:21 -0400 Subject: [PATCH] sata_mv: chip initialization fixes The interface control register of the 60xx (and later) Marvell chip requires certain bits to always be set when writing to it. These bits incorrectly read-back as zeros, so the pattern must be ORed in with each write of the register. Also, bit 12 should NOT be set (note that Marvell's own driver also had bit-12 wrong here). While we're at it, we also now do pci_set_master() in the init code. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/scsi/sata_mv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 3ed2f333d5a9..bb2409e761d0 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -1885,7 +1885,8 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio, if (IS_60XX(hpriv)) { u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL); - ifctl |= (1 << 12) | (1 << 7); + ifctl |= (1 << 7); /* enable gen2i speed */ + ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */ writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL); } @@ -2250,7 +2251,8 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, void __iomem *port_mmio = mv_port_base(mmio, port); u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL); - ifctl |= (1 << 12); + ifctl |= (1 << 7); /* enable gen2i speed */ + ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */ writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL); } @@ -2351,6 +2353,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) { return rc; } + pci_set_master(pdev); rc = pci_request_regions(pdev, DRV_NAME); if (rc) { -- cgit v1.2.3 From e857f141945f29c16f72ffcfdbce097f8be6c4e9 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Fri, 19 May 2006 16:33:03 -0400 Subject: [PATCH] sata_mv: spurious interrupt workaround The 60xx chips, and possibly others, incorrectly assert DEV_IRQ interrupts on a regular basis. The cause of this is under investigation (by me and in theory by Marvell also), but regardless we do need to deal with these events. This patch tidies up some interrupt handler code, and ensures that we ignore DEV_IRQ interrupts when the drive still has ATA_BUSY asserted. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/scsi/sata_mv.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index bb2409e761d0..65dc65304f51 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -1380,12 +1380,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, struct ata_port *ap = host_set->ports[port]; struct mv_port_priv *pp = ap->private_data; - hard_port = port & MV_PORT_MASK; /* range 0-3 */ + hard_port = mv_hardport_from_port(port); /* range 0..3 */ handled = 0; /* ensure ata_status is set if handled++ */ /* Note that DEV_IRQ might happen spuriously during EDMA, - * and should be ignored in such cases. We could mask it, - * but it's pretty rare and may not be worth the overhead. + * and should be ignored in such cases. + * The cause of this is still under investigation. */ if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { /* EDMA: check for response queue interrupt */ @@ -1399,6 +1399,11 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, ata_status = readb((void __iomem *) ap->ioaddr.status_addr); handled = 1; + /* ignore spurious intr if drive still BUSY */ + if (ata_status & ATA_BUSY) { + ata_status = 0; + handled = 0; + } } } -- cgit v1.2.3 From a6432436c5e14b416f27c8f87c5bf0bc36771f49 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Fri, 19 May 2006 16:36:36 -0400 Subject: [PATCH] sata_mv: remove local copy of queue indexes The driver currently keeps local copies of the hardware request/response queue indexes. But it expends significant effort ensuring consistency between the two views, and still gets it wrong after an error or reset occurs. This patch removes the local copies, in favour of just accessing the hardware whenever we need them. Eventually this may need to be tweaked again for NCQ, but for now this works and solves problems some users were seeing. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/scsi/sata_mv.c | 76 ++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 65dc65304f51..dea9d4e42586 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -308,9 +308,6 @@ struct mv_port_priv { dma_addr_t crpb_dma; struct mv_sg *sg_tbl; dma_addr_t sg_tbl_dma; - - unsigned req_producer; /* cp of req_in_ptr */ - unsigned rsp_consumer; /* cp of rsp_out_ptr */ u32 pp_flags; }; @@ -943,8 +940,6 @@ static int mv_port_start(struct ata_port *ap) writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); - pp->req_producer = pp->rsp_consumer = 0; - /* Don't turn on EDMA here...do it before DMA commands only. Else * we'll be unable to send non-data, PIO, etc due to restricted access * to shadow regs. @@ -1028,10 +1023,9 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) } } -static inline unsigned mv_inc_q_index(unsigned *index) +static inline unsigned mv_inc_q_index(unsigned index) { - *index = (*index + 1) & MV_MAX_Q_DEPTH_MASK; - return *index; + return (index + 1) & MV_MAX_Q_DEPTH_MASK; } static inline void mv_crqb_pack_cmd(u16 *cmdw, u8 data, u8 addr, unsigned last) @@ -1059,15 +1053,11 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) u16 *cw; struct ata_taskfile *tf; u16 flags = 0; + unsigned in_index; if (ATA_PROT_DMA != qc->tf.protocol) return; - /* the req producer index should be the same as we remember it */ - WARN_ON(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >> - EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != - pp->req_producer); - /* Fill in command request block */ if (!(qc->tf.flags & ATA_TFLAG_WRITE)) @@ -1075,13 +1065,17 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); flags |= qc->tag << CRQB_TAG_SHIFT; - pp->crqb[pp->req_producer].sg_addr = + /* get current queue index from hardware */ + in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS) + >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; + + pp->crqb[in_index].sg_addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff); - pp->crqb[pp->req_producer].sg_addr_hi = + pp->crqb[in_index].sg_addr_hi = cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16); - pp->crqb[pp->req_producer].ctrl_flags = cpu_to_le16(flags); + pp->crqb[in_index].ctrl_flags = cpu_to_le16(flags); - cw = &pp->crqb[pp->req_producer].ata_cmd[0]; + cw = &pp->crqb[in_index].ata_cmd[0]; tf = &qc->tf; /* Sadly, the CRQB cannot accomodate all registers--there are @@ -1150,16 +1144,12 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) struct mv_port_priv *pp = ap->private_data; struct mv_crqb_iie *crqb; struct ata_taskfile *tf; + unsigned in_index; u32 flags = 0; if (ATA_PROT_DMA != qc->tf.protocol) return; - /* the req producer index should be the same as we remember it */ - WARN_ON(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >> - EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != - pp->req_producer); - /* Fill in Gen IIE command request block */ if (!(qc->tf.flags & ATA_TFLAG_WRITE)) @@ -1168,7 +1158,11 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); flags |= qc->tag << CRQB_TAG_SHIFT; - crqb = (struct mv_crqb_iie *) &pp->crqb[pp->req_producer]; + /* get current queue index from hardware */ + in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS) + >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; + + crqb = (struct mv_crqb_iie *) &pp->crqb[in_index]; crqb->addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff); crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16); crqb->flags = cpu_to_le32(flags); @@ -1216,6 +1210,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) { void __iomem *port_mmio = mv_ap_base(qc->ap); struct mv_port_priv *pp = qc->ap->private_data; + unsigned in_index; u32 in_ptr; if (ATA_PROT_DMA != qc->tf.protocol) { @@ -1227,23 +1222,20 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) return ata_qc_issue_prot(qc); } - in_ptr = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS); + in_ptr = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS); + in_index = (in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; - /* the req producer index should be the same as we remember it */ - WARN_ON(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != - pp->req_producer); /* until we do queuing, the queue should be empty at this point */ - WARN_ON(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != - ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >> - EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); + WARN_ON(in_index != ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) + >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); - mv_inc_q_index(&pp->req_producer); /* now incr producer index */ + in_index = mv_inc_q_index(in_index); /* now incr producer index */ mv_start_dma(port_mmio, pp); /* and write the request in pointer to kick the EDMA to life */ in_ptr &= EDMA_REQ_Q_BASE_LO_MASK; - in_ptr |= pp->req_producer << EDMA_REQ_Q_PTR_SHIFT; + in_ptr |= in_index << EDMA_REQ_Q_PTR_SHIFT; writelfl(in_ptr, port_mmio + EDMA_REQ_Q_IN_PTR_OFS); return 0; @@ -1266,28 +1258,26 @@ static u8 mv_get_crpb_status(struct ata_port *ap) { void __iomem *port_mmio = mv_ap_base(ap); struct mv_port_priv *pp = ap->private_data; + unsigned out_index; u32 out_ptr; u8 ata_status; - out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); - - /* the response consumer index should be the same as we remember it */ - WARN_ON(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != - pp->rsp_consumer); + out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); + out_index = (out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; - ata_status = pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT; + ata_status = le16_to_cpu(pp->crpb[out_index].flags) + >> CRPB_FLAG_STATUS_SHIFT; /* increment our consumer index... */ - pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer); + out_index = mv_inc_q_index(out_index); /* and, until we do NCQ, there should only be 1 CRPB waiting */ - WARN_ON(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >> - EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != - pp->rsp_consumer); + WARN_ON(out_index != ((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) + >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); /* write out our inc'd consumer index so EDMA knows we're caught up */ out_ptr &= EDMA_RSP_Q_BASE_LO_MASK; - out_ptr |= pp->rsp_consumer << EDMA_RSP_Q_PTR_SHIFT; + out_ptr |= out_index << EDMA_RSP_Q_PTR_SHIFT; writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); /* Return ATA status register for completed CRPB */ -- cgit v1.2.3 From 559eedad7f7764dacca33980127b4615011230e4 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Fri, 19 May 2006 16:40:15 -0400 Subject: [PATCH] sata_mv: endian fix This fixes a byte-swap issue on PPC, found by Zang Roy-r61911 on the powerpc platform. His original patch also had some other platform-specific changes in #ifdef's, but I'm not sure yet how to incorporate them. Look for another patch for those (soon). Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/scsi/sata_mv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index dea9d4e42586..dcda579ee93a 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -1030,8 +1030,9 @@ static inline unsigned mv_inc_q_index(unsigned index) static inline void mv_crqb_pack_cmd(u16 *cmdw, u8 data, u8 addr, unsigned last) { - *cmdw = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS | + u16 tmp = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS | (last ? CRQB_CMD_LAST : 0); + *cmdw = cpu_to_le16(tmp); } /** -- cgit v1.2.3 From 63a25355cd5cd9a2d19a7c50eed4f0a8aa622f72 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Fri, 19 May 2006 16:41:27 -0400 Subject: [PATCH] sata_mv: version bump Increment the version number inside sata_mv.c. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/scsi/sata_mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index dcda579ee93a..9b8bca1ac1f0 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -37,7 +37,7 @@ #include #define DRV_NAME "sata_mv" -#define DRV_VERSION "0.6" +#define DRV_VERSION "0.7" enum { /* BAR's are enumerated in terms of pci_resource_start() terms */ -- cgit v1.2.3 From e2a7f77a7b4ab298a38c8d1f624628456069bdb0 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 18 May 2006 10:50:18 -0700 Subject: [PATCH] libata-core: fix current kernel-doc warnings Fix all current kernel-doc warnings. Signed-off-by: Randy Dunlap Signed-off-by: Jeff Garzik --- drivers/scsi/libata-core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index bd147207f25d..823dfa78c0ba 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -864,6 +864,9 @@ static unsigned int ata_id_xfermask(const u16 *id) /** * ata_port_queue_task - Queue port_task * @ap: The ata_port to queue port_task for + * @fn: workqueue function to be scheduled + * @data: data value to pass to workqueue function + * @delay: delay time for workqueue function * * Schedule @fn(@data) for execution after @delay jiffies using * port_task. There is one port_task per port and it's the @@ -2739,6 +2742,8 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap, * ata_dev_init_params - Issue INIT DEV PARAMS command * @ap: Port associated with device @dev * @dev: Device to which command will be sent + * @heads: Number of heads (taskfile parameter) + * @sectors: Number of sectors (taskfile parameter) * * LOCKING: * Kernel thread context (may sleep) @@ -4302,6 +4307,7 @@ int ata_device_resume(struct ata_port *ap, struct ata_device *dev) * ata_device_suspend - prepare a device for suspend * @ap: port the device is connected to * @dev: the device to suspend + * @state: target power management state * * Flush the cache on the drive, if appropriate, then issue a * standbynow command. -- cgit v1.2.3