Commit cae8da04 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI updates from James Bottomley:
 "This pull includes driver updates from the usual suspects (stex, hpsa,
  ncr5380, scsi_dh, qla2xxx, be2iscsi, hisi_sas, cxlflash, aacraid,
  mp3sas, megaraid_sas, ibmvscsi, ufs) plus an assortment of
  miscellaneous fixes.

  The major user visible change of this pull is that we've moved from
  monotonically increasing host number to an ida allocated one (meaning
  the numbers get re-used) because someone managed to wrap the count in
  an iscsi system.  We don't believe there will be any adverse
  consequences of this"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (230 commits)
  MAINTAINERS: use new email address for James Bottomley
  mpt3sas: Remove unnecessary synchronize_irq() before free_irq()
  sg: fix dxferp in from_to case
  cxlflash: Increase cmd_per_lun for better throughput
  cxlflash: Fix to avoid unnecessary scan with internal LUNs
  cxlflash: Reorder user context initialization
  cxlflash: Simplify attach path error cleanup
  cxlflash: Split out context initialization
  cxlflash: Unmap problem state area before detaching master context
  cxlflash: Simplify PCI registration
  scsi: storvsc: fix SRB_STATUS_ABORTED handling
  be2iscsi: set the boot_kset pointer to NULL in case of failure
  sd: Fix discard granularity when LBPRZ=1
  be2iscsi: Remove unnecessary synchronize_irq() before free_irq()
  scsi_sysfs: call 'device_add' after attaching device handler
  scsi_dh_emc: update 'access_state' field
  scsi_dh_rdac: update 'access_state' field
  scsi_dh_alua: update 'access_state' field
  scsi_dh_alua: use common definitions for ALUA state
  scsi: Add 'access_state' and 'preferred_path' attribute
  ...
parents 7bb7a748 a7dee8f4
......@@ -5,6 +5,7 @@ The HiSilicon SAS controller supports SAS/SATA.
Main node required properties:
- compatible : value should be as follows:
(a) "hisilicon,hip05-sas-v1" for v1 hw in hip05 chipset
(b) "hisilicon,hip06-sas-v2" for v2 hw in hip06 chipset
- sas-addr : array of 8 bytes for host SAS address
- reg : Address and length of the SAS register
- hisilicon,sas-syscon: phandle of syscon used for sas control
......@@ -13,7 +14,7 @@ Main node required properties:
- ctrl-clock-ena-reg : offset to controller clock enable register in ctrl reg
- queue-count : number of delivery and completion queues in the controller
- phy-count : number of phys accessible by the controller
- interrupts : Interrupts for phys, completion queues, and fatal
- interrupts : For v1 hw: Interrupts for phys, completion queues, and fatal
sources; the interrupts are ordered in 3 groups, as follows:
- Phy interrupts
- Completion queue interrupts
......@@ -30,6 +31,24 @@ Main node required properties:
Fatal interrupts : the fatal interrupts are ordered as follows:
- ECC
- AXI bus
For v2 hw: Interrupts for phys, Sata, and completion queues;
the interrupts are ordered in 3 groups, as follows:
- Phy interrupts
- Sata interrupts
- Completion queue interrupts
Phy interrupts : Each controller has 2 phy interrupts:
- phy up/down
- channel interrupt
Sata interrupts : Each phy on the controller has 1 Sata
interrupt. The interrupts are ordered in increasing
order.
Completion queue interrupts : each completion queue has 1
interrupt source. The interrupts are ordered in
increasing order.
Optional main node properties:
- hip06-sas-v2-quirk-amt : when set, indicates that the v2 controller has the
"am-max-transmissions" limitation.
Example:
sas0: sas@c1000000 {
......
......@@ -2,7 +2,7 @@ This file contains brief information about the SCSI tape driver.
The driver is currently maintained by Kai Mäkisara (email
Kai.Makisara@kolumbus.fi)
Last modified: Sun Aug 29 18:25:47 2010 by kai.makisara
Last modified: Tue Feb 9 21:54:16 2016 by kai.makisara
BASICS
......@@ -408,10 +408,15 @@ MTSETPART Moves the tape to the partition given by the argument at the
specified by MTSEEK. MTSETPART is inactive unless
MT_ST_CAN_PARTITIONS set.
MTMKPART Formats the tape with one partition (argument zero) or two
partitions (the argument gives in megabytes the size of
partition 1 that is physically the first partition of the
tape). The drive has to support partitions with size specified
by the initiator. Inactive unless MT_ST_CAN_PARTITIONS set.
partitions (argument non-zero). If the argument is positive,
it specifies the size of partition 1 in megabytes. For DDS
drives and several early drives this is the physically first
partition of the tape. If the argument is negative, its absolute
value specifies the size of partition 0 in megabytes. This is
the physically first partition of many later drives, like the
LTO drives from LTO-5 upwards. The drive has to support partitions
with size specified by the initiator. Inactive unless
MT_ST_CAN_PARTITIONS set.
MTSETDRVBUFFER
Is used for several purposes. The command is obtained from count
with mask MT_SET_OPTIONS, the low order bits are used as argument.
......
......@@ -5007,9 +5007,9 @@ F: Documentation/blockdev/cpqarray.txt
F: drivers/block/cpqarray.*
HEWLETT-PACKARD SMART ARRAY RAID DRIVER (hpsa)
M: Don Brace <don.brace@pmcs.com>
M: Don Brace <don.brace@microsemi.com>
L: iss_storagedev@hp.com
L: storagedev@pmcs.com
L: esc.storagedev@microsemi.com
L: linux-scsi@vger.kernel.org
S: Supported
F: Documentation/scsi/hpsa.txt
......@@ -6682,13 +6682,12 @@ S: Maintained
F: arch/arm/mach-lpc32xx/
LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
M: Nagalakshmi Nandigama <nagalakshmi.nandigama@avagotech.com>
M: Praveen Krishnamoorthy <praveen.krishnamoorthy@avagotech.com>
M: Sreekanth Reddy <sreekanth.reddy@avagotech.com>
M: Abhijit Mahajan <abhijit.mahajan@avagotech.com>
L: MPT-FusionLinux.pdl@avagotech.com
M: Sathya Prakash <sathya.prakash@broadcom.com>
M: Chaitra P B <chaitra.basappa@broadcom.com>
M: Suganath Prabu Subramani <suganath-prabu.subramani@broadcom.com>
L: MPT-FusionLinux.pdl@broadcom.com
L: linux-scsi@vger.kernel.org
W: http://www.lsilogic.com/support
W: http://www.avagotech.com/support/
S: Supported
F: drivers/message/fusion/
F: drivers/scsi/mpt2sas/
......@@ -9691,7 +9690,7 @@ F: drivers/scsi/sg.c
F: include/scsi/sg.h
SCSI SUBSYSTEM
M: "James E.J. Bottomley" <JBottomley@odin.com>
M: "James E.J. Bottomley" <jejb@linux.vnet.ibm.com>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
M: "Martin K. Petersen" <martin.petersen@oracle.com>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
......
......@@ -1801,8 +1801,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->pcidev = pdev;
if (mpt_mapresources(ioc)) {
kfree(ioc);
return r;
goto out_free_ioc;
}
/*
......@@ -1871,9 +1870,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
if (!ioc->reset_work_q) {
printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
ioc->name);
pci_release_selected_regions(pdev, ioc->bars);
kfree(ioc);
return -ENOMEM;
r = -ENOMEM;
goto out_unmap_resources;
}
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
......@@ -1995,16 +1993,27 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
spin_lock_init(&ioc->fw_event_lock);
snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
if (!ioc->fw_event_q) {
printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
ioc->name);
r = -ENOMEM;
goto out_remove_ioc;
}
if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
CAN_SLEEP)) != 0){
printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
ioc->name, r);
destroy_workqueue(ioc->fw_event_q);
ioc->fw_event_q = NULL;
list_del(&ioc->list);
if (ioc->alt_ioc)
ioc->alt_ioc->alt_ioc = NULL;
iounmap(ioc->memmap);
if (pci_is_enabled(pdev))
pci_disable_device(pdev);
if (r != -5)
pci_release_selected_regions(pdev, ioc->bars);
......@@ -2012,7 +2021,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->reset_work_q = NULL;
kfree(ioc);
pci_set_drvdata(pdev, NULL);
return r;
}
......@@ -2040,6 +2048,24 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
msecs_to_jiffies(MPT_POLLING_INTERVAL));
return 0;
out_remove_ioc:
list_del(&ioc->list);
if (ioc->alt_ioc)
ioc->alt_ioc->alt_ioc = NULL;
destroy_workqueue(ioc->reset_work_q);
ioc->reset_work_q = NULL;
out_unmap_resources:
iounmap(ioc->memmap);
pci_disable_device(pdev);
pci_release_selected_regions(pdev, ioc->bars);
out_free_ioc:
kfree(ioc);
return r;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -6229,7 +6255,7 @@ mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
out:
out:
if (pbuf)
pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
......@@ -6848,6 +6874,7 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh
*size = y;
}
#ifdef CONFIG_PROC_FS
static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
{
char expVer[32];
......@@ -6879,6 +6906,7 @@ static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int
seq_putc(m, '\n');
}
#endif
/**
* mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
......
......@@ -596,6 +596,7 @@ config XEN_SCSI_FRONTEND
config HYPERV_STORAGE
tristate "Microsoft Hyper-V virtual storage driver"
depends on SCSI && HYPERV
depends on m || SCSI_FC_ATTRS != m
default HYPERV
help
Select this option to enable the Hyper-V virtual storage driver.
......
......@@ -760,7 +760,7 @@ static struct scsi_cmnd *dequeue_next_cmd(struct Scsi_Host *instance)
struct NCR5380_cmd *ncmd;
struct scsi_cmnd *cmd;
if (list_empty(&hostdata->autosense)) {
if (hostdata->sensing || list_empty(&hostdata->autosense)) {
list_for_each_entry(ncmd, &hostdata->unissued, list) {
cmd = NCR5380_to_scmd(ncmd);
dsprintk(NDEBUG_QUEUES, instance, "dequeue: cmd=%p target=%d busy=0x%02x lun=%llu\n",
......@@ -793,7 +793,7 @@ static void requeue_cmd(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
struct NCR5380_hostdata *hostdata = shost_priv(instance);
struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
if (hostdata->sensing) {
if (hostdata->sensing == cmd) {
scsi_eh_restore_cmnd(cmd, &hostdata->ses);
list_add(&ncmd->list, &hostdata->autosense);
hostdata->sensing = NULL;
......@@ -815,15 +815,17 @@ static void NCR5380_main(struct work_struct *work)
struct NCR5380_hostdata *hostdata =
container_of(work, struct NCR5380_hostdata, main_task);
struct Scsi_Host *instance = hostdata->host;
struct scsi_cmnd *cmd;
int done;
do {
done = 1;
spin_lock_irq(&hostdata->lock);
while (!hostdata->connected &&
(cmd = dequeue_next_cmd(instance))) {
while (!hostdata->connected && !hostdata->selecting) {
struct scsi_cmnd *cmd = dequeue_next_cmd(instance);
if (!cmd)
break;
dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
......@@ -840,8 +842,7 @@ static void NCR5380_main(struct work_struct *work)
* entire unit.
*/
cmd = NCR5380_select(instance, cmd);
if (!cmd) {
if (!NCR5380_select(instance, cmd)) {
dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
} else {
dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
......@@ -1056,6 +1057,11 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
/* Reselection interrupt */
goto out;
}
if (!hostdata->selecting) {
/* Command was aborted */
NCR5380_write(MODE_REG, MR_BASE);
goto out;
}
if (err < 0) {
NCR5380_write(MODE_REG, MR_BASE);
shost_printk(KERN_ERR, instance,
......@@ -1759,9 +1765,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
unsigned char msgout = NOP;
int sink = 0;
int len;
#if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
int transfersize;
#endif
unsigned char *data;
unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
struct scsi_cmnd *cmd;
......@@ -1798,6 +1802,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
do_abort(instance);
cmd->result = DID_ERROR << 16;
complete_cmd(instance, cmd);
hostdata->connected = NULL;
return;
#endif
case PHASE_DATAIN:
......@@ -1847,20 +1852,23 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
sink = 1;
do_abort(instance);
cmd->result = DID_ERROR << 16;
complete_cmd(instance, cmd);
/* XXX - need to source or sink data here, as appropriate */
} else
cmd->SCp.this_residual -= transfersize - len;
} else
#endif /* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
{
spin_unlock_irq(&hostdata->lock);
NCR5380_transfer_pio(instance, &phase,
(int *)&cmd->SCp.this_residual,
/* Break up transfer into 3 ms chunks,
* presuming 6 accesses per handshake.
*/
transfersize = min((unsigned long)cmd->SCp.this_residual,
hostdata->accesses_per_ms / 2);
len = transfersize;
NCR5380_transfer_pio(instance, &phase, &len,
(unsigned char **)&cmd->SCp.ptr);
spin_lock_irq(&hostdata->lock);
cmd->SCp.this_residual -= transfersize - len;
}
break;
return;
case PHASE_MSGIN:
len = 1;
data = &tmp;
......@@ -2292,14 +2300,17 @@ static bool list_del_cmd(struct list_head *haystack,
* [disconnected -> connected ->]...
* [autosense -> connected ->] done
*
* If cmd is unissued then just remove it.
* If cmd is disconnected, try to select the target.
* If cmd is connected, try to send an abort message.
* If cmd is waiting for autosense, give it a chance to complete but check
* that it isn't left connected.
* If cmd was not found at all then presumably it has already been completed,
* in which case return SUCCESS to try to avoid further EH measures.
*
* If the command has not completed yet, we must not fail to find it.
* We have no option but to forget the aborted command (even if it still
* lacks sense data). The mid-layer may re-issue a command that is in error
* recovery (see scsi_send_eh_cmnd), but the logic and data structures in
* this driver are such that a command can appear on one queue only.
*
* The lock protects driver data structures, but EH handlers also use it
* to serialize their own execution and prevent their own re-entry.
*/
static int NCR5380_abort(struct scsi_cmnd *cmd)
......@@ -2322,6 +2333,7 @@ static int NCR5380_abort(struct scsi_cmnd *cmd)
"abort: removed %p from issue queue\n", cmd);
cmd->result = DID_ABORT << 16;
cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
goto out;
}
if (hostdata->selecting == cmd) {
......@@ -2336,58 +2348,21 @@ static int NCR5380_abort(struct scsi_cmnd *cmd)
if (list_del_cmd(&hostdata->disconnected, cmd)) {
dsprintk(NDEBUG_ABORT, instance,
"abort: removed %p from disconnected list\n", cmd);
cmd->result = DID_ERROR << 16;
if (!hostdata->connected)
NCR5380_select(instance, cmd);
if (hostdata->connected != cmd) {
complete_cmd(instance, cmd);
result = FAILED;
goto out;
}
/* Can't call NCR5380_select() and send ABORT because that
* means releasing the lock. Need a bus reset.
*/
set_host_byte(cmd, DID_ERROR);
complete_cmd(instance, cmd);
result = FAILED;
goto out;
}
if (hostdata->connected == cmd) {
dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
hostdata->connected = NULL;
if (do_abort(instance)) {
set_host_byte(cmd, DID_ERROR);
complete_cmd(instance, cmd);
result = FAILED;
goto out;
}
set_host_byte(cmd, DID_ABORT);
#ifdef REAL_DMA
hostdata->dma_len = 0;
#endif
if (cmd->cmnd[0] == REQUEST_SENSE)
complete_cmd(instance, cmd);
else {
struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
/* Perform autosense for this command */
list_add(&ncmd->list, &hostdata->autosense);
}
}
if (list_find_cmd(&hostdata->autosense, cmd)) {
dsprintk(NDEBUG_ABORT, instance,
"abort: found %p on sense queue\n", cmd);
spin_unlock_irqrestore(&hostdata->lock, flags);
queue_work(hostdata->work_q, &hostdata->main_task);
msleep(1000);
spin_lock_irqsave(&hostdata->lock, flags);
if (list_del_cmd(&hostdata->autosense, cmd)) {
dsprintk(NDEBUG_ABORT, instance,
"abort: removed %p from sense queue\n", cmd);
set_host_byte(cmd, DID_ABORT);
complete_cmd(instance, cmd);
goto out;
}
}
if (hostdata->connected == cmd) {
dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
hostdata->connected = NULL;
if (do_abort(instance)) {
set_host_byte(cmd, DID_ERROR);
complete_cmd(instance, cmd);
......@@ -2395,9 +2370,14 @@ static int NCR5380_abort(struct scsi_cmnd *cmd)
goto out;
}
set_host_byte(cmd, DID_ABORT);
#ifdef REAL_DMA
hostdata->dma_len = 0;
#endif
complete_cmd(instance, cmd);
goto out;
}
if (list_del_cmd(&hostdata->autosense, cmd)) {
dsprintk(NDEBUG_ABORT, instance,
"abort: removed %p from sense queue\n", cmd);
set_host_byte(cmd, DID_ERROR);
complete_cmd(instance, cmd);
}
......@@ -2450,7 +2430,16 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
* commands!
*/
hostdata->selecting = NULL;
if (list_del_cmd(&hostdata->unissued, cmd)) {
cmd->result = DID_RESET << 16;
cmd->scsi_done(cmd);
}
if (hostdata->selecting) {
hostdata->selecting->result = DID_RESET << 16;
complete_cmd(instance, hostdata->selecting);
hostdata->selecting = NULL;
}
list_for_each_entry(ncmd, &hostdata->disconnected, list) {
struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
......@@ -2458,6 +2447,7 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
set_host_byte(cmd, DID_RESET);
cmd->scsi_done(cmd);
}
INIT_LIST_HEAD(&hostdata->disconnected);
list_for_each_entry(ncmd, &hostdata->autosense, list) {
struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
......@@ -2465,6 +2455,7 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
set_host_byte(cmd, DID_RESET);
cmd->scsi_done(cmd);
}
INIT_LIST_HEAD(&hostdata->autosense);
if (hostdata->connected) {
set_host_byte(hostdata->connected, DID_RESET);
......@@ -2472,12 +2463,6 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
hostdata->connected = NULL;
}
if (hostdata->sensing) {
set_host_byte(hostdata->connected, DID_RESET);
complete_cmd(instance, hostdata->sensing);
hostdata->sensing = NULL;
}
for (i = 0; i < 8; ++i)
hostdata->busy[i] = 0;
#ifdef REAL_DMA
......
......@@ -323,7 +323,6 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
if (unlikely(!scsicmd || !scsicmd->scsi_done)) {
dprintk((KERN_WARNING "aac_valid_context: scsi command corrupt\n"));
aac_fib_complete(fibptr);
aac_fib_free(fibptr);
return 0;
}
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
......@@ -331,7 +330,6 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
if (unlikely(!device || !scsi_device_online(device))) {
dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n"));
aac_fib_complete(fibptr);
aac_fib_free(fibptr);
return 0;
}
return 1;
......@@ -541,7 +539,6 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
aac_fib_complete(fibptr);
aac_fib_free(fibptr);
scsicmd->scsi_done(scsicmd);
}
......@@ -557,7 +554,8 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
if (!(cmd_fibcontext = aac_fib_alloc(dev)))
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext)
return -ENOMEM;
aac_fib_init(cmd_fibcontext);
......@@ -586,7 +584,6 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);
aac_fib_complete(cmd_fibcontext);
aac_fib_free(cmd_fibcontext);
return -1;
}
......@@ -1024,7 +1021,6 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
aac_fib_complete(fibptr);
aac_fib_free(fibptr);
scsicmd->scsi_done(scsicmd);
}
......@@ -1040,7 +1036,8 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd)
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
if (!(cmd_fibcontext = aac_fib_alloc(dev)))
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext)
return -ENOMEM;
aac_fib_init(cmd_fibcontext);
......@@ -1068,7 +1065,6 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd)
printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status);
aac_fib_complete(cmd_fibcontext);
aac_fib_free(cmd_fibcontext);
return -1;
}
......@@ -1869,7 +1865,6 @@ static void io_callback(void *context, struct fib * fibptr)
break;
}
aac_fib_complete(fibptr);
aac_fib_free(fibptr);
scsicmd->scsi_done(scsicmd);
}
......@@ -1954,7 +1949,8 @@ static int aac_read(struct scsi_cmnd * scsicmd)
/*
* Alocate and initialize a Fib
*/
if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext) {
printk(KERN_WARNING "aac_read: fib allocation failed\n");
return -1;
}
......@@ -2051,7 +2047,8 @@ static int aac_write(struct scsi_cmnd * scsicmd)
/*
* Allocate and initialize a Fib then setup a BlockWrite command
*/
if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext) {
/* FIB temporarily unavailable,not catastrophic failure */
/* scsicmd->result = DID_ERROR << 16;
......@@ -2285,7 +2282,7 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd)
/*
* Allocate and initialize a Fib
*/
cmd_fibcontext = aac_fib_alloc(aac);
cmd_fibcontext = aac_fib_alloc_tag(aac, scsicmd);
if (!cmd_fibcontext)
return SCSI_MLQUEUE_HOST_BUSY;
......@@ -3157,7 +3154,6 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
scsicmd->result |= le32_to_cpu(srbreply->scsi_status);
aac_fib_complete(fibptr);
aac_fib_free(fibptr);
scsicmd->scsi_done(scsicmd);
}
......@@ -3187,9 +3183,10 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
/*
* Allocate and initialize a Fib then setup a BlockWrite command
*/
if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext)
return -1;
}
status = aac_adapter_scsi(cmd_fibcontext, scsicmd);
/*
......
......@@ -62,7 +62,7 @@ enum {
#define PMC_GLOBAL_INT_BIT0 0x00000001
#ifndef AAC_DRIVER_BUILD
# define AAC_DRIVER_BUILD 41010
# define AAC_DRIVER_BUILD 41052
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
......@@ -94,6 +94,13 @@ enum {
#define aac_phys_to_logical(x) ((x)+1)
#define aac_logical_to_phys(x) ((x)?(x)-1:0)
/*
* These macros are for keeping track of
* character device state.
*/
#define AAC_CHARDEV_UNREGISTERED (-1)
#define AAC_CHARDEV_NEEDS_REINIT (-2)
/* #define AAC_DETAILED_STATUS_INFO */
struct diskparm
......@@ -944,6 +951,7 @@ struct fib {
*/
struct list_head fiblink;