dect
/
linux-2.6
Archived
13
0
Fork 0

qla1280: sg chaining support

Interesting hardware setup...

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
Jens Axboe 2007-05-09 13:02:43 +02:00
parent b0f655d0ef
commit a044189137
1 changed files with 37 additions and 29 deletions

View File

@ -2775,7 +2775,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
struct device_reg __iomem *reg = ha->iobase; struct device_reg __iomem *reg = ha->iobase;
struct scsi_cmnd *cmd = sp->cmd; struct scsi_cmnd *cmd = sp->cmd;
cmd_a64_entry_t *pkt; cmd_a64_entry_t *pkt;
struct scatterlist *sg = NULL; struct scatterlist *sg = NULL, *s;
__le32 *dword_ptr; __le32 *dword_ptr;
dma_addr_t dma_handle; dma_addr_t dma_handle;
int status = 0; int status = 0;
@ -2889,13 +2889,16 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
* Load data segments. * Load data segments.
*/ */
if (seg_cnt) { /* If data transfer. */ if (seg_cnt) { /* If data transfer. */
int remseg = seg_cnt;
/* Setup packet address segment pointer. */ /* Setup packet address segment pointer. */
dword_ptr = (u32 *)&pkt->dseg_0_address; dword_ptr = (u32 *)&pkt->dseg_0_address;
if (cmd->use_sg) { /* If scatter gather */ if (cmd->use_sg) { /* If scatter gather */
/* Load command entry data segments. */ /* Load command entry data segments. */
for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) { for_each_sg(sg, s, seg_cnt, cnt) {
dma_handle = sg_dma_address(sg); if (cnt == 2)
break;
dma_handle = sg_dma_address(s);
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
if (ha->flags.use_pci_vchannel) if (ha->flags.use_pci_vchannel)
sn_pci_set_vchan(ha->pdev, sn_pci_set_vchan(ha->pdev,
@ -2906,12 +2909,12 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
cpu_to_le32(pci_dma_lo32(dma_handle)); cpu_to_le32(pci_dma_lo32(dma_handle));
*dword_ptr++ = *dword_ptr++ =
cpu_to_le32(pci_dma_hi32(dma_handle)); cpu_to_le32(pci_dma_hi32(dma_handle));
*dword_ptr++ = cpu_to_le32(sg_dma_len(sg)); *dword_ptr++ = cpu_to_le32(sg_dma_len(s));
sg++;
dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n", dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n",
cpu_to_le32(pci_dma_hi32(dma_handle)), cpu_to_le32(pci_dma_hi32(dma_handle)),
cpu_to_le32(pci_dma_lo32(dma_handle)), cpu_to_le32(pci_dma_lo32(dma_handle)),
cpu_to_le32(sg_dma_len(sg))); cpu_to_le32(sg_dma_len(sg_next(s))));
remseg--;
} }
dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather " dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather "
"command packet data - b %i, t %i, l %i \n", "command packet data - b %i, t %i, l %i \n",
@ -2926,7 +2929,9 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
dprintk(3, "S/G Building Continuation...seg_cnt=0x%x " dprintk(3, "S/G Building Continuation...seg_cnt=0x%x "
"remains\n", seg_cnt); "remains\n", seg_cnt);
while (seg_cnt > 0) { while (remseg > 0) {
/* Update sg start */
sg = s;
/* Adjust ring index. */ /* Adjust ring index. */
ha->req_ring_index++; ha->req_ring_index++;
if (ha->req_ring_index == REQUEST_ENTRY_CNT) { if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
@ -2952,9 +2957,10 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
(u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address; (u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address;
/* Load continuation entry data segments. */ /* Load continuation entry data segments. */
for (cnt = 0; cnt < 5 && seg_cnt; for_each_sg(sg, s, remseg, cnt) {
cnt++, seg_cnt--) { if (cnt == 5)
dma_handle = sg_dma_address(sg); break;
dma_handle = sg_dma_address(s);
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
if (ha->flags.use_pci_vchannel) if (ha->flags.use_pci_vchannel)
sn_pci_set_vchan(ha->pdev, sn_pci_set_vchan(ha->pdev,
@ -2966,12 +2972,12 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
*dword_ptr++ = *dword_ptr++ =
cpu_to_le32(pci_dma_hi32(dma_handle)); cpu_to_le32(pci_dma_hi32(dma_handle));
*dword_ptr++ = *dword_ptr++ =
cpu_to_le32(sg_dma_len(sg)); cpu_to_le32(sg_dma_len(s));
dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n", dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n",
cpu_to_le32(pci_dma_hi32(dma_handle)), cpu_to_le32(pci_dma_hi32(dma_handle)),
cpu_to_le32(pci_dma_lo32(dma_handle)), cpu_to_le32(pci_dma_lo32(dma_handle)),
cpu_to_le32(sg_dma_len(sg))); cpu_to_le32(sg_dma_len(s)));
sg++; remseg--;
} }
dprintk(5, "qla1280_64bit_start_scsi: " dprintk(5, "qla1280_64bit_start_scsi: "
"continuation packet data - b %i, t " "continuation packet data - b %i, t "
@ -3062,7 +3068,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
struct device_reg __iomem *reg = ha->iobase; struct device_reg __iomem *reg = ha->iobase;
struct scsi_cmnd *cmd = sp->cmd; struct scsi_cmnd *cmd = sp->cmd;
struct cmd_entry *pkt; struct cmd_entry *pkt;
struct scatterlist *sg = NULL; struct scatterlist *sg = NULL, *s;
__le32 *dword_ptr; __le32 *dword_ptr;
int status = 0; int status = 0;
int cnt; int cnt;
@ -3188,6 +3194,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
* Load data segments. * Load data segments.
*/ */
if (seg_cnt) { if (seg_cnt) {
int remseg = seg_cnt;
/* Setup packet address segment pointer. */ /* Setup packet address segment pointer. */
dword_ptr = &pkt->dseg_0_address; dword_ptr = &pkt->dseg_0_address;
@ -3196,22 +3203,25 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
qla1280_dump_buffer(1, (char *)sg, 4 * 16); qla1280_dump_buffer(1, (char *)sg, 4 * 16);
/* Load command entry data segments. */ /* Load command entry data segments. */
for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) { for_each_sg(sg, s, seg_cnt, cnt) {
if (cnt == 4)
break;
*dword_ptr++ = *dword_ptr++ =
cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); cpu_to_le32(pci_dma_lo32(sg_dma_address(s)));
*dword_ptr++ = *dword_ptr++ = cpu_to_le32(sg_dma_len(s));
cpu_to_le32(sg_dma_len(sg));
dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n", dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n",
(pci_dma_lo32(sg_dma_address(sg))), (pci_dma_lo32(sg_dma_address(s))),
(sg_dma_len(sg))); (sg_dma_len(s)));
sg++; remseg--;
} }
/* /*
* Build continuation packets. * Build continuation packets.
*/ */
dprintk(3, "S/G Building Continuation" dprintk(3, "S/G Building Continuation"
"...seg_cnt=0x%x remains\n", seg_cnt); "...seg_cnt=0x%x remains\n", seg_cnt);
while (seg_cnt > 0) { while (remseg > 0) {
/* Continue from end point */
sg = s;
/* Adjust ring index. */ /* Adjust ring index. */
ha->req_ring_index++; ha->req_ring_index++;
if (ha->req_ring_index == REQUEST_ENTRY_CNT) { if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
@ -3239,18 +3249,16 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
&((struct cont_entry *) pkt)->dseg_0_address; &((struct cont_entry *) pkt)->dseg_0_address;
/* Load continuation entry data segments. */ /* Load continuation entry data segments. */
for (cnt = 0; cnt < 7 && seg_cnt; for_each_sg(sg, s, remseg, cnt) {
cnt++, seg_cnt--) {
*dword_ptr++ = *dword_ptr++ =
cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); cpu_to_le32(pci_dma_lo32(sg_dma_address(s)));
*dword_ptr++ = *dword_ptr++ =
cpu_to_le32(sg_dma_len(sg)); cpu_to_le32(sg_dma_len(s));
dprintk(1, dprintk(1,
"S/G Segment Cont. phys_addr=0x%x, " "S/G Segment Cont. phys_addr=0x%x, "
"len=0x%x\n", "len=0x%x\n",
cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))), cpu_to_le32(pci_dma_lo32(sg_dma_address(s))),
cpu_to_le32(sg_dma_len(sg))); cpu_to_le32(sg_dma_len(s)));
sg++;
} }
dprintk(5, "qla1280_32bit_start_scsi: " dprintk(5, "qla1280_32bit_start_scsi: "
"continuation packet data - " "continuation packet data - "