aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2007-10-02 17:18:03 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:56:13 -0400
commit3892d88ae6fb186ff6205f764213b556d70800b0 (patch)
tree5435ca13a3d70569582887813a92f49a0ac7ca7c
parentf842b64e0ffbcc9ce48a3bf799d0b005094107c1 (diff)
[SCSI] gdth: !use_sg cleanup and use of scsi accessors
gdth_execute() will issue an internal, none scsi-standard commands onto __gdth_queuecommand(). Since it is not recommended to set struct scsi_cmnd IO members in llds, gdth now uses internal IO members for IO. In the case of gdth_execute() these members will be set properly. In case the command was issued from scsi-ml (by gdth_queuecommand) they will be set from scsi IO accessors. * define gdth IO accessors and use them throughout the driver. * use an sg-of-one in gdth_execute() and fix gdth_special_cmd() accordingly. * Clean the not use_sg code path and company Signed-off-by Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/gdth.c228
-rw-r--r--drivers/scsi/gdth.h7
2 files changed, 109 insertions, 126 deletions
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index a68004b0d90b..0153d1d8b12e 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -85,11 +85,11 @@
85 85
86/* The meaning of the Scsi_Pointer members in this driver is as follows: 86/* The meaning of the Scsi_Pointer members in this driver is as follows:
87 * ptr: Chaining 87 * ptr: Chaining
88 * this_residual: unused 88 * this_residual: gdth_bufflen
89 * buffer: unused 89 * buffer: gdth_sglist
90 * dma_handle: will drop in !use_sg patch. 90 * dma_handle: unused
91 * buffers_residual: unused 91 * buffers_residual: gdth_sg_count
92 * Status: DMA mem. mappings (FIXME: drop in !use_sg patch.) 92 * Status: unused
93 * Message: unused 93 * Message: unused
94 * have_data_in: unused 94 * have_data_in: unused
95 * sent_command: unused 95 * sent_command: unused
@@ -132,6 +132,7 @@
132#include <asm/uaccess.h> 132#include <asm/uaccess.h>
133#include <linux/spinlock.h> 133#include <linux/spinlock.h>
134#include <linux/blkdev.h> 134#include <linux/blkdev.h>
135#include <linux/scatterlist.h>
135 136
136#include "scsi.h" 137#include "scsi.h"
137#include <scsi/scsi_host.h> 138#include <scsi/scsi_host.h>
@@ -159,7 +160,7 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application,
159static void gdth_clear_events(void); 160static void gdth_clear_events(void);
160 161
161static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, 162static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
162 char *buffer,ushort count); 163 char *buffer, ushort count, int to_buffer);
163static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); 164static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp);
164static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive); 165static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive);
165 166
@@ -373,6 +374,47 @@ static const struct file_operations gdth_fops = {
373 .release = gdth_close, 374 .release = gdth_close,
374}; 375};
375 376
377/*
378 * gdth scsi_command access wrappers.
379 * below 6 functions are used throughout the driver to access scsi_command's
380 * io parameters. The reason we do not use the regular accessors from
381 * scsi_cmnd.h is because of gdth_execute(). Since it is unrecommended for
382 * llds to directly set scsi_cmnd's IO members. This driver will use SCp
383 * members for IO parameters, and will copy scsi_cmnd's members to Scp
384 * members in queuecommand. For internal commands through gdth_execute()
385 * SCp's members will be set directly.
386 */
387static inline unsigned gdth_bufflen(struct scsi_cmnd *cmd)
388{
389 return (unsigned)cmd->SCp.this_residual;
390}
391
392static inline void gdth_set_bufflen(struct scsi_cmnd *cmd, unsigned bufflen)
393{
394 cmd->SCp.this_residual = bufflen;
395}
396
397static inline unsigned gdth_sg_count(struct scsi_cmnd *cmd)
398{
399 return (unsigned)cmd->SCp.buffers_residual;
400}
401
402static inline void gdth_set_sg_count(struct scsi_cmnd *cmd, unsigned sg_count)
403{
404 cmd->SCp.buffers_residual = sg_count;
405}
406
407static inline struct scatterlist *gdth_sglist(struct scsi_cmnd *cmd)
408{
409 return cmd->SCp.buffer;
410}
411
412static inline void gdth_set_sglist(struct scsi_cmnd *cmd,
413 struct scatterlist *sglist)
414{
415 cmd->SCp.buffer = sglist;
416}
417
376#include "gdth_proc.h" 418#include "gdth_proc.h"
377#include "gdth_proc.c" 419#include "gdth_proc.c"
378 420
@@ -452,6 +494,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
452 gdth_ha_str *ha = shost_priv(sdev->host); 494 gdth_ha_str *ha = shost_priv(sdev->host);
453 Scsi_Cmnd *scp; 495 Scsi_Cmnd *scp;
454 struct gdth_cmndinfo cmndinfo; 496 struct gdth_cmndinfo cmndinfo;
497 struct scatterlist one_sg;
455 DECLARE_COMPLETION_ONSTACK(wait); 498 DECLARE_COMPLETION_ONSTACK(wait);
456 int rval; 499 int rval;
457 500
@@ -465,7 +508,10 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
465 /* use request field to save the ptr. to completion struct. */ 508 /* use request field to save the ptr. to completion struct. */
466 scp->request = (struct request *)&wait; 509 scp->request = (struct request *)&wait;
467 scp->timeout_per_command = timeout*HZ; 510 scp->timeout_per_command = timeout*HZ;
468 scp->request_buffer = gdtcmd; 511 sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd));
512 gdth_set_sglist(scp, &one_sg);
513 gdth_set_sg_count(scp, 1);
514 gdth_set_bufflen(scp, sizeof(*gdtcmd));
469 scp->cmd_len = 12; 515 scp->cmd_len = 12;
470 memcpy(scp->cmnd, cmnd, 12); 516 memcpy(scp->cmnd, cmnd, 12);
471 cmndinfo.priority = IOCTL_PRI; 517 cmndinfo.priority = IOCTL_PRI;
@@ -2303,24 +2349,28 @@ static void gdth_next(gdth_ha_str *ha)
2303 ha->hanum, cmd_index); 2349 ha->hanum, cmd_index);
2304 } 2350 }
2305} 2351}
2306 2352
2353/*
2354 * gdth_copy_internal_data() - copy to/from a buffer onto a scsi_cmnd's
2355 * buffers, kmap_atomic() as needed.
2356 */
2307static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, 2357static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
2308 char *buffer,ushort count) 2358 char *buffer, ushort count, int to_buffer)
2309{ 2359{
2310 ushort cpcount,i; 2360 ushort cpcount,i, max_sg = gdth_sg_count(scp);
2311 ushort cpsum,cpnow; 2361 ushort cpsum,cpnow;
2312 struct scatterlist *sl; 2362 struct scatterlist *sl;
2313 char *address; 2363 char *address;
2314 2364
2315 cpcount = count<=(ushort)scp->request_bufflen ? count:(ushort)scp->request_bufflen; 2365 cpcount = min_t(ushort, count, gdth_bufflen(scp));
2316 2366
2317 if (scp->use_sg) { 2367 if (cpcount) {
2318 sl = (struct scatterlist *)scp->request_buffer; 2368 cpsum=0;
2319 for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) { 2369 scsi_for_each_sg(scp, sl, max_sg, i) {
2320 unsigned long flags; 2370 unsigned long flags;
2321 cpnow = (ushort)sl->length; 2371 cpnow = (ushort)sl->length;
2322 TRACE(("copy_internal() now %d sum %d count %d %d\n", 2372 TRACE(("copy_internal() now %d sum %d count %d %d\n",
2323 cpnow,cpsum,cpcount,(ushort)scp->bufflen)); 2373 cpnow, cpsum, cpcount, gdth_bufflen(scp)));
2324 if (cpsum+cpnow > cpcount) 2374 if (cpsum+cpnow > cpcount)
2325 cpnow = cpcount - cpsum; 2375 cpnow = cpcount - cpsum;
2326 cpsum += cpnow; 2376 cpsum += cpnow;
@@ -2331,7 +2381,10 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
2331 } 2381 }
2332 local_irq_save(flags); 2382 local_irq_save(flags);
2333 address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; 2383 address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
2334 memcpy(address,buffer,cpnow); 2384 if (to_buffer)
2385 memcpy(buffer, address, cpnow);
2386 else
2387 memcpy(address, buffer, cpnow);
2335 flush_dcache_page(sl->page); 2388 flush_dcache_page(sl->page);
2336 kunmap_atomic(address, KM_BIO_SRC_IRQ); 2389 kunmap_atomic(address, KM_BIO_SRC_IRQ);
2337 local_irq_restore(flags); 2390 local_irq_restore(flags);
@@ -2339,9 +2392,10 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
2339 break; 2392 break;
2340 buffer += cpnow; 2393 buffer += cpnow;
2341 } 2394 }
2342 } else { 2395 } else if (count) {
2343 TRACE(("copy_internal() count %d\n",cpcount)); 2396 printk("GDT-HA %d: SCSI command with no buffers but data transfer expected!\n",
2344 memcpy((char*)scp->request_buffer,buffer,cpcount); 2397 ha->hanum);
2398 WARN_ON(1);
2345 } 2399 }
2346} 2400}
2347 2401
@@ -2384,7 +2438,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
2384 strcpy(inq.vendor,ha->oem_name); 2438 strcpy(inq.vendor,ha->oem_name);
2385 sprintf(inq.product,"Host Drive #%02d",t); 2439