X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fscsi%2Faha1740.c;h=f6722fd46008a2f451ceb645411e93f6b4115fae;hb=e482179d547ff250cab487859b6fc91995bbdbb5;hp=6b35ed8301e0dac3211968409505bc2f4f63fbb2;hpb=5ffd1a6aaacc25be8cd0770a51ec6d46add3a276;p=linux-2.6-omap-h63xx.git diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index 6b35ed8301e..f6722fd4600 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -223,8 +223,7 @@ static int aha1740_test_port(unsigned int base) } /* A "high" level interrupt handler */ -static irqreturn_t aha1740_intr_handle(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t aha1740_intr_handle(int irq, void *dev_id) { struct Scsi_Host *host = (struct Scsi_Host *) dev_id; void (*my_done)(Scsi_Cmnd *); @@ -272,20 +271,8 @@ static irqreturn_t aha1740_intr_handle(int irq, void *dev_id, continue; } sgptr = (struct aha1740_sg *) SCtmp->host_scribble; - if (SCtmp->use_sg) { - /* We used scatter-gather. - Do the unmapping dance. */ - dma_unmap_sg (&edev->dev, - (struct scatterlist *) SCtmp->request_buffer, - SCtmp->use_sg, - SCtmp->sc_data_direction); - } else { - dma_unmap_single (&edev->dev, - sgptr->buf_dma_addr, - SCtmp->request_bufflen, - DMA_BIDIRECTIONAL); - } - + scsi_dma_unmap(SCtmp); + /* Free the sg block */ dma_free_coherent (&edev->dev, sizeof (struct aha1740_sg), @@ -350,11 +337,9 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) unchar target = scmd_id(SCpnt); struct aha1740_hostdata *host = HOSTDATA(SCpnt->device->host); unsigned long flags; - void *buff = SCpnt->request_buffer; - int bufflen = SCpnt->request_bufflen; dma_addr_t sg_dma; struct aha1740_sg *sgptr; - int ecbno; + int ecbno, nseg; DEB(int i); if(*cmd == REQUEST_SENSE) { @@ -424,24 +409,23 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) } sgptr = (struct aha1740_sg *) SCpnt->host_scribble; sgptr->sg_dma_addr = sg_dma; - - if (SCpnt->use_sg) { - struct scatterlist * sgpnt; + + nseg = scsi_dma_map(SCpnt); + BUG_ON(nseg < 0); + if (nseg) { + struct scatterlist *sg; struct aha1740_chain * cptr; - int i, count; + int i; DEB(unsigned char * ptr); host->ecb[ecbno].sg = 1; /* SCSI Initiator Command * w/scatter-gather*/ - sgpnt = (struct scatterlist *) SCpnt->request_buffer; cptr = sgptr->sg_chain; - count = dma_map_sg (&host->edev->dev, sgpnt, SCpnt->use_sg, - SCpnt->sc_data_direction); - for(i=0; i < count; i++) { - cptr[i].datalen = sg_dma_len (sgpnt + i); - cptr[i].dataptr = sg_dma_address (sgpnt + i); + scsi_for_each_sg(SCpnt, sg, nseg, i) { + cptr[i].datalen = sg_dma_len (sg); + cptr[i].dataptr = sg_dma_address (sg); } - host->ecb[ecbno].datalen = count*sizeof(struct aha1740_chain); + host->ecb[ecbno].datalen = nseg * sizeof(struct aha1740_chain); host->ecb[ecbno].dataptr = sg_dma; #ifdef DEBUG printk("cptr %x: ",cptr); @@ -449,11 +433,8 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) for(i=0;i<24;i++) printk("%02x ", ptr[i]); #endif } else { - host->ecb[ecbno].datalen = bufflen; - sgptr->buf_dma_addr = dma_map_single (&host->edev->dev, - buff, bufflen, - DMA_BIDIRECTIONAL); - host->ecb[ecbno].dataptr = sgptr->buf_dma_addr; + host->ecb[ecbno].datalen = 0; + host->ecb[ecbno].dataptr = 0; } host->ecb[ecbno].lun = SCpnt->device->lun; host->ecb[ecbno].ses = 1; /* Suppress underrun errors */ @@ -582,12 +563,13 @@ static struct scsi_host_template aha1740_template = { .sg_tablesize = AHA1740_SCATTER, .cmd_per_lun = AHA1740_CMDLUN, .use_clustering = ENABLE_CLUSTERING, + .use_sg_chaining = ENABLE_SG_CHAINING, .eh_abort_handler = aha1740_eh_abort_handler, }; static int aha1740_probe (struct device *dev) { - int slotbase; + int slotbase, rc; unsigned int irq_level, irq_type, translation; struct Scsi_Host *shpnt; struct aha1740_hostdata *host; @@ -642,10 +624,16 @@ static int aha1740_probe (struct device *dev) } eisa_set_drvdata (edev, shpnt); - scsi_add_host (shpnt, dev); /* XXX handle failure */ + + rc = scsi_add_host (shpnt, dev); + if (rc) + goto err_irq; + scsi_scan_host (shpnt); return 0; + err_irq: + free_irq(irq_level, shpnt); err_unmap: dma_unmap_single (&edev->dev, host->ecb_dma_addr, sizeof (host->ecb), DMA_BIDIRECTIONAL);