Hi On Thu, 17 Mar 2005, Jens Axboe wrote:
> On Wed, Mar 16 2005, Guennadi Liakhovetski wrote: > > > > On Wed, 16 Mar 2005, Jens Axboe wrote: > > > The kmap() isn't just inefficient, it's a problem to iterate over the sg > > > list and kmap all the pages. That is illegal. > > > > Hm, what do you mean "illegal"? Could you explain why? > > You risk deadlocking. Emn, I am curious, would be nice to know details:-) > > One more fragment in the driver I wasn't sure about is this: > > > > unsigned long mask = > > ~((unsigned long)sg->length - 1) & PAGE_MASK; > > if ((sg_dma_address(sg) & mask) == (psge->address & mask)) { > > > > Is sg->length guaranteed to be something like a power of 2 or smaller > > than page? I thought about replacing the above with > > No, it's not guaranteed to be a power-of-2. > > > + if (sg_dma_address(sg) <= psge->address && sg_dma_address(sg) + > > psge->length > psge->address) { > > What is it trying to accomplish? So, I was not sure if the old check was correct, was it? The test is supposed to find the current sg-element. > > > @@ -1020,11 +1022,11 @@ > > reqlen, cmd->request_buffer, cmd->use_sg, > > srb->sg_count); > > > > - srb->virt_addr = page_address(sl->page); > > + srb->page = sl->page; > > + srb->offset = sl->offset; > > for (i = 0; i < srb->sg_count; i++) { > > - u32 busaddr = (u32)sg_dma_address(&sl[i]); > > - u32 seglen = (u32)sl[i].length; > > - sgp[i].address = busaddr; > > + u32 seglen = (u32)sg_dma_len(sl + i); > > + sgp[i].address = cpu_to_le32(0xffffffff & > > sg_dma_address(sl +i)); > > sgp[i].length = seglen; > > srb->total_xfer_length += seglen; > > } > > I don't understand this change, why the cpu_to_le32? Well, I copied it from tmscsim: pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl))); I am somewhat confused. In both cases these are bus addresses, right? and sg_dma_address() gives already the bus address, so, both are wrong? BTW, looking at tmscsim again, isn't this if( residual ) { bval = DC390_read8 (ScsiFifo); /* get one residual byte */ ptr = (u8 *) bus_to_virt( pSRB->SGBusAddr ); *ptr = bval; pSRB->SGBusAddr++; xferCnt++; pSRB->TotalXferredLen++; pSRB->SGToBeXferLen--; } also a case for dma_map_atomic? > > + local_irq_save(flags); > > + page_addr = kmap_atomic(srb->page, KM_USER0); > > + virt_addr = page_addr + srb->offset; > > + > > You can't use KM_USER0 here, use one of the bio assigned kmap types (you > can use KM_BIO_SRC_IRQ, for instance - the reason there are two is for > the bouncing that needs to kmap both source and destination at the same > time). Ok, will change that. > > + kunmap_atomic(page_addr, KM_IRQ0); > > + local_irq_restore(flags); > > Here you kunmap_atomic() with a different kmap type than you mapped > with? Must be the same. Auch, manual patch-editing error:-) > Same applies to the matchin section further down. Yep, will fix. Thanks Guennadi --------------------------------- Guennadi Liakhovetski, Ph.D. DSA Daten- und Systemtechnik GmbH Pascalstr. 28 D-52076 Aachen Germany - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html