Commit ee54cc6a authored by Boaz Harrosh's avatar Boaz Harrosh Committed by James Bottomley

[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: default avatarBoaz Harrosh <bharrosh@panasas.com>
Tested-by: default avatarJoerg Dorchain: <joerg@dorchain.net>
Tested-by: default avatarStefan Priebe <s.priebe@allied-internet.ag>
Tested-by: default avatarJon Chelton <jchelton@ffpglobal.com>
Cc: Stable Tree <stable@kernel.org>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent b31ddd31
...@@ -160,7 +160,7 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application, ...@@ -160,7 +160,7 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application,
static void gdth_clear_events(void); static void gdth_clear_events(void);
static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
char *buffer, ushort count, int to_buffer); char *buffer, ushort count);
static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp);
static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive); static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive);
...@@ -438,8 +438,8 @@ static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha) ...@@ -438,8 +438,8 @@ static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha)
for (i=0; i<GDTH_MAXCMDS; ++i) { for (i=0; i<GDTH_MAXCMDS; ++i) {
if (ha->cmndinfo[i].index == 0) { if (ha->cmndinfo[i].index == 0) {
priv = &ha->cmndinfo[i]; priv = &ha->cmndinfo[i];
priv->index = i+1;
memset(priv, 0, sizeof(*priv)); memset(priv, 0, sizeof(*priv));
priv->index = i+1;
break; break;
} }
} }
...@@ -486,7 +486,6 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, ...@@ -486,7 +486,6 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
gdth_ha_str *ha = shost_priv(sdev->host); gdth_ha_str *ha = shost_priv(sdev->host);
Scsi_Cmnd *scp; Scsi_Cmnd *scp;
struct gdth_cmndinfo cmndinfo; struct gdth_cmndinfo cmndinfo;
struct scatterlist one_sg;
DECLARE_COMPLETION_ONSTACK(wait); DECLARE_COMPLETION_ONSTACK(wait);
int rval; int rval;
...@@ -500,13 +499,10 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, ...@@ -500,13 +499,10 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
/* use request field to save the ptr. to completion struct. */ /* use request field to save the ptr. to completion struct. */
scp->request = (struct request *)&wait; scp->request = (struct request *)&wait;
scp->timeout_per_command = timeout*HZ; scp->timeout_per_command = timeout*HZ;
sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd));
gdth_set_sglist(scp, &one_sg);
gdth_set_sg_count(scp, 1);
gdth_set_bufflen(scp, sizeof(*gdtcmd));
scp->cmd_len = 12; scp->cmd_len = 12;
memcpy(scp->cmnd, cmnd, 12); memcpy(scp->cmnd, cmnd, 12);
cmndinfo.priority = IOCTL_PRI; cmndinfo.priority = IOCTL_PRI;
cmndinfo.internal_cmd_str = gdtcmd;
cmndinfo.internal_command = 1; cmndinfo.internal_command = 1;
TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0]));
...@@ -2348,7 +2344,7 @@ static void gdth_next(gdth_ha_str *ha) ...@@ -2348,7 +2344,7 @@ static void gdth_next(gdth_ha_str *ha)
* buffers, kmap_atomic() as needed. * buffers, kmap_atomic() as needed.
*/ */
static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
char *buffer, ushort count, int to_buffer) char *buffer, ushort count)
{ {
ushort cpcount,i, max_sg = gdth_sg_count(scp); ushort cpcount,i, max_sg = gdth_sg_count(scp);
ushort cpsum,cpnow; ushort cpsum,cpnow;
...@@ -2374,10 +2370,7 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, ...@@ -2374,10 +2370,7 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
} }
local_irq_save(flags); local_irq_save(flags);
address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset; address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
if (to_buffer) memcpy(address, buffer, cpnow);
memcpy(buffer, address, cpnow);
else
memcpy(address, buffer, cpnow);
flush_dcache_page(sg_page(sl)); flush_dcache_page(sg_page(sl));
kunmap_atomic(address, KM_BIO_SRC_IRQ); kunmap_atomic(address, KM_BIO_SRC_IRQ);
local_irq_restore(flags); local_irq_restore(flags);
...@@ -2431,7 +2424,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) ...@@ -2431,7 +2424,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
strcpy(inq.vendor,ha->oem_name); strcpy(inq.vendor,ha->oem_name);
sprintf(inq.product,"Host Drive #%02d",t); sprintf(inq.product,"Host Drive #%02d",t);
strcpy(inq.revision," "); strcpy(inq.revision," ");
gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0); gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data));
break; break;
case REQUEST_SENSE: case REQUEST_SENSE:
...@@ -2441,7 +2434,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) ...@@ -2441,7 +2434,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
sd.key = NO_SENSE; sd.key = NO_SENSE;
sd.info = 0; sd.info = 0;
sd.add_length= 0; sd.add_length= 0;
gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0); gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data));
break; break;
case MODE_SENSE: case MODE_SENSE:
...@@ -2453,7 +2446,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) ...@@ -2453,7 +2446,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0); gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data));
break; break;
case READ_CAPACITY: case READ_CAPACITY:
...@@ -2463,7 +2456,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) ...@@ -2463,7 +2456,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
else else
rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1);
rdc.block_length = cpu_to_be32(SECTOR_SIZE); rdc.block_length = cpu_to_be32(SECTOR_SIZE);
gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0); gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data));
break; break;
case SERVICE_ACTION_IN: case SERVICE_ACTION_IN:
...@@ -2475,7 +2468,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) ...@@ -2475,7 +2468,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1);
rdc16.block_length = cpu_to_be32(SECTOR_SIZE); rdc16.block_length = cpu_to_be32(SECTOR_SIZE);
gdth_copy_internal_data(ha, scp, (char*)&rdc16, gdth_copy_internal_data(ha, scp, (char*)&rdc16,
sizeof(gdth_rdcap16_data), 0); sizeof(gdth_rdcap16_data));
} else { } else {
scp->result = DID_ABORT << 16; scp->result = DID_ABORT << 16;
} }
...@@ -2845,6 +2838,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) ...@@ -2845,6 +2838,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
{ {
register gdth_cmd_str *cmdp; register gdth_cmd_str *cmdp;
struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
int cmd_index; int cmd_index;
cmdp= ha->pccb; cmdp= ha->pccb;
...@@ -2853,7 +2847,7 @@ static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) ...@@ -2853,7 +2847,7 @@ static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
if (ha->type==GDT_EISA && ha->cmd_cnt>0) if (ha->type==GDT_EISA && ha->cmd_cnt>0)
return 0; return 0;
gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1); *cmdp = *cmndinfo->internal_cmd_str;
cmdp->RequestBuffer = scp; cmdp->RequestBuffer = scp;
/* search free command index */ /* search free command index */
......
...@@ -915,6 +915,7 @@ typedef struct { ...@@ -915,6 +915,7 @@ typedef struct {
struct gdth_cmndinfo { /* per-command private info */ struct gdth_cmndinfo { /* per-command private info */
int index; int index;
int internal_command; /* don't call scsi_done */ int internal_command; /* don't call scsi_done */
gdth_cmd_str *internal_cmd_str; /* crier for internal messages*/
dma_addr_t sense_paddr; /* sense dma-addr */ dma_addr_t sense_paddr; /* sense dma-addr */
unchar priority; unchar priority;
int timeout; int timeout;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment