aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/gdth.c
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2008-02-27 18:29:15 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-27 18:54:26 -0500
commitee54cc6af95a7fa09da298493b853a9e64fa8abd (patch)
tree70b68585a4d0261b82bb605dd272991225dc7fc2 /drivers/scsi/gdth.c
parentb31ddd31c266c2ad1b708cad0d3d8e0aa7fa2737 (diff)
[SCSI] gdth: fix to internal commands execution
The recent patch named: [SCSI] gdth: !use_sg cleanup and use of scsi accessors has done a bad job in handling internal commands issued by gdth_execute(). Internal commands are issued with device gdth_cmd_str ready made directly to the card, without any mapping or translations of scsi commands. So here I added a gdth_cmd_str pointer to the gdth_cmndinfo private structure which is then copied directly to host. following this patch is a cleanup that removes the home cooked accessors and reverts them to regular scsi_cmnd accessors. Since they are not used anymore. After review maybe the 2 patches should be squashed together. FIXME: There is still a problem with gdth_get_info(). as reported there is a WARN_ON trigerd in dma_free_coherent() when doing: $ cat /proc/sys/gdth/0 Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Tested-by: Joerg Dorchain: <joerg@dorchain.net> Tested-by: Stefan Priebe <s.priebe@allied-internet.ag> Tested-by: Jon Chelton <jchelton@ffpglobal.com> Cc: Stable Tree <stable@kernel.org> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/gdth.c')
-rw-r--r--drivers/scsi/gdth.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 23d1a28b929d..27ebd336409b 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -160,7 +160,7 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application,
160static void gdth_clear_events(void); 160static void gdth_clear_events(void);
161 161
162static 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,
163 char *buffer, ushort count, int to_buffer); 163 char *buffer, ushort count);
164static 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);
165static 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);
166 166
@@ -438,8 +438,8 @@ static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha)
438 for (i=0; i<GDTH_MAXCMDS; ++i) { 438 for (i=0; i<GDTH_MAXCMDS; ++i) {
439 if (ha->cmndinfo[i].index == 0) { 439 if (ha->cmndinfo[i].index == 0) {
440 priv = &ha->cmndinfo[i]; 440 priv = &ha->cmndinfo[i];
441 priv->index = i+1;
442 memset(priv, 0, sizeof(*priv)); 441 memset(priv, 0, sizeof(*priv));
442 priv->index = i+1;
443 break; 443 break;
444 } 444 }
445 } 445 }
@@ -486,7 +486,6 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
486 gdth_ha_str *ha = shost_priv(sdev->host); 486 gdth_ha_str *ha = shost_priv(sdev->host);
487 Scsi_Cmnd *scp; 487 Scsi_Cmnd *scp;
488 struct gdth_cmndinfo cmndinfo; 488 struct gdth_cmndinfo cmndinfo;
489 struct scatterlist one_sg;
490 DECLARE_COMPLETION_ONSTACK(wait); 489 DECLARE_COMPLETION_ONSTACK(wait);
491 int rval; 490 int rval;
492 491
@@ -500,13 +499,10 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
500 /* use request field to save the ptr. to completion struct. */ 499 /* use request field to save the ptr. to completion struct. */
501 scp->request = (struct request *)&wait; 500 scp->request = (struct request *)&wait;
502 scp->timeout_per_command = timeout*HZ; 501 scp->timeout_per_command = timeout*HZ;
503 sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd));
504 gdth_set_sglist(scp, &one_sg);
505 gdth_set_sg_count(scp, 1);
506 gdth_set_bufflen(scp, sizeof(*gdtcmd));
507 scp->cmd_len = 12; 502 scp->cmd_len = 12;
508 memcpy(scp->cmnd, cmnd, 12); 503 memcpy(scp->cmnd, cmnd, 12);
509 cmndinfo.priority = IOCTL_PRI; 504 cmndinfo.priority = IOCTL_PRI;
505 cmndinfo.internal_cmd_str = gdtcmd;
510 cmndinfo.internal_command = 1; 506 cmndinfo.internal_command = 1;
511 507
512 TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); 508 TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0]));
@@ -2348,7 +2344,7 @@ static void gdth_next(gdth_ha_str *ha)
2348 * buffers, kmap_atomic() as needed. 2344 * buffers, kmap_atomic() as needed.
2349 */ 2345 */
2350static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, 2346static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
2351 char *buffer, ushort count, int to_buffer) 2347 char *buffer, ushort count)
2352{ 2348{
2353 ushort cpcount,i, max_sg = gdth_sg_count(scp); 2349 ushort cpcount,i, max_sg = gdth_sg_count(scp);
2354 ushort cpsum,cpnow; 2350 ushort cpsum,cpnow;
@@ -2374,10 +2370,7 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
2374 } 2370 }
2375 local_irq_save(flags); 2371 local_irq_save(flags);
2376 address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset; 2372 address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
2377 if (to_buffer) 2373 memcpy(address, buffer, cpnow);
2378 memcpy(buffer, address, cpnow);
2379 else
2380 memcpy(address, buffer, cpnow);
2381 flush_dcache_page(sg_page(sl)); 2374 flush_dcache_page(sg_page(sl));
2382 kunmap_atomic(address, KM_BIO_SRC_IRQ); 2375 kunmap_atomic(address, KM_BIO_SRC_IRQ);
2383 local_irq_restore(flags); 2376 local_irq_restore(flags);
@@ -2431,7 +2424,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
2431 strcpy(inq.vendor,ha->oem_name); 2424 strcpy(inq.vendor,ha->oem_name);
2432 sprintf(inq.product,"Host Drive #%02d",t); 2425 sprintf(inq.product,"Host Drive #%02d",t);
2433 strcpy(inq.revision," "); 2426 strcpy(inq.revision," ");
2434 gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0); 2427 gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data));
2435 break; 2428 break;
2436 2429
2437 case REQUEST_SENSE: 2430 case REQUEST_SENSE:
@@ -2441,7 +2434,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
2441 sd.key = NO_SENSE; 2434 sd.key = NO_SENSE;
2442 sd.info = 0; 2435 sd.info = 0;
2443 sd.add_length= 0; 2436 sd.add_length= 0;
2444 gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0); 2437 gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data));
2445 break; 2438 break;
2446 2439
2447 case MODE_SENSE: 2440 case MODE_SENSE:
@@ -2453,7 +2446,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
2453 mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; 2446 mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
2454 mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; 2447 mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
2455 mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); 2448 mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
2456 gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0); 2449 gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data));
2457 break; 2450 break;
2458 2451
2459 case READ_CAPACITY: 2452 case READ_CAPACITY:
@@ -2463,7 +2456,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
2463 else 2456 else
2464 rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); 2457 rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1);
2465 rdc.block_length = cpu_to_be32(SECTOR_SIZE); 2458 rdc.block_length = cpu_to_be32(SECTOR_SIZE);
2466 gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0); 2459 gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data));
2467 break; 2460 break;
2468 2461
2469 case SERVICE_ACTION_IN: 2462 case SERVICE_ACTION_IN:
@@ -2475,7 +2468,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
2475 rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); 2468 rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1);
2476 rdc16.block_length = cpu_to_be32(SECTOR_SIZE); 2469 rdc16.block_length = cpu_to_be32(SECTOR_SIZE);
2477 gdth_copy_internal_data(ha, scp, (char*)&rdc16, 2470 gdth_copy_internal_data(ha, scp, (char*)&rdc16,
2478 sizeof(gdth_rdcap16_data), 0); 2471 sizeof(gdth_rdcap16_data));
2479 } else { 2472 } else {
2480 scp->result = DID_ABORT << 16; 2473 scp->result = DID_ABORT << 16;
2481 } 2474 }
@@ -2845,6 +2838,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
2845static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) 2838static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
2846{ 2839{
2847 register gdth_cmd_str *cmdp; 2840 register gdth_cmd_str *cmdp;
2841 struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
2848 int cmd_index; 2842 int cmd_index;
2849 2843
2850 cmdp= ha->pccb; 2844 cmdp= ha->pccb;
@@ -2853,7 +2847,7 @@ static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
2853 if (ha->type==GDT_EISA && ha->cmd_cnt>0) 2847 if (ha->type==GDT_EISA && ha->cmd_cnt>0)
2854 return 0; 2848 return 0;
2855 2849
2856 gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1); 2850 *cmdp = *cmndinfo->internal_cmd_str;
2857 cmdp->RequestBuffer = scp; 2851 cmdp->RequestBuffer = scp;
2858 2852
2859 /* search free command index */ 2853 /* search free command index */