[PATCH] sata_promise: Add TX4200 (PDC40519) ID
The Promise TX4200 is a 4-port SATA controller based on the PDC40519 chip. It meets the description of the 20619, so just a simple ID needs to be added to support this hardware. Thanks to Martin Povolný for testing. Signed-off-by: Daniel Drake <[EMAIL PROTECTED]> --- linux-2.6.13-rc3-git9/drivers/scsi/sata_promise.c.orig 2005-07-28 13:29:47.0 +0100 +++ linux-2.6.13-rc3-git9/drivers/scsi/sata_promise.c 2005-07-28 13:30:54.0 +0100 @@ -181,6 +181,8 @@ static struct pci_device_id pdc_ata_pci_ board_20319 }, { PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20319 }, + { PCI_VENDOR_ID_PROMISE, 0x3519, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_20319 }, { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20319 },
libata suspend/resume
Hi, An increasing number of laptop vendors seem to be including sata controllers now, and so we're looking at shipping the libata suspend/resume patch. The discussion about suspend in the scsi layer doesn't seem to have ended very conclusively, and I haven't been able to find any sign of that code ending up anywhere. What's the current status with this? Thanks, -- Matthew Garrett | [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH linux-2.6.13-rc3] Mod15Write quirk against v2.6.13
On Wed, Jul 20, 2005 at 02:13:55PM -0700, Michael Madore wrote: > Hi, > > I have been successfully using your mod15write quirk patch with 2.6.12- > rc3. I recently applied the patch (with a minor reject) to 2.6.12.3. > Reading seems to work fine, but writing to the disk results in the > following output: > > irq 169: nobody cared! > > Call Trace: {__report_bad_irq+53} > {note_interrupt+92} >{__do_IRQ+256} {do_IRQ+72} >{ret_from_intr+0} > {default_idle+0} >{default_idle+34} {cpu_idle > +71} >{start_secondary+564} > handlers: > [] (ata_interrupt+0x0/0x180 [libata]) > [] (snd_intel8x0_interrupt+0x0/0x240 [snd_intel8x0]) > Disabling IRQ #169 > > Shortly thereafter, there is a kernel oops and the machine has to be > rebooted. Do you have an updated driver for 2.6.12? I assume something > has changed in libata. > Hello, Michael, again. Hello, Jeff, Albert & ATA guys. This is reply message to Michael's private mail reporting patch apply failure and (after hand-fixing it) malfunction. I hope Michael wouldn't mind adding recipients to this reply. sata_sil Mod15Write workaround was broken by the following commit by Albert Lee. Commit: 21b1ed74ee3667dcabcba92e486988ea9119a085 [PATCH] libata: Prevent the interrupt handler from completing a command twice This commit clears ATA_QCFLAG_ACTIVE in ata_qc_complete() and doesn't handle IRQ if ATA_QCFLAG_ACTIVE is cleared on entry to interrupt routine. As m15w workaround executes single command multiple times, the flag is cleared after the first chunk completion and the following interrupt gets ignored resulting in "nobody cared" interrupt error. The following changes are made in m15w workaround to fix this. * Moved clearing of ATA_QCFLAG_ACTIVE before invoking ->complete_fn, so that ->complete_fn can mangle with the flag. This doesn't affect any users. * Added setting ATA_QCFLAG_ACTIVE in m15w chunk completion function. One thing that bothers me is how Albert's commit and the original ata_host_intr tell IRQ subsystem that an interrupt isn't ours when we know that we have generated a spurious interrupt. IMHO, we always should enter ata_host_intr and always tell IRQ subsystem that it's our interrupt if bmdma_status tells us so, regardless of ata status value. The current code is likely to cause "nobody cared" error which can be avoided. Also, Jeff, I know you're very busy, but what do you think about taking m15w workaround into ata tree? It's been around for a while now and I haven't received any complaints (except for this one) yet. The workaround is ugly but it surely helps and I'm willing to maintain it. This patch is against v2.6.13-rc3 but also applies to v2.6.12 (with a fuss). Thanks. Signed-off-by: Tejun Heo <[EMAIL PROTECTED]> diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -3087,8 +3087,8 @@ void ata_qc_complete(struct ata_queued_c ata_sg_clean(qc); /* call completion callback */ - rc = qc->complete_fn(qc, drv_stat); qc->flags &= ~ATA_QCFLAG_ACTIVE; + rc = qc->complete_fn(qc, drv_stat); /* if callback indicates not to complete command (non-zero), * return immediately diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -71,9 +71,12 @@ enum { static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static void sil_dev_config(struct ata_port *ap, struct ata_device *dev); +static void sil_qc_prep (struct ata_queued_cmd *qc); +static void sil_eng_timeout (struct ata_port *ap); static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void sil_post_set_mode (struct ata_port *ap); +static void sil_host_stop (struct ata_host_set *host_set); static struct pci_device_id sil_pci_tbl[] = { { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, @@ -152,16 +155,16 @@ static struct ata_port_operations sil_op .bmdma_start= ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, - .qc_prep= ata_qc_prep, + .qc_prep= sil_qc_prep, .qc_issue = ata_qc_issue_prot, - .eng_timeout= ata_eng_timeout, + .eng_timeout= sil_eng_timeout, .irq_handler= ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .scr_read = sil_scr_read, .scr_write = sil_scr_write, .port_start = ata_port_start, .port_stop = ata_port_stop, - .host_stop = ata_host_stop, + .host_stop = sil_host_stop, }; static struct ata_port_info sil_port_
Plextor 712 sa write issue
Greetings, I am able to read-only mount and read from my Plextor 712-SA DVD burner, but I cannot mount the drive read-write. I wonder if anyone here might have some suggestions about how I could solve this problem. Here is the error message I get when I try this to mount -t iso9660 /dev/scd0 /mnt/cdrecorder -o rw: --- Jul 28 11:37:54 HTPC kernel: cdrom: sr0: mrw address space DMA selected Jul 28 11:37:54 HTPC kernel: attempt to access beyond end of device Jul 28 11:37:54 HTPC kernel: sr0: rw=0, want=68, limit=4 Jul 28 11:37:54 HTPC kernel: isofs_fill_super: bread failed, dev=sr0, iso_blknum=16, block=16 --- I am running under 2.6.12.3, with ATA_ENABLE_ATAPI and ATA_ENABLE_PATA in libata.h turned on. My motherboard is an Intel 915G, with a Intel 82801 FW/FB (ICH6) Sata controller. I see that there are a variety of branches out there for SATA. Should I try any of them? Or can you suggest any other strategy for solving this problem? Also: Is this a known issue? Should I open a bug report in Bugzilla on this? I'm pretty ignorant about the workings of SATA, so I can't be much help with coding. But if a developer would like to try out some fixes on my configuration, I'd be happy work with him or her to do the testing. Thanks in advance for your help, -Polly Start your day with Yahoo! - make it your home page http://www.yahoo.com/r/hs - To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/3] Add disk hotswap support to libata
On Thu, 21 Jul 2005 21:35:24 EDT, Jeff Garzik wrote: >As soon as I finish SATA ATAPI (this week[end]), I'll take a look at >this. A quick review of the patches didn't turn up anything terribly >objectionable, though :) > I would like to offer to test when you are ready. Some older and new SATAPI drives, various chipsets (ICH{5,6}, TX4 on the way). And a SATA analyzer for anything really odd. ++doug - To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
copyright and linux patches
For libata and submitted patches, how is copyright dealt with? Based on some googling, it sounds like each project decides on its own policy of whether ownership is transfered to the maintainer, stays with the submitter, or does something else. This isn't a question of licensing; it's just a question of how copyright and patches work for libata and linux. I'm also not expecting a legal answer, just some idea about what's intended =) Thanks, Tim Thelin - To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: copyright and linux patches
On Thu, Jul 28, 2005 at 12:03:41PM -0700, Timothy Thelin wrote: > > For libata and submitted patches, how is copyright dealt with? Based on > some googling, it sounds like each project decides on its own policy of > whether ownership is transfered to the maintainer, stays with the submitter, > or does something else. No doubt someone will correct me if I'm wrong, but my understanding is that the actual copyright remains w/ the submitter. The license is, of course, GPL. John -- John W. Linville [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/3] Add disk hotswap support to libata
Doug Maxey wrote: On Thu, 21 Jul 2005 21:35:24 EDT, Jeff Garzik wrote: As soon as I finish SATA ATAPI (this week[end]), I'll take a look at this. A quick review of the patches didn't turn up anything terribly objectionable, though :) I would like to offer to test when you are ready. Some older and new SATAPI drives, various chipsets (ICH{5,6}, TX4 on the way). And a SATA analyzer for anything really odd. Great! It'll be posted here on linux-ide, so just keep an eye out. Analysis of any portion of libata, with a SATA analyzer, would be much appreciated. Jeff - To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[git patches] 2.4.x SATA update
Please pull from the 'upstream' branch of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-2.4.git which will update 2.4.x SATA to the latest, according to the attached diffstat/changelog/patch. drivers/scsi/ahci.c | 127 ++--- drivers/scsi/ata_piix.c | 32 +- drivers/scsi/libata-core.c| 555 +- drivers/scsi/libata-scsi.c| 18 - drivers/scsi/libata.h |2 drivers/scsi/sata_nv.c|2 drivers/scsi/sata_promise.c | 30 ++ drivers/scsi/sata_qstor.c |2 drivers/scsi/sata_sil.c | 10 drivers/scsi/sata_sis.c |1 drivers/scsi/sata_svw.c | 28 +- drivers/scsi/sata_sx4.c |2 drivers/scsi/sata_uli.c |1 drivers/scsi/sata_via.c |1 drivers/scsi/sata_vsc.c |1 include/linux/ata.h |1 include/linux/libata-compat.h |3 include/linux/libata.h| 67 + 18 files changed, 741 insertions(+), 142 deletions(-) commit c9a8f5ab981ced23e95b72b25aa83e37880f2287 Author: Jeff Garzik <[EMAIL PROTECTED]> Date: Sat Jul 23 20:12:48 2005 -0400 libata: update to 2.6.x latest Minor stuff: * doc updates * pci id updates * new ->host_stop behavior * fix bugs in PIO data xfer, SATA probe, large disk SCSI xlat diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -38,7 +38,8 @@ #include #define DRV_NAME "ahci" -#define DRV_VERSION"1.00" +#define DRV_VERSION"1.01" + enum { AHCI_PCI_BAR= 5, @@ -48,6 +49,7 @@ enum { AHCI_CMD_SLOT_SZ= 32 * 32, AHCI_RX_FIS_SZ = 256, AHCI_CMD_TBL_HDR= 0x80, + AHCI_CMD_TBL_CDB= 0x40, AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16), AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ + AHCI_RX_FIS_SZ, @@ -132,6 +134,9 @@ enum { PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */ PORT_CMD_ICC_PARTIAL= (0x2 << 28), /* Put i/f in partial state */ PORT_CMD_ICC_SLUMBER= (0x6 << 28), /* Put i/f in slumber state */ + + /* hpriv->flags bits */ + AHCI_FLAG_MSI = (1 << 0), }; struct ahci_cmd_hdr { @@ -181,13 +186,14 @@ static void ahci_qc_prep(struct ata_queu static u8 ahci_check_status(struct ata_port *ap); static u8 ahci_check_err(struct ata_port *ap); static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); +static void ahci_remove_one (struct pci_dev *pdev); static Scsi_Host_Template ahci_sht = { .module = THIS_MODULE, .name = DRV_NAME, - .ioctl = ata_scsi_ioctl, .detect = ata_scsi_detect, .release= ata_scsi_release, + .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, .eh_strategy_handler= ata_scsi_error, .can_queue = ATA_DEF_QUEUE, @@ -256,6 +262,12 @@ static struct pci_device_id ahci_pci_tbl board_ahci }, /* ICH7R */ { PCI_VENDOR_ID_AL, 0x5288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* ULi M5288 */ + { PCI_VENDOR_ID_INTEL, 0x2681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_ahci }, /* ESB2 */ + { PCI_VENDOR_ID_INTEL, 0x2682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_ahci }, /* ESB2 */ + { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_ahci }, /* ESB2 */ { } /* terminate list */ }; @@ -264,7 +276,7 @@ static struct pci_driver ahci_pci_driver .name = DRV_NAME, .id_table = ahci_pci_tbl, .probe = ahci_init_one, - .remove = ata_pci_remove_one, + .remove = ahci_remove_one, }; @@ -282,6 +294,8 @@ static void ahci_host_stop(struct ata_ho { struct ahci_host_priv *hpriv = host_set->private_data; kfree(hpriv); + + ata_host_stop(host_set); } static int ahci_port_start(struct ata_port *ap) @@ -289,26 +303,19 @@ static int ahci_port_start(struct ata_po struct device *dev = ap->host_set->dev; struct ahci_host_priv *hpriv = ap->host_set->private_data; struct ahci_port_priv *pp; - int rc; void *mem, *mmio = ap->host_set->mmio_base; void *port_mmio = ahci_port_base(mmio, ap->port_no); dma_addr_t mem_dma; - rc = ata_port_start(ap); - if (rc) - return rc; - pp = kmalloc(sizeof(*pp), GFP_KERNEL); - if (!pp) { - rc = -ENOMEM; - goto err_out; - } + if (!pp) + return -ENOMEM; memset(pp, 0, sizeof(*pp)); mem = dma_alloc_coherent(dev,
Re: [PATCH linux-2.6.13-rc3] SATA: rewritten sil24 driver
Tejun Heo wrote: Hello, Jeff. This is rewritten sil24 driver against v2.6.13-rc3. It seems to work and am currently running stress test on it (random raw read of concurrency 4, repeatitive mount/copy/checksup/unmount). I'll keep running stress test for at least 12 hours and let you know if something goes wrong. I've also tested basic error handling and it seems to work. I've merged this into the 'sil24' branch of libata-dev.git, and moved the original driver from Silicon Image into the 'sil24-original' branch. So, please submit an incremental patch for any future changes to this driver. Comments below, need a few fixups before pushing upstream, most likely. Also, a question: do you have hardware docs? diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -499,6 +499,14 @@ config SCSI_SATA_SIL If unsure, say N. +config SCSI_SATA_SIL24 + tristate "Silicon Image 3124/3132 SATA support" + depends on SCSI_SATA && PCI && EXPERIMENTAL + help + This option enables support for Silicon Image 3124/3132 Serial ATA. + + If unsure, say N. + config SCSI_SATA_SIS tristate "SiS 964/180 SATA support" depends on SCSI_SATA && PCI && EXPERIMENTAL diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -126,6 +126,7 @@ obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o obj-$(CONFIG_SCSI_SATA_QSTOR) += libata.o sata_qstor.o obj-$(CONFIG_SCSI_SATA_SIL)+= libata.o sata_sil.o +obj-$(CONFIG_SCSI_SATA_SIL24) += libata.o sata_sil24.o obj-$(CONFIG_SCSI_SATA_VIA)+= libata.o sata_via.o obj-$(CONFIG_SCSI_SATA_VITESSE)+= libata.o sata_vsc.o obj-$(CONFIG_SCSI_SATA_SIS)+= libata.o sata_sis.o diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c new file mode 100644 --- /dev/null +++ b/drivers/scsi/sata_sil24.c @@ -0,0 +1,786 @@ +/* + * sata_sil24.c - Driver for Silicon Image 3124/3132 SATA-2 controllers + * + * Copyright 2005 Tejun Heo + * + * Based on preview driver from Silicon Image. + * + * NOTE: No NCQ/ATAPI support yet. The preview driver didn't support + * NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make + * those work. Enabling those shouldn't be difficult. Basic + * structure is all there (in libata-dev tree). If you have any + * information about this hardware, please contact me or linux-ide. + * Info is needed on... + * + * - How to issue tagged commands and turn on sactive on issue accordingly. + * - Where to put an ATAPI command and how to tell the device to send it. + * - How to enable/use 64bit. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "scsi.h" +#include +#include + +#define DRV_NAME "sata_sil24" +#define DRV_VERSION"0.20"/* Silicon Image's preview driver was 0.10 */ + +#define NR_PORTS 4 + +/* + * Port request block (PRB) 32 bytes + */ +struct sil24_prb { + u16 ctrl; + u16 prot; + u32 rx_cnt; + u8 fis[6 * 4]; +}; + +/* + * Scatter gather entry (SGE) 16 bytes + */ +struct sil24_sge { + u64 addr; + u32 cnt; + u32 flags; +}; + +/* + * Port multiplier + */ +struct sil24_port_multiplier { + u32 diag; + u32 sactive; +}; I know this is unlikely, but just asking... you didn't test this with a port multiplier, did you? +enum { + /* +* Global controller registers (128 bytes @ BAR0) +*/ + /* 32 bit regs */ + HOST_SLOT_STAT = 0x00, /* 32 bit slot stat * 4 */ + HOST_CTRL = 0x40, + HOST_IRQ_STAT = 0x44, + HOST_PHY_CFG= 0x48, + HOST_BIST_CTRL = 0x50, + HOST_BIST_PTRN = 0x54, + HOST_BIST_STAT = 0x58, + HOST_MEM_BIST_STAT = 0x5c, + HOST_FLASH_CMD = 0x70, + /* 8 bit regs */ + HOST_FLASH_DATA = 0x74, + HOST_TRANSITION_DETECT = 0x75, + HOST_GPIO_CTRL = 0x76, + HOST_I2C_ADDR = 0x78, /* 32 bit */ + HOST_I2C_DATA = 0x7c, + HOST_I2C_XFER_CNT = 0x7e, + HOST_I2C_CTRL = 0x7f, + + /* HOST_SLOT_STAT bits */ + HOST_SSTAT_ATTN = (1 << 31), + + /* +* Po
Re: [PATCH] ata_piix.c: check PCI sub-class code before AHCI disabling
Greg Felix wrote: This patch adds functionality to check the PCI sub-class code of an AHCI capable device before disabling AHCI. It fixes a bug where an ICH7 sata controller is being setup by the BIOS as sub-class 1 (ide) and the AHCI control registers weren't being initialized, thus causing an IO error in piix_disable_ahci(). Thanks, Greg Felix Signed-off-by: Gregory Felix <[EMAIL PROTECTED]> Applied to 2.6.x, and uploads to 'upstream' branch of libata-dev.git. Will apply to 2.4.x as soon as Marcelo pulls what I just submitted. Jeff - To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC][PATCH] libata ATAPI alignment
So, one thing that's terribly ugly about SATA ATAPI is that we need to pad DMA transfers to the next 32-bit boundary, if the length is not evenly divisible by 4. Messing with the scatterlist to accomplish this is terribly ugly no matter how you slice it. One way would be to create my own scatterlist, via memcpy and then manual labor. Another way would be to special case a pad buffer, appending it onto the end of various scatterlist code. Complicating matters, we currently must support two methods of data buffer submission: a single kernel virtual address, or a struct scatterlist. Review is requested by any and all parties, as well as suggestions for a prettier approach. This is one of the last steps needed to get ATAPI going. diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -44,7 +44,7 @@ enum { AHCI_PCI_BAR= 5, - AHCI_MAX_SG = 168, /* hardware max is 64K */ + AHCI_MAX_SG = 300, /* hardware max is 64K */ AHCI_DMA_BOUNDARY = 0x, AHCI_USE_CLUSTERING = 0, AHCI_CMD_SLOT_SZ= 32 * 32, @@ -197,7 +197,7 @@ static Scsi_Host_Template ahci_sht = { .eh_strategy_handler= ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id= ATA_SHT_THIS_ID, - .sg_tablesize = AHCI_MAX_SG, + .sg_tablesize = AHCI_MAX_SG - 1, .max_sectors= ATA_MAX_SECTORS, .cmd_per_lun= ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, @@ -313,8 +313,15 @@ static int ahci_port_start(struct ata_po return -ENOMEM; memset(pp, 0, sizeof(*pp)); + ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, &ap->pad_dma, GFP_KERNEL); + if (!ap->pad) { + kfree(pp); + return -ENOMEM; + } + mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) { + dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); kfree(pp); return -ENOMEM; } @@ -390,6 +397,7 @@ static void ahci_port_stop(struct ata_po ap->private_data = NULL; dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, pp->cmd_slot, pp->cmd_slot_dma); + dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); kfree(pp); } @@ -474,7 +482,8 @@ static void ahci_tf_read(struct ata_port static void ahci_fill_sg(struct ata_queued_cmd *qc) { - struct ahci_port_priv *pp = qc->ap->private_data; + struct ata_port *ap = qc->ap; + struct ahci_port_priv *pp = ap->private_data; unsigned int i; VPRINTK("ENTER\n"); @@ -493,6 +502,24 @@ static void ahci_fill_sg(struct ata_queu pp->cmd_tbl_sg[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); pp->cmd_tbl_sg[i].flags_size = cpu_to_le32(sg_len - 1); } + + /* if we added a small buffer, to pad xfer to next 32-bit bound, +* add it to the s/g list here +*/ + if (qc->flags & ATA_QCFLAG_PADDED) { + dma_addr_t pad_addr = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ); + u32 len; + + /* fixup last s/g entry */ + len = le32_to_cpu(pp->cmd_tbl_sg[i - 1].flags_size); + pp->cmd_tbl_sg[i - 1].flags_size = + cpu_to_le32(len - qc->pad_len); + + /* append pad buffer to s/g list */ + pp->cmd_tbl_sg[i].addr = cpu_to_le32(pad_addr & 0x); + pp->cmd_tbl_sg[i].addr_hi = cpu_to_le32((pad_addr >> 16) >> 16); + pp->cmd_tbl_sg[i].flags_size = cpu_to_le32(ATA_DMA_PAD_SZ - 1); + } } static void ahci_qc_prep(struct ata_queued_cmd *qc) @@ -501,13 +528,16 @@ static void ahci_qc_prep(struct ata_queu struct ahci_port_priv *pp = ap->private_data; u32 opts; const u32 cmd_fis_len = 5; /* five dwords */ + unsigned int n_elem = qc->n_elem; /* * Fill in command slot information (currently only one slot, * slot 0, is currently since we don't do queueing) */ - opts = (qc->n_elem << 16) | cmd_fis_len; + if (qc->flags & ATA_QCFLAG_PADDED) + n_elem++; + opts = (n_elem << 16) | cmd_fis_len; if (qc->tf.flags & ATA_TFLAG_WRITE) opts |= AHCI_CMD_WRITE; if (is_atapi_taskfile(&qc->tf)) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -2144,6 +2144,8 @@ static void ata_sg_clean(struct ata_queu struct ata_port *ap = qc->ap; struct scatterlist *sg = qc->sg; int dir = qc->dma_dir; + unsigned int copy_pad = 0; + void *pad_buf = NULL; assert(qc->flags & ATA
[git patch] 2.6.x libata fix
Please pull from 'upstream' branch of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git to obtain the fix described in the attached diffstat/changelog/patch. drivers/scsi/ata_piix.c | 19 +-- 1 files changed, 13 insertions(+), 6 deletions(-) commit 7b6dbd6872ca1d0c03dc0e0a7108d79c8dafa793 Author: Greg Felix <[EMAIL PROTECTED]> Date: Thu Jul 28 15:54:15 2005 -0400 libata: Check PCI sub-class code before disabling AHCI This patch adds functionality to check the PCI sub-class code of an AHCI capable device before disabling AHCI. It fixes a bug where an ICH7 sata controller is being setup by the BIOS as sub-class 1 (ide) and the AHCI control registers weren't being initialized, thus causing an IO error in piix_disable_ahci(). Signed-off-by: Gregory Felix <[EMAIL PROTECTED]> diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c @@ -38,6 +38,7 @@ enum { PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ ICH5_PMR= 0x90, /* port mapping register */ ICH5_PCS= 0x92, /* port control and status */ + PIIX_SCC= 0x0A, /* sub-class code register */ PIIX_FLAG_AHCI = (1 << 28), /* AHCI possible */ PIIX_FLAG_CHECKINTR = (1 << 29), /* make sure PCI INTx enabled */ @@ -62,6 +63,8 @@ enum { ich6_sata_rm= 4, ich7_sata = 5, esb2_sata = 6, + + PIIX_AHCI_DEVICE= 6, }; static int piix_init_one (struct pci_dev *pdev, @@ -574,11 +577,11 @@ static int piix_disable_ahci(struct pci_ addr = pci_resource_start(pdev, AHCI_PCI_BAR); if (!addr || !pci_resource_len(pdev, AHCI_PCI_BAR)) return 0; - + mmio = ioremap(addr, 64); if (!mmio) return -ENOMEM; - + tmp = readl(mmio + AHCI_GLOBAL_CTL); if (tmp & AHCI_ENABLE) { tmp &= ~AHCI_ENABLE; @@ -588,7 +591,7 @@ static int piix_disable_ahci(struct pci_ if (tmp & AHCI_ENABLE) rc = -EIO; } - + iounmap(mmio); return rc; } @@ -626,9 +629,13 @@ static int piix_init_one (struct pci_dev port_info[1] = NULL; if (port_info[0]->host_flags & PIIX_FLAG_AHCI) { - int rc = piix_disable_ahci(pdev); - if (rc) - return rc; + u8 tmp; + pci_read_config_byte(pdev, PIIX_SCC, &tmp); + if (tmp == PIIX_AHCI_DEVICE) { + int rc = piix_disable_ahci(pdev); + if (rc) + return rc; + } } if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) {