diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2008-02-27 18:29:15 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-02-27 18:54:26 -0500 |
commit | ee54cc6af95a7fa09da298493b853a9e64fa8abd (patch) | |
tree | 70b68585a4d0261b82bb605dd272991225dc7fc2 /drivers/scsi | |
parent | b31ddd31c266c2ad1b708cad0d3d8e0aa7fa2737 (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')
-rw-r--r-- | drivers/scsi/gdth.c | 30 | ||||
-rw-r--r-- | drivers/scsi/gdth.h | 1 |
2 files changed, 13 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, | |||
160 | static void gdth_clear_events(void); | 160 | static void gdth_clear_events(void); |
161 | 161 | ||
162 | static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, | 162 | static 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); |
164 | static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); | 164 | static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); |
165 | static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive); | 165 | static 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 | */ |
2350 | static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, | 2346 | static 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) | |||
2845 | static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) | 2838 | static 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 */ |
diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index 1434c6b0297c..26e4e92515e0 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h | |||
@@ -915,6 +915,7 @@ typedef struct { | |||
915 | struct gdth_cmndinfo { /* per-command private info */ | 915 | struct gdth_cmndinfo { /* per-command private info */ |
916 | int index; | 916 | int index; |
917 | int internal_command; /* don't call scsi_done */ | 917 | int internal_command; /* don't call scsi_done */ |
918 | gdth_cmd_str *internal_cmd_str; /* crier for internal messages*/ | ||
918 | dma_addr_t sense_paddr; /* sense dma-addr */ | 919 | dma_addr_t sense_paddr; /* sense dma-addr */ |
919 | unchar priority; | 920 | unchar priority; |
920 | int timeout; | 921 | int timeout; |