On Sun, 28 Oct 2007 06:29:32 -0400, Jeff Garzik wrote: > BTW, looking at the Promise code I see > > > cam_con.h: > > /* for ASIC bug, limit the last element of SG byteCount must < 32 Dword */ > > #define SG_COUNT_ASIC_BUG 32 > > //#define SG_COUNT_ASIC_BUG 128 > > and in the code itself > > > /* check PRD table, last element <= (32 Dword), fix ASIC bug */ > > (though the code obviously uses SG_COUNT_ASIC_BUG==32, as the first > paste indicates) > > so it seems like Promise first used 128 (32 dwords), but then backed > down to 32 (8 dwords). > > Either way, we definitely have an ASIC bug to work around, it seems... You're looking at the old pdc-ultra2 driver. The newer unified sataii150-300 driver (v1.01.0.23) upped the value to 41*4. I've reviewed Alexander's patch, and I'm currently testing it with the add-on patch below (fix sg_tablesize, code formatting stuff, fix uninitialised 'addr' in a VPRINTK). /Mikael --- linux-2.6.24-rc1/drivers/ata/sata_promise.c.~1~ 2007-10-28 11:58:01.000000000 +0100 +++ linux-2.6.24-rc1/drivers/ata/sata_promise.c 2007-10-28 12:20:53.000000000 +0100 @@ -155,7 +155,7 @@ static struct scsi_host_template pdc_ata .queuecommand = ata_scsi_queuecmd, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = LIBATA_MAX_PRD, + .sg_tablesize = LIBATA_MAX_PRD-1, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -542,7 +542,7 @@ static void pdc_fill_sg(struct ata_queue if (!(qc->flags & ATA_QCFLAG_DMAMAP)) return; - + WARN_ON(qc->__sg == NULL); WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); @@ -579,18 +579,15 @@ static void pdc_fill_sg(struct ata_queue if (len > SG_COUNT_ASIC_BUG) { u32 addr; - /* if len < 2*SG_COUNT_ASIC_BUG then last - segment will be larger than next-to-last. - Somewhat ugly :( - */ VPRINTK("Splitting last PRD.\n"); + addr = le32_to_cpu(ap->prd[idx - 1].addr); ap->prd[idx - 1].flags_len -= cpu_to_le32(SG_COUNT_ASIC_BUG); VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx - 1, addr, SG_COUNT_ASIC_BUG); - - addr = le32_to_cpu(ap->prd[idx - 1].addr) + len - SG_COUNT_ASIC_BUG; - len = SG_COUNT_ASIC_BUG; + + addr = addr + len - SG_COUNT_ASIC_BUG; + len = SG_COUNT_ASIC_BUG; ap->prd[idx].addr = cpu_to_le32(addr); ap->prd[idx].flags_len = cpu_to_le32(len); VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len); - To unsubscribe from this list: 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