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> 46*f940fcd8SPaul Gortmaker #include <linux/export.h> 471da177e4SLinus Torvalds #include <scsi/scsi.h> 481da177e4SLinus Torvalds #include <scsi/scsi_cmnd.h> 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds #include "usb.h" 511da177e4SLinus Torvalds #include "protocol.h" 521da177e4SLinus Torvalds #include "debug.h" 531da177e4SLinus Torvalds #include "scsiglue.h" 541da177e4SLinus Torvalds #include "transport.h" 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds /*********************************************************************** 571da177e4SLinus Torvalds * Protocol routines 581da177e4SLinus Torvalds ***********************************************************************/ 591da177e4SLinus Torvalds 603dae5345SAlan Stern void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) 611da177e4SLinus Torvalds { 623dae5345SAlan Stern /* Pad the SCSI command with zeros out to 12 bytes 631da177e4SLinus Torvalds * 641da177e4SLinus Torvalds * NOTE: This only works because a scsi_cmnd struct field contains 651da177e4SLinus Torvalds * a unsigned char cmnd[16], so we know we have storage available 661da177e4SLinus Torvalds */ 671da177e4SLinus Torvalds for (; srb->cmd_len<12; srb->cmd_len++) 681da177e4SLinus Torvalds srb->cmnd[srb->cmd_len] = 0; 691da177e4SLinus Torvalds 701da177e4SLinus Torvalds /* set command length to 12 bytes */ 711da177e4SLinus Torvalds srb->cmd_len = 12; 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds /* send the command to the transport layer */ 741da177e4SLinus Torvalds usb_stor_invoke_transport(srb, us); 751da177e4SLinus Torvalds } 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us) 781da177e4SLinus Torvalds { 791da177e4SLinus Torvalds /* fix some commands -- this is a form of mode translation 801da177e4SLinus Torvalds * UFI devices only accept 12 byte long commands 811da177e4SLinus Torvalds * 821da177e4SLinus Torvalds * NOTE: This only works because a scsi_cmnd struct field contains 831da177e4SLinus Torvalds * a unsigned char cmnd[16], so we know we have storage available 841da177e4SLinus Torvalds */ 851da177e4SLinus Torvalds 861da177e4SLinus Torvalds /* Pad the ATAPI command with zeros */ 871da177e4SLinus Torvalds for (; srb->cmd_len<12; srb->cmd_len++) 881da177e4SLinus Torvalds srb->cmnd[srb->cmd_len] = 0; 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds /* set command length to 12 bytes (this affects the transport layer) */ 911da177e4SLinus Torvalds srb->cmd_len = 12; 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds /* XXX We should be constantly re-evaluating the need for these */ 941da177e4SLinus Torvalds 951da177e4SLinus Torvalds /* determine the correct data length for these commands */ 961da177e4SLinus Torvalds switch (srb->cmnd[0]) { 971da177e4SLinus Torvalds 981da177e4SLinus Torvalds /* for INQUIRY, UFI devices only ever return 36 bytes */ 991da177e4SLinus Torvalds case INQUIRY: 1001da177e4SLinus Torvalds srb->cmnd[4] = 36; 1011da177e4SLinus Torvalds break; 1021da177e4SLinus Torvalds 1031da177e4SLinus Torvalds /* again, for MODE_SENSE_10, we get the minimum (8) */ 1041da177e4SLinus Torvalds case MODE_SENSE_10: 1051da177e4SLinus Torvalds srb->cmnd[7] = 0; 1061da177e4SLinus Torvalds srb->cmnd[8] = 8; 1071da177e4SLinus Torvalds break; 1081da177e4SLinus Torvalds 1091da177e4SLinus Torvalds /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */ 1101da177e4SLinus Torvalds case REQUEST_SENSE: 1111da177e4SLinus Torvalds srb->cmnd[4] = 18; 1121da177e4SLinus Torvalds break; 1131da177e4SLinus Torvalds } /* end switch on cmnd[0] */ 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds /* send the command to the transport layer */ 1161da177e4SLinus Torvalds usb_stor_invoke_transport(srb, us); 1171da177e4SLinus Torvalds } 1181da177e4SLinus Torvalds 1191da177e4SLinus Torvalds void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, 1201da177e4SLinus Torvalds struct us_data *us) 1211da177e4SLinus Torvalds { 1221da177e4SLinus Torvalds /* send the command to the transport layer */ 1231da177e4SLinus Torvalds usb_stor_invoke_transport(srb, us); 1241da177e4SLinus Torvalds } 125e6e244b6SAlan Stern EXPORT_SYMBOL_GPL(usb_stor_transparent_scsi_command); 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds /*********************************************************************** 1281da177e4SLinus Torvalds * Scatter-gather transfer buffer access routines 1291da177e4SLinus Torvalds ***********************************************************************/ 1301da177e4SLinus Torvalds 1311da177e4SLinus Torvalds /* Copy a buffer of length buflen to/from the srb's transfer buffer. 132dd829d23SBoaz Harrosh * Update the **sgptr and *offset variables so that the next copy will 1337084191dSAlan Stern * pick up from where this one left off. 1347084191dSAlan Stern */ 1351da177e4SLinus Torvalds unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, 1361f6f31a0SJens Axboe unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr, 1371da177e4SLinus Torvalds unsigned int *offset, enum xfer_buf_dir dir) 1381da177e4SLinus Torvalds { 1391da177e4SLinus Torvalds unsigned int cnt; 1407084191dSAlan Stern struct scatterlist *sg = *sgptr; 1411da177e4SLinus Torvalds 142dd829d23SBoaz Harrosh /* We have to go through the list one entry 1431da177e4SLinus Torvalds * at a time. Each s-g entry contains some number of pages, and 1441da177e4SLinus Torvalds * each page has to be kmap()'ed separately. If the page is already 1451da177e4SLinus Torvalds * in kernel-addressable memory then kmap() will return its address. 1461da177e4SLinus Torvalds * If the page is not directly accessible -- such as a user buffer 1471da177e4SLinus Torvalds * located in high memory -- then kmap() will map it to a temporary 1487084191dSAlan Stern * position in the kernel's virtual address space. 1497084191dSAlan Stern */ 1501f6f31a0SJens Axboe 1511f6f31a0SJens Axboe if (!sg) 152dd829d23SBoaz Harrosh sg = scsi_sglist(srb); 1531da177e4SLinus Torvalds 1541da177e4SLinus Torvalds /* This loop handles a single s-g list entry, which may 1551da177e4SLinus Torvalds * include multiple pages. Find the initial page structure 1561da177e4SLinus Torvalds * and the starting offset within the page, and update 1577084191dSAlan Stern * the *offset and **sgptr values for the next loop. 1587084191dSAlan Stern */ 1591da177e4SLinus Torvalds cnt = 0; 1607084191dSAlan Stern while (cnt < buflen && sg) { 16145711f1aSJens Axboe struct page *page = sg_page(sg) + 1621da177e4SLinus Torvalds ((sg->offset + *offset) >> PAGE_SHIFT); 1637084191dSAlan Stern unsigned int poff = (sg->offset + *offset) & (PAGE_SIZE-1); 1641da177e4SLinus Torvalds unsigned int sglen = sg->length - *offset; 1651da177e4SLinus Torvalds 1661da177e4SLinus Torvalds if (sglen > buflen - cnt) { 1671da177e4SLinus Torvalds 1681da177e4SLinus Torvalds /* Transfer ends within this s-g entry */ 1691da177e4SLinus Torvalds sglen = buflen - cnt; 1701da177e4SLinus Torvalds *offset += sglen; 1711da177e4SLinus Torvalds } else { 1721da177e4SLinus Torvalds 1731da177e4SLinus Torvalds /* Transfer continues to next s-g entry */ 1741da177e4SLinus Torvalds *offset = 0; 1751f6f31a0SJens Axboe sg = sg_next(sg); 1761da177e4SLinus Torvalds } 1771da177e4SLinus Torvalds 1781da177e4SLinus Torvalds /* Transfer the data for all the pages in this 1791da177e4SLinus Torvalds * s-g entry. For each page: call kmap(), do the 1801da177e4SLinus Torvalds * transfer, and call kunmap() immediately after. */ 1811da177e4SLinus Torvalds while (sglen > 0) { 1821da177e4SLinus Torvalds unsigned int plen = min(sglen, (unsigned int) 1831da177e4SLinus Torvalds PAGE_SIZE - poff); 1841da177e4SLinus Torvalds unsigned char *ptr = kmap(page); 1851da177e4SLinus Torvalds 1861da177e4SLinus Torvalds if (dir == TO_XFER_BUF) 1871da177e4SLinus Torvalds memcpy(ptr + poff, buffer + cnt, plen); 1881da177e4SLinus Torvalds else 1891da177e4SLinus Torvalds memcpy(buffer + cnt, ptr + poff, plen); 1901da177e4SLinus Torvalds kunmap(page); 1911da177e4SLinus Torvalds 1921da177e4SLinus Torvalds /* Start at the beginning of the next page */ 1931da177e4SLinus Torvalds poff = 0; 1941da177e4SLinus Torvalds ++page; 1951da177e4SLinus Torvalds cnt += plen; 1961da177e4SLinus Torvalds sglen -= plen; 1971da177e4SLinus Torvalds } 1981da177e4SLinus Torvalds } 1991f6f31a0SJens Axboe *sgptr = sg; 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds /* Return the amount actually transferred */ 2021da177e4SLinus Torvalds return cnt; 2031da177e4SLinus Torvalds } 204e6e244b6SAlan Stern EXPORT_SYMBOL_GPL(usb_stor_access_xfer_buf); 2051da177e4SLinus Torvalds 2061da177e4SLinus Torvalds /* Store the contents of buffer into srb's transfer buffer and set the 2077084191dSAlan Stern * SCSI residue. 2087084191dSAlan Stern */ 2091da177e4SLinus Torvalds void usb_stor_set_xfer_buf(unsigned char *buffer, 2101da177e4SLinus Torvalds unsigned int buflen, struct scsi_cmnd *srb) 2111da177e4SLinus Torvalds { 2121f6f31a0SJens Axboe unsigned int offset = 0; 2131f6f31a0SJens Axboe struct scatterlist *sg = NULL; 2141da177e4SLinus Torvalds 2156d512a80SAlan Stern buflen = min(buflen, scsi_bufflen(srb)); 2167084191dSAlan Stern buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, 2171da177e4SLinus Torvalds TO_XFER_BUF); 218dd829d23SBoaz Harrosh if (buflen < scsi_bufflen(srb)) 219dd829d23SBoaz Harrosh scsi_set_resid(srb, scsi_bufflen(srb) - buflen); 2201da177e4SLinus Torvalds } 221e6e244b6SAlan Stern EXPORT_SYMBOL_GPL(usb_stor_set_xfer_buf); 222