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

Reply via email to