From mboxrd@z Thu Jan 1 00:00:00 1970 From: Luben Tuikov Subject: Re: [example PATCH - not for applying] exclude certain commands Date: Mon, 28 Apr 2003 15:05:42 -0400 Sender: linux-scsi-owner@vger.kernel.org Message-ID: <3EAD7B86.8060300@rogers.com> References: <20030426151356.A8697@one-eyed-alien.net> <1051397024.4089.86.camel@mulgrave> <20030426183428.B8697@one-eyed-alien.net> <1051409717.4089.146.camel@mulgrave> <20030427023517.A15212@one-eyed-alien.net> <1051458107.2427.25.camel@fuzzy> <20030427125237.A23693@one-eyed-alien.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Return-path: Received: from fep02-mail.bloor.is.net.cable.rogers.com ([66.185.86.72]:3084 "EHLO fep02-mail.bloor.is.net.cable.rogers.com") by vger.kernel.org with ESMTP id S261251AbTD1Sxj (ORCPT ); Mon, 28 Apr 2003 14:53:39 -0400 In-Reply-To: <20030427125237.A23693@one-eyed-alien.net> List-Id: linux-scsi@vger.kernel.org To: Matthew Dharm Cc: James Bottomley , Andries.Brouwer@cwi.nl, greg@kroah.com, SCSI Mailing List , linux-usb-devel@lists.sourceforge.net Matthew Dharm wrote: > On Sun, Apr 27, 2003 at 10:41:45AM -0500, James Bottomley wrote: > >>So the algorithm is quite simple: you get the command length from the >>group (using a table with one exception for the 32 byte commands), and >>then extract the transfer length from the command > > > I'm with you up to about this point. > > So tell me how many bytes my command wanted to move? READ_10 specifies the > transfer length is 'blocks'. How many bytes are in a block is > device-dependent. > > Some commands (i.e. INQUIRY) specify transfer length in bytes. Others > (i.e. READ_10) specify it in blocks, and the size of a block is not known > based simply on the current command. Matt, You cannot really constrict yourself to the CDB only. As a transport/interconnect (what a LLDD is, as well as USB Storage) you get an Execute Command remote procedure call, in SCSI Core this is represented by struct scsi_cmnd. Execute Command rpc contains all that the transport/ic needs in order to deliver the command to the device server (who will execute the CDB) and perform (the interconnect) the data transfer. The reference you want to take a peek at is SAM-3r6, 5.1 -- this is what USB storage is working with, not just the CDB. Now, you've been talking about the Data-Out buffer size. This is either ALLOCATION LENGTH (normally bytes), or TRANFER LENGTH (READ/WRITE, normally blocks). The reference here is SPC3r12, 4.3.4.4 Transfer Length and 4.3.4.6 Allocation Length. Please note that Data-Out buffer size *is* the Expected (maxumum) Data Tranfer Length, the device server may tranfer less data, (request_bufflen, bufflen). This is what the standards specify, and what SCSI Core sets it to. The actual memory buffer may be bigger. The device server may transfer less data, but not more. The device server will NOT modify the returned data to reflect the insufficient data-in buffer. So to repeat what the standards say and what SCSI Core does: sr_bufflen, request_buflen, buflen *is* the Expected (maxumum) Data Tranfer Length: - when it means Allocation Length it is the maximum available space (e.g. IQUIRY, Request Sense), (The transport CANNOT write more data than this!) - when it means Transfer Length it is the Expected Data Transfer Length (READ/WRITE), and I say ``expected'' less any End Of Media or similar errors pop up, (i.e. number of blocks from CDB * block_size = this value). I.e. the _actual_ buffer size *is* IRRELEVANT to LLDD and the Transport/IC -- since it maybe an offset to another yet bigger buffer and SCSI Core/Appl. Client maybe requesting part of some data (see SAM-3r6, 5.4.3). Some transports provide an Overflow and Underflow bits in the transport protocol to let the Initiator port (LLDD) know about any residuals -- SCSI Core struct scsi_cmnd supports only an underflow residual (bytes that were not transferred out of the number of bytes that were expected to be transferred). I don't know much about USB Storage, but what do you think about this: add an unsigned overflow_resid to struct scsi_cmnd, and set it to an applicable value when a USB storage device provided more data to be transferred, but the buffer was too small. (I can see how this will not work, if you need a large enough ptr to just write the data to...) -- Luben