Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: [SCSI] aic94xx: fix section mismatch [SCSI] u14-34f: Fix 32bit only problem [SCSI] dpt_i2o: sysfs code [SCSI] dpt_i2o: 64 bit support [SCSI] dpt_i2o: move from virt_to_bus/bus_to_virt to dma_alloc_coherent [SCSI] dpt_i2o: use standard __init / __exit code [SCSI] megaraid_sas: fix suspend/resume sections [SCSI] aacraid: Add Power Management support [SCSI] aacraid: Fix jbod operations scan issues [SCSI] aacraid: Fix warning about macro side-effects [SCSI] add support for variable length extended commands [SCSI] Let scsi_cmnd->cmnd use request->cmd buffer [SCSI] bsg: add large command support [SCSI] aacraid: Fix down_interruptible() to check the return value correctly [SCSI] megaraid_sas; Update the Version and Changelog [SCSI] ibmvscsi: Handle non SCSI error status [SCSI] bug fix for free list handling [SCSI] ipr: Rename ipr's state scsi host attribute to prevent collisions [SCSI] megaraid_mbox: fix Dell CERC firmware problem
This commit is contained in:
commit
d626e3bf72
43 changed files with 884 additions and 291 deletions
|
@ -1,3 +1,25 @@
|
||||||
|
1 Release Date : Mon. March 10 11:02:31 PDT 2008 -
|
||||||
|
(emaild-id:megaraidlinux@lsi.com)
|
||||||
|
Sumant Patro
|
||||||
|
Bo Yang
|
||||||
|
|
||||||
|
2 Current Version : 00.00.03.20-RC1
|
||||||
|
3 Older Version : 00.00.03.16
|
||||||
|
|
||||||
|
1. Rollback the sense info implementation
|
||||||
|
Sense buffer ptr data type in the ioctl path is reverted back
|
||||||
|
to u32 * as in previous versions of driver.
|
||||||
|
|
||||||
|
2. Fixed the driver frame count.
|
||||||
|
When Driver sent wrong frame count to firmware. As this
|
||||||
|
particular command is sent to drive, FW is seeing continuous
|
||||||
|
chip resets and so the command will timeout.
|
||||||
|
|
||||||
|
3. Add the new controller(1078DE) support to the driver
|
||||||
|
and Increase the max_wait to 60 from 10 in the controller
|
||||||
|
operational status. With this max_wait increase, driver will
|
||||||
|
make sure the FW will finish the pending cmd for KDUMP case.
|
||||||
|
|
||||||
1 Release Date : Thur. Nov. 07 16:30:43 PST 2007 -
|
1 Release Date : Thur. Nov. 07 16:30:43 PST 2007 -
|
||||||
(emaild-id:megaraidlinux@lsi.com)
|
(emaild-id:megaraidlinux@lsi.com)
|
||||||
Sumant Patro
|
Sumant Patro
|
||||||
|
|
12
block/bsg.c
12
block/bsg.c
|
@ -174,7 +174,11 @@ static int bsg_io_schedule(struct bsg_device *bd)
|
||||||
static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
|
static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
|
||||||
struct sg_io_v4 *hdr, int has_write_perm)
|
struct sg_io_v4 *hdr, int has_write_perm)
|
||||||
{
|
{
|
||||||
memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
|
if (hdr->request_len > BLK_MAX_CDB) {
|
||||||
|
rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
|
||||||
|
if (!rq->cmd)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request,
|
if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request,
|
||||||
hdr->request_len))
|
hdr->request_len))
|
||||||
|
@ -211,8 +215,6 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw)
|
||||||
|
|
||||||
if (hdr->guard != 'Q')
|
if (hdr->guard != 'Q')
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (hdr->request_len > BLK_MAX_CDB)
|
|
||||||
return -EINVAL;
|
|
||||||
if (hdr->dout_xfer_len > (q->max_sectors << 9) ||
|
if (hdr->dout_xfer_len > (q->max_sectors << 9) ||
|
||||||
hdr->din_xfer_len > (q->max_sectors << 9))
|
hdr->din_xfer_len > (q->max_sectors << 9))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -302,6 +304,8 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr)
|
||||||
}
|
}
|
||||||
return rq;
|
return rq;
|
||||||
out:
|
out:
|
||||||
|
if (rq->cmd != rq->__cmd)
|
||||||
|
kfree(rq->cmd);
|
||||||
blk_put_request(rq);
|
blk_put_request(rq);
|
||||||
if (next_rq) {
|
if (next_rq) {
|
||||||
blk_rq_unmap_user(next_rq->bio);
|
blk_rq_unmap_user(next_rq->bio);
|
||||||
|
@ -455,6 +459,8 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
|
||||||
ret = rq->errors;
|
ret = rq->errors;
|
||||||
|
|
||||||
blk_rq_unmap_user(bio);
|
blk_rq_unmap_user(bio);
|
||||||
|
if (rq->cmd != rq->__cmd)
|
||||||
|
kfree(rq->cmd);
|
||||||
blk_put_request(rq);
|
blk_put_request(rq);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -33,13 +33,12 @@
|
||||||
#include <scsi/scsi_cmnd.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
|
|
||||||
/* Command group 3 is reserved and should never be used. */
|
/* Command group 3 is reserved and should never be used. */
|
||||||
const unsigned char scsi_command_size[8] =
|
const unsigned char scsi_command_size_tbl[8] =
|
||||||
{
|
{
|
||||||
6, 10, 10, 12,
|
6, 10, 10, 12,
|
||||||
16, 12, 10, 10
|
16, 12, 10, 10
|
||||||
};
|
};
|
||||||
|
EXPORT_SYMBOL(scsi_command_size_tbl);
|
||||||
EXPORT_SYMBOL(scsi_command_size);
|
|
||||||
|
|
||||||
#include <scsi/sg.h>
|
#include <scsi/sg.h>
|
||||||
|
|
||||||
|
|
|
@ -1487,7 +1487,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
|
||||||
if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0)
|
if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
|
memcpy(orb->request.command_block, cmd->cmnd, cmd->cmd_len);
|
||||||
|
|
||||||
orb->base.callback = complete_command_orb;
|
orb->base.callback = complete_command_orb;
|
||||||
orb->base.request_bus =
|
orb->base.request_bus =
|
||||||
|
|
|
@ -1055,7 +1055,7 @@ static void zfcp_scsi_dbf_event(const char *tag, const char *tag2, int level,
|
||||||
rec->scsi_result = scsi_cmnd->result;
|
rec->scsi_result = scsi_cmnd->result;
|
||||||
rec->scsi_cmnd = (unsigned long)scsi_cmnd;
|
rec->scsi_cmnd = (unsigned long)scsi_cmnd;
|
||||||
rec->scsi_serial = scsi_cmnd->serial_number;
|
rec->scsi_serial = scsi_cmnd->serial_number;
|
||||||
memcpy(rec->scsi_opcode, &scsi_cmnd->cmnd,
|
memcpy(rec->scsi_opcode, scsi_cmnd->cmnd,
|
||||||
min((int)scsi_cmnd->cmd_len,
|
min((int)scsi_cmnd->cmd_len,
|
||||||
ZFCP_DBF_SCSI_OPCODE));
|
ZFCP_DBF_SCSI_OPCODE));
|
||||||
rec->scsi_retries = scsi_cmnd->retries;
|
rec->scsi_retries = scsi_cmnd->retries;
|
||||||
|
|
|
@ -4014,7 +4014,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
|
||||||
ZFCP_LOG_TRACE("scpnt->result =0x%x, command was:\n",
|
ZFCP_LOG_TRACE("scpnt->result =0x%x, command was:\n",
|
||||||
scpnt->result);
|
scpnt->result);
|
||||||
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE,
|
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE,
|
||||||
(void *) &scpnt->cmnd, scpnt->cmd_len);
|
scpnt->cmnd, scpnt->cmd_len);
|
||||||
|
|
||||||
ZFCP_LOG_TRACE("%i bytes sense data provided by FCP\n",
|
ZFCP_LOG_TRACE("%i bytes sense data provided by FCP\n",
|
||||||
fcp_rsp_iu->fcp_sns_len);
|
fcp_rsp_iu->fcp_sns_len);
|
||||||
|
|
|
@ -599,7 +599,7 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
|
||||||
(struct NCR_700_command_slot *)SCp->host_scribble;
|
(struct NCR_700_command_slot *)SCp->host_scribble;
|
||||||
|
|
||||||
dma_unmap_single(hostdata->dev, slot->pCmd,
|
dma_unmap_single(hostdata->dev, slot->pCmd,
|
||||||
sizeof(SCp->cmnd), DMA_TO_DEVICE);
|
MAX_COMMAND_SIZE, DMA_TO_DEVICE);
|
||||||
if (slot->flags == NCR_700_FLAG_AUTOSENSE) {
|
if (slot->flags == NCR_700_FLAG_AUTOSENSE) {
|
||||||
char *cmnd = NCR_700_get_sense_cmnd(SCp->device);
|
char *cmnd = NCR_700_get_sense_cmnd(SCp->device);
|
||||||
#ifdef NCR_700_DEBUG
|
#ifdef NCR_700_DEBUG
|
||||||
|
@ -1004,7 +1004,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
||||||
* here */
|
* here */
|
||||||
NCR_700_unmap(hostdata, SCp, slot);
|
NCR_700_unmap(hostdata, SCp, slot);
|
||||||
dma_unmap_single(hostdata->dev, slot->pCmd,
|
dma_unmap_single(hostdata->dev, slot->pCmd,
|
||||||
sizeof(SCp->cmnd),
|
MAX_COMMAND_SIZE,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
|
|
||||||
cmnd[0] = REQUEST_SENSE;
|
cmnd[0] = REQUEST_SENSE;
|
||||||
|
@ -1901,7 +1901,7 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
|
||||||
}
|
}
|
||||||
slot->resume_offset = 0;
|
slot->resume_offset = 0;
|
||||||
slot->pCmd = dma_map_single(hostdata->dev, SCp->cmnd,
|
slot->pCmd = dma_map_single(hostdata->dev, SCp->cmnd,
|
||||||
sizeof(SCp->cmnd), DMA_TO_DEVICE);
|
MAX_COMMAND_SIZE, DMA_TO_DEVICE);
|
||||||
NCR_700_start_command(SCp);
|
NCR_700_start_command(SCp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -504,10 +504,9 @@ config SCSI_AIC7XXX_OLD
|
||||||
source "drivers/scsi/aic7xxx/Kconfig.aic79xx"
|
source "drivers/scsi/aic7xxx/Kconfig.aic79xx"
|
||||||
source "drivers/scsi/aic94xx/Kconfig"
|
source "drivers/scsi/aic94xx/Kconfig"
|
||||||
|
|
||||||
# All the I2O code and drivers do not seem to be 64bit safe.
|
|
||||||
config SCSI_DPT_I2O
|
config SCSI_DPT_I2O
|
||||||
tristate "Adaptec I2O RAID support "
|
tristate "Adaptec I2O RAID support "
|
||||||
depends on !64BIT && SCSI && PCI && VIRT_TO_BUS
|
depends on SCSI && PCI && VIRT_TO_BUS
|
||||||
help
|
help
|
||||||
This driver supports all of Adaptec's I2O based RAID controllers as
|
This driver supports all of Adaptec's I2O based RAID controllers as
|
||||||
well as the DPT SmartRaid V cards. This is an Adaptec maintained
|
well as the DPT SmartRaid V cards. This is an Adaptec maintained
|
||||||
|
|
|
@ -895,7 +895,7 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru
|
||||||
} else {
|
} else {
|
||||||
scb->tag_msg = 0; /* No tag support */
|
scb->tag_msg = 0; /* No tag support */
|
||||||
}
|
}
|
||||||
memcpy(&scb->cdb[0], &cmd->cmnd, scb->cdb_len);
|
memcpy(scb->cdb, cmd->cmnd, scb->cdb_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -498,6 +498,11 @@ static void _aac_probe_container2(void * context, struct fib * fibptr)
|
||||||
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
|
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
|
||||||
(le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
|
(le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
|
||||||
fsa_dev_ptr->valid = 1;
|
fsa_dev_ptr->valid = 1;
|
||||||
|
/* sense_key holds the current state of the spin-up */
|
||||||
|
if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY))
|
||||||
|
fsa_dev_ptr->sense_data.sense_key = NOT_READY;
|
||||||
|
else if (fsa_dev_ptr->sense_data.sense_key == NOT_READY)
|
||||||
|
fsa_dev_ptr->sense_data.sense_key = NO_SENSE;
|
||||||
fsa_dev_ptr->type = le32_to_cpu(dresp->mnt[0].vol);
|
fsa_dev_ptr->type = le32_to_cpu(dresp->mnt[0].vol);
|
||||||
fsa_dev_ptr->size
|
fsa_dev_ptr->size
|
||||||
= ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +
|
= ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +
|
||||||
|
@ -1509,20 +1514,35 @@ static void io_callback(void *context, struct fib * fibptr)
|
||||||
scsi_dma_unmap(scsicmd);
|
scsi_dma_unmap(scsicmd);
|
||||||
|
|
||||||
readreply = (struct aac_read_reply *)fib_data(fibptr);
|
readreply = (struct aac_read_reply *)fib_data(fibptr);
|
||||||
if (le32_to_cpu(readreply->status) == ST_OK)
|
switch (le32_to_cpu(readreply->status)) {
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
case ST_OK:
|
||||||
else {
|
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||||
|
SAM_STAT_GOOD;
|
||||||
|
dev->fsa_dev[cid].sense_data.sense_key = NO_SENSE;
|
||||||
|
break;
|
||||||
|
case ST_NOT_READY:
|
||||||
|
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||||
|
SAM_STAT_CHECK_CONDITION;
|
||||||
|
set_sense(&dev->fsa_dev[cid].sense_data, NOT_READY,
|
||||||
|
SENCODE_BECOMING_READY, ASENCODE_BECOMING_READY, 0, 0);
|
||||||
|
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
||||||
|
min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
|
||||||
|
SCSI_SENSE_BUFFERSIZE));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
#ifdef AAC_DETAILED_STATUS_INFO
|
#ifdef AAC_DETAILED_STATUS_INFO
|
||||||
printk(KERN_WARNING "io_callback: io failed, status = %d\n",
|
printk(KERN_WARNING "io_callback: io failed, status = %d\n",
|
||||||
le32_to_cpu(readreply->status));
|
le32_to_cpu(readreply->status));
|
||||||
#endif
|
#endif
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
|
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||||
|
SAM_STAT_CHECK_CONDITION;
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
||||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
||||||
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
||||||
min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
|
min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
|
||||||
SCSI_SENSE_BUFFERSIZE));
|
SCSI_SENSE_BUFFERSIZE));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
aac_fib_complete(fibptr);
|
aac_fib_complete(fibptr);
|
||||||
aac_fib_free(fibptr);
|
aac_fib_free(fibptr);
|
||||||
|
@ -1863,6 +1883,84 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void aac_start_stop_callback(void *context, struct fib *fibptr)
|
||||||
|
{
|
||||||
|
struct scsi_cmnd *scsicmd = context;
|
||||||
|
|
||||||
|
if (!aac_valid_context(scsicmd, fibptr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
BUG_ON(fibptr == NULL);
|
||||||
|
|
||||||
|
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||||
|
|
||||||
|
aac_fib_complete(fibptr);
|
||||||
|
aac_fib_free(fibptr);
|
||||||
|
scsicmd->scsi_done(scsicmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int aac_start_stop(struct scsi_cmnd *scsicmd)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
struct fib *cmd_fibcontext;
|
||||||
|
struct aac_power_management *pmcmd;
|
||||||
|
struct scsi_device *sdev = scsicmd->device;
|
||||||
|
struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
|
||||||
|
|
||||||
|
if (!(aac->supplement_adapter_info.SupportedOptions2 &
|
||||||
|
AAC_OPTION_POWER_MANAGEMENT)) {
|
||||||
|
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||||
|
SAM_STAT_GOOD;
|
||||||
|
scsicmd->scsi_done(scsicmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aac->in_reset)
|
||||||
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate and initialize a Fib
|
||||||
|
*/
|
||||||
|
cmd_fibcontext = aac_fib_alloc(aac);
|
||||||
|
if (!cmd_fibcontext)
|
||||||
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
|
|
||||||
|
aac_fib_init(cmd_fibcontext);
|
||||||
|
|
||||||
|
pmcmd = fib_data(cmd_fibcontext);
|
||||||
|
pmcmd->command = cpu_to_le32(VM_ContainerConfig);
|
||||||
|
pmcmd->type = cpu_to_le32(CT_POWER_MANAGEMENT);
|
||||||
|
/* Eject bit ignored, not relevant */
|
||||||
|
pmcmd->sub = (scsicmd->cmnd[4] & 1) ?
|
||||||
|
cpu_to_le32(CT_PM_START_UNIT) : cpu_to_le32(CT_PM_STOP_UNIT);
|
||||||
|
pmcmd->cid = cpu_to_le32(sdev_id(sdev));
|
||||||
|
pmcmd->parm = (scsicmd->cmnd[1] & 1) ?
|
||||||
|
cpu_to_le32(CT_PM_UNIT_IMMEDIATE) : 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now send the Fib to the adapter
|
||||||
|
*/
|
||||||
|
status = aac_fib_send(ContainerCommand,
|
||||||
|
cmd_fibcontext,
|
||||||
|
sizeof(struct aac_power_management),
|
||||||
|
FsaNormal,
|
||||||
|
0, 1,
|
||||||
|
(fib_callback)aac_start_stop_callback,
|
||||||
|
(void *)scsicmd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that the command queued to the controller
|
||||||
|
*/
|
||||||
|
if (status == -EINPROGRESS) {
|
||||||
|
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
aac_fib_complete(cmd_fibcontext);
|
||||||
|
aac_fib_free(cmd_fibcontext);
|
||||||
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* aac_scsi_cmd() - Process SCSI command
|
* aac_scsi_cmd() - Process SCSI command
|
||||||
* @scsicmd: SCSI command block
|
* @scsicmd: SCSI command block
|
||||||
|
@ -1899,7 +1997,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||||
* If the target container doesn't exist, it may have
|
* If the target container doesn't exist, it may have
|
||||||
* been newly created
|
* been newly created
|
||||||
*/
|
*/
|
||||||
if ((fsa_dev_ptr[cid].valid & 1) == 0) {
|
if (((fsa_dev_ptr[cid].valid & 1) == 0) ||
|
||||||
|
(fsa_dev_ptr[cid].sense_data.sense_key ==
|
||||||
|
NOT_READY)) {
|
||||||
switch (scsicmd->cmnd[0]) {
|
switch (scsicmd->cmnd[0]) {
|
||||||
case SERVICE_ACTION_IN:
|
case SERVICE_ACTION_IN:
|
||||||
if (!(dev->raw_io_interface) ||
|
if (!(dev->raw_io_interface) ||
|
||||||
|
@ -2091,8 +2191,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||||
scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
|
scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
|
||||||
/* Do not cache partition table for arrays */
|
/* Do not cache partition table for arrays */
|
||||||
scsicmd->device->removable = 1;
|
scsicmd->device->removable = 1;
|
||||||
|
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
SAM_STAT_GOOD;
|
||||||
scsicmd->scsi_done(scsicmd);
|
scsicmd->scsi_done(scsicmd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2187,15 +2287,32 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||||
* These commands are all No-Ops
|
* These commands are all No-Ops
|
||||||
*/
|
*/
|
||||||
case TEST_UNIT_READY:
|
case TEST_UNIT_READY:
|
||||||
|
if (fsa_dev_ptr[cid].sense_data.sense_key == NOT_READY) {
|
||||||
|
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||||
|
SAM_STAT_CHECK_CONDITION;
|
||||||
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
|
NOT_READY, SENCODE_BECOMING_READY,
|
||||||
|
ASENCODE_BECOMING_READY, 0, 0);
|
||||||
|
memcpy(scsicmd->sense_buffer,
|
||||||
|
&dev->fsa_dev[cid].sense_data,
|
||||||
|
min_t(size_t,
|
||||||
|
sizeof(dev->fsa_dev[cid].sense_data),
|
||||||
|
SCSI_SENSE_BUFFERSIZE));
|
||||||
|
scsicmd->scsi_done(scsicmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* FALLTHRU */
|
||||||
case RESERVE:
|
case RESERVE:
|
||||||
case RELEASE:
|
case RELEASE:
|
||||||
case REZERO_UNIT:
|
case REZERO_UNIT:
|
||||||
case REASSIGN_BLOCKS:
|
case REASSIGN_BLOCKS:
|
||||||
case SEEK_10:
|
case SEEK_10:
|
||||||
case START_STOP:
|
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||||
scsicmd->scsi_done(scsicmd);
|
scsicmd->scsi_done(scsicmd);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case START_STOP:
|
||||||
|
return aac_start_stop(scsicmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (scsicmd->cmnd[0])
|
switch (scsicmd->cmnd[0])
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef AAC_DRIVER_BUILD
|
#ifndef AAC_DRIVER_BUILD
|
||||||
# define AAC_DRIVER_BUILD 2455
|
# define AAC_DRIVER_BUILD 2456
|
||||||
# define AAC_DRIVER_BRANCH "-ms"
|
# define AAC_DRIVER_BRANCH "-ms"
|
||||||
#endif
|
#endif
|
||||||
#define MAXIMUM_NUM_CONTAINERS 32
|
#define MAXIMUM_NUM_CONTAINERS 32
|
||||||
|
@ -34,8 +34,8 @@
|
||||||
#define CONTAINER_TO_ID(cont) (cont)
|
#define CONTAINER_TO_ID(cont) (cont)
|
||||||
#define CONTAINER_TO_LUN(cont) (0)
|
#define CONTAINER_TO_LUN(cont) (0)
|
||||||
|
|
||||||
#define aac_phys_to_logical(x) (x+1)
|
#define aac_phys_to_logical(x) ((x)+1)
|
||||||
#define aac_logical_to_phys(x) (x?x-1:0)
|
#define aac_logical_to_phys(x) ((x)?(x)-1:0)
|
||||||
|
|
||||||
/* #define AAC_DETAILED_STATUS_INFO */
|
/* #define AAC_DETAILED_STATUS_INFO */
|
||||||
|
|
||||||
|
@ -424,6 +424,8 @@ struct aac_init
|
||||||
*/
|
*/
|
||||||
__le32 InitFlags; /* flags for supported features */
|
__le32 InitFlags; /* flags for supported features */
|
||||||
#define INITFLAGS_NEW_COMM_SUPPORTED 0x00000001
|
#define INITFLAGS_NEW_COMM_SUPPORTED 0x00000001
|
||||||
|
#define INITFLAGS_DRIVER_USES_UTC_TIME 0x00000010
|
||||||
|
#define INITFLAGS_DRIVER_SUPPORTS_PM 0x00000020
|
||||||
__le32 MaxIoCommands; /* max outstanding commands */
|
__le32 MaxIoCommands; /* max outstanding commands */
|
||||||
__le32 MaxIoSize; /* largest I/O command */
|
__le32 MaxIoSize; /* largest I/O command */
|
||||||
__le32 MaxFibSize; /* largest FIB to adapter */
|
__le32 MaxFibSize; /* largest FIB to adapter */
|
||||||
|
@ -867,8 +869,10 @@ struct aac_supplement_adapter_info
|
||||||
};
|
};
|
||||||
#define AAC_FEATURE_FALCON cpu_to_le32(0x00000010)
|
#define AAC_FEATURE_FALCON cpu_to_le32(0x00000010)
|
||||||
#define AAC_FEATURE_JBOD cpu_to_le32(0x08000000)
|
#define AAC_FEATURE_JBOD cpu_to_le32(0x08000000)
|
||||||
#define AAC_OPTION_MU_RESET cpu_to_le32(0x00000001)
|
/* SupportedOptions2 */
|
||||||
#define AAC_OPTION_IGNORE_RESET cpu_to_le32(0x00000002)
|
#define AAC_OPTION_MU_RESET cpu_to_le32(0x00000001)
|
||||||
|
#define AAC_OPTION_IGNORE_RESET cpu_to_le32(0x00000002)
|
||||||
|
#define AAC_OPTION_POWER_MANAGEMENT cpu_to_le32(0x00000004)
|
||||||
#define AAC_SIS_VERSION_V3 3
|
#define AAC_SIS_VERSION_V3 3
|
||||||
#define AAC_SIS_SLOT_UNKNOWN 0xFF
|
#define AAC_SIS_SLOT_UNKNOWN 0xFF
|
||||||
|
|
||||||
|
@ -1148,6 +1152,7 @@ struct aac_dev
|
||||||
#define ST_DQUOT 69
|
#define ST_DQUOT 69
|
||||||
#define ST_STALE 70
|
#define ST_STALE 70
|
||||||
#define ST_REMOTE 71
|
#define ST_REMOTE 71
|
||||||
|
#define ST_NOT_READY 72
|
||||||
#define ST_BADHANDLE 10001
|
#define ST_BADHANDLE 10001
|
||||||
#define ST_NOT_SYNC 10002
|
#define ST_NOT_SYNC 10002
|
||||||
#define ST_BAD_COOKIE 10003
|
#define ST_BAD_COOKIE 10003
|
||||||
|
@ -1269,6 +1274,18 @@ struct aac_synchronize_reply {
|
||||||
u8 data[16];
|
u8 data[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define CT_POWER_MANAGEMENT 245
|
||||||
|
#define CT_PM_START_UNIT 2
|
||||||
|
#define CT_PM_STOP_UNIT 3
|
||||||
|
#define CT_PM_UNIT_IMMEDIATE 1
|
||||||
|
struct aac_power_management {
|
||||||
|
__le32 command; /* VM_ContainerConfig */
|
||||||
|
__le32 type; /* CT_POWER_MANAGEMENT */
|
||||||
|
__le32 sub; /* CT_PM_* */
|
||||||
|
__le32 cid;
|
||||||
|
__le32 parm; /* CT_PM_sub_* */
|
||||||
|
};
|
||||||
|
|
||||||
#define CT_PAUSE_IO 65
|
#define CT_PAUSE_IO 65
|
||||||
#define CT_RELEASE_IO 66
|
#define CT_RELEASE_IO 66
|
||||||
struct aac_pause {
|
struct aac_pause {
|
||||||
|
@ -1536,6 +1553,7 @@ struct aac_mntent {
|
||||||
#define FSCS_NOTCLEAN 0x0001 /* fsck is necessary before mounting */
|
#define FSCS_NOTCLEAN 0x0001 /* fsck is necessary before mounting */
|
||||||
#define FSCS_READONLY 0x0002 /* possible result of broken mirror */
|
#define FSCS_READONLY 0x0002 /* possible result of broken mirror */
|
||||||
#define FSCS_HIDDEN 0x0004 /* should be ignored - set during a clear */
|
#define FSCS_HIDDEN 0x0004 /* should be ignored - set during a clear */
|
||||||
|
#define FSCS_NOT_READY 0x0008 /* Array spinning up to fulfil request */
|
||||||
|
|
||||||
struct aac_query_mount {
|
struct aac_query_mount {
|
||||||
__le32 command;
|
__le32 command;
|
||||||
|
|
|
@ -97,6 +97,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
||||||
init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
|
init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
|
||||||
dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
|
dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
|
||||||
}
|
}
|
||||||
|
init->InitFlags |= cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME |
|
||||||
|
INITFLAGS_DRIVER_SUPPORTS_PM);
|
||||||
init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
|
init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
|
||||||
init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
|
init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
|
||||||
init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
|
init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
|
||||||
|
|
|
@ -515,7 +515,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
|
||||||
}
|
}
|
||||||
udelay(5);
|
udelay(5);
|
||||||
}
|
}
|
||||||
} else if (down_interruptible(&fibptr->event_wait) == 0) {
|
} else if (down_interruptible(&fibptr->event_wait)) {
|
||||||
fibptr->done = 2;
|
fibptr->done = 2;
|
||||||
up(&fibptr->event_wait);
|
up(&fibptr->event_wait);
|
||||||
}
|
}
|
||||||
|
@ -906,15 +906,22 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
|
||||||
case AifEnAddJBOD:
|
case AifEnAddJBOD:
|
||||||
case AifEnDeleteJBOD:
|
case AifEnDeleteJBOD:
|
||||||
container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
|
container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
|
||||||
if ((container >> 28))
|
if ((container >> 28)) {
|
||||||
|
container = (u32)-1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
channel = (container >> 24) & 0xF;
|
channel = (container >> 24) & 0xF;
|
||||||
if (channel >= dev->maximum_num_channels)
|
if (channel >= dev->maximum_num_channels) {
|
||||||
|
container = (u32)-1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
id = container & 0xFFFF;
|
id = container & 0xFFFF;
|
||||||
if (id >= dev->maximum_num_physicals)
|
if (id >= dev->maximum_num_physicals) {
|
||||||
|
container = (u32)-1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
lun = (container >> 16) & 0xFF;
|
lun = (container >> 16) & 0xFF;
|
||||||
|
container = (u32)-1;
|
||||||
channel = aac_phys_to_logical(channel);
|
channel = aac_phys_to_logical(channel);
|
||||||
device_config_needed =
|
device_config_needed =
|
||||||
(((__le32 *)aifcmd->data)[0] ==
|
(((__le32 *)aifcmd->data)[0] ==
|
||||||
|
@ -933,13 +940,18 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
|
||||||
case EM_DRIVE_REMOVAL:
|
case EM_DRIVE_REMOVAL:
|
||||||
container = le32_to_cpu(
|
container = le32_to_cpu(
|
||||||
((__le32 *)aifcmd->data)[2]);
|
((__le32 *)aifcmd->data)[2]);
|
||||||
if ((container >> 28))
|
if ((container >> 28)) {
|
||||||
|
container = (u32)-1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
channel = (container >> 24) & 0xF;
|
channel = (container >> 24) & 0xF;
|
||||||
if (channel >= dev->maximum_num_channels)
|
if (channel >= dev->maximum_num_channels) {
|
||||||
|
container = (u32)-1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
id = container & 0xFFFF;
|
id = container & 0xFFFF;
|
||||||
lun = (container >> 16) & 0xFF;
|
lun = (container >> 16) & 0xFF;
|
||||||
|
container = (u32)-1;
|
||||||
if (id >= dev->maximum_num_physicals) {
|
if (id >= dev->maximum_num_physicals) {
|
||||||
/* legacy dev_t ? */
|
/* legacy dev_t ? */
|
||||||
if ((0x2000 <= id) || lun || channel ||
|
if ((0x2000 <= id) || lun || channel ||
|
||||||
|
@ -1025,9 +1037,10 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
container = 0;
|
||||||
|
retry_next:
|
||||||
if (device_config_needed == NOTHING)
|
if (device_config_needed == NOTHING)
|
||||||
for (container = 0; container < dev->maximum_num_containers;
|
for (; container < dev->maximum_num_containers; ++container) {
|
||||||
++container) {
|
|
||||||
if ((dev->fsa_dev[container].config_waiting_on == 0) &&
|
if ((dev->fsa_dev[container].config_waiting_on == 0) &&
|
||||||
(dev->fsa_dev[container].config_needed != NOTHING) &&
|
(dev->fsa_dev[container].config_needed != NOTHING) &&
|
||||||
time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) {
|
time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) {
|
||||||
|
@ -1110,6 +1123,11 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
|
||||||
}
|
}
|
||||||
if (device_config_needed == ADD)
|
if (device_config_needed == ADD)
|
||||||
scsi_add_device(dev->scsi_host_ptr, channel, id, lun);
|
scsi_add_device(dev->scsi_host_ptr, channel, id, lun);
|
||||||
|
if (channel == CONTAINER_CHANNEL) {
|
||||||
|
container++;
|
||||||
|
device_config_needed = NOTHING;
|
||||||
|
goto retry_next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _aac_reset_adapter(struct aac_dev *aac, int forced)
|
static int _aac_reset_adapter(struct aac_dev *aac, int forced)
|
||||||
|
|
|
@ -401,6 +401,8 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
|
||||||
static int aac_slave_configure(struct scsi_device *sdev)
|
static int aac_slave_configure(struct scsi_device *sdev)
|
||||||
{
|
{
|
||||||
struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
|
struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
|
||||||
|
if (aac->jbod && (sdev->type == TYPE_DISK))
|
||||||
|
sdev->removable = 1;
|
||||||
if ((sdev->type == TYPE_DISK) &&
|
if ((sdev->type == TYPE_DISK) &&
|
||||||
(sdev_channel(sdev) != CONTAINER_CHANNEL) &&
|
(sdev_channel(sdev) != CONTAINER_CHANNEL) &&
|
||||||
(!aac->jbod || sdev->inq_periph_qual) &&
|
(!aac->jbod || sdev->inq_periph_qual) &&
|
||||||
|
@ -809,6 +811,12 @@ static ssize_t aac_show_flags(struct device *cdev,
|
||||||
"SAI_READ_CAPACITY_16\n");
|
"SAI_READ_CAPACITY_16\n");
|
||||||
if (dev->jbod)
|
if (dev->jbod)
|
||||||
len += snprintf(buf + len, PAGE_SIZE - len, "SUPPORTED_JBOD\n");
|
len += snprintf(buf + len, PAGE_SIZE - len, "SUPPORTED_JBOD\n");
|
||||||
|
if (dev->supplement_adapter_info.SupportedOptions2 &
|
||||||
|
AAC_OPTION_POWER_MANAGEMENT)
|
||||||
|
len += snprintf(buf + len, PAGE_SIZE - len,
|
||||||
|
"SUPPORTED_POWER_MANAGEMENT\n");
|
||||||
|
if (dev->msi)
|
||||||
|
len += snprintf(buf + len, PAGE_SIZE - len, "PCI_HAS_MSI\n");
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,7 +1114,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
|
||||||
aac->pdev = pdev;
|
aac->pdev = pdev;
|
||||||
aac->name = aac_driver_template.name;
|
aac->name = aac_driver_template.name;
|
||||||
aac->id = shost->unique_id;
|
aac->id = shost->unique_id;
|
||||||
aac->cardtype = index;
|
aac->cardtype = index;
|
||||||
INIT_LIST_HEAD(&aac->entry);
|
INIT_LIST_HEAD(&aac->entry);
|
||||||
|
|
||||||
aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL);
|
aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL);
|
||||||
|
@ -1146,19 +1154,19 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
|
||||||
goto out_deinit;
|
goto out_deinit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lets override negotiations and drop the maximum SG limit to 34
|
* Lets override negotiations and drop the maximum SG limit to 34
|
||||||
*/
|
*/
|
||||||
if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) &&
|
if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) &&
|
||||||
(shost->sg_tablesize > 34)) {
|
(shost->sg_tablesize > 34)) {
|
||||||
shost->sg_tablesize = 34;
|
shost->sg_tablesize = 34;
|
||||||
shost->max_sectors = (shost->sg_tablesize * 8) + 112;
|
shost->max_sectors = (shost->sg_tablesize * 8) + 112;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) &&
|
if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) &&
|
||||||
(shost->sg_tablesize > 17)) {
|
(shost->sg_tablesize > 17)) {
|
||||||
shost->sg_tablesize = 17;
|
shost->sg_tablesize = 17;
|
||||||
shost->max_sectors = (shost->sg_tablesize * 8) + 112;
|
shost->max_sectors = (shost->sg_tablesize * 8) + 112;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = pci_set_dma_max_seg_size(pdev,
|
error = pci_set_dma_max_seg_size(pdev,
|
||||||
(aac->adapter_info.options & AAC_OPT_NEW_COMM) ?
|
(aac->adapter_info.options & AAC_OPT_NEW_COMM) ?
|
||||||
|
@ -1174,7 +1182,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
|
||||||
else
|
else
|
||||||
aac->printf_enabled = 0;
|
aac->printf_enabled = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* max channel will be the physical channels plus 1 virtual channel
|
* max channel will be the physical channels plus 1 virtual channel
|
||||||
* all containers are on the virtual channel 0 (CONTAINER_CHANNEL)
|
* all containers are on the virtual channel 0 (CONTAINER_CHANNEL)
|
||||||
* physical channels are address by their actual physical number+1
|
* physical channels are address by their actual physical number+1
|
||||||
|
|
|
@ -529,10 +529,10 @@ static void asd_remove_dev_attrs(struct asd_ha_struct *asd_ha)
|
||||||
/* The first entry, 0, is used for dynamic ids, the rest for devices
|
/* The first entry, 0, is used for dynamic ids, the rest for devices
|
||||||
* we know about.
|
* we know about.
|
||||||
*/
|
*/
|
||||||
static struct asd_pcidev_struct {
|
static const struct asd_pcidev_struct {
|
||||||
const char * name;
|
const char * name;
|
||||||
int (*setup)(struct asd_ha_struct *asd_ha);
|
int (*setup)(struct asd_ha_struct *asd_ha);
|
||||||
} asd_pcidev_data[] = {
|
} asd_pcidev_data[] __devinitconst = {
|
||||||
/* Id 0 is used for dynamic ids. */
|
/* Id 0 is used for dynamic ids. */
|
||||||
{ .name = "Adaptec AIC-94xx SAS/SATA Host Adapter",
|
{ .name = "Adaptec AIC-94xx SAS/SATA Host Adapter",
|
||||||
.setup = asd_aic9410_setup
|
.setup = asd_aic9410_setup
|
||||||
|
@ -735,7 +735,7 @@ static int asd_unregister_sas_ha(struct asd_ha_struct *asd_ha)
|
||||||
static int __devinit asd_pci_probe(struct pci_dev *dev,
|
static int __devinit asd_pci_probe(struct pci_dev *dev,
|
||||||
const struct pci_device_id *id)
|
const struct pci_device_id *id)
|
||||||
{
|
{
|
||||||
struct asd_pcidev_struct *asd_dev;
|
const struct asd_pcidev_struct *asd_dev;
|
||||||
unsigned asd_id = (unsigned) id->driver_data;
|
unsigned asd_id = (unsigned) id->driver_data;
|
||||||
struct asd_ha_struct *asd_ha;
|
struct asd_ha_struct *asd_ha;
|
||||||
struct Scsi_Host *shost;
|
struct Scsi_Host *shost;
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#define SERVICE_ACTION_OUT_12 0xa9
|
#define SERVICE_ACTION_OUT_12 0xa9
|
||||||
#define SERVICE_ACTION_IN_16 0x9e
|
#define SERVICE_ACTION_IN_16 0x9e
|
||||||
#define SERVICE_ACTION_OUT_16 0x9f
|
#define SERVICE_ACTION_OUT_16 0x9f
|
||||||
#define VARIABLE_LENGTH_CMD 0x7f
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -210,7 +209,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
|
||||||
cdb0 = cdbp[0];
|
cdb0 = cdbp[0];
|
||||||
switch(cdb0) {
|
switch(cdb0) {
|
||||||
case VARIABLE_LENGTH_CMD:
|
case VARIABLE_LENGTH_CMD:
|
||||||
len = cdbp[7] + 8;
|
len = scsi_varlen_cdb_length(cdbp);
|
||||||
if (len < 10) {
|
if (len < 10) {
|
||||||
printk("short variable length command, "
|
printk("short variable length command, "
|
||||||
"len=%d ext_len=%d", len, cdb_len);
|
"len=%d ext_len=%d", len, cdb_len);
|
||||||
|
@ -300,7 +299,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
|
||||||
cdb0 = cdbp[0];
|
cdb0 = cdbp[0];
|
||||||
switch(cdb0) {
|
switch(cdb0) {
|
||||||
case VARIABLE_LENGTH_CMD:
|
case VARIABLE_LENGTH_CMD:
|
||||||
len = cdbp[7] + 8;
|
len = scsi_varlen_cdb_length(cdbp);
|
||||||
if (len < 10) {
|
if (len < 10) {
|
||||||
printk("short opcode=0x%x command, len=%d "
|
printk("short opcode=0x%x command, len=%d "
|
||||||
"ext_len=%d", cdb0, len, cdb_len);
|
"ext_len=%d", cdb0, len, cdb_len);
|
||||||
|
@ -335,10 +334,7 @@ void __scsi_print_command(unsigned char *cdb)
|
||||||
int k, len;
|
int k, len;
|
||||||
|
|
||||||
print_opcode_name(cdb, 0);
|
print_opcode_name(cdb, 0);
|
||||||
if (VARIABLE_LENGTH_CMD == cdb[0])
|
len = scsi_command_size(cdb);
|
||||||
len = cdb[7] + 8;
|
|
||||||
else
|
|
||||||
len = COMMAND_SIZE(cdb[0]);
|
|
||||||
/* print out all bytes in cdb */
|
/* print out all bytes in cdb */
|
||||||
for (k = 0; k < len; ++k)
|
for (k = 0; k < len; ++k)
|
||||||
printk(" %02x", cdb[k]);
|
printk(" %02x", cdb[k]);
|
||||||
|
|
|
@ -89,7 +89,7 @@ typedef struct {
|
||||||
int njobs; /* # of jobs sent to HA */
|
int njobs; /* # of jobs sent to HA */
|
||||||
int qdepth; /* Controller queue depth. */
|
int qdepth; /* Controller queue depth. */
|
||||||
int wakebase; /* mpx wakeup base index. */
|
int wakebase; /* mpx wakeup base index. */
|
||||||
uLONG SGsize; /* Scatter/Gather list size. */
|
uINT SGsize; /* Scatter/Gather list size. */
|
||||||
unsigned heads; /* heads for drives on cntlr. */
|
unsigned heads; /* heads for drives on cntlr. */
|
||||||
unsigned sectors; /* sectors for drives on cntlr. */
|
unsigned sectors; /* sectors for drives on cntlr. */
|
||||||
uCHAR do_drive32; /* Flag for Above 16 MB Ability */
|
uCHAR do_drive32; /* Flag for Above 16 MB Ability */
|
||||||
|
@ -97,8 +97,8 @@ typedef struct {
|
||||||
char idPAL[4]; /* 4 Bytes Of The ID Pal */
|
char idPAL[4]; /* 4 Bytes Of The ID Pal */
|
||||||
uCHAR primary; /* 1 For Primary, 0 For Secondary */
|
uCHAR primary; /* 1 For Primary, 0 For Secondary */
|
||||||
uCHAR eataVersion; /* EATA Version */
|
uCHAR eataVersion; /* EATA Version */
|
||||||
uLONG cpLength; /* EATA Command Packet Length */
|
uINT cpLength; /* EATA Command Packet Length */
|
||||||
uLONG spLength; /* EATA Status Packet Length */
|
uINT spLength; /* EATA Status Packet Length */
|
||||||
uCHAR drqNum; /* DRQ Index (0,5,6,7) */
|
uCHAR drqNum; /* DRQ Index (0,5,6,7) */
|
||||||
uCHAR flag1; /* EATA Flags 1 (Byte 9) */
|
uCHAR flag1; /* EATA Flags 1 (Byte 9) */
|
||||||
uCHAR flag2; /* EATA Flags 2 (Byte 30) */
|
uCHAR flag2; /* EATA Flags 2 (Byte 30) */
|
||||||
|
@ -107,23 +107,23 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uSHORT length; // Remaining length of this
|
uSHORT length; // Remaining length of this
|
||||||
uSHORT drvrHBAnum; // Relative HBA # used by the driver
|
uSHORT drvrHBAnum; // Relative HBA # used by the driver
|
||||||
uLONG baseAddr; // Base I/O address
|
uINT baseAddr; // Base I/O address
|
||||||
uSHORT blinkState; // Blink LED state (0=Not in blink LED)
|
uSHORT blinkState; // Blink LED state (0=Not in blink LED)
|
||||||
uCHAR pciBusNum; // PCI Bus # (Optional)
|
uCHAR pciBusNum; // PCI Bus # (Optional)
|
||||||
uCHAR pciDeviceNum; // PCI Device # (Optional)
|
uCHAR pciDeviceNum; // PCI Device # (Optional)
|
||||||
uSHORT hbaFlags; // Miscellaneous HBA flags
|
uSHORT hbaFlags; // Miscellaneous HBA flags
|
||||||
uSHORT Interrupt; // Interrupt set for this device.
|
uSHORT Interrupt; // Interrupt set for this device.
|
||||||
# if (defined(_DPT_ARC))
|
# if (defined(_DPT_ARC))
|
||||||
uLONG baseLength;
|
uINT baseLength;
|
||||||
ADAPTER_OBJECT *AdapterObject;
|
ADAPTER_OBJECT *AdapterObject;
|
||||||
LARGE_INTEGER DmaLogicalAddress;
|
LARGE_INTEGER DmaLogicalAddress;
|
||||||
PVOID DmaVirtualAddress;
|
PVOID DmaVirtualAddress;
|
||||||
LARGE_INTEGER ReplyLogicalAddress;
|
LARGE_INTEGER ReplyLogicalAddress;
|
||||||
PVOID ReplyVirtualAddress;
|
PVOID ReplyVirtualAddress;
|
||||||
# else
|
# else
|
||||||
uLONG reserved1; // Reserved for future expansion
|
uINT reserved1; // Reserved for future expansion
|
||||||
uLONG reserved2; // Reserved for future expansion
|
uINT reserved2; // Reserved for future expansion
|
||||||
uLONG reserved3; // Reserved for future expansion
|
uINT reserved3; // Reserved for future expansion
|
||||||
# endif
|
# endif
|
||||||
} drvrHBAinfo_S;
|
} drvrHBAinfo_S;
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,7 @@
|
||||||
/* to make sure we are talking the same size under all OS's */
|
/* to make sure we are talking the same size under all OS's */
|
||||||
typedef unsigned char sigBYTE;
|
typedef unsigned char sigBYTE;
|
||||||
typedef unsigned short sigWORD;
|
typedef unsigned short sigWORD;
|
||||||
#if (defined(_MULTI_DATAMODEL) && defined(sun) && !defined(_ILP32))
|
typedef unsigned int sigINT;
|
||||||
typedef uint32_t sigLONG;
|
|
||||||
#else
|
|
||||||
typedef unsigned long sigLONG;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* use sigWORDLittleEndian for:
|
* use sigWORDLittleEndian for:
|
||||||
|
@ -300,7 +296,7 @@ typedef struct dpt_sig {
|
||||||
sigBYTE dsFiletype; /* type of file */
|
sigBYTE dsFiletype; /* type of file */
|
||||||
sigBYTE dsFiletypeFlags; /* flags to specify load type, etc. */
|
sigBYTE dsFiletypeFlags; /* flags to specify load type, etc. */
|
||||||
sigBYTE dsOEM; /* OEM file was created for */
|
sigBYTE dsOEM; /* OEM file was created for */
|
||||||
sigLONG dsOS; /* which Operating systems */
|
sigINT dsOS; /* which Operating systems */
|
||||||
sigWORD dsCapabilities; /* RAID levels, etc. */
|
sigWORD dsCapabilities; /* RAID levels, etc. */
|
||||||
sigWORD dsDeviceSupp; /* Types of SCSI devices supported */
|
sigWORD dsDeviceSupp; /* Types of SCSI devices supported */
|
||||||
sigWORD dsAdapterSupp; /* DPT adapter families supported */
|
sigWORD dsAdapterSupp; /* DPT adapter families supported */
|
||||||
|
|
|
@ -145,8 +145,8 @@
|
||||||
uCHAR smartROMRevision;
|
uCHAR smartROMRevision;
|
||||||
uSHORT flags; /* See bit definitions above */
|
uSHORT flags; /* See bit definitions above */
|
||||||
uSHORT conventionalMemSize; /* in KB */
|
uSHORT conventionalMemSize; /* in KB */
|
||||||
uLONG extendedMemSize; /* in KB */
|
uINT extendedMemSize; /* in KB */
|
||||||
uLONG osType; /* Same as DPTSIG's definition */
|
uINT osType; /* Same as DPTSIG's definition */
|
||||||
uCHAR osMajorVersion;
|
uCHAR osMajorVersion;
|
||||||
uCHAR osMinorVersion; /* The OS version */
|
uCHAR osMinorVersion; /* The OS version */
|
||||||
uCHAR osRevision;
|
uCHAR osRevision;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -84,7 +84,6 @@ static int adpt_device_reset(struct scsi_cmnd* cmd);
|
||||||
#define PCI_DPT_DEVICE_ID (0xA501) // DPT PCI I2O Device ID
|
#define PCI_DPT_DEVICE_ID (0xA501) // DPT PCI I2O Device ID
|
||||||
#define PCI_DPT_RAPTOR_DEVICE_ID (0xA511)
|
#define PCI_DPT_RAPTOR_DEVICE_ID (0xA511)
|
||||||
|
|
||||||
//#define REBOOT_NOTIFIER 1
|
|
||||||
/* Debugging macro from Linux Device Drivers - Rubini */
|
/* Debugging macro from Linux Device Drivers - Rubini */
|
||||||
#undef PDEBUG
|
#undef PDEBUG
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -229,14 +228,19 @@ typedef struct _adpt_hba {
|
||||||
u32 post_fifo_size;
|
u32 post_fifo_size;
|
||||||
u32 reply_fifo_size;
|
u32 reply_fifo_size;
|
||||||
u32* reply_pool;
|
u32* reply_pool;
|
||||||
|
dma_addr_t reply_pool_pa;
|
||||||
u32 sg_tablesize; // Scatter/Gather List Size.
|
u32 sg_tablesize; // Scatter/Gather List Size.
|
||||||
u8 top_scsi_channel;
|
u8 top_scsi_channel;
|
||||||
u8 top_scsi_id;
|
u8 top_scsi_id;
|
||||||
u8 top_scsi_lun;
|
u8 top_scsi_lun;
|
||||||
|
u8 dma64;
|
||||||
|
|
||||||
i2o_status_block* status_block;
|
i2o_status_block* status_block;
|
||||||
|
dma_addr_t status_block_pa;
|
||||||
i2o_hrt* hrt;
|
i2o_hrt* hrt;
|
||||||
|
dma_addr_t hrt_pa;
|
||||||
i2o_lct* lct;
|
i2o_lct* lct;
|
||||||
|
dma_addr_t lct_pa;
|
||||||
uint lct_size;
|
uint lct_size;
|
||||||
struct i2o_device* devices;
|
struct i2o_device* devices;
|
||||||
struct adpt_channel channel[MAX_CHANNEL];
|
struct adpt_channel channel[MAX_CHANNEL];
|
||||||
|
@ -249,6 +253,7 @@ typedef struct _adpt_hba {
|
||||||
void __iomem *FwDebugBLEDflag_P;// Virtual Addr Of FW Debug BLED
|
void __iomem *FwDebugBLEDflag_P;// Virtual Addr Of FW Debug BLED
|
||||||
void __iomem *FwDebugBLEDvalue_P;// Virtual Addr Of FW Debug BLED
|
void __iomem *FwDebugBLEDvalue_P;// Virtual Addr Of FW Debug BLED
|
||||||
u32 FwDebugFlags;
|
u32 FwDebugFlags;
|
||||||
|
u32 *ioctl_reply_context[4];
|
||||||
} adpt_hba;
|
} adpt_hba;
|
||||||
|
|
||||||
struct sg_simple_element {
|
struct sg_simple_element {
|
||||||
|
@ -264,9 +269,6 @@ static void adpt_i2o_sys_shutdown(void);
|
||||||
static int adpt_init(void);
|
static int adpt_init(void);
|
||||||
static int adpt_i2o_build_sys_table(void);
|
static int adpt_i2o_build_sys_table(void);
|
||||||
static irqreturn_t adpt_isr(int irq, void *dev_id);
|
static irqreturn_t adpt_isr(int irq, void *dev_id);
|
||||||
#ifdef REBOOT_NOTIFIER
|
|
||||||
static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d);
|
static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d);
|
||||||
static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
|
static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
|
||||||
|
@ -275,7 +277,8 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
|
||||||
static const char *adpt_i2o_get_class_name(int class);
|
static const char *adpt_i2o_get_class_name(int class);
|
||||||
#endif
|
#endif
|
||||||
static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid,
|
static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid,
|
||||||
void *opblk, int oplen, void *resblk, int reslen);
|
void *opblk, dma_addr_t opblk_pa, int oplen,
|
||||||
|
void *resblk, dma_addr_t resblk_pa, int reslen);
|
||||||
static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout);
|
static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout);
|
||||||
static int adpt_i2o_lct_get(adpt_hba* pHba);
|
static int adpt_i2o_lct_get(adpt_hba* pHba);
|
||||||
static int adpt_i2o_parse_lct(adpt_hba* pHba);
|
static int adpt_i2o_parse_lct(adpt_hba* pHba);
|
||||||
|
@ -289,7 +292,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
|
||||||
static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
|
static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
|
||||||
static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice);
|
static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice);
|
||||||
static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd);
|
static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd);
|
||||||
static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht);
|
static s32 adpt_scsi_host_alloc(adpt_hba* pHba,struct scsi_host_template * sht);
|
||||||
static s32 adpt_hba_reset(adpt_hba* pHba);
|
static s32 adpt_hba_reset(adpt_hba* pHba);
|
||||||
static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
|
static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
|
||||||
static s32 adpt_rescan(adpt_hba* pHba);
|
static s32 adpt_rescan(adpt_hba* pHba);
|
||||||
|
|
|
@ -465,7 +465,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
|
||||||
scp->request = (struct request *)&wait;
|
scp->request = (struct request *)&wait;
|
||||||
scp->timeout_per_command = timeout*HZ;
|
scp->timeout_per_command = timeout*HZ;
|
||||||
scp->cmd_len = 12;
|
scp->cmd_len = 12;
|
||||||
memcpy(scp->cmnd, cmnd, 12);
|
scp->cmnd = cmnd;
|
||||||
cmndinfo.priority = IOCTL_PRI;
|
cmndinfo.priority = IOCTL_PRI;
|
||||||
cmndinfo.internal_cmd_str = gdtcmd;
|
cmndinfo.internal_cmd_str = gdtcmd;
|
||||||
cmndinfo.internal_command = 1;
|
cmndinfo.internal_command = 1;
|
||||||
|
|
|
@ -763,9 +763,9 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp,
|
||||||
scp,
|
scp,
|
||||||
host->host_no, scp->device->channel,
|
host->host_no, scp->device->channel,
|
||||||
scp->device->id, scp->device->lun,
|
scp->device->id, scp->device->lun,
|
||||||
*((u32 *)&scp->cmnd),
|
((u32 *)scp->cmnd)[0],
|
||||||
*((u32 *)&scp->cmnd + 1),
|
((u32 *)scp->cmnd)[1],
|
||||||
*((u32 *)&scp->cmnd + 2),
|
((u32 *)scp->cmnd)[2],
|
||||||
_req->index, _req->req_virt);
|
_req->index, _req->req_virt);
|
||||||
|
|
||||||
scp->result = 0;
|
scp->result = 0;
|
||||||
|
|
|
@ -686,7 +686,7 @@ static void handle_cmd_rsp(struct srp_event_struct *evt_struct)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmnd) {
|
if (cmnd) {
|
||||||
cmnd->result = rsp->status;
|
cmnd->result |= rsp->status;
|
||||||
if (((cmnd->result >> 1) & 0x1f) == CHECK_CONDITION)
|
if (((cmnd->result >> 1) & 0x1f) == CHECK_CONDITION)
|
||||||
memcpy(cmnd->sense_buffer,
|
memcpy(cmnd->sense_buffer,
|
||||||
rsp->data,
|
rsp->data,
|
||||||
|
@ -730,6 +730,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
|
||||||
u16 lun = lun_from_dev(cmnd->device);
|
u16 lun = lun_from_dev(cmnd->device);
|
||||||
u8 out_fmt, in_fmt;
|
u8 out_fmt, in_fmt;
|
||||||
|
|
||||||
|
cmnd->result = (DID_OK << 16);
|
||||||
evt_struct = get_event_struct(&hostdata->pool);
|
evt_struct = get_event_struct(&hostdata->pool);
|
||||||
if (!evt_struct)
|
if (!evt_struct)
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
|
@ -738,7 +739,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
|
||||||
srp_cmd = &evt_struct->iu.srp.cmd;
|
srp_cmd = &evt_struct->iu.srp.cmd;
|
||||||
memset(srp_cmd, 0x00, SRP_MAX_IU_LEN);
|
memset(srp_cmd, 0x00, SRP_MAX_IU_LEN);
|
||||||
srp_cmd->opcode = SRP_CMD;
|
srp_cmd->opcode = SRP_CMD;
|
||||||
memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(cmnd->cmnd));
|
memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(srp_cmd->cdb));
|
||||||
srp_cmd->lun = ((u64) lun) << 48;
|
srp_cmd->lun = ((u64) lun) << 48;
|
||||||
|
|
||||||
if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) {
|
if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) {
|
||||||
|
@ -1347,6 +1348,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
|
||||||
|
|
||||||
del_timer(&evt_struct->timer);
|
del_timer(&evt_struct->timer);
|
||||||
|
|
||||||
|
if (crq->status != VIOSRP_OK && evt_struct->cmnd)
|
||||||
|
evt_struct->cmnd->result = DID_ERROR << 16;
|
||||||
if (evt_struct->done)
|
if (evt_struct->done)
|
||||||
evt_struct->done(evt_struct);
|
evt_struct->done(evt_struct);
|
||||||
else
|
else
|
||||||
|
|
|
@ -59,6 +59,15 @@ enum viosrp_crq_formats {
|
||||||
VIOSRP_INLINE_FORMAT = 0x07
|
VIOSRP_INLINE_FORMAT = 0x07
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum viosrp_crq_status {
|
||||||
|
VIOSRP_OK = 0x0,
|
||||||
|
VIOSRP_NONRECOVERABLE_ERR = 0x1,
|
||||||
|
VIOSRP_VIOLATES_MAX_XFER = 0x2,
|
||||||
|
VIOSRP_PARTNER_PANIC = 0x3,
|
||||||
|
VIOSRP_DEVICE_BUSY = 0x8,
|
||||||
|
VIOSRP_ADAPTER_FAIL = 0x10
|
||||||
|
};
|
||||||
|
|
||||||
struct viosrp_crq {
|
struct viosrp_crq {
|
||||||
u8 valid; /* used by RPA */
|
u8 valid; /* used by RPA */
|
||||||
u8 format; /* SCSI vs out-of-band */
|
u8 format; /* SCSI vs out-of-band */
|
||||||
|
|
|
@ -2590,7 +2590,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
|
||||||
cblk->hastat = 0;
|
cblk->hastat = 0;
|
||||||
cblk->tastat = 0;
|
cblk->tastat = 0;
|
||||||
/* Command the command */
|
/* Command the command */
|
||||||
memcpy(&cblk->cdb[0], &cmnd->cmnd, cmnd->cmd_len);
|
memcpy(cblk->cdb, cmnd->cmnd, cmnd->cmd_len);
|
||||||
|
|
||||||
/* Set up tags */
|
/* Set up tags */
|
||||||
if (cmnd->device->tagged_supported) { /* Tag Support */
|
if (cmnd->device->tagged_supported) { /* Tag Support */
|
||||||
|
|
|
@ -2791,7 +2791,7 @@ static ssize_t ipr_store_adapter_state(struct device *dev,
|
||||||
|
|
||||||
static struct device_attribute ipr_ioa_state_attr = {
|
static struct device_attribute ipr_ioa_state_attr = {
|
||||||
.attr = {
|
.attr = {
|
||||||
.name = "state",
|
.name = "online_state",
|
||||||
.mode = S_IRUGO | S_IWUSR,
|
.mode = S_IRUGO | S_IWUSR,
|
||||||
},
|
},
|
||||||
.show = ipr_show_adapter_state,
|
.show = ipr_show_adapter_state,
|
||||||
|
|
|
@ -3168,6 +3168,23 @@ megaraid_mbox_support_random_del(adapter_t *adapter)
|
||||||
uint8_t raw_mbox[sizeof(mbox_t)];
|
uint8_t raw_mbox[sizeof(mbox_t)];
|
||||||
int rval;
|
int rval;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Newer firmware on Dell CERC expect a different
|
||||||
|
* random deletion handling, so disable it.
|
||||||
|
*/
|
||||||
|
if (adapter->pdev->vendor == PCI_VENDOR_ID_AMI &&
|
||||||
|
adapter->pdev->device == PCI_DEVICE_ID_AMI_MEGARAID3 &&
|
||||||
|
adapter->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
|
||||||
|
adapter->pdev->subsystem_device == PCI_SUBSYS_ID_CERC_ATA100_4CH &&
|
||||||
|
(adapter->fw_version[0] > '6' ||
|
||||||
|
(adapter->fw_version[0] == '6' &&
|
||||||
|
adapter->fw_version[2] > '6') ||
|
||||||
|
(adapter->fw_version[0] == '6'
|
||||||
|
&& adapter->fw_version[2] == '6'
|
||||||
|
&& adapter->fw_version[3] > '1'))) {
|
||||||
|
con_log(CL_DLEVEL1, ("megaraid: disable random deletion\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
mbox = (mbox_t *)raw_mbox;
|
mbox = (mbox_t *)raw_mbox;
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@
|
||||||
#define PCI_SUBSYS_ID_PERC3_QC 0x0471
|
#define PCI_SUBSYS_ID_PERC3_QC 0x0471
|
||||||
#define PCI_SUBSYS_ID_PERC3_DC 0x0493
|
#define PCI_SUBSYS_ID_PERC3_DC 0x0493
|
||||||
#define PCI_SUBSYS_ID_PERC3_SC 0x0475
|
#define PCI_SUBSYS_ID_PERC3_SC 0x0475
|
||||||
|
#define PCI_SUBSYS_ID_CERC_ATA100_4CH 0x0511
|
||||||
|
|
||||||
|
|
||||||
#define MBOX_MAX_SCSI_CMDS 128 // number of cmds reserved for kernel
|
#define MBOX_MAX_SCSI_CMDS 128 // number of cmds reserved for kernel
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
* 2 of the License, or (at your option) any later version.
|
* 2 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* FILE : megaraid_sas.c
|
* FILE : megaraid_sas.c
|
||||||
* Version : v00.00.03.16-rc1
|
* Version : v00.00.03.20-rc1
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* (email-id : megaraidlinux@lsi.com)
|
* (email-id : megaraidlinux@lsi.com)
|
||||||
|
@ -2650,12 +2650,13 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
/**
|
/**
|
||||||
* megasas_suspend - driver suspend entry point
|
* megasas_suspend - driver suspend entry point
|
||||||
* @pdev: PCI device structure
|
* @pdev: PCI device structure
|
||||||
* @state: PCI power state to suspend routine
|
* @state: PCI power state to suspend routine
|
||||||
*/
|
*/
|
||||||
static int __devinit
|
static int
|
||||||
megasas_suspend(struct pci_dev *pdev, pm_message_t state)
|
megasas_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host;
|
struct Scsi_Host *host;
|
||||||
|
@ -2687,7 +2688,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||||
* megasas_resume- driver resume entry point
|
* megasas_resume- driver resume entry point
|
||||||
* @pdev: PCI device structure
|
* @pdev: PCI device structure
|
||||||
*/
|
*/
|
||||||
static int __devinit
|
static int
|
||||||
megasas_resume(struct pci_dev *pdev)
|
megasas_resume(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
int rval;
|
int rval;
|
||||||
|
@ -2782,12 +2783,16 @@ megasas_resume(struct pci_dev *pdev)
|
||||||
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#define megasas_suspend NULL
|
||||||
|
#define megasas_resume NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* megasas_detach_one - PCI hot"un"plug entry point
|
* megasas_detach_one - PCI hot"un"plug entry point
|
||||||
* @pdev: PCI device structure
|
* @pdev: PCI device structure
|
||||||
*/
|
*/
|
||||||
static void megasas_detach_one(struct pci_dev *pdev)
|
static void __devexit megasas_detach_one(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct Scsi_Host *host;
|
struct Scsi_Host *host;
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
/*
|
/*
|
||||||
* MegaRAID SAS Driver meta data
|
* MegaRAID SAS Driver meta data
|
||||||
*/
|
*/
|
||||||
#define MEGASAS_VERSION "00.00.03.16-rc1"
|
#define MEGASAS_VERSION "00.00.03.20-rc1"
|
||||||
#define MEGASAS_RELDATE "Nov. 07, 2007"
|
#define MEGASAS_RELDATE "March 10, 2008"
|
||||||
#define MEGASAS_EXT_VERSION "Thu. Nov. 07 10:09:32 PDT 2007"
|
#define MEGASAS_EXT_VERSION "Mon. March 10 11:02:31 PDT 2008"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Device IDs
|
* Device IDs
|
||||||
|
|
|
@ -2858,7 +2858,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||||
|
|
||||||
/* Load SCSI command packet. */
|
/* Load SCSI command packet. */
|
||||||
pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
|
pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
|
||||||
memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
|
memcpy(pkt->scsi_cdb, CMD_CDBP(cmd), CMD_CDBLEN(cmd));
|
||||||
/* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
|
/* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
|
||||||
|
|
||||||
/* Set transfer direction. */
|
/* Set transfer direction. */
|
||||||
|
@ -3127,7 +3127,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||||
|
|
||||||
/* Load SCSI command packet. */
|
/* Load SCSI command packet. */
|
||||||
pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
|
pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
|
||||||
memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
|
memcpy(pkt->scsi_cdb, CMD_CDBP(cmd), CMD_CDBLEN(cmd));
|
||||||
|
|
||||||
/*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
|
/*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
|
||||||
/* Set transfer direction. */
|
/* Set transfer direction. */
|
||||||
|
|
|
@ -78,15 +78,6 @@ static void scsi_done(struct scsi_cmnd *cmd);
|
||||||
/* Do not call reset on error if we just did a reset within 15 sec. */
|
/* Do not call reset on error if we just did a reset within 15 sec. */
|
||||||
#define MIN_RESET_PERIOD (15*HZ)
|
#define MIN_RESET_PERIOD (15*HZ)
|
||||||
|
|
||||||
/*
|
|
||||||
* Macro to determine the size of SCSI command. This macro takes vendor
|
|
||||||
* unique commands into account. SCSI commands in groups 6 and 7 are
|
|
||||||
* vendor unique and we will depend upon the command length being
|
|
||||||
* supplied correctly in cmd_len.
|
|
||||||
*/
|
|
||||||
#define CDB_SIZE(cmd) (((((cmd)->cmnd[0] >> 5) & 7) < 6) ? \
|
|
||||||
COMMAND_SIZE((cmd)->cmnd[0]) : (cmd)->cmd_len)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note - the initial logging level can be set here to log events at boot time.
|
* Note - the initial logging level can be set here to log events at boot time.
|
||||||
* After the system is up, you may enable logging via the /proc interface.
|
* After the system is up, you may enable logging via the /proc interface.
|
||||||
|
@ -469,6 +460,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
|
||||||
cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask);
|
cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask);
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
scsi_put_host_cmd_pool(gfp_mask);
|
scsi_put_host_cmd_pool(gfp_mask);
|
||||||
|
shost->cmd_pool = NULL;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
list_add(&cmd->list, &shost->free_list);
|
list_add(&cmd->list, &shost->free_list);
|
||||||
|
@ -481,6 +473,13 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
|
||||||
*/
|
*/
|
||||||
void scsi_destroy_command_freelist(struct Scsi_Host *shost)
|
void scsi_destroy_command_freelist(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* If cmd_pool is NULL the free list was not initialized, so
|
||||||
|
* do not attempt to release resources.
|
||||||
|
*/
|
||||||
|
if (!shost->cmd_pool)
|
||||||
|
return;
|
||||||
|
|
||||||
while (!list_empty(&shost->free_list)) {
|
while (!list_empty(&shost->free_list)) {
|
||||||
struct scsi_cmnd *cmd;
|
struct scsi_cmnd *cmd;
|
||||||
|
|
||||||
|
@ -701,9 +700,11 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
|
||||||
* Before we queue this command, check if the command
|
* Before we queue this command, check if the command
|
||||||
* length exceeds what the host adapter can handle.
|
* length exceeds what the host adapter can handle.
|
||||||
*/
|
*/
|
||||||
if (CDB_SIZE(cmd) > cmd->device->host->max_cmd_len) {
|
if (cmd->cmd_len > cmd->device->host->max_cmd_len) {
|
||||||
SCSI_LOG_MLQUEUE(3,
|
SCSI_LOG_MLQUEUE(3,
|
||||||
printk("queuecommand : command too long.\n"));
|
printk("queuecommand : command too long. "
|
||||||
|
"cdb_size=%d host->max_cmd_len=%d\n",
|
||||||
|
cmd->cmd_len, cmd->device->host->max_cmd_len));
|
||||||
cmd->result = (DID_ABORT << 16);
|
cmd->result = (DID_ABORT << 16);
|
||||||
|
|
||||||
scsi_done(cmd);
|
scsi_done(cmd);
|
||||||
|
|
|
@ -626,7 +626,7 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
|
||||||
* @scmd: SCSI command structure to hijack
|
* @scmd: SCSI command structure to hijack
|
||||||
* @ses: structure to save restore information
|
* @ses: structure to save restore information
|
||||||
* @cmnd: CDB to send. Can be NULL if no new cmnd is needed
|
* @cmnd: CDB to send. Can be NULL if no new cmnd is needed
|
||||||
* @cmnd_size: size in bytes of @cmnd
|
* @cmnd_size: size in bytes of @cmnd (must be <= BLK_MAX_CDB)
|
||||||
* @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored)
|
* @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored)
|
||||||
*
|
*
|
||||||
* This function is used to save a scsi command information before re-execution
|
* This function is used to save a scsi command information before re-execution
|
||||||
|
@ -648,12 +648,14 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
|
||||||
* command.
|
* command.
|
||||||
*/
|
*/
|
||||||
ses->cmd_len = scmd->cmd_len;
|
ses->cmd_len = scmd->cmd_len;
|
||||||
memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd));
|
ses->cmnd = scmd->cmnd;
|
||||||
ses->data_direction = scmd->sc_data_direction;
|
ses->data_direction = scmd->sc_data_direction;
|
||||||
ses->sdb = scmd->sdb;
|
ses->sdb = scmd->sdb;
|
||||||
ses->next_rq = scmd->request->next_rq;
|
ses->next_rq = scmd->request->next_rq;
|
||||||
ses->result = scmd->result;
|
ses->result = scmd->result;
|
||||||
|
|
||||||
|
scmd->cmnd = ses->eh_cmnd;
|
||||||
|
memset(scmd->cmnd, 0, BLK_MAX_CDB);
|
||||||
memset(&scmd->sdb, 0, sizeof(scmd->sdb));
|
memset(&scmd->sdb, 0, sizeof(scmd->sdb));
|
||||||
scmd->request->next_rq = NULL;
|
scmd->request->next_rq = NULL;
|
||||||
|
|
||||||
|
@ -665,14 +667,13 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
|
||||||
scmd->sdb.table.sgl = &ses->sense_sgl;
|
scmd->sdb.table.sgl = &ses->sense_sgl;
|
||||||
scmd->sc_data_direction = DMA_FROM_DEVICE;
|
scmd->sc_data_direction = DMA_FROM_DEVICE;
|
||||||
scmd->sdb.table.nents = 1;
|
scmd->sdb.table.nents = 1;
|
||||||
memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
|
|
||||||
scmd->cmnd[0] = REQUEST_SENSE;
|
scmd->cmnd[0] = REQUEST_SENSE;
|
||||||
scmd->cmnd[4] = scmd->sdb.length;
|
scmd->cmnd[4] = scmd->sdb.length;
|
||||||
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
|
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
|
||||||
} else {
|
} else {
|
||||||
scmd->sc_data_direction = DMA_NONE;
|
scmd->sc_data_direction = DMA_NONE;
|
||||||
if (cmnd) {
|
if (cmnd) {
|
||||||
memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
|
BUG_ON(cmnd_size > BLK_MAX_CDB);
|
||||||
memcpy(scmd->cmnd, cmnd, cmnd_size);
|
memcpy(scmd->cmnd, cmnd, cmnd_size);
|
||||||
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
|
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
|
||||||
}
|
}
|
||||||
|
@ -705,7 +706,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
|
||||||
* Restore original data
|
* Restore original data
|
||||||
*/
|
*/
|
||||||
scmd->cmd_len = ses->cmd_len;
|
scmd->cmd_len = ses->cmd_len;
|
||||||
memcpy(scmd->cmnd, ses->cmnd, sizeof(scmd->cmnd));
|
scmd->cmnd = ses->cmnd;
|
||||||
scmd->sc_data_direction = ses->data_direction;
|
scmd->sc_data_direction = ses->data_direction;
|
||||||
scmd->sdb = ses->sdb;
|
scmd->sdb = ses->sdb;
|
||||||
scmd->request->next_rq = ses->next_rq;
|
scmd->request->next_rq = ses->next_rq;
|
||||||
|
@ -1775,8 +1776,8 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
|
||||||
scmd->request = &req;
|
scmd->request = &req;
|
||||||
memset(&scmd->eh_timeout, 0, sizeof(scmd->eh_timeout));
|
memset(&scmd->eh_timeout, 0, sizeof(scmd->eh_timeout));
|
||||||
|
|
||||||
memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd));
|
scmd->cmnd = req.cmd;
|
||||||
|
|
||||||
scmd->scsi_done = scsi_reset_provider_done_command;
|
scmd->scsi_done = scsi_reset_provider_done_command;
|
||||||
memset(&scmd->sdb, 0, sizeof(scmd->sdb));
|
memset(&scmd->sdb, 0, sizeof(scmd->sdb));
|
||||||
|
|
||||||
|
|
|
@ -445,7 +445,7 @@ static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
|
||||||
scsi_set_resid(cmd, 0);
|
scsi_set_resid(cmd, 0);
|
||||||
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
|
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
|
||||||
if (cmd->cmd_len == 0)
|
if (cmd->cmd_len == 0)
|
||||||
cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
|
cmd->cmd_len = scsi_command_size(cmd->cmnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scsi_device_unbusy(struct scsi_device *sdev)
|
void scsi_device_unbusy(struct scsi_device *sdev)
|
||||||
|
@ -1094,6 +1094,8 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev,
|
||||||
cmd->tag = req->tag;
|
cmd->tag = req->tag;
|
||||||
cmd->request = req;
|
cmd->request = req;
|
||||||
|
|
||||||
|
cmd->cmnd = req->cmd;
|
||||||
|
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1131,8 +1133,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
|
||||||
req->buffer = NULL;
|
req->buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd));
|
|
||||||
memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
|
|
||||||
cmd->cmd_len = req->cmd_len;
|
cmd->cmd_len = req->cmd_len;
|
||||||
if (!req->data_len)
|
if (!req->data_len)
|
||||||
cmd->sc_data_direction = DMA_NONE;
|
cmd->sc_data_direction = DMA_NONE;
|
||||||
|
@ -1169,6 +1169,7 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
|
||||||
if (unlikely(!cmd))
|
if (unlikely(!cmd))
|
||||||
return BLKPREP_DEFER;
|
return BLKPREP_DEFER;
|
||||||
|
|
||||||
|
memset(cmd->cmnd, 0, BLK_MAX_CDB);
|
||||||
return scsi_init_io(cmd, GFP_ATOMIC);
|
return scsi_init_io(cmd, GFP_ATOMIC);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(scsi_setup_fs_cmnd);
|
EXPORT_SYMBOL(scsi_setup_fs_cmnd);
|
||||||
|
|
|
@ -107,6 +107,8 @@ struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost,
|
||||||
cmd->jiffies_at_alloc = jiffies;
|
cmd->jiffies_at_alloc = jiffies;
|
||||||
cmd->request = rq;
|
cmd->request = rq;
|
||||||
|
|
||||||
|
cmd->cmnd = rq->cmd;
|
||||||
|
|
||||||
rq->special = cmd;
|
rq->special = cmd;
|
||||||
rq->cmd_type = REQ_TYPE_SPECIAL;
|
rq->cmd_type = REQ_TYPE_SPECIAL;
|
||||||
rq->cmd_flags |= REQ_TYPE_BLOCK_PC;
|
rq->cmd_flags |= REQ_TYPE_BLOCK_PC;
|
||||||
|
|
|
@ -744,7 +744,8 @@ static int wait_on_busy(unsigned long iobase, unsigned int loop) {
|
||||||
static int board_inquiry(unsigned int j) {
|
static int board_inquiry(unsigned int j) {
|
||||||
struct mscp *cpp;
|
struct mscp *cpp;
|
||||||
dma_addr_t id_dma_addr;
|
dma_addr_t id_dma_addr;
|
||||||
unsigned int time, limit = 0;
|
unsigned int limit = 0;
|
||||||
|
unsigned long time;
|
||||||
|
|
||||||
id_dma_addr = pci_map_single(HD(j)->pdev, HD(j)->board_id,
|
id_dma_addr = pci_map_single(HD(j)->pdev, HD(j)->board_id,
|
||||||
sizeof(HD(j)->board_id), PCI_DMA_BIDIRECTIONAL);
|
sizeof(HD(j)->board_id), PCI_DMA_BIDIRECTIONAL);
|
||||||
|
@ -1392,7 +1393,8 @@ static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) {
|
static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) {
|
||||||
unsigned int i, j, time, k, c, limit = 0;
|
unsigned int i, j, k, c, limit = 0;
|
||||||
|
unsigned long time;
|
||||||
int arg_done = FALSE;
|
int arg_done = FALSE;
|
||||||
struct scsi_cmnd *SCpnt;
|
struct scsi_cmnd *SCpnt;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(save_cmnd, srb->cmnd, sizeof(save_cmnd));
|
memcpy(save_cmnd, srb->cmnd, sizeof(save_cmnd));
|
||||||
memset(srb->cmnd, 0, sizeof(srb->cmnd));
|
memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
|
||||||
|
|
||||||
/* check if we support the command */
|
/* check if we support the command */
|
||||||
if (save_cmnd[1] >> 5) /* MULTIPLE_COUNT */
|
if (save_cmnd[1] >> 5) /* MULTIPLE_COUNT */
|
||||||
|
|
|
@ -292,6 +292,7 @@ struct isd200_info {
|
||||||
|
|
||||||
/* maximum number of LUNs supported */
|
/* maximum number of LUNs supported */
|
||||||
unsigned char MaxLUNs;
|
unsigned char MaxLUNs;
|
||||||
|
unsigned char cmnd[BLK_MAX_CDB];
|
||||||
struct scsi_cmnd srb;
|
struct scsi_cmnd srb;
|
||||||
struct scatterlist sg;
|
struct scatterlist sg;
|
||||||
};
|
};
|
||||||
|
@ -450,6 +451,7 @@ static int isd200_action( struct us_data *us, int action,
|
||||||
|
|
||||||
memset(&ata, 0, sizeof(ata));
|
memset(&ata, 0, sizeof(ata));
|
||||||
memset(&srb_dev, 0, sizeof(srb_dev));
|
memset(&srb_dev, 0, sizeof(srb_dev));
|
||||||
|
srb->cmnd = info->cmnd;
|
||||||
srb->device = &srb_dev;
|
srb->device = &srb_dev;
|
||||||
++srb->serial_number;
|
++srb->serial_number;
|
||||||
|
|
||||||
|
|
|
@ -29,13 +29,6 @@
|
||||||
#define SCSI_MAX_SG_CHAIN_SEGMENTS SCSI_MAX_SG_SEGMENTS
|
#define SCSI_MAX_SG_CHAIN_SEGMENTS SCSI_MAX_SG_SEGMENTS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* SCSI command lengths
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern const unsigned char scsi_command_size[8];
|
|
||||||
#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7]
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special value for scanning to specify scanning or rescanning of all
|
* Special value for scanning to specify scanning or rescanning of all
|
||||||
* possible channels, (target) ids, or luns on a given shost.
|
* possible channels, (target) ids, or luns on a given shost.
|
||||||
|
@ -109,6 +102,7 @@ extern const unsigned char scsi_command_size[8];
|
||||||
#define MODE_SENSE_10 0x5a
|
#define MODE_SENSE_10 0x5a
|
||||||
#define PERSISTENT_RESERVE_IN 0x5e
|
#define PERSISTENT_RESERVE_IN 0x5e
|
||||||
#define PERSISTENT_RESERVE_OUT 0x5f
|
#define PERSISTENT_RESERVE_OUT 0x5f
|
||||||
|
#define VARIABLE_LENGTH_CMD 0x7f
|
||||||
#define REPORT_LUNS 0xa0
|
#define REPORT_LUNS 0xa0
|
||||||
#define MAINTENANCE_IN 0xa3
|
#define MAINTENANCE_IN 0xa3
|
||||||
#define MOVE_MEDIUM 0xa5
|
#define MOVE_MEDIUM 0xa5
|
||||||
|
@ -135,6 +129,38 @@ extern const unsigned char scsi_command_size[8];
|
||||||
#define ATA_16 0x85 /* 16-byte pass-thru */
|
#define ATA_16 0x85 /* 16-byte pass-thru */
|
||||||
#define ATA_12 0xa1 /* 12-byte pass-thru */
|
#define ATA_12 0xa1 /* 12-byte pass-thru */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SCSI command lengths
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SCSI_MAX_VARLEN_CDB_SIZE 260
|
||||||
|
|
||||||
|
/* defined in T10 SCSI Primary Commands-2 (SPC2) */
|
||||||
|
struct scsi_varlen_cdb_hdr {
|
||||||
|
u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */
|
||||||
|
u8 control;
|
||||||
|
u8 misc[5];
|
||||||
|
u8 additional_cdb_length; /* total cdb length - 8 */
|
||||||
|
__be16 service_action;
|
||||||
|
/* service specific data follows */
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
scsi_varlen_cdb_length(const void *hdr)
|
||||||
|
{
|
||||||
|
return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const unsigned char scsi_command_size_tbl[8];
|
||||||
|
#define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7]
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
scsi_command_size(const unsigned char *cmnd)
|
||||||
|
{
|
||||||
|
return (cmnd[0] == VARIABLE_LENGTH_CMD) ?
|
||||||
|
scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
|
* SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
|
||||||
* T10/1561-D Revision 4 Draft dated 7th November 2002.
|
* T10/1561-D Revision 4 Draft dated 7th November 2002.
|
||||||
|
|
|
@ -7,10 +7,28 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/scatterlist.h>
|
#include <linux/scatterlist.h>
|
||||||
|
#include <linux/blkdev.h>
|
||||||
|
|
||||||
struct Scsi_Host;
|
struct Scsi_Host;
|
||||||
struct scsi_device;
|
struct scsi_device;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MAX_COMMAND_SIZE is:
|
||||||
|
* The longest fixed-length SCSI CDB as per the SCSI standard.
|
||||||
|
* fixed-length means: commands that their size can be determined
|
||||||
|
* by their opcode and the CDB does not carry a length specifier, (unlike
|
||||||
|
* the VARIABLE_LENGTH_CMD(0x7f) command). This is actually not exactly
|
||||||
|
* true and the SCSI standard also defines extended commands and
|
||||||
|
* vendor specific commands that can be bigger than 16 bytes. The kernel
|
||||||
|
* will support these using the same infrastructure used for VARLEN CDB's.
|
||||||
|
* So in effect MAX_COMMAND_SIZE means the maximum size command scsi-ml
|
||||||
|
* supports without specifying a cmd_len by ULD's
|
||||||
|
*/
|
||||||
|
#define MAX_COMMAND_SIZE 16
|
||||||
|
#if (MAX_COMMAND_SIZE > BLK_MAX_CDB)
|
||||||
|
# error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB
|
||||||
|
#endif
|
||||||
|
|
||||||
struct scsi_data_buffer {
|
struct scsi_data_buffer {
|
||||||
struct sg_table table;
|
struct sg_table table;
|
||||||
unsigned length;
|
unsigned length;
|
||||||
|
@ -60,12 +78,11 @@ struct scsi_cmnd {
|
||||||
int allowed;
|
int allowed;
|
||||||
int timeout_per_command;
|
int timeout_per_command;
|
||||||
|
|
||||||
unsigned char cmd_len;
|
unsigned short cmd_len;
|
||||||
enum dma_data_direction sc_data_direction;
|
enum dma_data_direction sc_data_direction;
|
||||||
|
|
||||||
/* These elements define the operation we are about to perform */
|
/* These elements define the operation we are about to perform */
|
||||||
#define MAX_COMMAND_SIZE 16
|
unsigned char *cmnd;
|
||||||
unsigned char cmnd[MAX_COMMAND_SIZE];
|
|
||||||
|
|
||||||
struct timer_list eh_timeout; /* Used to time out the command. */
|
struct timer_list eh_timeout; /* Used to time out the command. */
|
||||||
|
|
||||||
|
|
|
@ -75,11 +75,11 @@ struct scsi_eh_save {
|
||||||
int result;
|
int result;
|
||||||
enum dma_data_direction data_direction;
|
enum dma_data_direction data_direction;
|
||||||
unsigned char cmd_len;
|
unsigned char cmd_len;
|
||||||
unsigned char cmnd[MAX_COMMAND_SIZE];
|
unsigned char *cmnd;
|
||||||
struct scsi_data_buffer sdb;
|
struct scsi_data_buffer sdb;
|
||||||
struct request *next_rq;
|
struct request *next_rq;
|
||||||
|
|
||||||
/* new command support */
|
/* new command support */
|
||||||
|
unsigned char eh_cmnd[BLK_MAX_CDB];
|
||||||
struct scatterlist sense_sgl;
|
struct scatterlist sense_sgl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -573,13 +573,11 @@ struct Scsi_Host {
|
||||||
/*
|
/*
|
||||||
* The maximum length of SCSI commands that this host can accept.
|
* The maximum length of SCSI commands that this host can accept.
|
||||||
* Probably 12 for most host adapters, but could be 16 for others.
|
* Probably 12 for most host adapters, but could be 16 for others.
|
||||||
|
* or 260 if the driver supports variable length cdbs.
|
||||||
* For drivers that don't set this field, a value of 12 is
|
* For drivers that don't set this field, a value of 12 is
|
||||||
* assumed. I am leaving this as a number rather than a bit
|
* assumed.
|
||||||
* because you never know what subsequent SCSI standards might do
|
|
||||||
* (i.e. could there be a 20 byte or a 24-byte command a few years
|
|
||||||
* down the road?).
|
|
||||||
*/
|
*/
|
||||||
unsigned char max_cmd_len;
|
unsigned short max_cmd_len;
|
||||||
|
|
||||||
int this_id;
|
int this_id;
|
||||||
int can_queue;
|
int can_queue;
|
||||||
|
|
Loading…
Reference in a new issue