11da177e4SLinus Torvalds /* Driver for USB Mass Storage compliant devices 21da177e4SLinus Torvalds * 31da177e4SLinus Torvalds * Current development and maintenance by: 41da177e4SLinus Torvalds * (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Developed with the assistance of: 71da177e4SLinus Torvalds * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org) 81da177e4SLinus Torvalds * (c) 2002 Alan Stern (stern@rowland.org) 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * Initial work by: 111da177e4SLinus Torvalds * (c) 1999 Michael Gee (michael@linuxspecific.com) 121da177e4SLinus Torvalds * 131da177e4SLinus Torvalds * This driver is based on the 'USB Mass Storage Class' document. This 141da177e4SLinus Torvalds * describes in detail the protocol used to communicate with such 151da177e4SLinus Torvalds * devices. Clearly, the designers had SCSI and ATAPI commands in 161da177e4SLinus Torvalds * mind when they created this document. The commands are all very 171da177e4SLinus Torvalds * similar to commands in the SCSI-II and ATAPI specifications. 181da177e4SLinus Torvalds * 191da177e4SLinus Torvalds * It is important to note that in a number of cases this class 201da177e4SLinus Torvalds * exhibits class-specific exemptions from the USB specification. 211da177e4SLinus Torvalds * Notably the usage of NAK, STALL and ACK differs from the norm, in 221da177e4SLinus Torvalds * that they are used to communicate wait, failed and OK on commands. 231da177e4SLinus Torvalds * 241da177e4SLinus Torvalds * Also, for certain devices, the interrupt endpoint is used to convey 251da177e4SLinus Torvalds * status of a command. 261da177e4SLinus Torvalds * 271da177e4SLinus Torvalds * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more 281da177e4SLinus Torvalds * information about this driver. 291da177e4SLinus Torvalds * 301da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify it 311da177e4SLinus Torvalds * under the terms of the GNU General Public License as published by the 321da177e4SLinus Torvalds * Free Software Foundation; either version 2, or (at your option) any 331da177e4SLinus Torvalds * later version. 341da177e4SLinus Torvalds * 351da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful, but 361da177e4SLinus Torvalds * WITHOUT ANY WARRANTY; without even the implied warranty of 371da177e4SLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 381da177e4SLinus Torvalds * General Public License for more details. 391da177e4SLinus Torvalds * 401da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License along 411da177e4SLinus Torvalds * with this program; if not, write to the Free Software Foundation, Inc., 421da177e4SLinus Torvalds * 675 Mass Ave, Cambridge, MA 02139, USA. 431da177e4SLinus Torvalds */ 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds #include <linux/highmem.h> 461da177e4SLinus Torvalds #include <scsi/scsi.h> 471da177e4SLinus Torvalds #include <scsi/scsi_cmnd.h> 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds #include "usb.h" 501da177e4SLinus Torvalds #include "protocol.h" 511da177e4SLinus Torvalds #include "debug.h" 521da177e4SLinus Torvalds #include "scsiglue.h" 531da177e4SLinus Torvalds #include "transport.h" 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds /*********************************************************************** 561da177e4SLinus Torvalds * Protocol routines 571da177e4SLinus Torvalds ***********************************************************************/ 581da177e4SLinus Torvalds 593dae5345SAlan Stern void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) 601da177e4SLinus Torvalds { 613dae5345SAlan Stern /* Pad the SCSI command with zeros out to 12 bytes 621da177e4SLinus Torvalds * 631da177e4SLinus Torvalds * NOTE: This only works because a scsi_cmnd struct field contains 641da177e4SLinus Torvalds * a unsigned char cmnd[16], so we know we have storage available 651da177e4SLinus Torvalds */ 661da177e4SLinus Torvalds for (; srb->cmd_len<12; srb->cmd_len++) 671da177e4SLinus Torvalds srb->cmnd[srb->cmd_len] = 0; 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds /* set command length to 12 bytes */ 701da177e4SLinus Torvalds srb->cmd_len = 12; 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds /* send the command to the transport layer */ 731da177e4SLinus Torvalds usb_stor_invoke_transport(srb, us); 741da177e4SLinus Torvalds } 751da177e4SLinus Torvalds 761da177e4SLinus Torvalds void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us) 771da177e4SLinus Torvalds { 781da177e4SLinus Torvalds /* fix some commands -- this is a form of mode translation 791da177e4SLinus Torvalds * UFI devices only accept 12 byte long commands 801da177e4SLinus Torvalds * 811da177e4SLinus Torvalds * NOTE: This only works because a scsi_cmnd struct field contains 821da177e4SLinus Torvalds * a unsigned char cmnd[16], so we know we have storage available 831da177e4SLinus Torvalds */ 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds /* Pad the ATAPI command with zeros */ 861da177e4SLinus Torvalds for (; srb->cmd_len<12; srb->cmd_len++) 871da177e4SLinus Torvalds srb->cmnd[srb->cmd_len] = 0; 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds /* set command length to 12 bytes (this affects the transport layer) */ 901da177e4SLinus Torvalds srb->cmd_len = 12; 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds /* XXX We should be constantly re-evaluating the need for these */ 931da177e4SLinus Torvalds 941da177e4SLinus Torvalds /* determine the correct data length for these commands */ 951da177e4SLinus Torvalds switch (srb->cmnd[0]) { 961da177e4SLinus Torvalds 971da177e4SLinus Torvalds /* for INQUIRY, UFI devices only ever return 36 bytes */ 981da177e4SLinus Torvalds case INQUIRY: 991da177e4SLinus Torvalds srb->cmnd[4] = 36; 1001da177e4SLinus Torvalds break; 1011da177e4SLinus Torvalds 1021da177e4SLinus Torvalds /* again, for MODE_SENSE_10, we get the minimum (8) */ 1031da177e4SLinus Torvalds case MODE_SENSE_10: 1041da177e4SLinus Torvalds srb->cmnd[7] = 0; 1051da177e4SLinus Torvalds srb->cmnd[8] = 8; 1061da177e4SLinus Torvalds break; 1071da177e4SLinus Torvalds 1081da177e4SLinus Torvalds /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */ 1091da177e4SLinus Torvalds case REQUEST_SENSE: 1101da177e4SLinus Torvalds srb->cmnd[4] = 18; 1111da177e4SLinus Torvalds break; 1121da177e4SLinus Torvalds } /* end switch on cmnd[0] */ 1131da177e4SLinus Torvalds 1141da177e4SLinus Torvalds /* send the command to the transport layer */ 1151da177e4SLinus Torvalds usb_stor_invoke_transport(srb, us); 1161da177e4SLinus Torvalds } 1171da177e4SLinus Torvalds 1181da177e4SLinus Torvalds void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, 1191da177e4SLinus Torvalds struct us_data *us) 1201da177e4SLinus Torvalds { 1211da177e4SLinus Torvalds /* send the command to the transport layer */ 1221da177e4SLinus Torvalds usb_stor_invoke_transport(srb, us); 1231da177e4SLinus Torvalds } 124*e6e244b6SAlan Stern EXPORT_SYMBOL_GPL(usb_stor_transparent_scsi_command); 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds /*********************************************************************** 1271da177e4SLinus Torvalds * Scatter-gather transfer buffer access routines 1281da177e4SLinus Torvalds ***********************************************************************/ 1291da177e4SLinus Torvalds 1301da177e4SLinus Torvalds /* Copy a buffer of length buflen to/from the srb's transfer buffer. 131dd829d23SBoaz Harrosh * Update the **sgptr and *offset variables so that the next copy will 1327084191dSAlan Stern * pick up from where this one left off. 1337084191dSAlan Stern */ 1341da177e4SLinus Torvalds unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, 1351f6f31a0SJens Axboe unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr, 1361da177e4SLinus Torvalds unsigned int *offset, enum xfer_buf_dir dir) 1371da177e4SLinus Torvalds { 1381da177e4SLinus Torvalds unsigned int cnt; 1397084191dSAlan Stern struct scatterlist *sg = *sgptr; 1401da177e4SLinus Torvalds 141dd829d23SBoaz Harrosh /* We have to go through the list one entry 1421da177e4SLinus Torvalds * at a time. Each s-g entry contains some number of pages, and 1431da177e4SLinus Torvalds * each page has to be kmap()'ed separately. If the page is already 1441da177e4SLinus Torvalds * in kernel-addressable memory then kmap() will return its address. 1451da177e4SLinus Torvalds * If the page is not directly accessible -- such as a user buffer 1461da177e4SLinus Torvalds * located in high memory -- then kmap() will map it to a temporary 1477084191dSAlan Stern * position in the kernel's virtual address space. 1487084191dSAlan Stern */ 1491f6f31a0SJens Axboe 1501f6f31a0SJens Axboe if (!sg) 151dd829d23SBoaz Harrosh sg = scsi_sglist(srb); 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds /* This loop handles a single s-g list entry, which may 1541da177e4SLinus Torvalds * include multiple pages. Find the initial page structure 1551da177e4SLinus Torvalds * and the starting offset within the page, and update 1567084191dSAlan Stern * the *offset and **sgptr values for the next loop. 1577084191dSAlan Stern */ 1581da177e4SLinus Torvalds cnt = 0; 1597084191dSAlan Stern while (cnt < buflen && sg) { 16045711f1aSJens Axboe struct page *page = sg_page(sg) + 1611da177e4SLinus Torvalds ((sg->offset + *offset) >> PAGE_SHIFT); 1627084191dSAlan Stern unsigned int poff = (sg->offset + *offset) & (PAGE_SIZE-1); 1631da177e4SLinus Torvalds unsigned int sglen = sg->length - *offset; 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds if (sglen > buflen - cnt) { 1661da177e4SLinus Torvalds 1671da177e4SLinus Torvalds /* Transfer ends within this s-g entry */ 1681da177e4SLinus Torvalds sglen = buflen - cnt; 1691da177e4SLinus Torvalds *offset += sglen; 1701da177e4SLinus Torvalds } else { 1711da177e4SLinus Torvalds 1721da177e4SLinus Torvalds /* Transfer continues to next s-g entry */ 1731da177e4SLinus Torvalds *offset = 0; 1741f6f31a0SJens Axboe sg = sg_next(sg); 1751da177e4SLinus Torvalds } 1761da177e4SLinus Torvalds 1771da177e4SLinus Torvalds /* Transfer the data for all the pages in this 1781da177e4SLinus Torvalds * s-g entry. For each page: call kmap(), do the 1791da177e4SLinus Torvalds * transfer, and call kunmap() immediately after. */ 1801da177e4SLinus Torvalds while (sglen > 0) { 1811da177e4SLinus Torvalds unsigned int plen = min(sglen, (unsigned int) 1821da177e4SLinus Torvalds PAGE_SIZE - poff); 1831da177e4SLinus Torvalds unsigned char *ptr = kmap(page); 1841da177e4SLinus Torvalds 1851da177e4SLinus Torvalds if (dir == TO_XFER_BUF) 1861da177e4SLinus Torvalds memcpy(ptr + poff, buffer + cnt, plen); 1871da177e4SLinus Torvalds else 1881da177e4SLinus Torvalds memcpy(buffer + cnt, ptr + poff, plen); 1891da177e4SLinus Torvalds kunmap(page); 1901da177e4SLinus Torvalds 1911da177e4SLinus Torvalds /* Start at the beginning of the next page */ 1921da177e4SLinus Torvalds poff = 0; 1931da177e4SLinus Torvalds ++page; 1941da177e4SLinus Torvalds cnt += plen; 1951da177e4SLinus Torvalds sglen -= plen; 1961da177e4SLinus Torvalds } 1971da177e4SLinus Torvalds } 1981f6f31a0SJens Axboe *sgptr = sg; 1991da177e4SLinus Torvalds 2001da177e4SLinus Torvalds /* Return the amount actually transferred */ 2011da177e4SLinus Torvalds return cnt; 2021da177e4SLinus Torvalds } 203*e6e244b6SAlan Stern EXPORT_SYMBOL_GPL(usb_stor_access_xfer_buf); 2041da177e4SLinus Torvalds 2051da177e4SLinus Torvalds /* Store the contents of buffer into srb's transfer buffer and set the 2067084191dSAlan Stern * SCSI residue. 2077084191dSAlan Stern */ 2081da177e4SLinus Torvalds void usb_stor_set_xfer_buf(unsigned char *buffer, 2091da177e4SLinus Torvalds unsigned int buflen, struct scsi_cmnd *srb) 2101da177e4SLinus Torvalds { 2111f6f31a0SJens Axboe unsigned int offset = 0; 2121f6f31a0SJens Axboe struct scatterlist *sg = NULL; 2131da177e4SLinus Torvalds 2146d512a80SAlan Stern buflen = min(buflen, scsi_bufflen(srb)); 2157084191dSAlan Stern buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, 2161da177e4SLinus Torvalds TO_XFER_BUF); 217dd829d23SBoaz Harrosh if (buflen < scsi_bufflen(srb)) 218dd829d23SBoaz Harrosh scsi_set_resid(srb, scsi_bufflen(srb) - buflen); 2191da177e4SLinus Torvalds } 220*e6e244b6SAlan Stern EXPORT_SYMBOL_GPL(usb_stor_set_xfer_buf); 221