adapter_t *adapter;
scb_t *scb;
int busy=0;
+ unsigned long flags;
adapter = (adapter_t *)scmd->device->host->hostdata;
* return 0 in that case.
*/
+ spin_lock_irqsave(&adapter->lock, flags);
scb = mega_build_cmd(adapter, scmd, &busy);
if(scb) {
}
return 0;
}
+ spin_unlock_irqrestore(&adapter->lock, flags);
return busy;
}
if(islogical) {
switch (cmd->cmnd[0]) {
case TEST_UNIT_READY:
- memset(cmd->request_buffer, 0, cmd->request_bufflen);
-
#if MEGA_HAVE_CLUSTERING
/*
* Do we support clustering and is the support enabled
return NULL;
#endif
- case MODE_SENSE:
+ case MODE_SENSE: {
+ char *buf;
+
+ if (cmd->use_sg) {
+ struct scatterlist *sg;
+
+ sg = (struct scatterlist *)cmd->request_buffer;
+ buf = kmap_atomic(sg->page, KM_IRQ0) +
+ sg->offset;
+ } else
+ buf = cmd->request_buffer;
memset(cmd->request_buffer, 0, cmd->cmnd[4]);
+ if (cmd->use_sg) {
+ struct scatterlist *sg;
+
+ sg = (struct scatterlist *)cmd->request_buffer;
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
+ }
cmd->result = (DID_OK << 16);
cmd->scsi_done(cmd);
return NULL;
+ }
case READ_CAPACITY:
case INQUIRY:
list_for_each(pos, &adapter->completed_list) {
- Scsi_Pointer* spos = (Scsi_Pointer *)pos;
+ struct scsi_pointer* spos = (struct scsi_pointer *)pos;
cmd = list_entry(spos, Scsi_Cmnd, SCp);
cmd->scsi_done(cmd);
static void
mega_free_scb(adapter_t *adapter, scb_t *scb)
{
+ unsigned long length;
+
switch( scb->dma_type ) {
case MEGA_DMA_TYPE_NONE:
break;
case MEGA_BULK_DATA:
+ if (scb->cmd->use_sg == 0)
+ length = scb->cmd->request_bufflen;
+ else {
+ struct scatterlist *sgl =
+ (struct scatterlist *)scb->cmd->request_buffer;
+ length = sgl->length;
+ }
pci_unmap_page(adapter->dev, scb->dma_h_bulkdata,
- scb->cmd->request_bufflen, scb->dma_direction);
+ length, scb->dma_direction);
break;
case MEGA_SGLIST:
struct scatterlist *sgl;
struct page *page;
unsigned long offset;
+ unsigned int length;
Scsi_Cmnd *cmd;
int sgcnt;
int idx;
cmd = scb->cmd;
/* Scatter-gather not used */
- if( !cmd->use_sg ) {
-
- page = virt_to_page(cmd->request_buffer);
- offset = offset_in_page(cmd->request_buffer);
+ if( cmd->use_sg == 0 || (cmd->use_sg == 1 &&
+ !adapter->has_64bit_addr)) {
+
+ if (cmd->use_sg == 0) {
+ page = virt_to_page(cmd->request_buffer);
+ offset = offset_in_page(cmd->request_buffer);
+ length = cmd->request_bufflen;
+ } else {
+ sgl = (struct scatterlist *)cmd->request_buffer;
+ page = sgl->page;
+ offset = sgl->offset;
+ length = sgl->length;
+ }
scb->dma_h_bulkdata = pci_map_page(adapter->dev,
page, offset,
- cmd->request_bufflen,
+ length,
scb->dma_direction);
scb->dma_type = MEGA_BULK_DATA;
*/
if( adapter->has_64bit_addr ) {
scb->sgl64[0].address = scb->dma_h_bulkdata;
- scb->sgl64[0].length = cmd->request_bufflen;
+ scb->sgl64[0].length = length;
*buf = (u32)scb->sgl_dma_addr;
- *len = (u32)cmd->request_bufflen;
+ *len = (u32)length;
return 1;
}
else {
*buf = (u32)scb->dma_h_bulkdata;
- *len = (u32)cmd->request_bufflen;
+ *len = (u32)length;
}
return 0;
}
if( sgcnt > adapter->sglen ) BUG();
+ *len = 0;
+
for( idx = 0; idx < sgcnt; idx++, sgl++ ) {
if( adapter->has_64bit_addr ) {
scb->sgl64[idx].address = sg_dma_address(sgl);
- scb->sgl64[idx].length = sg_dma_len(sgl);
+ *len += scb->sgl64[idx].length = sg_dma_len(sgl);
}
else {
scb->sgl[idx].address = sg_dma_address(sgl);
- scb->sgl[idx].length = sg_dma_len(sgl);
+ *len += scb->sgl[idx].length = sg_dma_len(sgl);
}
}
/* Reset pointer and length fields */
*buf = scb->sgl_dma_addr;
- /*
- * For passthru command, dataxferlen must be set, even for commands
- * with a sg list
- */
- *len = (u32)cmd->request_bufflen;
-
/* Return count of SG requests */
return sgcnt;
}
mc.cmd = MEGA_CLUSTER_CMD;
mc.opcode = MEGA_RESET_RESERVATIONS;
- if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) {
+ if( mega_internal_command(adapter, &mc, NULL) != 0 ) {
printk(KERN_WARNING
"megaraid: reservation reset failed.\n");
}
mc.cmd = FC_NEW_CONFIG;
mc.opcode = OP_DCMD_READ_CONFIG;
- if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) {
+ if( mega_internal_command(adapter, &mc, NULL) ) {
len = sprintf(page, "40LD read config failed.\n");
else {
mc.cmd = NEW_READ_CONFIG_8LD;
- if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) {
+ if( mega_internal_command(adapter, &mc, NULL) ) {
mc.cmd = READ_CONFIG_8LD;
- if( mega_internal_command(adapter, LOCK_INT, &mc,
+ if( mega_internal_command(adapter, &mc,
NULL) ){
len = sprintf(page,
/*
* Issue the command
*/
- mega_internal_command(adapter, LOCK_INT, &mc, pthru);
+ mega_internal_command(adapter, &mc, pthru);
rval = mega_n_to_m((void __user *)arg, &mc);
/*
* Issue the command
*/
- mega_internal_command(adapter, LOCK_INT, &mc, NULL);
+ mega_internal_command(adapter, &mc, NULL);
rval = mega_n_to_m((void __user *)arg, &mc);
mc.opcode = OP_DEL_LOGDRV;
mc.subopcode = logdrv;
- rval = mega_internal_command(adapter, LOCK_INT, &mc, NULL);
+ rval = mega_internal_command(adapter, &mc, NULL);
/* log this event */
if(rval) {
mc.xferaddr = (u32)dma_handle;
- if ( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) {
+ if ( mega_internal_command(adapter, &mc, NULL) != 0 ) {
return -1;
}
mc.cmd = MEGA_MBOXCMD_PASSTHRU;
mc.xferaddr = (u32)pthru_dma_handle;
- rval = mega_internal_command(adapter, LOCK_INT, &mc, pthru);
+ rval = mega_internal_command(adapter, &mc, pthru);
pci_free_consistent(pdev, sizeof(mega_passthru), pthru,
pthru_dma_handle);
/**
* mega_internal_command()
* @adapter - pointer to our soft state
- * @ls - the scope of the exclusion lock.
* @mc - the mailbox command
* @pthru - Passthru structure for DCDB commands
*
* Note: parameter 'pthru' is null for non-passthru commands.
*/
static int
-mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc,
- mega_passthru *pthru )
+mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
{
Scsi_Cmnd *scmd;
struct scsi_device *sdev;
scb->idx = CMDID_INT_CMDS;
- /*
- * Get the lock only if the caller has not acquired it already
- */
- if( ls == LOCK_INT ) spin_lock_irqsave(&adapter->lock, flags);
-
megaraid_queue(scmd, mega_internal_done);
- if( ls == LOCK_INT ) spin_unlock_irqrestore(&adapter->lock, flags);
-
wait_for_completion(&adapter->int_waitq);
rval = scmd->result;