Patch RFC: Promise SATA300 TX4 hardware bug workaround.
Hello. I have ported the workaround for the hardware bug that causes data corruption on Promise SATA300 TX4 cards to RELENG_7. Bug description: SATA300 TX4 hardware chokes if last PRD entry (in a dma transfer) is larger than 164 bytes. This was found while analysing vendor-supplied linux driver. Workaround: Split trailing PRD entry if it's larger that 164 bytes. Two supplied patches do fix problem on my machine. There is, however, a style problem with them. It seems like PRD entry count is limited at 256. I have not found a good way to guarantee that one entry is always available to do the split, thus the ugly solution of patching ata-dma.c. Patches, patched and original files are at http://lxnt.info/tx4/freebsd/. --- ata-chipset.c.orig 2007-11-02 01:05:49.0 +0300 +++ ata-chipset.c 2007-11-02 01:05:49.0 +0300 @@ -142,6 +142,7 @@ static int ata_promise_mio_command(struct ata_request *request); static void ata_promise_mio_reset(device_t dev); static void ata_promise_mio_dmainit(device_t dev); +static void ata_promise_mio_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); static void ata_promise_mio_setmode(device_t dev, int mode); static void ata_promise_sx4_intr(void *data); static int ata_promise_sx4_command(struct ata_request *request); @@ -185,7 +186,6 @@ static int ata_check_80pin(device_t dev, int mode); static int ata_mode2idx(int mode); - /* * generic ATA support functions */ @@ -3759,8 +3759,44 @@ static void ata_promise_mio_dmainit(device_t dev) { +struct ata_channel *ch = device_get_softc(dev); + /* note start and stop are not used here */ ata_dmainit(dev); + +if (ch->dma) + ch->dma->setprd = ata_promise_mio_dmasetprd; +} + +static void +ata_promise_mio_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) +{ +#define PDC_MAXLASTSGSIZE 41*4 +struct ata_dmasetprd_args *args = xsc; +struct ata_dma_prdentry *prd = args->dmatab; +int i; + +if ((args->error = error)) + return; + +for (i = 0; i < nsegs; i++) { + prd[i].addr = htole32(segs[i].ds_addr); + prd[i].count = htole32(segs[i].ds_len); +} + +if (segs[i - 1].ds_len > PDC_MAXLASTSGSIZE) { + /* + printf("splitting trailing PRD of %ld (limit %d)\n", segs[i - 1].ds_len, PDC_MAXLASTSGSIZE); + */ + prd[i - 1].count = htole32(segs[i - 1].ds_len - PDC_MAXLASTSGSIZE); + prd[i].count = htole32(PDC_MAXLASTSGSIZE); + prd[i].addr = htole32(segs[i - 1].ds_addr + PDC_MAXLASTSGSIZE); + i ++; + nsegs ++; +} + +prd[i - 1].count |= htole32(ATA_DMA_EOT); +args->nsegs = nsegs; } static void --- ata-dma.c.orig 2007-11-02 01:05:53.0 +0300 +++ ata-dma.c 2007-11-02 01:05:53.0 +0300 @@ -113,7 +113,7 @@ if (bus_dma_tag_create(ch->dma->dmatag,ch->dma->alignment,ch->dma->boundary, ch->dma->max_address, BUS_SPACE_MAXADDR, NULL, NULL, ch->dma->max_iosize, - ATA_DMA_ENTRIES, ch->dma->segsize, + ATA_DMA_ENTRIES - 1, ch->dma->segsize, 0, NULL, NULL, &ch->dma->data_tag)) goto error; -- ./lxnt ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"
Re: Patch RFC: Promise SATA300 TX4 hardware bug workaround.
Søren Schmidt wrote: Søren Schmidt wrote: Good catch! However from my quick glimpse at the Promise sources the limit seems to be 32 Dwords ie 32*4 = 128bytes. Please see driver named 4_sataii150-300_linux2.6-src_x86-64_v1.01.0.23 I'll investigate further and ask Promise for the gory details, stay tuned... I dont think the PRD count limitation is a real problem, I've newer seen that long a list and IIRC we newer do more than 64K transfers in one go (yet). In (current) practice, yes, but check should be there even if only to document the limit. Anyhow I need to get checks in for that not just here... Give me a few days and I'll get this figured out for 7-rel... Oh, and I forgot, do you have a surefire way to reproduce the problem so the fix can be tested ? dd if=/dev/ad8 of=/dev/null bs=1048576 count=1000 works every time. I have tested it on my home machine: without the patch first timeouts and errors appear about 10 seconds into the read. with the patch a read of entire disk (320G) completed without errors. Previous tests of analogous linux driver fix shown no errors and no data corruption on two write-whole-drive, read-whole-drive cycles. I've newer been able to trigger this problem myself so far. Seems like the bug is highly configuration-dependent, or pci-chiset-depended, or just present in some production runs and not other. -- ./lxnt ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"
Re: Patch RFC: Promise SATA300 TX4 hardware bug workaround.
Arno J. Klaassen wrote: > definitely an improvement, but not sufficient (for my setup ) : > > amd64-releng_6 on an ASUS A8V UP (box ran rock-stable > for years i386-releng_5 with same hardware apart TX4 and > drives) > > from dmesg : > Setup is identical to mine, except for the drives. http://lxnt.info/tx4/freebsd/dmesg.text > > Improvement : I now can fsck /dev/concat/data without > ad6 being detached It was that bad? wow. > Persistent problem : when I rsync an nfs-mounted disk to /dev/concat/data, > I get after about some Gigs of data have been transfered : > That's strange. Are you sure cables, PSU and line power are ok? Back in October upgrading PSU halved the error count for me (under linux). > > I will test again with "#define PDC_MAXLASTSGSIZE 32*4" (just to see > if that makes a difference) > Please do. -- ./lxnt ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"
Re: Patch RFC: Promise SATA300 TX4 hardware bug workaround.
Arno J. Klaassen wrote: > > Rather than the marginal HW part, it seems, for me, closely related to > MB/BIOS (as well (Alexander apperently has about the same setup as I > have for this test)): > [...] > > I vaguely remember from another PR that the Promise card does > something with PCI-bursting which fbsd does not detect and/or > handle correctly (and beyond my simple skills as dumb tester, but > maybe the linux-sources contain a clue about that as well). > Analysis of chip initialization in vendor-supplied, Linux and FreeBSD drivers shows that FreeBSD's one: - does not enable something called 'BMR_BURST', - performs hotplug init in one write (instead of two read-modify-writes ), - does an extra write (offset 0x54) which is not done in other drivers. Analysis text: http://lxnt.info/tx4/chipinit.text Patch with ported chipinit (dangerous to use with anything from Promise other than sata300 tx4 !!): http://lxnt.info/tx4/freebsd/chipinit.patch (cumulative) http://lxnt.info/tx4/freebsd/ata-chipset.c+chipinit (patched source) Note two things: 1. I have not compiled or tested this patch. Please do. 2. I may have missed this bug because I'm frequently rebooting between Linux and FreeBSD, and what Linux driver initialized may have lasted the reboots. -- ./lxnt ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"
Re: Patch RFC: Promise SATA300 TX4 hardware bug workaround.
Roman Kurakin wrote: By the way, is there any chance to get RAID5 working with this controller? Software only. -- ./lxnt ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"
Re: In search of a video card
xorquew...@googlemail.com wrote: Finally settled on a Radeon x1950 I second that. PCIe X1950Pro with 256Mb RAM is best card price/{performance, stability} - wise you can get right now. -- ./lxnt ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"