Scsi - Index of

Scsi - Index of Scsi - Index of

07.06.2013 Views

195 * pick up from where this one left off. */ 196 197 unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, 198 unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, 199 unsigned int *offset, enum xfer_buf_dir dir) 200 { 201 unsigned int cnt; 202 203 /* If not using scatter-gather, just transfer the data directly. 204 * Make certain it will fit in the available buffer space. */ 205 if (srb->use_sg == 0) { 206 if (*offset >= srb->request_bufflen) 207 return 0; 208 cnt = min(buflen, srb->request_bufflen - *offset); 209 if (dir == TO_XFER_BUF) 210 memcpy((unsigned char *) srb->request_buffer + *offset, 211 buffer, cnt); 212 else 213 memcpy(buffer, (unsigned char *) srb->request_buffer + 214 *offset, cnt); 215 *offset += cnt; 216 217 /* Using scatter-gather. We have to go through the list one entry 218 * at a time. Each s-g entry contains some number of pages, and 219 * each page has to be kmap()'ed separately. If the page is already 220 * in kernel-addressable memory then kmap() will return its address. 221 * If the page is not directly accessible -- such as a user buffer 222 * located in high memory -- then kmap() will map it to a temporary 223 * position in the kernel's virtual address space. */ 224 } else { 225 struct scatterlist *sg = 226 (struct scatterlist *) srb->request_buffer 227 + *index; 228 229 /* This loop handles a single s-g list entry, which may 230 * include multiple pages. Find the initial page structure 133 231 * and the starting offset within the page, and update 232 * the *offset and *index values for the next loop. */ 233 cnt = 0; 234 while (cnt < buflen && *index < srb->use_sg) { 235 struct page *page = sg->page + 236 ((sg->offset + *offset) >> PAGE_SHIFT); 237 unsigned int poff =

238 (sg->offset + *offset) & (PAGE_SIZE-1); 239 unsigned int sglen = sg->length - *offset; 240 241 if (sglen > buflen - cnt) { 242 243 /* Transfer ends within this s-g entry */ 244 sglen = buflen - cnt; 245 *offset += sglen; 246 } else { 247 248 /* Transfer continues to next s-g entry */ 249 *offset = 0; 250 ++*index; 251 ++sg; 252 } 253 254 /* Transfer the data for all the pages in this 255 * s-g entry. For each page: call kmap(), do the 256 * transfer, and call kunmap() immediately after. */ 257 while (sglen > 0) { 258 unsigned int plen = min(sglen, (unsigned int) 259 PAGE_SIZE - poff); 260 unsigned char *ptr = kmap(page); 261 262 if (dir == TO_XFER_BUF) 263 memcpy(ptr + poff, buffer + cnt, plen); 264 else 265 memcpy(buffer + cnt, ptr + poff, plen); 266 kunmap(page); 267 268 /* Start at the beginning of the next page */ 269 poff = 0; 270 ++page; 271 cnt += plen; 272 sglen -= plen; 273 } 274 } 134 275 } 276 277 /* Return the amount actually transferred */ 278 return cnt; 279 } 风,总是在最温柔的时候醉人;

238 (sg-><strong>of</strong>fset + *<strong>of</strong>fset) & (PAGE_SIZE-1);<br />

239 unsigned int sglen = sg->length - *<strong>of</strong>fset;<br />

240<br />

241 if (sglen > buflen - cnt) {<br />

242<br />

243 /* Transfer ends within this s-g entry */<br />

244 sglen = buflen - cnt;<br />

245 *<strong>of</strong>fset += sglen;<br />

246 } else {<br />

247<br />

248 /* Transfer continues to next s-g entry */<br />

249 *<strong>of</strong>fset = 0;<br />

250 ++*index;<br />

251 ++sg;<br />

252 }<br />

253<br />

254 /* Transfer the data for all the pages in this<br />

255 * s-g entry. For each page: call kmap(), do the<br />

256 * transfer, and call kunmap() immediately after. */<br />

257 while (sglen > 0) {<br />

258 unsigned int plen = min(sglen, (unsigned int)<br />

259 PAGE_SIZE - p<strong>of</strong>f);<br />

260 unsigned char *ptr = kmap(page);<br />

261<br />

262 if (dir == TO_XFER_BUF)<br />

263 memcpy(ptr + p<strong>of</strong>f, buffer + cnt, plen);<br />

264 else<br />

265 memcpy(buffer + cnt, ptr + p<strong>of</strong>f, plen);<br />

266 kunmap(page);<br />

267<br />

268 /* Start at the beginning <strong>of</strong> the next page */<br />

269 p<strong>of</strong>f = 0;<br />

270 ++page;<br />

271 cnt += plen;<br />

272 sglen -= plen;<br />

273 }<br />

274 }<br />

134<br />

275 }<br />

276<br />

277 /* Return the amount actually transferred */<br />

278 return cnt;<br />

279 }<br />

风,总是在最温柔的时候醉人;

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!