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: (137 commits) [SCSI] iscsi: bidi support for iscsi_tcp [SCSI] iscsi: bidi support at the generic libiscsi level [SCSI] iscsi: extended cdb support [SCSI] zfcp: Fix error handling for blocked unit for send FCP command [SCSI] zfcp: Remove zfcp_erp_wait from slave destory handler to fix deadlock [SCSI] zfcp: fix 31 bit compile warnings [SCSI] bsg: no need to set BSG_F_BLOCK bit in bsg_complete_all_commands [SCSI] bsg: remove minor in struct bsg_device [SCSI] bsg: use better helper list functions [SCSI] bsg: replace kobject_get with blk_get_queue [SCSI] bsg: takes a ref to struct device in fops->open [SCSI] qla1280: remove version check [SCSI] libsas: fix endianness bug in sas_ata [SCSI] zfcp: fix compiler warning caused by poking inside new semaphore (linux-next) [SCSI] aacraid: Do not describe check_reset parameter with its value [SCSI] aacraid: Fix down_interruptible() to check the return value [SCSI] sun3_scsi_vme: add MODULE_LICENSE [SCSI] st: rename flush_write_buffer() [SCSI] tgt: use KMEM_CACHE macro [SCSI] initio: fix big endian problems for auto request sense ...
This commit is contained in:
commit
2cca775bae
133 changed files with 4890 additions and 4406 deletions
|
@ -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: Mon Mar 7 21:14:44 2005 by kai.makisara
|
||||
Last modified: Sun Feb 24 21:59:07 2008 by kai.makisara
|
||||
|
||||
|
||||
BASICS
|
||||
|
@ -133,6 +133,11 @@ the defaults set by the user. The value -1 means the default is not set. The
|
|||
file 'dev' contains the device numbers corresponding to this device. The links
|
||||
'device' and 'driver' point to the SCSI device and driver entries.
|
||||
|
||||
Each directory also contains the entry 'options' which shows the currently
|
||||
enabled driver and mode options. The value in the file is a bit mask where the
|
||||
bit definitions are the same as those used with MTSETDRVBUFFER in setting the
|
||||
options.
|
||||
|
||||
A link named 'tape' is made from the SCSI device directory to the class
|
||||
directory corresponding to the mode 0 auto-rewind device (e.g., st0).
|
||||
|
||||
|
@ -372,6 +377,11 @@ MTSETDRVBUFFER
|
|||
MT_ST_SYSV sets the SYSV semantics (mode)
|
||||
MT_ST_NOWAIT enables immediate mode (i.e., don't wait for
|
||||
the command to finish) for some commands (e.g., rewind)
|
||||
MT_ST_SILI enables setting the SILI bit in SCSI commands when
|
||||
reading in variable block mode to enhance performance when
|
||||
reading blocks shorter than the byte count; set this only
|
||||
if you are sure that the drive supports SILI and the HBA
|
||||
correctly returns transfer residuals
|
||||
MT_ST_DEBUGGING debugging (global; debugging must be
|
||||
compiled into the driver)
|
||||
MT_ST_SETBOOLEANS
|
||||
|
|
|
@ -201,22 +201,6 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
|
|||
simscsi_sg_readwrite(sc, mode, offset);
|
||||
}
|
||||
|
||||
static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
|
||||
{
|
||||
|
||||
int i;
|
||||
unsigned thislen;
|
||||
struct scatterlist *slp;
|
||||
|
||||
scsi_for_each_sg(sc, slp, scsi_sg_count(sc), i) {
|
||||
if (!len)
|
||||
break;
|
||||
thislen = min(len, slp->length);
|
||||
memcpy(sg_virt(slp), buf, thislen);
|
||||
len -= thislen;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
||||
{
|
||||
|
@ -258,7 +242,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
|||
buf[6] = 0; /* reserved */
|
||||
buf[7] = 0; /* various flags */
|
||||
memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28);
|
||||
simscsi_fillresult(sc, buf, 36);
|
||||
scsi_sg_copy_from_buffer(sc, buf, 36);
|
||||
sc->result = GOOD;
|
||||
break;
|
||||
|
||||
|
@ -306,14 +290,15 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
|||
buf[5] = 0;
|
||||
buf[6] = 2;
|
||||
buf[7] = 0;
|
||||
simscsi_fillresult(sc, buf, 8);
|
||||
scsi_sg_copy_from_buffer(sc, buf, 8);
|
||||
sc->result = GOOD;
|
||||
break;
|
||||
|
||||
case MODE_SENSE:
|
||||
case MODE_SENSE_10:
|
||||
/* sd.c uses this to determine whether disk does write-caching. */
|
||||
simscsi_fillresult(sc, (char *)empty_zero_page, scsi_bufflen(sc));
|
||||
scsi_sg_copy_from_buffer(sc, (char *)empty_zero_page,
|
||||
PAGE_SIZE);
|
||||
sc->result = GOOD;
|
||||
break;
|
||||
|
||||
|
|
52
block/bsg.c
52
block/bsg.c
|
@ -37,7 +37,6 @@ struct bsg_device {
|
|||
struct list_head done_list;
|
||||
struct hlist_node dev_list;
|
||||
atomic_t ref_count;
|
||||
int minor;
|
||||
int queued_cmds;
|
||||
int done_cmds;
|
||||
wait_queue_head_t wq_done;
|
||||
|
@ -368,7 +367,7 @@ static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd)
|
|||
|
||||
spin_lock_irq(&bd->lock);
|
||||
if (bd->done_cmds) {
|
||||
bc = list_entry(bd->done_list.next, struct bsg_command, list);
|
||||
bc = list_first_entry(&bd->done_list, struct bsg_command, list);
|
||||
list_del(&bc->list);
|
||||
bd->done_cmds--;
|
||||
}
|
||||
|
@ -468,8 +467,6 @@ static int bsg_complete_all_commands(struct bsg_device *bd)
|
|||
|
||||
dprintk("%s: entered\n", bd->name);
|
||||
|
||||
set_bit(BSG_F_BLOCK, &bd->flags);
|
||||
|
||||
/*
|
||||
* wait for all commands to complete
|
||||
*/
|
||||
|
@ -705,6 +702,7 @@ static struct bsg_device *bsg_alloc_device(void)
|
|||
static int bsg_put_device(struct bsg_device *bd)
|
||||
{
|
||||
int ret = 0;
|
||||
struct device *dev = bd->queue->bsg_dev.dev;
|
||||
|
||||
mutex_lock(&bsg_mutex);
|
||||
|
||||
|
@ -730,6 +728,7 @@ static int bsg_put_device(struct bsg_device *bd)
|
|||
kfree(bd);
|
||||
out:
|
||||
mutex_unlock(&bsg_mutex);
|
||||
put_device(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -738,22 +737,26 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
|
|||
struct file *file)
|
||||
{
|
||||
struct bsg_device *bd;
|
||||
int ret;
|
||||
#ifdef BSG_DEBUG
|
||||
unsigned char buf[32];
|
||||
#endif
|
||||
ret = blk_get_queue(rq);
|
||||
if (ret)
|
||||
return ERR_PTR(-ENXIO);
|
||||
|
||||
bd = bsg_alloc_device();
|
||||
if (!bd)
|
||||
if (!bd) {
|
||||
blk_put_queue(rq);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
bd->queue = rq;
|
||||
kobject_get(&rq->kobj);
|
||||
bsg_set_block(bd, file);
|
||||
|
||||
atomic_set(&bd->ref_count, 1);
|
||||
bd->minor = iminor(inode);
|
||||
mutex_lock(&bsg_mutex);
|
||||
hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(bd->minor));
|
||||
hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode)));
|
||||
|
||||
strncpy(bd->name, rq->bsg_dev.class_dev->class_id, sizeof(bd->name) - 1);
|
||||
dprintk("bound to <%s>, max queue %d\n",
|
||||
|
@ -763,23 +766,21 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
|
|||
return bd;
|
||||
}
|
||||
|
||||
static struct bsg_device *__bsg_get_device(int minor)
|
||||
static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q)
|
||||
{
|
||||
struct bsg_device *bd = NULL;
|
||||
struct bsg_device *bd;
|
||||
struct hlist_node *entry;
|
||||
|
||||
mutex_lock(&bsg_mutex);
|
||||
|
||||
hlist_for_each(entry, bsg_dev_idx_hash(minor)) {
|
||||
bd = hlist_entry(entry, struct bsg_device, dev_list);
|
||||
if (bd->minor == minor) {
|
||||
hlist_for_each_entry(bd, entry, bsg_dev_idx_hash(minor), dev_list) {
|
||||
if (bd->queue == q) {
|
||||
atomic_inc(&bd->ref_count);
|
||||
break;
|
||||
goto found;
|
||||
}
|
||||
|
||||
bd = NULL;
|
||||
}
|
||||
|
||||
bd = NULL;
|
||||
found:
|
||||
mutex_unlock(&bsg_mutex);
|
||||
return bd;
|
||||
}
|
||||
|
@ -789,21 +790,27 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)
|
|||
struct bsg_device *bd;
|
||||
struct bsg_class_device *bcd;
|
||||
|
||||
bd = __bsg_get_device(iminor(inode));
|
||||
if (bd)
|
||||
return bd;
|
||||
|
||||
/*
|
||||
* find the class device
|
||||
*/
|
||||
mutex_lock(&bsg_mutex);
|
||||
bcd = idr_find(&bsg_minor_idr, iminor(inode));
|
||||
if (bcd)
|
||||
get_device(bcd->dev);
|
||||
mutex_unlock(&bsg_mutex);
|
||||
|
||||
if (!bcd)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
return bsg_add_device(inode, bcd->queue, file);
|
||||
bd = __bsg_get_device(iminor(inode), bcd->queue);
|
||||
if (bd)
|
||||
return bd;
|
||||
|
||||
bd = bsg_add_device(inode, bcd->queue, file);
|
||||
if (IS_ERR(bd))
|
||||
put_device(bcd->dev);
|
||||
|
||||
return bd;
|
||||
}
|
||||
|
||||
static int bsg_open(struct inode *inode, struct file *file)
|
||||
|
@ -942,7 +949,6 @@ void bsg_unregister_queue(struct request_queue *q)
|
|||
class_device_unregister(bcd->class_dev);
|
||||
put_device(bcd->dev);
|
||||
bcd->class_dev = NULL;
|
||||
bcd->dev = NULL;
|
||||
mutex_unlock(&bsg_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bsg_unregister_queue);
|
||||
|
|
|
@ -2332,11 +2332,7 @@ void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
|
|||
{
|
||||
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
|
||||
|
||||
cmd->sense_buffer[0] = 0x70; /* fixed format, current */
|
||||
cmd->sense_buffer[2] = sk;
|
||||
cmd->sense_buffer[7] = 18 - 8; /* additional sense length */
|
||||
cmd->sense_buffer[12] = asc;
|
||||
cmd->sense_buffer[13] = ascq;
|
||||
scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -108,7 +108,8 @@ EXPORT_SYMBOL_GPL(anon_transport_class_register);
|
|||
*/
|
||||
void anon_transport_class_unregister(struct anon_transport_class *atc)
|
||||
{
|
||||
attribute_container_unregister(&atc->container);
|
||||
if (unlikely(attribute_container_unregister(&atc->container)))
|
||||
BUG();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(anon_transport_class_unregister);
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ MODULE_VERSION(my_VERSION);
|
|||
/*
|
||||
* cmd line parameters
|
||||
*/
|
||||
static int mpt_msi_enable;
|
||||
static int mpt_msi_enable = -1;
|
||||
module_param(mpt_msi_enable, int, 0);
|
||||
MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
|
||||
|
||||
|
@ -1686,6 +1686,11 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
ioc->bus_type = SAS;
|
||||
}
|
||||
|
||||
if (ioc->bus_type == SAS && mpt_msi_enable == -1)
|
||||
ioc->msi_enable = 1;
|
||||
else
|
||||
ioc->msi_enable = mpt_msi_enable;
|
||||
|
||||
if (ioc->errata_flag_1064)
|
||||
pci_disable_io_access(pdev);
|
||||
|
||||
|
@ -1831,7 +1836,7 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
|
||||
|
||||
free_irq(ioc->pci_irq, ioc);
|
||||
if (mpt_msi_enable)
|
||||
if (ioc->msi_enable)
|
||||
pci_disable_msi(ioc->pcidev);
|
||||
ioc->pci_irq = -1;
|
||||
pci_save_state(pdev);
|
||||
|
@ -2057,15 +2062,17 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
|||
if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
|
||||
ioc->pci_irq = -1;
|
||||
if (ioc->pcidev->irq) {
|
||||
if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
|
||||
if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
|
||||
printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
|
||||
ioc->name);
|
||||
else
|
||||
ioc->msi_enable = 0;
|
||||
rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
|
||||
IRQF_SHARED, ioc->name, ioc);
|
||||
if (rc < 0) {
|
||||
printk(MYIOC_s_ERR_FMT "Unable to allocate "
|
||||
"interrupt %d!\n", ioc->name, ioc->pcidev->irq);
|
||||
if (mpt_msi_enable)
|
||||
if (ioc->msi_enable)
|
||||
pci_disable_msi(ioc->pcidev);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
@ -2173,7 +2180,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
|||
/*
|
||||
* Initalize link list for inactive raid volumes.
|
||||
*/
|
||||
init_MUTEX(&ioc->raid_data.inactive_list_mutex);
|
||||
mutex_init(&ioc->raid_data.inactive_list_mutex);
|
||||
INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
|
||||
|
||||
if (ioc->bus_type == SAS) {
|
||||
|
@ -2261,7 +2268,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
|||
out:
|
||||
if ((ret != 0) && irq_allocated) {
|
||||
free_irq(ioc->pci_irq, ioc);
|
||||
if (mpt_msi_enable)
|
||||
if (ioc->msi_enable)
|
||||
pci_disable_msi(ioc->pcidev);
|
||||
}
|
||||
return ret;
|
||||
|
@ -2443,7 +2450,7 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc)
|
|||
|
||||
if (ioc->pci_irq != -1) {
|
||||
free_irq(ioc->pci_irq, ioc);
|
||||
if (mpt_msi_enable)
|
||||
if (ioc->msi_enable)
|
||||
pci_disable_msi(ioc->pcidev);
|
||||
ioc->pci_irq = -1;
|
||||
}
|
||||
|
@ -5159,13 +5166,13 @@ mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
|
|||
if (list_empty(&ioc->raid_data.inactive_list))
|
||||
return;
|
||||
|
||||
down(&ioc->raid_data.inactive_list_mutex);
|
||||
mutex_lock(&ioc->raid_data.inactive_list_mutex);
|
||||
list_for_each_entry_safe(component_info, pNext,
|
||||
&ioc->raid_data.inactive_list, list) {
|
||||
list_del(&component_info->list);
|
||||
kfree(component_info);
|
||||
}
|
||||
up(&ioc->raid_data.inactive_list_mutex);
|
||||
mutex_unlock(&ioc->raid_data.inactive_list_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5224,7 +5231,7 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
|
|||
if (!handle_inactive_volumes)
|
||||
goto out;
|
||||
|
||||
down(&ioc->raid_data.inactive_list_mutex);
|
||||
mutex_lock(&ioc->raid_data.inactive_list_mutex);
|
||||
for (i = 0; i < buffer->NumPhysDisks; i++) {
|
||||
if(mpt_raid_phys_disk_pg0(ioc,
|
||||
buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
|
||||
|
@ -5244,7 +5251,7 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
|
|||
list_add_tail(&component_info->list,
|
||||
&ioc->raid_data.inactive_list);
|
||||
}
|
||||
up(&ioc->raid_data.inactive_list_mutex);
|
||||
mutex_unlock(&ioc->raid_data.inactive_list_mutex);
|
||||
|
||||
out:
|
||||
if (buffer)
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include "lsi/mpi_type.h"
|
||||
#include "lsi/mpi.h" /* Fusion MPI(nterface) basic defs */
|
||||
|
@ -531,7 +532,7 @@ struct inactive_raid_component_info {
|
|||
typedef struct _RaidCfgData {
|
||||
IOCPage2_t *pIocPg2; /* table of Raid Volumes */
|
||||
IOCPage3_t *pIocPg3; /* table of physical disks */
|
||||
struct semaphore inactive_list_mutex;
|
||||
struct mutex inactive_list_mutex;
|
||||
struct list_head inactive_list; /* link list for physical
|
||||
disk that belong in
|
||||
inactive volumes */
|
||||
|
@ -630,6 +631,7 @@ typedef struct _MPT_ADAPTER
|
|||
int mtrr_reg;
|
||||
struct pci_dev *pcidev; /* struct pci_dev pointer */
|
||||
int bars; /* bitmask of BAR's that must be configured */
|
||||
int msi_enable;
|
||||
u8 __iomem *memmap; /* mmap address */
|
||||
struct Scsi_Host *sh; /* Scsi Host pointer */
|
||||
SpiCfgData spi_data; /* Scsi config. data */
|
||||
|
@ -693,7 +695,6 @@ typedef struct _MPT_ADAPTER
|
|||
struct mutex sas_discovery_mutex;
|
||||
u8 sas_discovery_runtime;
|
||||
u8 sas_discovery_ignore_events;
|
||||
u16 handle;
|
||||
int sas_index; /* index refrencing */
|
||||
MPT_SAS_MGMT sas_mgmt;
|
||||
struct work_struct sas_persist_task;
|
||||
|
|
|
@ -230,6 +230,20 @@ static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
|
|||
return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
|
||||
}
|
||||
|
||||
static struct mptsas_portinfo *
|
||||
mptsas_get_hba_portinfo(MPT_ADAPTER *ioc)
|
||||
{
|
||||
struct list_head *head = &ioc->sas_topology;
|
||||
struct mptsas_portinfo *pi = NULL;
|
||||
|
||||
/* always the first entry on sas_topology list */
|
||||
|
||||
if (!list_empty(head))
|
||||
pi = list_entry(head->next, struct mptsas_portinfo, list);
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
/*
|
||||
* mptsas_find_portinfo_by_handle
|
||||
*
|
||||
|
@ -1290,7 +1304,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
|
|||
struct mptsas_portinfo *port_info;
|
||||
|
||||
mutex_lock(&ioc->sas_topology_mutex);
|
||||
port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
|
||||
port_info = mptsas_get_hba_portinfo(ioc);
|
||||
if (port_info && port_info->phy_info)
|
||||
sas_address =
|
||||
port_info->phy_info[0].phy->identify.sas_address;
|
||||
|
@ -2028,8 +2042,7 @@ static int mptsas_probe_one_phy(struct device *dev,
|
|||
int i;
|
||||
|
||||
mutex_lock(&ioc->sas_topology_mutex);
|
||||
port_info = mptsas_find_portinfo_by_handle(ioc,
|
||||
ioc->handle);
|
||||
port_info = mptsas_get_hba_portinfo(ioc);
|
||||
mutex_unlock(&ioc->sas_topology_mutex);
|
||||
|
||||
for (i = 0; i < port_info->num_phys; i++)
|
||||
|
@ -2099,8 +2112,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
|
|||
|
||||
mptsas_sas_io_unit_pg1(ioc);
|
||||
mutex_lock(&ioc->sas_topology_mutex);
|
||||
ioc->handle = hba->phy_info[0].handle;
|
||||
port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
|
||||
port_info = mptsas_get_hba_portinfo(ioc);
|
||||
if (!port_info) {
|
||||
port_info = hba;
|
||||
list_add_tail(&port_info->list, &ioc->sas_topology);
|
||||
|
|
|
@ -2304,14 +2304,14 @@ mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
|
|||
if (list_empty(&ioc->raid_data.inactive_list))
|
||||
goto out;
|
||||
|
||||
down(&ioc->raid_data.inactive_list_mutex);
|
||||
mutex_lock(&ioc->raid_data.inactive_list_mutex);
|
||||
list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
|
||||
list) {
|
||||
if ((component_info->d.PhysDiskID == id) &&
|
||||
(component_info->d.PhysDiskBus == channel))
|
||||
rc = 1;
|
||||
}
|
||||
up(&ioc->raid_data.inactive_list_mutex);
|
||||
mutex_unlock(&ioc->raid_data.inactive_list_mutex);
|
||||
|
||||
out:
|
||||
return rc;
|
||||
|
@ -2341,14 +2341,14 @@ mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
|
|||
if (list_empty(&ioc->raid_data.inactive_list))
|
||||
goto out;
|
||||
|
||||
down(&ioc->raid_data.inactive_list_mutex);
|
||||
mutex_lock(&ioc->raid_data.inactive_list_mutex);
|
||||
list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
|
||||
list) {
|
||||
if ((component_info->d.PhysDiskID == id) &&
|
||||
(component_info->d.PhysDiskBus == channel))
|
||||
rc = component_info->d.PhysDiskNum;
|
||||
}
|
||||
up(&ioc->raid_data.inactive_list_mutex);
|
||||
mutex_unlock(&ioc->raid_data.inactive_list_mutex);
|
||||
|
||||
out:
|
||||
return rc;
|
||||
|
|
|
@ -1030,10 +1030,10 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
|
|||
|
||||
/* initialize debug locks */
|
||||
|
||||
spin_lock_init(&adapter->erp_dbf_lock);
|
||||
spin_lock_init(&adapter->hba_dbf_lock);
|
||||
spin_lock_init(&adapter->san_dbf_lock);
|
||||
spin_lock_init(&adapter->scsi_dbf_lock);
|
||||
spin_lock_init(&adapter->rec_dbf_lock);
|
||||
|
||||
retval = zfcp_adapter_debug_register(adapter);
|
||||
if (retval)
|
||||
|
@ -1325,10 +1325,10 @@ zfcp_nameserver_enqueue(struct zfcp_adapter *adapter)
|
|||
|
||||
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FC
|
||||
|
||||
static void
|
||||
zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
|
||||
struct fsf_status_read_buffer *status_buffer)
|
||||
static void zfcp_fsf_incoming_els_rscn(struct zfcp_fsf_req *fsf_req)
|
||||
{
|
||||
struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data;
|
||||
struct zfcp_adapter *adapter = fsf_req->adapter;
|
||||
struct fcp_rscn_head *fcp_rscn_head;
|
||||
struct fcp_rscn_element *fcp_rscn_element;
|
||||
struct zfcp_port *port;
|
||||
|
@ -1375,7 +1375,8 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
|
|||
ZFCP_LOG_INFO("incoming RSCN, trying to open "
|
||||
"port 0x%016Lx\n", port->wwpn);
|
||||
zfcp_erp_port_reopen(port,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
82, fsf_req);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1406,10 +1407,10 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
|
||||
struct fsf_status_read_buffer *status_buffer)
|
||||
static void zfcp_fsf_incoming_els_plogi(struct zfcp_fsf_req *fsf_req)
|
||||
{
|
||||
struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data;
|
||||
struct zfcp_adapter *adapter = fsf_req->adapter;
|
||||
struct fsf_plogi *els_plogi;
|
||||
struct zfcp_port *port;
|
||||
unsigned long flags;
|
||||
|
@ -1428,14 +1429,14 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
|
|||
status_buffer->d_id,
|
||||
zfcp_get_busid_by_adapter(adapter));
|
||||
} else {
|
||||
zfcp_erp_port_forced_reopen(port, 0);
|
||||
zfcp_erp_port_forced_reopen(port, 0, 83, fsf_req);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter,
|
||||
struct fsf_status_read_buffer *status_buffer)
|
||||
static void zfcp_fsf_incoming_els_logo(struct zfcp_fsf_req *fsf_req)
|
||||
{
|
||||
struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data;
|
||||
struct zfcp_adapter *adapter = fsf_req->adapter;
|
||||
struct fcp_logo *els_logo = (struct fcp_logo *) status_buffer->payload;
|
||||
struct zfcp_port *port;
|
||||
unsigned long flags;
|
||||
|
@ -1453,7 +1454,7 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter,
|
|||
status_buffer->d_id,
|
||||
zfcp_get_busid_by_adapter(adapter));
|
||||
} else {
|
||||
zfcp_erp_port_forced_reopen(port, 0);
|
||||
zfcp_erp_port_forced_reopen(port, 0, 84, fsf_req);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1480,12 +1481,12 @@ zfcp_fsf_incoming_els(struct zfcp_fsf_req *fsf_req)
|
|||
|
||||
zfcp_san_dbf_event_incoming_els(fsf_req);
|
||||
if (els_type == LS_PLOGI)
|
||||
zfcp_fsf_incoming_els_plogi(adapter, status_buffer);
|
||||
zfcp_fsf_incoming_els_plogi(fsf_req);
|
||||
else if (els_type == LS_LOGO)
|
||||
zfcp_fsf_incoming_els_logo(adapter, status_buffer);
|
||||
zfcp_fsf_incoming_els_logo(fsf_req);
|
||||
else if ((els_type & 0xffff0000) == LS_RSCN)
|
||||
/* we are only concerned with the command, not the length */
|
||||
zfcp_fsf_incoming_els_rscn(adapter, status_buffer);
|
||||
zfcp_fsf_incoming_els_rscn(fsf_req);
|
||||
else
|
||||
zfcp_fsf_incoming_els_unknown(adapter, status_buffer);
|
||||
}
|
||||
|
|
|
@ -170,9 +170,10 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device)
|
|||
BUG_ON(!zfcp_reqlist_isempty(adapter));
|
||||
adapter->req_no = 0;
|
||||
|
||||
zfcp_erp_modify_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING,
|
||||
ZFCP_SET);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
zfcp_erp_modify_adapter_status(adapter, 10, NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 85,
|
||||
NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
goto out;
|
||||
|
||||
|
@ -197,7 +198,7 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device)
|
|||
|
||||
down(&zfcp_data.config_sema);
|
||||
adapter = dev_get_drvdata(&ccw_device->dev);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 86, NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
zfcp_erp_thread_kill(adapter);
|
||||
up(&zfcp_data.config_sema);
|
||||
|
@ -223,24 +224,21 @@ zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
|
|||
case CIO_GONE:
|
||||
ZFCP_LOG_NORMAL("adapter %s: device gone\n",
|
||||
zfcp_get_busid_by_adapter(adapter));
|
||||
debug_text_event(adapter->erp_dbf,1,"dev_gone");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL);
|
||||
break;
|
||||
case CIO_NO_PATH:
|
||||
ZFCP_LOG_NORMAL("adapter %s: no path\n",
|
||||
zfcp_get_busid_by_adapter(adapter));
|
||||
debug_text_event(adapter->erp_dbf,1,"no_path");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL);
|
||||
break;
|
||||
case CIO_OPER:
|
||||
ZFCP_LOG_NORMAL("adapter %s: operational again\n",
|
||||
zfcp_get_busid_by_adapter(adapter));
|
||||
debug_text_event(adapter->erp_dbf,1,"dev_oper");
|
||||
zfcp_erp_modify_adapter_status(adapter,
|
||||
zfcp_erp_modify_adapter_status(adapter, 11, NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING,
|
||||
ZFCP_SET);
|
||||
zfcp_erp_adapter_reopen(adapter,
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
89, NULL);
|
||||
break;
|
||||
}
|
||||
zfcp_erp_wait(adapter);
|
||||
|
@ -272,7 +270,7 @@ zfcp_ccw_shutdown(struct ccw_device *cdev)
|
|||
|
||||
down(&zfcp_data.config_sema);
|
||||
adapter = dev_get_drvdata(&cdev->dev);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, 90, NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
up(&zfcp_data.config_sema);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
228
drivers/s390/scsi/zfcp_dbf.h
Normal file
228
drivers/s390/scsi/zfcp_dbf.h
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* Copyright IBM Corp. 2008, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef ZFCP_DBF_H
|
||||
#define ZFCP_DBF_H
|
||||
|
||||
#include "zfcp_fsf.h"
|
||||
|
||||
#define ZFCP_DBF_TAG_SIZE 4
|
||||
|
||||
struct zfcp_dbf_dump {
|
||||
u8 tag[ZFCP_DBF_TAG_SIZE];
|
||||
u32 total_size; /* size of total dump data */
|
||||
u32 offset; /* how much data has being already dumped */
|
||||
u32 size; /* how much data comes with this record */
|
||||
u8 data[]; /* dump data */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_rec_dbf_record_thread {
|
||||
u32 total;
|
||||
u32 ready;
|
||||
u32 running;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_rec_dbf_record_target {
|
||||
u64 ref;
|
||||
u32 status;
|
||||
u32 d_id;
|
||||
u64 wwpn;
|
||||
u64 fcp_lun;
|
||||
u32 erp_count;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_rec_dbf_record_trigger {
|
||||
u8 want;
|
||||
u8 need;
|
||||
u32 as;
|
||||
u32 ps;
|
||||
u32 us;
|
||||
u64 ref;
|
||||
u64 action;
|
||||
u64 wwpn;
|
||||
u64 fcp_lun;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_rec_dbf_record_action {
|
||||
u32 status;
|
||||
u32 step;
|
||||
u64 action;
|
||||
u64 fsf_req;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_rec_dbf_record {
|
||||
u8 id;
|
||||
u8 id2;
|
||||
union {
|
||||
struct zfcp_rec_dbf_record_action action;
|
||||
struct zfcp_rec_dbf_record_thread thread;
|
||||
struct zfcp_rec_dbf_record_target target;
|
||||
struct zfcp_rec_dbf_record_trigger trigger;
|
||||
} u;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum {
|
||||
ZFCP_REC_DBF_ID_ACTION,
|
||||
ZFCP_REC_DBF_ID_THREAD,
|
||||
ZFCP_REC_DBF_ID_TARGET,
|
||||
ZFCP_REC_DBF_ID_TRIGGER,
|
||||
};
|
||||
|
||||
struct zfcp_hba_dbf_record_response {
|
||||
u32 fsf_command;
|
||||
u64 fsf_reqid;
|
||||
u32 fsf_seqno;
|
||||
u64 fsf_issued;
|
||||
u32 fsf_prot_status;
|
||||
u32 fsf_status;
|
||||
u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
|
||||
u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
|
||||
u32 fsf_req_status;
|
||||
u8 sbal_first;
|
||||
u8 sbal_curr;
|
||||
u8 sbal_last;
|
||||
u8 pool;
|
||||
u64 erp_action;
|
||||
union {
|
||||
struct {
|
||||
u64 cmnd;
|
||||
u64 serial;
|
||||
} fcp;
|
||||
struct {
|
||||
u64 wwpn;
|
||||
u32 d_id;
|
||||
u32 port_handle;
|
||||
} port;
|
||||
struct {
|
||||
u64 wwpn;
|
||||
u64 fcp_lun;
|
||||
u32 port_handle;
|
||||
u32 lun_handle;
|
||||
} unit;
|
||||
struct {
|
||||
u32 d_id;
|
||||
u8 ls_code;
|
||||
} els;
|
||||
} u;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_hba_dbf_record_status {
|
||||
u8 failed;
|
||||
u32 status_type;
|
||||
u32 status_subtype;
|
||||
struct fsf_queue_designator
|
||||
queue_designator;
|
||||
u32 payload_size;
|
||||
#define ZFCP_DBF_UNSOL_PAYLOAD 80
|
||||
#define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL 32
|
||||
#define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD 56
|
||||
#define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT 2 * sizeof(u32)
|
||||
u8 payload[ZFCP_DBF_UNSOL_PAYLOAD];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_hba_dbf_record_qdio {
|
||||
u32 status;
|
||||
u32 qdio_error;
|
||||
u32 siga_error;
|
||||
u8 sbal_index;
|
||||
u8 sbal_count;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_hba_dbf_record {
|
||||
u8 tag[ZFCP_DBF_TAG_SIZE];
|
||||
u8 tag2[ZFCP_DBF_TAG_SIZE];
|
||||
union {
|
||||
struct zfcp_hba_dbf_record_response response;
|
||||
struct zfcp_hba_dbf_record_status status;
|
||||
struct zfcp_hba_dbf_record_qdio qdio;
|
||||
} u;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_san_dbf_record_ct_request {
|
||||
u16 cmd_req_code;
|
||||
u8 revision;
|
||||
u8 gs_type;
|
||||
u8 gs_subtype;
|
||||
u8 options;
|
||||
u16 max_res_size;
|
||||
u32 len;
|
||||
#define ZFCP_DBF_CT_PAYLOAD 24
|
||||
u8 payload[ZFCP_DBF_CT_PAYLOAD];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_san_dbf_record_ct_response {
|
||||
u16 cmd_rsp_code;
|
||||
u8 revision;
|
||||
u8 reason_code;
|
||||
u8 expl;
|
||||
u8 vendor_unique;
|
||||
u32 len;
|
||||
u8 payload[ZFCP_DBF_CT_PAYLOAD];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_san_dbf_record_els {
|
||||
u8 ls_code;
|
||||
u32 len;
|
||||
#define ZFCP_DBF_ELS_PAYLOAD 32
|
||||
#define ZFCP_DBF_ELS_MAX_PAYLOAD 1024
|
||||
u8 payload[ZFCP_DBF_ELS_PAYLOAD];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_san_dbf_record {
|
||||
u8 tag[ZFCP_DBF_TAG_SIZE];
|
||||
u64 fsf_reqid;
|
||||
u32 fsf_seqno;
|
||||
u32 s_id;
|
||||
u32 d_id;
|
||||
union {
|
||||
struct zfcp_san_dbf_record_ct_request ct_req;
|
||||
struct zfcp_san_dbf_record_ct_response ct_resp;
|
||||
struct zfcp_san_dbf_record_els els;
|
||||
} u;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_scsi_dbf_record {
|
||||
u8 tag[ZFCP_DBF_TAG_SIZE];
|
||||
u8 tag2[ZFCP_DBF_TAG_SIZE];
|
||||
u32 scsi_id;
|
||||
u32 scsi_lun;
|
||||
u32 scsi_result;
|
||||
u64 scsi_cmnd;
|
||||
u64 scsi_serial;
|
||||
#define ZFCP_DBF_SCSI_OPCODE 16
|
||||
u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
|
||||
u8 scsi_retries;
|
||||
u8 scsi_allowed;
|
||||
u64 fsf_reqid;
|
||||
u32 fsf_seqno;
|
||||
u64 fsf_issued;
|
||||
u64 old_fsf_reqid;
|
||||
u8 rsp_validity;
|
||||
u8 rsp_scsi_status;
|
||||
u32 rsp_resid;
|
||||
u8 rsp_code;
|
||||
#define ZFCP_DBF_SCSI_FCP_SNS_INFO 16
|
||||
#define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO 256
|
||||
u32 sns_info_len;
|
||||
u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* ZFCP_DBF_H */
|
|
@ -47,6 +47,7 @@
|
|||
#include <asm/qdio.h>
|
||||
#include <asm/debug.h>
|
||||
#include <asm/ebcdic.h>
|
||||
#include "zfcp_dbf.h"
|
||||
#include "zfcp_fsf.h"
|
||||
|
||||
|
||||
|
@ -261,167 +262,6 @@ struct fcp_logo {
|
|||
wwn_t nport_wwpn;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* DBF stuff
|
||||
*/
|
||||
#define ZFCP_DBF_TAG_SIZE 4
|
||||
|
||||
struct zfcp_dbf_dump {
|
||||
u8 tag[ZFCP_DBF_TAG_SIZE];
|
||||
u32 total_size; /* size of total dump data */
|
||||
u32 offset; /* how much data has being already dumped */
|
||||
u32 size; /* how much data comes with this record */
|
||||
u8 data[]; /* dump data */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* FIXME: to be inflated when reworking the erp dbf */
|
||||
struct zfcp_erp_dbf_record {
|
||||
u8 dummy[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_hba_dbf_record_response {
|
||||
u32 fsf_command;
|
||||
u64 fsf_reqid;
|
||||
u32 fsf_seqno;
|
||||
u64 fsf_issued;
|
||||
u32 fsf_prot_status;
|
||||
u32 fsf_status;
|
||||
u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
|
||||
u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
|
||||
u32 fsf_req_status;
|
||||
u8 sbal_first;
|
||||
u8 sbal_curr;
|
||||
u8 sbal_last;
|
||||
u8 pool;
|
||||
u64 erp_action;
|
||||
union {
|
||||
struct {
|
||||
u64 scsi_cmnd;
|
||||
u64 scsi_serial;
|
||||
} send_fcp;
|
||||
struct {
|
||||
u64 wwpn;
|
||||
u32 d_id;
|
||||
u32 port_handle;
|
||||
} port;
|
||||
struct {
|
||||
u64 wwpn;
|
||||
u64 fcp_lun;
|
||||
u32 port_handle;
|
||||
u32 lun_handle;
|
||||
} unit;
|
||||
struct {
|
||||
u32 d_id;
|
||||
u8 ls_code;
|
||||
} send_els;
|
||||
} data;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_hba_dbf_record_status {
|
||||
u8 failed;
|
||||
u32 status_type;
|
||||
u32 status_subtype;
|
||||
struct fsf_queue_designator
|
||||
queue_designator;
|
||||
u32 payload_size;
|
||||
#define ZFCP_DBF_UNSOL_PAYLOAD 80
|
||||
#define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL 32
|
||||
#define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD 56
|
||||
#define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT 2 * sizeof(u32)
|
||||
u8 payload[ZFCP_DBF_UNSOL_PAYLOAD];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_hba_dbf_record_qdio {
|
||||
u32 status;
|
||||
u32 qdio_error;
|
||||
u32 siga_error;
|
||||
u8 sbal_index;
|
||||
u8 sbal_count;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_hba_dbf_record {
|
||||
u8 tag[ZFCP_DBF_TAG_SIZE];
|
||||
u8 tag2[ZFCP_DBF_TAG_SIZE];
|
||||
union {
|
||||
struct zfcp_hba_dbf_record_response response;
|
||||
struct zfcp_hba_dbf_record_status status;
|
||||
struct zfcp_hba_dbf_record_qdio qdio;
|
||||
} type;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_san_dbf_record_ct {
|
||||
union {
|
||||
struct {
|
||||
u16 cmd_req_code;
|
||||
u8 revision;
|
||||
u8 gs_type;
|
||||
u8 gs_subtype;
|
||||
u8 options;
|
||||
u16 max_res_size;
|
||||
} request;
|
||||
struct {
|
||||
u16 cmd_rsp_code;
|
||||
u8 revision;
|
||||
u8 reason_code;
|
||||
u8 reason_code_expl;
|
||||
u8 vendor_unique;
|
||||
} response;
|
||||
} type;
|
||||
u32 payload_size;
|
||||
#define ZFCP_DBF_CT_PAYLOAD 24
|
||||
u8 payload[ZFCP_DBF_CT_PAYLOAD];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_san_dbf_record_els {
|
||||
u8 ls_code;
|
||||
u32 payload_size;
|
||||
#define ZFCP_DBF_ELS_PAYLOAD 32
|
||||
#define ZFCP_DBF_ELS_MAX_PAYLOAD 1024
|
||||
u8 payload[ZFCP_DBF_ELS_PAYLOAD];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_san_dbf_record {
|
||||
u8 tag[ZFCP_DBF_TAG_SIZE];
|
||||
u64 fsf_reqid;
|
||||
u32 fsf_seqno;
|
||||
u32 s_id;
|
||||
u32 d_id;
|
||||
union {
|
||||
struct zfcp_san_dbf_record_ct ct;
|
||||
struct zfcp_san_dbf_record_els els;
|
||||
} type;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_scsi_dbf_record {
|
||||
u8 tag[ZFCP_DBF_TAG_SIZE];
|
||||
u8 tag2[ZFCP_DBF_TAG_SIZE];
|
||||
u32 scsi_id;
|
||||
u32 scsi_lun;
|
||||
u32 scsi_result;
|
||||
u64 scsi_cmnd;
|
||||
u64 scsi_serial;
|
||||
#define ZFCP_DBF_SCSI_OPCODE 16
|
||||
u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
|
||||
u8 scsi_retries;
|
||||
u8 scsi_allowed;
|
||||
u64 fsf_reqid;
|
||||
u32 fsf_seqno;
|
||||
u64 fsf_issued;
|
||||
union {
|
||||
u64 old_fsf_reqid;
|
||||
struct {
|
||||
u8 rsp_validity;
|
||||
u8 rsp_scsi_status;
|
||||
u32 rsp_resid;
|
||||
u8 rsp_code;
|
||||
#define ZFCP_DBF_SCSI_FCP_SNS_INFO 16
|
||||
#define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO 256
|
||||
u32 sns_info_len;
|
||||
u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];
|
||||
} fcp;
|
||||
} type;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* FC-FS stuff
|
||||
*/
|
||||
|
@ -634,7 +474,6 @@ do { \
|
|||
ZFCP_STATUS_PORT_NO_SCSI_ID)
|
||||
|
||||
/* logical unit status */
|
||||
#define ZFCP_STATUS_UNIT_NOTSUPPUNITRESET 0x00000001
|
||||
#define ZFCP_STATUS_UNIT_TEMPORARY 0x00000002
|
||||
#define ZFCP_STATUS_UNIT_SHARED 0x00000004
|
||||
#define ZFCP_STATUS_UNIT_READONLY 0x00000008
|
||||
|
@ -917,15 +756,15 @@ struct zfcp_adapter {
|
|||
u32 erp_low_mem_count; /* nr of erp actions waiting
|
||||
for memory */
|
||||
struct zfcp_port *nameserver_port; /* adapter's nameserver */
|
||||
debug_info_t *erp_dbf;
|
||||
debug_info_t *rec_dbf;
|
||||
debug_info_t *hba_dbf;
|
||||
debug_info_t *san_dbf; /* debug feature areas */
|
||||
debug_info_t *scsi_dbf;
|
||||
spinlock_t erp_dbf_lock;
|
||||
spinlock_t rec_dbf_lock;
|
||||
spinlock_t hba_dbf_lock;
|
||||
spinlock_t san_dbf_lock;
|
||||
spinlock_t scsi_dbf_lock;
|
||||
struct zfcp_erp_dbf_record erp_dbf_buf;
|
||||
struct zfcp_rec_dbf_record rec_dbf_buf;
|
||||
struct zfcp_hba_dbf_record hba_dbf_buf;
|
||||
struct zfcp_san_dbf_record san_dbf_buf;
|
||||
struct zfcp_scsi_dbf_record scsi_dbf_buf;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -131,22 +131,25 @@ extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, int);
|
|||
extern struct fc_function_template zfcp_transport_functions;
|
||||
|
||||
/******************************** ERP ****************************************/
|
||||
extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u32, int);
|
||||
extern int zfcp_erp_adapter_reopen(struct zfcp_adapter *, int);
|
||||
extern int zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int);
|
||||
extern void zfcp_erp_adapter_failed(struct zfcp_adapter *);
|
||||
extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u8, void *,
|
||||
u32, int);
|
||||
extern int zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, u8, void *);
|
||||
extern int zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, u8, void *);
|
||||
extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, u8, void *);
|
||||
|
||||
extern void zfcp_erp_modify_port_status(struct zfcp_port *, u32, int);
|
||||
extern int zfcp_erp_port_reopen(struct zfcp_port *, int);
|
||||
extern int zfcp_erp_port_shutdown(struct zfcp_port *, int);
|
||||
extern int zfcp_erp_port_forced_reopen(struct zfcp_port *, int);
|
||||
extern void zfcp_erp_port_failed(struct zfcp_port *);
|
||||
extern int zfcp_erp_port_reopen_all(struct zfcp_adapter *, int);
|
||||
extern void zfcp_erp_modify_port_status(struct zfcp_port *, u8, void *, u32,
|
||||
int);
|
||||
extern int zfcp_erp_port_reopen(struct zfcp_port *, int, u8, void *);
|
||||
extern int zfcp_erp_port_shutdown(struct zfcp_port *, int, u8, void *);
|
||||
extern int zfcp_erp_port_forced_reopen(struct zfcp_port *, int, u8, void *);
|
||||
extern void zfcp_erp_port_failed(struct zfcp_port *, u8, void *);
|
||||
extern int zfcp_erp_port_reopen_all(struct zfcp_adapter *, int, u8, void *);
|
||||
|
||||
extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, u32, int);
|
||||
extern int zfcp_erp_unit_reopen(struct zfcp_unit *, int);
|
||||
extern int zfcp_erp_unit_shutdown(struct zfcp_unit *, int);
|
||||
extern void zfcp_erp_unit_failed(struct zfcp_unit *);
|
||||
extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, u8, void *, u32,
|
||||
int);
|
||||
extern int zfcp_erp_unit_reopen(struct zfcp_unit *, int, u8, void *);
|
||||
extern int zfcp_erp_unit_shutdown(struct zfcp_unit *, int, u8, void *);
|
||||
extern void zfcp_erp_unit_failed(struct zfcp_unit *, u8, void *);
|
||||
|
||||
extern int zfcp_erp_thread_setup(struct zfcp_adapter *);
|
||||
extern int zfcp_erp_thread_kill(struct zfcp_adapter *);
|
||||
|
@ -155,15 +158,25 @@ extern void zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long);
|
|||
|
||||
extern int zfcp_test_link(struct zfcp_port *);
|
||||
|
||||
extern void zfcp_erp_port_boxed(struct zfcp_port *);
|
||||
extern void zfcp_erp_unit_boxed(struct zfcp_unit *);
|
||||
extern void zfcp_erp_port_access_denied(struct zfcp_port *);
|
||||
extern void zfcp_erp_unit_access_denied(struct zfcp_unit *);
|
||||
extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *);
|
||||
extern void zfcp_erp_port_access_changed(struct zfcp_port *);
|
||||
extern void zfcp_erp_unit_access_changed(struct zfcp_unit *);
|
||||
extern void zfcp_erp_port_boxed(struct zfcp_port *, u8 id, void *ref);
|
||||
extern void zfcp_erp_unit_boxed(struct zfcp_unit *, u8 id, void *ref);
|
||||
extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8 id, void *ref);
|
||||
extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8 id, void *ref);
|
||||
extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *);
|
||||
extern void zfcp_erp_port_access_changed(struct zfcp_port *, u8, void *);
|
||||
extern void zfcp_erp_unit_access_changed(struct zfcp_unit *, u8, void *);
|
||||
|
||||
/******************************** AUX ****************************************/
|
||||
extern void zfcp_rec_dbf_event_thread(u8 id, struct zfcp_adapter *adapter,
|
||||
int lock);
|
||||
extern void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *);
|
||||
extern void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port);
|
||||
extern void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit);
|
||||
extern void zfcp_rec_dbf_event_trigger(u8 id, void *ref, u8 want, u8 need,
|
||||
void *action, struct zfcp_adapter *,
|
||||
struct zfcp_port *, struct zfcp_unit *);
|
||||
extern void zfcp_rec_dbf_event_action(u8 id, struct zfcp_erp_action *);
|
||||
|
||||
extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *);
|
||||
extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *,
|
||||
struct fsf_status_read_buffer *);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -175,8 +175,9 @@ zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status,
|
|||
* which is set again in case we have missed by a mile.
|
||||
*/
|
||||
zfcp_erp_adapter_reopen(adapter,
|
||||
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED, 140,
|
||||
NULL);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
@ -239,8 +240,6 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
|
|||
struct zfcp_fsf_req *fsf_req;
|
||||
unsigned long flags;
|
||||
|
||||
debug_long_event(adapter->erp_dbf, 4, req_id);
|
||||
|
||||
spin_lock_irqsave(&adapter->req_list_lock, flags);
|
||||
fsf_req = zfcp_reqlist_find(adapter, req_id);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *,
|
|||
void (*done) (struct scsi_cmnd *));
|
||||
static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *);
|
||||
static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *);
|
||||
static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *);
|
||||
static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *);
|
||||
static int zfcp_task_management_function(struct zfcp_unit *, u8,
|
||||
struct scsi_cmnd *);
|
||||
|
@ -51,6 +52,7 @@ struct zfcp_data zfcp_data = {
|
|||
.queuecommand = zfcp_scsi_queuecommand,
|
||||
.eh_abort_handler = zfcp_scsi_eh_abort_handler,
|
||||
.eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler,
|
||||
.eh_target_reset_handler = zfcp_scsi_eh_target_reset_handler,
|
||||
.eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler,
|
||||
.can_queue = 4096,
|
||||
.this_id = -1,
|
||||
|
@ -179,11 +181,10 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
|
|||
struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
|
||||
|
||||
if (unit) {
|
||||
zfcp_erp_wait(unit->port->adapter);
|
||||
atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status);
|
||||
sdpnt->hostdata = NULL;
|
||||
unit->device = NULL;
|
||||
zfcp_erp_unit_failed(unit);
|
||||
zfcp_erp_unit_failed(unit, 12, NULL);
|
||||
zfcp_unit_put(unit);
|
||||
} else
|
||||
ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at "
|
||||
|
@ -442,58 +443,32 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
|
||||
static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
|
||||
{
|
||||
int retval;
|
||||
struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata;
|
||||
struct zfcp_unit *unit = scpnt->device->hostdata;
|
||||
|
||||
if (!unit) {
|
||||
ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n");
|
||||
retval = SUCCESS;
|
||||
goto out;
|
||||
WARN_ON(1);
|
||||
return SUCCESS;
|
||||
}
|
||||
ZFCP_LOG_NORMAL("resetting unit 0x%016Lx on port 0x%016Lx, adapter %s\n",
|
||||
unit->fcp_lun, unit->port->wwpn,
|
||||
zfcp_get_busid_by_adapter(unit->port->adapter));
|
||||
retval = zfcp_task_management_function(unit,
|
||||
FCP_LOGICAL_UNIT_RESET,
|
||||
scpnt);
|
||||
return retval ? FAILED : SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we do not know whether the unit supports 'logical unit reset'
|
||||
* then try 'logical unit reset' and proceed with 'target reset'
|
||||
* if 'logical unit reset' fails.
|
||||
* If the unit is known not to support 'logical unit reset' then
|
||||
* skip 'logical unit reset' and try 'target reset' immediately.
|
||||
*/
|
||||
if (!atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
|
||||
&unit->status)) {
|
||||
retval = zfcp_task_management_function(unit,
|
||||
FCP_LOGICAL_UNIT_RESET,
|
||||
scpnt);
|
||||
if (retval) {
|
||||
ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit);
|
||||
if (retval == -ENOTSUPP)
|
||||
atomic_set_mask
|
||||
(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
|
||||
&unit->status);
|
||||
/* fall through and try 'target reset' next */
|
||||
} else {
|
||||
ZFCP_LOG_DEBUG("unit reset succeeded (unit=%p)\n",
|
||||
unit);
|
||||
/* avoid 'target reset' */
|
||||
retval = SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
|
||||
{
|
||||
int retval;
|
||||
struct zfcp_unit *unit = scpnt->device->hostdata;
|
||||
|
||||
if (!unit) {
|
||||
WARN_ON(1);
|
||||
return SUCCESS;
|
||||
}
|
||||
retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt);
|
||||
if (retval) {
|
||||
ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit);
|
||||
retval = FAILED;
|
||||
} else {
|
||||
ZFCP_LOG_DEBUG("target reset succeeded (unit=%p)\n", unit);
|
||||
retval = SUCCESS;
|
||||
}
|
||||
out:
|
||||
return retval;
|
||||
return retval ? FAILED : SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -553,7 +528,7 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
|
|||
unit->fcp_lun, unit->port->wwpn,
|
||||
zfcp_get_busid_by_adapter(unit->port->adapter));
|
||||
|
||||
zfcp_erp_adapter_reopen(adapter, 0);
|
||||
zfcp_erp_adapter_reopen(adapter, 0, 141, scpnt);
|
||||
zfcp_erp_wait(adapter);
|
||||
|
||||
return SUCCESS;
|
||||
|
|
|
@ -89,7 +89,7 @@ zfcp_sysfs_port_add_store(struct device *dev, struct device_attribute *attr, con
|
|||
|
||||
retval = 0;
|
||||
|
||||
zfcp_erp_port_reopen(port, 0);
|
||||
zfcp_erp_port_reopen(port, 0, 91, NULL);
|
||||
zfcp_erp_wait(port->adapter);
|
||||
zfcp_port_put(port);
|
||||
out:
|
||||
|
@ -147,7 +147,7 @@ zfcp_sysfs_port_remove_store(struct device *dev, struct device_attribute *attr,
|
|||
goto out;
|
||||
}
|
||||
|
||||
zfcp_erp_port_shutdown(port, 0);
|
||||
zfcp_erp_port_shutdown(port, 0, 92, NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
zfcp_port_put(port);
|
||||
zfcp_port_dequeue(port);
|
||||
|
@ -191,9 +191,10 @@ zfcp_sysfs_adapter_failed_store(struct device *dev, struct device_attribute *att
|
|||
goto out;
|
||||
}
|
||||
|
||||
zfcp_erp_modify_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING,
|
||||
ZFCP_SET);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
zfcp_erp_modify_adapter_status(adapter, 44, NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 93,
|
||||
NULL);
|
||||
zfcp_erp_wait(adapter);
|
||||
out:
|
||||
up(&zfcp_data.config_sema);
|
||||
|
|
|
@ -94,7 +94,7 @@ zfcp_sysfs_unit_add_store(struct device *dev, struct device_attribute *attr, con
|
|||
|
||||
retval = 0;
|
||||
|
||||
zfcp_erp_unit_reopen(unit, 0);
|
||||
zfcp_erp_unit_reopen(unit, 0, 94, NULL);
|
||||
zfcp_erp_wait(unit->port->adapter);
|
||||
zfcp_unit_put(unit);
|
||||
out:
|
||||
|
@ -150,7 +150,7 @@ zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr,
|
|||
goto out;
|
||||
}
|
||||
|
||||
zfcp_erp_unit_shutdown(unit, 0);
|
||||
zfcp_erp_unit_shutdown(unit, 0, 95, NULL);
|
||||
zfcp_erp_wait(unit->port->adapter);
|
||||
zfcp_unit_put(unit);
|
||||
zfcp_unit_dequeue(unit);
|
||||
|
@ -193,8 +193,9 @@ zfcp_sysfs_port_failed_store(struct device *dev, struct device_attribute *attr,
|
|||
goto out;
|
||||
}
|
||||
|
||||
zfcp_erp_modify_port_status(port, ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
|
||||
zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
zfcp_erp_modify_port_status(port, 45, NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
|
||||
zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, 96, NULL);
|
||||
zfcp_erp_wait(port->adapter);
|
||||
out:
|
||||
up(&zfcp_data.config_sema);
|
||||
|
|
|
@ -94,8 +94,9 @@ zfcp_sysfs_unit_failed_store(struct device *dev, struct device_attribute *attr,
|
|||
goto out;
|
||||
}
|
||||
|
||||
zfcp_erp_modify_unit_status(unit, ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
|
||||
zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
zfcp_erp_modify_unit_status(unit, 46, NULL,
|
||||
ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
|
||||
zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, 97, NULL);
|
||||
zfcp_erp_wait(unit->port->adapter);
|
||||
out:
|
||||
up(&zfcp_data.config_sema);
|
||||
|
|
|
@ -1838,12 +1838,11 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
|
|||
if (scsi_sg_count(srb)) {
|
||||
if ((scsi_sg_count(srb) == 1) &&
|
||||
(scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
|
||||
if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) {
|
||||
struct scatterlist *sg = scsi_sglist(srb);
|
||||
char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
|
||||
memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
|
||||
kunmap_atomic(buf - sg->offset, KM_IRQ0);
|
||||
}
|
||||
if (srb->sc_data_direction == DMA_TO_DEVICE ||
|
||||
srb->sc_data_direction == DMA_BIDIRECTIONAL)
|
||||
scsi_sg_copy_to_buffer(srb,
|
||||
tw_dev->generic_buffer_virt[request_id],
|
||||
TW_SECTOR_SIZE);
|
||||
command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
|
||||
command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH);
|
||||
} else {
|
||||
|
@ -1915,13 +1914,11 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
|
|||
(cmd->sc_data_direction == DMA_FROM_DEVICE ||
|
||||
cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
|
||||
if (scsi_sg_count(cmd) == 1) {
|
||||
struct scatterlist *sg = scsi_sglist(tw_dev->srb[request_id]);
|
||||
char *buf;
|
||||
unsigned long flags = 0;
|
||||
unsigned long flags;
|
||||
void *buf = tw_dev->generic_buffer_virt[request_id];
|
||||
|
||||
local_irq_save(flags);
|
||||
buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
|
||||
memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
|
||||
kunmap_atomic(buf - sg->offset, KM_IRQ0);
|
||||
scsi_sg_copy_from_buffer(cmd, buf, TW_SECTOR_SIZE);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
}
|
||||
|
@ -2028,8 +2025,6 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
|
|||
}
|
||||
tw_dev = (TW_Device_Extension *)host->hostdata;
|
||||
|
||||
memset(tw_dev, 0, sizeof(TW_Device_Extension));
|
||||
|
||||
/* Save values to device extension */
|
||||
tw_dev->host = host;
|
||||
tw_dev->tw_pci_dev = pdev;
|
||||
|
|
|
@ -1463,18 +1463,10 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
|
|||
void *data, unsigned int len)
|
||||
{
|
||||
struct scsi_cmnd *cmd = tw_dev->srb[request_id];
|
||||
void *buf;
|
||||
unsigned int transfer_len;
|
||||
unsigned long flags = 0;
|
||||
struct scatterlist *sg = scsi_sglist(cmd);
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
|
||||
transfer_len = min(sg->length, len);
|
||||
|
||||
memcpy(buf, data, transfer_len);
|
||||
|
||||
kunmap_atomic(buf - sg->offset, KM_IRQ0);
|
||||
scsi_sg_copy_from_buffer(cmd, data, len);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
|
@ -2294,8 +2286,6 @@ static int __devinit tw_probe(struct pci_dev *pdev, const struct pci_device_id *
|
|||
}
|
||||
tw_dev = (TW_Device_Extension *)host->hostdata;
|
||||
|
||||
memset(tw_dev, 0, sizeof(TW_Device_Extension));
|
||||
|
||||
/* Save values to device extension */
|
||||
tw_dev->host = host;
|
||||
tw_dev->tw_pci_dev = pdev;
|
||||
|
|
|
@ -896,7 +896,7 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda
|
|||
IRQ_Channel = PCI_Device->irq;
|
||||
IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
|
||||
PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
|
||||
#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
|
||||
#ifdef CONFIG_SCSI_FLASHPOINT
|
||||
if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
|
||||
BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0);
|
||||
BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
|
||||
|
@ -1006,6 +1006,9 @@ static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
|
|||
}
|
||||
|
||||
|
||||
#else
|
||||
#define BusLogic_InitializeProbeInfoList(adapter) \
|
||||
BusLogic_InitializeProbeInfoListISA(adapter)
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
|
||||
|
|
|
@ -33,23 +33,6 @@
|
|||
#define PACKED __attribute__((packed))
|
||||
#endif
|
||||
|
||||
/*
|
||||
FlashPoint support is only available for the Intel x86 Architecture with
|
||||
CONFIG_PCI set.
|
||||
*/
|
||||
|
||||
#ifndef __i386__
|
||||
#undef CONFIG_SCSI_OMIT_FLASHPOINT
|
||||
#define CONFIG_SCSI_OMIT_FLASHPOINT
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PCI
|
||||
#undef CONFIG_SCSI_OMIT_FLASHPOINT
|
||||
#define CONFIG_SCSI_OMIT_FLASHPOINT
|
||||
#define BusLogic_InitializeProbeInfoListISA BusLogic_InitializeProbeInfoList
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Define the maximum number of BusLogic Host Adapters supported by this driver.
|
||||
*/
|
||||
|
@ -178,7 +161,7 @@ static int BusLogic_HostAdapterAddressCount[3] = { 0, BusLogic_MultiMasterAddres
|
|||
Define macros for testing the Host Adapter Type.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
|
||||
#ifdef CONFIG_SCSI_FLASHPOINT
|
||||
|
||||
#define BusLogic_MultiMasterHostAdapterP(HostAdapter) \
|
||||
(HostAdapter->HostAdapterType == BusLogic_MultiMaster)
|
||||
|
@ -871,7 +854,7 @@ struct BusLogic_CCB {
|
|||
void (*CallbackFunction) (struct BusLogic_CCB *); /* Bytes 40-43 */
|
||||
u32 BaseAddress; /* Bytes 44-47 */
|
||||
enum BusLogic_CompletionCode CompletionCode; /* Byte 48 */
|
||||
#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
|
||||
#ifdef CONFIG_SCSI_FLASHPOINT
|
||||
unsigned char:8; /* Byte 49 */
|
||||
unsigned short OS_Flags; /* Bytes 50-51 */
|
||||
unsigned char Private[48]; /* Bytes 52-99 */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
|
||||
#ifdef CONFIG_SCSI_FLASHPOINT
|
||||
|
||||
#define MAX_CARDS 8
|
||||
#undef BUSTYPE_PCI
|
||||
|
@ -7626,7 +7626,7 @@ FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
|
|||
#define FlashPoint_InterruptPending FlashPoint__InterruptPending
|
||||
#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
|
||||
|
||||
#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
|
||||
#else /* !CONFIG_SCSI_FLASHPOINT */
|
||||
|
||||
/*
|
||||
Define prototypes for the FlashPoint SCCB Manager Functions.
|
||||
|
@ -7641,4 +7641,4 @@ extern bool FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
|
|||
extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
|
||||
extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
|
||||
|
||||
#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */
|
||||
#endif /* CONFIG_SCSI_FLASHPOINT */
|
||||
|
|
|
@ -588,18 +588,20 @@ config SCSI_BUSLOGIC
|
|||
<http://www.tldp.org/docs.html#howto>, and the files
|
||||
<file:Documentation/scsi/BusLogic.txt> and
|
||||
<file:Documentation/scsi/FlashPoint.txt> for more information.
|
||||
Note that support for FlashPoint is only available for 32-bit
|
||||
x86 configurations.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called BusLogic.
|
||||
|
||||
config SCSI_OMIT_FLASHPOINT
|
||||
bool "Omit FlashPoint support"
|
||||
depends on SCSI_BUSLOGIC
|
||||
config SCSI_FLASHPOINT
|
||||
bool "FlashPoint support"
|
||||
depends on SCSI_BUSLOGIC && PCI && X86_32
|
||||
help
|
||||
This option allows you to omit the FlashPoint support from the
|
||||
This option allows you to add FlashPoint support to the
|
||||
BusLogic SCSI driver. The FlashPoint SCCB Manager code is
|
||||
substantial, so users of MultiMaster Host Adapters may wish to omit
|
||||
it.
|
||||
substantial, so users of MultiMaster Host Adapters may not
|
||||
wish to include it.
|
||||
|
||||
config SCSI_DMX3191D
|
||||
tristate "DMX3191D SCSI support"
|
||||
|
|
|
@ -179,6 +179,9 @@ int __init a2091_detect(struct scsi_host_template *tpnt)
|
|||
DMA(instance)->DAWR = DAWR_A2091;
|
||||
regs.SASR = &(DMA(instance)->SASR);
|
||||
regs.SCMD = &(DMA(instance)->SCMD);
|
||||
HDATA(instance)->no_sync = 0xff;
|
||||
HDATA(instance)->fast = 0;
|
||||
HDATA(instance)->dma_mode = CTRL_DMA;
|
||||
wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
|
||||
request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, "A2091 SCSI",
|
||||
instance);
|
||||
|
|
|
@ -178,6 +178,9 @@ int __init a3000_detect(struct scsi_host_template *tpnt)
|
|||
DMA(a3000_host)->DAWR = DAWR_A3000;
|
||||
regs.SASR = &(DMA(a3000_host)->SASR);
|
||||
regs.SCMD = &(DMA(a3000_host)->SCMD);
|
||||
HDATA(a3000_host)->no_sync = 0xff;
|
||||
HDATA(a3000_host)->fast = 0;
|
||||
HDATA(a3000_host)->dma_mode = CTRL_DMA;
|
||||
wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15);
|
||||
if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI",
|
||||
a3000_intr))
|
||||
|
|
|
@ -205,7 +205,7 @@ MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health"
|
|||
|
||||
int aac_check_reset = 1;
|
||||
module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the"
|
||||
MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the"
|
||||
" adapter. a value of -1 forces the reset to adapters programmed to"
|
||||
" ignore it.");
|
||||
|
||||
|
@ -379,24 +379,6 @@ int aac_get_containers(struct aac_dev *dev)
|
|||
return status;
|
||||
}
|
||||
|
||||
static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
|
||||
{
|
||||
void *buf;
|
||||
int transfer_len;
|
||||
struct scatterlist *sg = scsi_sglist(scsicmd);
|
||||
|
||||
buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
|
||||
transfer_len = min(sg->length, len + offset);
|
||||
|
||||
transfer_len -= offset;
|
||||
if (buf && transfer_len > 0)
|
||||
memcpy(buf + offset, data, transfer_len);
|
||||
|
||||
flush_kernel_dcache_page(kmap_atomic_to_page(buf - sg->offset));
|
||||
kunmap_atomic(buf - sg->offset, KM_IRQ0);
|
||||
|
||||
}
|
||||
|
||||
static void get_container_name_callback(void *context, struct fib * fibptr)
|
||||
{
|
||||
struct aac_get_name_resp * get_name_reply;
|
||||
|
@ -419,14 +401,17 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
|
|||
while (*sp == ' ')
|
||||
++sp;
|
||||
if (*sp) {
|
||||
struct inquiry_data inq;
|
||||
char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)];
|
||||
int count = sizeof(d);
|
||||
char *dp = d;
|
||||
do {
|
||||
*dp++ = (*sp) ? *sp++ : ' ';
|
||||
} while (--count > 0);
|
||||
aac_internal_transfer(scsicmd, d,
|
||||
offsetof(struct inquiry_data, inqd_pid), sizeof(d));
|
||||
|
||||
scsi_sg_copy_to_buffer(scsicmd, &inq, sizeof(inq));
|
||||
memcpy(inq.inqd_pid, d, sizeof(d));
|
||||
scsi_sg_copy_from_buffer(scsicmd, &inq, sizeof(inq));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -811,7 +796,7 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
|
|||
sp[2] = 0;
|
||||
sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
|
||||
le32_to_cpu(get_serial_reply->uid));
|
||||
aac_internal_transfer(scsicmd, sp, 0, sizeof(sp));
|
||||
scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp));
|
||||
}
|
||||
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
|
@ -1986,8 +1971,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||
arr[4] = 0x0;
|
||||
arr[5] = 0x80;
|
||||
arr[1] = scsicmd->cmnd[2];
|
||||
aac_internal_transfer(scsicmd, &inq_data, 0,
|
||||
sizeof(inq_data));
|
||||
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
||||
sizeof(inq_data));
|
||||
scsicmd->result = DID_OK << 16 |
|
||||
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
} else if (scsicmd->cmnd[2] == 0x80) {
|
||||
|
@ -1995,8 +1980,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||
arr[3] = setinqserial(dev, &arr[4],
|
||||
scmd_id(scsicmd));
|
||||
arr[1] = scsicmd->cmnd[2];
|
||||
aac_internal_transfer(scsicmd, &inq_data, 0,
|
||||
sizeof(inq_data));
|
||||
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
||||
sizeof(inq_data));
|
||||
return aac_get_container_serial(scsicmd);
|
||||
} else {
|
||||
/* vpd page not implemented */
|
||||
|
@ -2027,7 +2012,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||
if (cid == host->this_id) {
|
||||
setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types));
|
||||
inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
|
||||
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
|
||||
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
||||
sizeof(inq_data));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
return 0;
|
||||
|
@ -2036,7 +2022,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||
return -1;
|
||||
setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
|
||||
inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
|
||||
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
|
||||
scsi_sg_copy_from_buffer(scsicmd, &inq_data, sizeof(inq_data));
|
||||
return aac_get_container_name(scsicmd);
|
||||
}
|
||||
case SERVICE_ACTION_IN:
|
||||
|
@ -2047,6 +2033,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||
{
|
||||
u64 capacity;
|
||||
char cp[13];
|
||||
unsigned int alloc_len;
|
||||
|
||||
dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n"));
|
||||
capacity = fsa_dev_ptr[cid].size - 1;
|
||||
|
@ -2063,18 +2050,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||
cp[10] = 2;
|
||||
cp[11] = 0;
|
||||
cp[12] = 0;
|
||||
aac_internal_transfer(scsicmd, cp, 0,
|
||||
min_t(size_t, scsicmd->cmnd[13], sizeof(cp)));
|
||||
if (sizeof(cp) < scsicmd->cmnd[13]) {
|
||||
unsigned int len, offset = sizeof(cp);
|
||||
|
||||
memset(cp, 0, offset);
|
||||
do {
|
||||
len = min_t(size_t, scsicmd->cmnd[13] - offset,
|
||||
sizeof(cp));
|
||||
aac_internal_transfer(scsicmd, cp, offset, len);
|
||||
} while ((offset += len) < scsicmd->cmnd[13]);
|
||||
}
|
||||
alloc_len = ((scsicmd->cmnd[10] << 24)
|
||||
+ (scsicmd->cmnd[11] << 16)
|
||||
+ (scsicmd->cmnd[12] << 8) + scsicmd->cmnd[13]);
|
||||
|
||||
alloc_len = min_t(size_t, alloc_len, sizeof(cp));
|
||||
scsi_sg_copy_from_buffer(scsicmd, cp, alloc_len);
|
||||
if (alloc_len < scsi_bufflen(scsicmd))
|
||||
scsi_set_resid(scsicmd,
|
||||
scsi_bufflen(scsicmd) - alloc_len);
|
||||
|
||||
/* Do not cache partition table for arrays */
|
||||
scsicmd->device->removable = 1;
|
||||
|
@ -2104,7 +2089,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||
cp[5] = 0;
|
||||
cp[6] = 2;
|
||||
cp[7] = 0;
|
||||
aac_internal_transfer(scsicmd, cp, 0, sizeof(cp));
|
||||
scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
|
||||
/* Do not cache partition table for arrays */
|
||||
scsicmd->device->removable = 1;
|
||||
|
||||
|
@ -2139,7 +2124,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||
if (mode_buf_length > scsicmd->cmnd[4])
|
||||
mode_buf_length = scsicmd->cmnd[4];
|
||||
}
|
||||
aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length);
|
||||
scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length);
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
|
||||
|
@ -2174,7 +2159,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||
if (mode_buf_length > scsicmd->cmnd[8])
|
||||
mode_buf_length = scsicmd->cmnd[8];
|
||||
}
|
||||
aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length);
|
||||
scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length);
|
||||
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
|
|
|
@ -515,10 +515,12 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
|
|||
}
|
||||
udelay(5);
|
||||
}
|
||||
} else
|
||||
(void)down_interruptible(&fibptr->event_wait);
|
||||
} else if (down_interruptible(&fibptr->event_wait) == 0) {
|
||||
fibptr->done = 2;
|
||||
up(&fibptr->event_wait);
|
||||
}
|
||||
spin_lock_irqsave(&fibptr->event_lock, flags);
|
||||
if (fibptr->done == 0) {
|
||||
if ((fibptr->done == 0) || (fibptr->done == 2)) {
|
||||
fibptr->done = 2; /* Tell interrupt we aborted */
|
||||
spin_unlock_irqrestore(&fibptr->event_lock, flags);
|
||||
return -EINTR;
|
||||
|
@ -594,7 +596,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
|
|||
if (le32_to_cpu(*q->headers.consumer) >= q->entries)
|
||||
*q->headers.consumer = cpu_to_le32(1);
|
||||
else
|
||||
*q->headers.consumer = cpu_to_le32(le32_to_cpu(*q->headers.consumer)+1);
|
||||
le32_add_cpu(q->headers.consumer, 1);
|
||||
|
||||
if (wasfull) {
|
||||
switch (qid) {
|
||||
|
|
|
@ -1413,6 +1413,10 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
|
|||
unsigned long flags;
|
||||
int nseg;
|
||||
|
||||
nseg = scsi_dma_map(cmd);
|
||||
if (nseg < 0)
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
|
||||
ahd_lock(ahd, &flags);
|
||||
|
||||
/*
|
||||
|
@ -1430,6 +1434,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
|
|||
if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
|
||||
ahd->flags |= AHD_RESOURCE_SHORTAGE;
|
||||
ahd_unlock(ahd, &flags);
|
||||
scsi_dma_unmap(cmd);
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
}
|
||||
|
||||
|
@ -1485,8 +1490,6 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
|
|||
ahd_set_sense_residual(scb, 0);
|
||||
scb->sg_count = 0;
|
||||
|
||||
nseg = scsi_dma_map(cmd);
|
||||
BUG_ON(nseg < 0);
|
||||
if (nseg > 0) {
|
||||
void *sg = scb->sg_list;
|
||||
struct scatterlist *cur_seg;
|
||||
|
|
|
@ -1398,12 +1398,18 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
|
|||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
nseg = scsi_dma_map(cmd);
|
||||
if (nseg < 0)
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
|
||||
/*
|
||||
* Get an scb to use.
|
||||
*/
|
||||
scb = ahc_get_scb(ahc);
|
||||
if (!scb)
|
||||
if (!scb) {
|
||||
scsi_dma_unmap(cmd);
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
}
|
||||
|
||||
scb->io_ctx = cmd;
|
||||
scb->platform_data->dev = dev;
|
||||
|
@ -1464,8 +1470,6 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
|
|||
ahc_set_sense_residual(scb, 0);
|
||||
scb->sg_count = 0;
|
||||
|
||||
nseg = scsi_dma_map(cmd);
|
||||
BUG_ON(nseg < 0);
|
||||
if (nseg > 0) {
|
||||
struct ahc_dma_seg *sg;
|
||||
struct scatterlist *cur_seg;
|
||||
|
|
|
@ -1837,7 +1837,7 @@ type_check(symbol_t *symbol, expression_t *expression, int opcode)
|
|||
int and_op;
|
||||
|
||||
and_op = FALSE;
|
||||
if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ)
|
||||
if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || opcode == AIC_OP_JZ)
|
||||
and_op = TRUE;
|
||||
|
||||
/*
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
|
||||
extern struct kmem_cache *asd_dma_token_cache;
|
||||
extern struct kmem_cache *asd_ascb_cache;
|
||||
extern char sas_addr_str[2*SAS_ADDR_SIZE + 1];
|
||||
|
||||
static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr)
|
||||
{
|
||||
|
@ -68,21 +67,6 @@ static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr)
|
|||
*p = '\0';
|
||||
}
|
||||
|
||||
static inline void asd_destringify_sas_addr(u8 *sas_addr, const char *p)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SAS_ADDR_SIZE; i++) {
|
||||
u8 h, l;
|
||||
if (!*p)
|
||||
break;
|
||||
h = isdigit(*p) ? *p-'0' : *p-'A'+10;
|
||||
p++;
|
||||
l = isdigit(*p) ? *p-'0' : *p-'A'+10;
|
||||
p++;
|
||||
sas_addr[i] = (h<<4) | l;
|
||||
}
|
||||
}
|
||||
|
||||
struct asd_ha_struct;
|
||||
struct asd_ascb;
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define SET_DDB(_ddb, _ha) set_bit(_ddb, (_ha)->hw_prof.ddb_bitmap)
|
||||
#define CLEAR_DDB(_ddb, _ha) clear_bit(_ddb, (_ha)->hw_prof.ddb_bitmap)
|
||||
|
||||
static inline int asd_get_ddb(struct asd_ha_struct *asd_ha)
|
||||
static int asd_get_ddb(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
int ddb, i;
|
||||
|
||||
|
@ -71,7 +71,7 @@ out:
|
|||
#define NCQ_DATA_SCB_PTR offsetof(struct asd_ddb_stp_sata_target_port, ncq_data_scb_ptr)
|
||||
#define ITNL_TIMEOUT offsetof(struct asd_ddb_ssp_smp_target_port, itnl_timeout)
|
||||
|
||||
static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb)
|
||||
static void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb)
|
||||
{
|
||||
if (!ddb || ddb >= 0xFFFF)
|
||||
return;
|
||||
|
@ -79,7 +79,7 @@ static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb)
|
|||
CLEAR_DDB(ddb, asd_ha);
|
||||
}
|
||||
|
||||
static inline void asd_set_ddb_type(struct domain_device *dev)
|
||||
static void asd_set_ddb_type(struct domain_device *dev)
|
||||
{
|
||||
struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
|
||||
int ddb = (int) (unsigned long) dev->lldd_dev;
|
||||
|
@ -109,7 +109,7 @@ static int asd_init_sata_tag_ddb(struct domain_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int asd_init_sata(struct domain_device *dev)
|
||||
static int asd_init_sata(struct domain_device *dev)
|
||||
{
|
||||
struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
|
||||
int ddb = (int) (unsigned long) dev->lldd_dev;
|
||||
|
|
|
@ -738,6 +738,8 @@ static void asd_dump_lseq_state(struct asd_ha_struct *asd_ha, int lseq)
|
|||
PRINT_LMIP_dword(asd_ha, lseq, DEV_PRES_TIMER_TERM_TS);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/**
|
||||
* asd_dump_ddb_site -- dump a CSEQ DDB site
|
||||
* @asd_ha: pointer to host adapter structure
|
||||
|
@ -880,6 +882,8 @@ void asd_dump_scb_sites(struct asd_ha_struct *asd_ha)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
/**
|
||||
* ads_dump_seq_state -- dump CSEQ and LSEQ states
|
||||
* @asd_ha: pointer to host adapter structure
|
||||
|
@ -922,7 +926,9 @@ void asd_dump_frame_rcvd(struct asd_phy *phy,
|
|||
spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||
}
|
||||
|
||||
static inline void asd_dump_scb(struct asd_ascb *ascb, int ind)
|
||||
#if 0
|
||||
|
||||
static void asd_dump_scb(struct asd_ascb *ascb, int ind)
|
||||
{
|
||||
asd_printk("scb%d: vaddr: 0x%p, dma_handle: 0x%llx, next: 0x%llx, "
|
||||
"index:%d, opcode:0x%02x\n",
|
||||
|
@ -956,4 +962,6 @@ void asd_dump_scb_list(struct asd_ascb *ascb, int num)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
#endif /* ASD_DEBUG */
|
||||
|
|
|
@ -29,24 +29,15 @@
|
|||
|
||||
#ifdef ASD_DEBUG
|
||||
|
||||
void asd_dump_ddb_0(struct asd_ha_struct *asd_ha);
|
||||
void asd_dump_target_ddb(struct asd_ha_struct *asd_ha, u16 site_no);
|
||||
void asd_dump_scb_sites(struct asd_ha_struct *asd_ha);
|
||||
void asd_dump_seq_state(struct asd_ha_struct *asd_ha, u8 lseq_mask);
|
||||
void asd_dump_frame_rcvd(struct asd_phy *phy,
|
||||
struct done_list_struct *dl);
|
||||
void asd_dump_scb_list(struct asd_ascb *ascb, int num);
|
||||
#else /* ASD_DEBUG */
|
||||
|
||||
static inline void asd_dump_ddb_0(struct asd_ha_struct *asd_ha) { }
|
||||
static inline void asd_dump_target_ddb(struct asd_ha_struct *asd_ha,
|
||||
u16 site_no) { }
|
||||
static inline void asd_dump_scb_sites(struct asd_ha_struct *asd_ha) { }
|
||||
static inline void asd_dump_seq_state(struct asd_ha_struct *asd_ha,
|
||||
u8 lseq_mask) { }
|
||||
static inline void asd_dump_frame_rcvd(struct asd_phy *phy,
|
||||
struct done_list_struct *dl) { }
|
||||
static inline void asd_dump_scb_list(struct asd_ascb *ascb, int num) { }
|
||||
#endif /* ASD_DEBUG */
|
||||
|
||||
#endif /* _AIC94XX_DUMP_H_ */
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#include "aic94xx.h"
|
||||
#include "aic94xx_reg.h"
|
||||
|
@ -38,16 +39,14 @@ u32 MBAR0_SWB_SIZE;
|
|||
|
||||
/* ---------- Initialization ---------- */
|
||||
|
||||
static void asd_get_user_sas_addr(struct asd_ha_struct *asd_ha)
|
||||
static int asd_get_user_sas_addr(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
extern char sas_addr_str[];
|
||||
/* If the user has specified a WWN it overrides other settings
|
||||
*/
|
||||
if (sas_addr_str[0] != '\0')
|
||||
asd_destringify_sas_addr(asd_ha->hw_prof.sas_addr,
|
||||
sas_addr_str);
|
||||
else if (asd_ha->hw_prof.sas_addr[0] != 0)
|
||||
asd_stringify_sas_addr(sas_addr_str, asd_ha->hw_prof.sas_addr);
|
||||
/* adapter came with a sas address */
|
||||
if (asd_ha->hw_prof.sas_addr[0])
|
||||
return 0;
|
||||
|
||||
return sas_request_addr(asd_ha->sas_ha.core.shost,
|
||||
asd_ha->hw_prof.sas_addr);
|
||||
}
|
||||
|
||||
static void asd_propagate_sas_addr(struct asd_ha_struct *asd_ha)
|
||||
|
@ -251,7 +250,7 @@ static int asd_init_scbs(struct asd_ha_struct *asd_ha)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha)
|
||||
static void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
asd_ha->hw_prof.max_scbs = asd_get_cmdctx_size(asd_ha)/ASD_SCB_SIZE;
|
||||
asd_ha->hw_prof.max_ddbs = asd_get_devctx_size(asd_ha)/ASD_DDB_SIZE;
|
||||
|
@ -657,8 +656,7 @@ int asd_init_hw(struct asd_ha_struct *asd_ha)
|
|||
|
||||
asd_init_ctxmem(asd_ha);
|
||||
|
||||
asd_get_user_sas_addr(asd_ha);
|
||||
if (!asd_ha->hw_prof.sas_addr[0]) {
|
||||
if (asd_get_user_sas_addr(asd_ha)) {
|
||||
asd_printk("No SAS Address provided for %s\n",
|
||||
pci_name(asd_ha->pcidev));
|
||||
err = -ENODEV;
|
||||
|
@ -773,7 +771,7 @@ static void asd_dl_tasklet_handler(unsigned long data)
|
|||
* asd_process_donelist_isr -- schedule processing of done list entries
|
||||
* @asd_ha: pointer to host adapter structure
|
||||
*/
|
||||
static inline void asd_process_donelist_isr(struct asd_ha_struct *asd_ha)
|
||||
static void asd_process_donelist_isr(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
tasklet_schedule(&asd_ha->seq.dl_tasklet);
|
||||
}
|
||||
|
@ -782,7 +780,7 @@ static inline void asd_process_donelist_isr(struct asd_ha_struct *asd_ha)
|
|||
* asd_com_sas_isr -- process device communication interrupt (COMINT)
|
||||
* @asd_ha: pointer to host adapter structure
|
||||
*/
|
||||
static inline void asd_com_sas_isr(struct asd_ha_struct *asd_ha)
|
||||
static void asd_com_sas_isr(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
u32 comstat = asd_read_reg_dword(asd_ha, COMSTAT);
|
||||
|
||||
|
@ -821,7 +819,7 @@ static inline void asd_com_sas_isr(struct asd_ha_struct *asd_ha)
|
|||
asd_chip_reset(asd_ha);
|
||||
}
|
||||
|
||||
static inline void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus)
|
||||
static void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus)
|
||||
{
|
||||
static const char *halt_code[256] = {
|
||||
"UNEXPECTED_INTERRUPT0",
|
||||
|
@ -908,7 +906,7 @@ static inline void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus)
|
|||
* asd_dch_sas_isr -- process device channel interrupt (DEVINT)
|
||||
* @asd_ha: pointer to host adapter structure
|
||||
*/
|
||||
static inline void asd_dch_sas_isr(struct asd_ha_struct *asd_ha)
|
||||
static void asd_dch_sas_isr(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
u32 dchstatus = asd_read_reg_dword(asd_ha, DCHSTATUS);
|
||||
|
||||
|
@ -923,7 +921,7 @@ static inline void asd_dch_sas_isr(struct asd_ha_struct *asd_ha)
|
|||
* ads_rbi_exsi_isr -- process external system interface interrupt (INITERR)
|
||||
* @asd_ha: pointer to host adapter structure
|
||||
*/
|
||||
static inline void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha)
|
||||
static void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
u32 stat0r = asd_read_reg_dword(asd_ha, ASISTAT0R);
|
||||
|
||||
|
@ -971,7 +969,7 @@ static inline void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha)
|
|||
*
|
||||
* Asserted on PCIX errors: target abort, etc.
|
||||
*/
|
||||
static inline void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha)
|
||||
static void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
u16 status;
|
||||
u32 pcix_status;
|
||||
|
@ -1044,8 +1042,8 @@ irqreturn_t asd_hw_isr(int irq, void *dev_id)
|
|||
|
||||
/* ---------- SCB handling ---------- */
|
||||
|
||||
static inline struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha,
|
||||
gfp_t gfp_flags)
|
||||
static struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
extern struct kmem_cache *asd_ascb_cache;
|
||||
struct asd_seq_data *seq = &asd_ha->seq;
|
||||
|
@ -1144,8 +1142,8 @@ struct asd_ascb *asd_ascb_alloc_list(struct asd_ha_struct
|
|||
*
|
||||
* LOCKING: called with the pending list lock held.
|
||||
*/
|
||||
static inline void asd_swap_head_scb(struct asd_ha_struct *asd_ha,
|
||||
struct asd_ascb *ascb)
|
||||
static void asd_swap_head_scb(struct asd_ha_struct *asd_ha,
|
||||
struct asd_ascb *ascb)
|
||||
{
|
||||
struct asd_seq_data *seq = &asd_ha->seq;
|
||||
struct asd_ascb *last = list_entry(ascb->list.prev,
|
||||
|
@ -1171,7 +1169,7 @@ static inline void asd_swap_head_scb(struct asd_ha_struct *asd_ha,
|
|||
* intended to be called from asd_post_ascb_list(), just prior to
|
||||
* posting the SCBs to the sequencer.
|
||||
*/
|
||||
static inline void asd_start_scb_timers(struct list_head *list)
|
||||
static void asd_start_scb_timers(struct list_head *list)
|
||||
{
|
||||
struct asd_ascb *ascb;
|
||||
list_for_each_entry(ascb, list, list) {
|
||||
|
|
|
@ -391,8 +391,6 @@ void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc);
|
|||
void asd_control_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
|
||||
void asd_turn_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
|
||||
int asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask);
|
||||
void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id,
|
||||
u8 subfunc);
|
||||
|
||||
void asd_ascb_timedout(unsigned long data);
|
||||
int asd_chip_hardrst(struct asd_ha_struct *asd_ha);
|
||||
|
|
|
@ -56,8 +56,6 @@ MODULE_PARM_DESC(collector, "\n"
|
|||
"\tThe aic94xx SAS LLDD supports both modes.\n"
|
||||
"\tDefault: 0 (Direct Mode).\n");
|
||||
|
||||
char sas_addr_str[2*SAS_ADDR_SIZE + 1] = "";
|
||||
|
||||
static struct scsi_transport_template *aic94xx_transport_template;
|
||||
static int asd_scan_finished(struct Scsi_Host *, unsigned long);
|
||||
static void asd_scan_start(struct Scsi_Host *);
|
||||
|
@ -547,7 +545,7 @@ static struct asd_pcidev_struct {
|
|||
},
|
||||
};
|
||||
|
||||
static inline int asd_create_ha_caches(struct asd_ha_struct *asd_ha)
|
||||
static int asd_create_ha_caches(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
asd_ha->scb_pool = dma_pool_create(ASD_DRIVER_NAME "_scb_pool",
|
||||
&asd_ha->pcidev->dev,
|
||||
|
@ -565,7 +563,7 @@ static inline int asd_create_ha_caches(struct asd_ha_struct *asd_ha)
|
|||
* asd_free_edbs -- free empty data buffers
|
||||
* asd_ha: pointer to host adapter structure
|
||||
*/
|
||||
static inline void asd_free_edbs(struct asd_ha_struct *asd_ha)
|
||||
static void asd_free_edbs(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
struct asd_seq_data *seq = &asd_ha->seq;
|
||||
int i;
|
||||
|
@ -576,7 +574,7 @@ static inline void asd_free_edbs(struct asd_ha_struct *asd_ha)
|
|||
seq->edb_arr = NULL;
|
||||
}
|
||||
|
||||
static inline void asd_free_escbs(struct asd_ha_struct *asd_ha)
|
||||
static void asd_free_escbs(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
struct asd_seq_data *seq = &asd_ha->seq;
|
||||
int i;
|
||||
|
@ -591,7 +589,7 @@ static inline void asd_free_escbs(struct asd_ha_struct *asd_ha)
|
|||
seq->escb_arr = NULL;
|
||||
}
|
||||
|
||||
static inline void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha)
|
||||
static void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
* Offset comes before value to remind that the operation of
|
||||
* this function is *offs = val.
|
||||
*/
|
||||
static inline void asd_write_byte(struct asd_ha_struct *asd_ha,
|
||||
unsigned long offs, u8 val)
|
||||
static void asd_write_byte(struct asd_ha_struct *asd_ha,
|
||||
unsigned long offs, u8 val)
|
||||
{
|
||||
if (unlikely(asd_ha->iospace))
|
||||
outb(val,
|
||||
|
@ -43,8 +43,8 @@ static inline void asd_write_byte(struct asd_ha_struct *asd_ha,
|
|||
wmb();
|
||||
}
|
||||
|
||||
static inline void asd_write_word(struct asd_ha_struct *asd_ha,
|
||||
unsigned long offs, u16 val)
|
||||
static void asd_write_word(struct asd_ha_struct *asd_ha,
|
||||
unsigned long offs, u16 val)
|
||||
{
|
||||
if (unlikely(asd_ha->iospace))
|
||||
outw(val,
|
||||
|
@ -54,8 +54,8 @@ static inline void asd_write_word(struct asd_ha_struct *asd_ha,
|
|||
wmb();
|
||||
}
|
||||
|
||||
static inline void asd_write_dword(struct asd_ha_struct *asd_ha,
|
||||
unsigned long offs, u32 val)
|
||||
static void asd_write_dword(struct asd_ha_struct *asd_ha,
|
||||
unsigned long offs, u32 val)
|
||||
{
|
||||
if (unlikely(asd_ha->iospace))
|
||||
outl(val,
|
||||
|
@ -67,8 +67,7 @@ static inline void asd_write_dword(struct asd_ha_struct *asd_ha,
|
|||
|
||||
/* Reading from device address space.
|
||||
*/
|
||||
static inline u8 asd_read_byte(struct asd_ha_struct *asd_ha,
|
||||
unsigned long offs)
|
||||
static u8 asd_read_byte(struct asd_ha_struct *asd_ha, unsigned long offs)
|
||||
{
|
||||
u8 val;
|
||||
if (unlikely(asd_ha->iospace))
|
||||
|
@ -80,8 +79,8 @@ static inline u8 asd_read_byte(struct asd_ha_struct *asd_ha,
|
|||
return val;
|
||||
}
|
||||
|
||||
static inline u16 asd_read_word(struct asd_ha_struct *asd_ha,
|
||||
unsigned long offs)
|
||||
static u16 asd_read_word(struct asd_ha_struct *asd_ha,
|
||||
unsigned long offs)
|
||||
{
|
||||
u16 val;
|
||||
if (unlikely(asd_ha->iospace))
|
||||
|
@ -93,8 +92,8 @@ static inline u16 asd_read_word(struct asd_ha_struct *asd_ha,
|
|||
return val;
|
||||
}
|
||||
|
||||
static inline u32 asd_read_dword(struct asd_ha_struct *asd_ha,
|
||||
unsigned long offs)
|
||||
static u32 asd_read_dword(struct asd_ha_struct *asd_ha,
|
||||
unsigned long offs)
|
||||
{
|
||||
u32 val;
|
||||
if (unlikely(asd_ha->iospace))
|
||||
|
@ -124,22 +123,22 @@ static inline u32 asd_mem_offs_swb(void)
|
|||
/* We know that the register wanted is in the range
|
||||
* of the sliding window.
|
||||
*/
|
||||
#define ASD_READ_SW(ww, type, ord) \
|
||||
static inline type asd_read_##ww##_##ord (struct asd_ha_struct *asd_ha,\
|
||||
u32 reg) \
|
||||
{ \
|
||||
struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \
|
||||
u32 map_offs=(reg - io_handle-> ww##_base )+asd_mem_offs_##ww ();\
|
||||
return asd_read_##ord (asd_ha, (unsigned long) map_offs); \
|
||||
#define ASD_READ_SW(ww, type, ord) \
|
||||
static type asd_read_##ww##_##ord(struct asd_ha_struct *asd_ha, \
|
||||
u32 reg) \
|
||||
{ \
|
||||
struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \
|
||||
u32 map_offs = (reg - io_handle->ww##_base) + asd_mem_offs_##ww();\
|
||||
return asd_read_##ord(asd_ha, (unsigned long)map_offs); \
|
||||
}
|
||||
|
||||
#define ASD_WRITE_SW(ww, type, ord) \
|
||||
static inline void asd_write_##ww##_##ord (struct asd_ha_struct *asd_ha,\
|
||||
u32 reg, type val) \
|
||||
{ \
|
||||
struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \
|
||||
u32 map_offs=(reg - io_handle-> ww##_base )+asd_mem_offs_##ww ();\
|
||||
asd_write_##ord (asd_ha, (unsigned long) map_offs, val); \
|
||||
#define ASD_WRITE_SW(ww, type, ord) \
|
||||
static void asd_write_##ww##_##ord(struct asd_ha_struct *asd_ha, \
|
||||
u32 reg, type val) \
|
||||
{ \
|
||||
struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \
|
||||
u32 map_offs = (reg - io_handle->ww##_base) + asd_mem_offs_##ww();\
|
||||
asd_write_##ord(asd_ha, (unsigned long)map_offs, val); \
|
||||
}
|
||||
|
||||
ASD_READ_SW(swa, u8, byte);
|
||||
|
@ -186,7 +185,7 @@ ASD_WRITE_SW(swc, u32, dword);
|
|||
* @asd_ha: pointer to host adapter structure
|
||||
* @reg: register desired to be within range of the new window
|
||||
*/
|
||||
static inline void asd_move_swb(struct asd_ha_struct *asd_ha, u32 reg)
|
||||
static void asd_move_swb(struct asd_ha_struct *asd_ha, u32 reg)
|
||||
{
|
||||
u32 base = reg & ~(MBAR0_SWB_SIZE-1);
|
||||
pci_write_config_dword(asd_ha->pcidev, PCI_CONF_MBAR0_SWB, base);
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
| CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \
|
||||
| CURRENT_OOB_ERROR)
|
||||
|
||||
static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
|
||||
static void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
|
||||
{
|
||||
struct sas_phy *sas_phy = phy->sas_phy.phy;
|
||||
|
||||
|
@ -81,7 +81,7 @@ static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
|
|||
phy->sas_phy.oob_mode = SATA_OOB_MODE;
|
||||
}
|
||||
|
||||
static inline void asd_phy_event_tasklet(struct asd_ascb *ascb,
|
||||
static void asd_phy_event_tasklet(struct asd_ascb *ascb,
|
||||
struct done_list_struct *dl)
|
||||
{
|
||||
struct asd_ha_struct *asd_ha = ascb->ha;
|
||||
|
@ -125,8 +125,7 @@ static inline void asd_phy_event_tasklet(struct asd_ascb *ascb,
|
|||
}
|
||||
|
||||
/* If phys are enabled sparsely, this will do the right thing. */
|
||||
static inline unsigned ord_phy(struct asd_ha_struct *asd_ha,
|
||||
struct asd_phy *phy)
|
||||
static unsigned ord_phy(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
|
||||
{
|
||||
u8 enabled_mask = asd_ha->hw_prof.enabled_phys;
|
||||
int i, k = 0;
|
||||
|
@ -151,7 +150,7 @@ static inline unsigned ord_phy(struct asd_ha_struct *asd_ha,
|
|||
* LOCKING: the frame_rcvd_lock needs to be held since this parses the frame
|
||||
* buffer.
|
||||
*/
|
||||
static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr)
|
||||
static void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr)
|
||||
{
|
||||
if (phy->sas_phy.frame_rcvd[0] == 0x34
|
||||
&& phy->sas_phy.oob_mode == SATA_OOB_MODE) {
|
||||
|
@ -232,9 +231,9 @@ static void asd_deform_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
|
|||
spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags);
|
||||
}
|
||||
|
||||
static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
|
||||
struct done_list_struct *dl,
|
||||
int edb_id, int phy_id)
|
||||
static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
|
||||
struct done_list_struct *dl,
|
||||
int edb_id, int phy_id)
|
||||
{
|
||||
unsigned long flags;
|
||||
int edb_el = edb_id + ascb->edb_index;
|
||||
|
@ -255,9 +254,9 @@ static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
|
|||
sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED);
|
||||
}
|
||||
|
||||
static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
|
||||
struct done_list_struct *dl,
|
||||
int phy_id)
|
||||
static void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
|
||||
struct done_list_struct *dl,
|
||||
int phy_id)
|
||||
{
|
||||
struct asd_ha_struct *asd_ha = ascb->ha;
|
||||
struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
|
||||
|
@ -308,9 +307,9 @@ out:
|
|||
;
|
||||
}
|
||||
|
||||
static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
|
||||
struct done_list_struct *dl,
|
||||
int phy_id)
|
||||
static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
|
||||
struct done_list_struct *dl,
|
||||
int phy_id)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha;
|
||||
|
@ -715,7 +714,7 @@ out:
|
|||
asd_ascb_free(ascb);
|
||||
}
|
||||
|
||||
static inline void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd)
|
||||
static void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd)
|
||||
{
|
||||
/* disable all speeds, then enable defaults */
|
||||
*speed_mask = SAS_SPEED_60_DIS | SAS_SPEED_30_DIS | SAS_SPEED_15_DIS
|
||||
|
@ -820,6 +819,8 @@ void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc)
|
|||
|
||||
/* ---------- INITIATE LINK ADM TASK ---------- */
|
||||
|
||||
#if 0
|
||||
|
||||
static void link_adm_tasklet_complete(struct asd_ascb *ascb,
|
||||
struct done_list_struct *dl)
|
||||
{
|
||||
|
@ -852,6 +853,8 @@ void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id,
|
|||
ascb->tasklet_complete = link_adm_tasklet_complete;
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
/* ---------- SCB timer ---------- */
|
||||
|
||||
/**
|
||||
|
|
|
@ -590,8 +590,8 @@ static int asd_reset_flash(struct asd_ha_struct *asd_ha)
|
|||
return err;
|
||||
}
|
||||
|
||||
static inline int asd_read_flash_seg(struct asd_ha_struct *asd_ha,
|
||||
void *buffer, u32 offs, int size)
|
||||
static int asd_read_flash_seg(struct asd_ha_struct *asd_ha,
|
||||
void *buffer, u32 offs, int size)
|
||||
{
|
||||
asd_read_reg_string(asd_ha, buffer, asd_ha->hw_prof.flash.bar+offs,
|
||||
size);
|
||||
|
|
|
@ -60,7 +60,7 @@ static u16 last_scb_site_no;
|
|||
*
|
||||
* Return 0 on success, negative on failure.
|
||||
*/
|
||||
int asd_pause_cseq(struct asd_ha_struct *asd_ha)
|
||||
static int asd_pause_cseq(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
int count = PAUSE_TRIES;
|
||||
u32 arp2ctl;
|
||||
|
@ -87,7 +87,7 @@ int asd_pause_cseq(struct asd_ha_struct *asd_ha)
|
|||
*
|
||||
* Return 0 on success, negative on error.
|
||||
*/
|
||||
int asd_unpause_cseq(struct asd_ha_struct *asd_ha)
|
||||
static int asd_unpause_cseq(struct asd_ha_struct *asd_ha)
|
||||
{
|
||||
u32 arp2ctl;
|
||||
int count = PAUSE_TRIES;
|
||||
|
@ -115,7 +115,7 @@ int asd_unpause_cseq(struct asd_ha_struct *asd_ha)
|
|||
*
|
||||
* Return 0 on success, negative on error.
|
||||
*/
|
||||
static inline int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq)
|
||||
static int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq)
|
||||
{
|
||||
u32 arp2ctl;
|
||||
int count = PAUSE_TRIES;
|
||||
|
@ -143,7 +143,7 @@ static inline int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq)
|
|||
*
|
||||
* Return 0 on success, negative on failure.
|
||||
*/
|
||||
int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask)
|
||||
static int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask)
|
||||
{
|
||||
int lseq;
|
||||
int err = 0;
|
||||
|
@ -164,7 +164,7 @@ int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask)
|
|||
*
|
||||
* Return 0 on success, negative on error.
|
||||
*/
|
||||
static inline int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq)
|
||||
static int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq)
|
||||
{
|
||||
u32 arp2ctl;
|
||||
int count = PAUSE_TRIES;
|
||||
|
@ -186,27 +186,6 @@ static inline int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* asd_unpause_lseq - unpause the link sequencer(s)
|
||||
* @asd_ha: pointer to host adapter structure
|
||||
* @lseq_mask: mask of link sequencers of interest
|
||||
*
|
||||
* Return 0 on success, negative on failure.
|
||||
*/
|
||||
int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask)
|
||||
{
|
||||
int lseq;
|
||||
int err = 0;
|
||||
|
||||
for_each_sequencer(lseq_mask, lseq_mask, lseq) {
|
||||
err = asd_seq_unpause_lseq(asd_ha, lseq);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------- Downloading CSEQ/LSEQ microcode ---------- */
|
||||
|
||||
static int asd_verify_cseq(struct asd_ha_struct *asd_ha, const u8 *_prog,
|
||||
|
|
|
@ -58,10 +58,6 @@ struct sequencer_file_header {
|
|||
} __attribute__((packed));
|
||||
|
||||
#ifdef __KERNEL__
|
||||
int asd_pause_cseq(struct asd_ha_struct *asd_ha);
|
||||
int asd_unpause_cseq(struct asd_ha_struct *asd_ha);
|
||||
int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask);
|
||||
int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask);
|
||||
int asd_init_seqs(struct asd_ha_struct *asd_ha);
|
||||
int asd_start_seqs(struct asd_ha_struct *asd_ha);
|
||||
int asd_release_firmware(void);
|
||||
|
|
|
@ -33,7 +33,7 @@ static void asd_unbuild_ata_ascb(struct asd_ascb *a);
|
|||
static void asd_unbuild_smp_ascb(struct asd_ascb *a);
|
||||
static void asd_unbuild_ssp_ascb(struct asd_ascb *a);
|
||||
|
||||
static inline void asd_can_dequeue(struct asd_ha_struct *asd_ha, int num)
|
||||
static void asd_can_dequeue(struct asd_ha_struct *asd_ha, int num)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
@ -51,9 +51,9 @@ static const u8 data_dir_flags[] = {
|
|||
[PCI_DMA_NONE] = DATA_DIR_NONE, /* NO TRANSFER */
|
||||
};
|
||||
|
||||
static inline int asd_map_scatterlist(struct sas_task *task,
|
||||
struct sg_el *sg_arr,
|
||||
gfp_t gfp_flags)
|
||||
static int asd_map_scatterlist(struct sas_task *task,
|
||||
struct sg_el *sg_arr,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
struct asd_ascb *ascb = task->lldd_task;
|
||||
struct asd_ha_struct *asd_ha = ascb->ha;
|
||||
|
@ -131,7 +131,7 @@ err_unmap:
|
|||
return res;
|
||||
}
|
||||
|
||||
static inline void asd_unmap_scatterlist(struct asd_ascb *ascb)
|
||||
static void asd_unmap_scatterlist(struct asd_ascb *ascb)
|
||||
{
|
||||
struct asd_ha_struct *asd_ha = ascb->ha;
|
||||
struct sas_task *task = ascb->uldd_task;
|
||||
|
@ -527,7 +527,7 @@ static void asd_unbuild_ssp_ascb(struct asd_ascb *a)
|
|||
|
||||
/* ---------- Execute Task ---------- */
|
||||
|
||||
static inline int asd_can_queue(struct asd_ha_struct *asd_ha, int num)
|
||||
static int asd_can_queue(struct asd_ha_struct *asd_ha, int num)
|
||||
{
|
||||
int res = 0;
|
||||
unsigned long flags;
|
||||
|
|
|
@ -336,7 +336,7 @@ static void asd_tmf_tasklet_complete(struct asd_ascb *ascb,
|
|||
asd_ascb_free(ascb);
|
||||
}
|
||||
|
||||
static inline int asd_clear_nexus(struct sas_task *task)
|
||||
static int asd_clear_nexus(struct sas_task *task)
|
||||
{
|
||||
int res = TMF_RESP_FUNC_FAILED;
|
||||
int leftover;
|
||||
|
|
|
@ -2983,7 +2983,6 @@ static struct scsi_host_template acornscsi_template = {
|
|||
.this_id = 7,
|
||||
.sg_tablesize = SG_ALL,
|
||||
.cmd_per_lun = 2,
|
||||
.unchecked_isa_dma = 0,
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
.proc_name = "acornscsi",
|
||||
};
|
||||
|
|
|
@ -222,7 +222,6 @@ static struct scsi_host_template cumanascsi_template = {
|
|||
.this_id = 7,
|
||||
.sg_tablesize = SG_ALL,
|
||||
.cmd_per_lun = 2,
|
||||
.unchecked_isa_dma = 0,
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
.proc_name = "CumanaSCSI-1",
|
||||
};
|
||||
|
|
|
@ -113,7 +113,7 @@ static const struct {
|
|||
unsigned char asc;
|
||||
unsigned char ascq;
|
||||
int errno;
|
||||
} err[] = {
|
||||
} ch_err[] = {
|
||||
/* Just filled in what looks right. Hav'nt checked any standard paper for
|
||||
these errno assignments, so they may be wrong... */
|
||||
{
|
||||
|
@ -155,11 +155,11 @@ static int ch_find_errno(struct scsi_sense_hdr *sshdr)
|
|||
/* Check to see if additional sense information is available */
|
||||
if (scsi_sense_valid(sshdr) &&
|
||||
sshdr->asc != 0) {
|
||||
for (i = 0; err[i].errno != 0; i++) {
|
||||
if (err[i].sense == sshdr->sense_key &&
|
||||
err[i].asc == sshdr->asc &&
|
||||
err[i].ascq == sshdr->ascq) {
|
||||
errno = -err[i].errno;
|
||||
for (i = 0; ch_err[i].errno != 0; i++) {
|
||||
if (ch_err[i].sense == sshdr->sense_key &&
|
||||
ch_err[i].asc == sshdr->asc &&
|
||||
ch_err[i].ascq == sshdr->ascq) {
|
||||
errno = -ch_err[i].errno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -721,8 +721,8 @@ static long ch_ioctl(struct file *file,
|
|||
case CHIOGELEM:
|
||||
{
|
||||
struct changer_get_element cge;
|
||||
u_char cmd[12];
|
||||
u_char *buffer;
|
||||
u_char ch_cmd[12];
|
||||
u_char *buffer;
|
||||
unsigned int elem;
|
||||
int result,i;
|
||||
|
||||
|
@ -739,17 +739,18 @@ static long ch_ioctl(struct file *file,
|
|||
mutex_lock(&ch->lock);
|
||||
|
||||
voltag_retry:
|
||||
memset(cmd,0,sizeof(cmd));
|
||||
cmd[0] = READ_ELEMENT_STATUS;
|
||||
cmd[1] = (ch->device->lun << 5) |
|
||||
memset(ch_cmd, 0, sizeof(ch_cmd));
|
||||
ch_cmd[0] = READ_ELEMENT_STATUS;
|
||||
ch_cmd[1] = (ch->device->lun << 5) |
|
||||
(ch->voltags ? 0x10 : 0) |
|
||||
ch_elem_to_typecode(ch,elem);
|
||||
cmd[2] = (elem >> 8) & 0xff;
|
||||
cmd[3] = elem & 0xff;
|
||||
cmd[5] = 1;
|
||||
cmd[9] = 255;
|
||||
ch_cmd[2] = (elem >> 8) & 0xff;
|
||||
ch_cmd[3] = elem & 0xff;
|
||||
ch_cmd[5] = 1;
|
||||
ch_cmd[9] = 255;
|
||||
|
||||
if (0 == (result = ch_do_scsi(ch, cmd, buffer, 256, DMA_FROM_DEVICE))) {
|
||||
result = ch_do_scsi(ch, ch_cmd, buffer, 256, DMA_FROM_DEVICE);
|
||||
if (!result) {
|
||||
cge.cge_status = buffer[18];
|
||||
cge.cge_flags = 0;
|
||||
if (buffer[18] & CESTATUS_EXCEPT) {
|
||||
|
|
|
@ -4761,7 +4761,6 @@ static struct scsi_host_template dc395x_driver_template = {
|
|||
.cmd_per_lun = DC395x_MAX_CMD_PER_LUN,
|
||||
.eh_abort_handler = dc395x_eh_abort,
|
||||
.eh_bus_reset_handler = dc395x_eh_bus_reset,
|
||||
.unchecked_isa_dma = 0,
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
};
|
||||
|
||||
|
|
|
@ -815,8 +815,6 @@ static int register_pio_HBA(long base, struct get_conf *gc, struct pci_dev *pdev
|
|||
else
|
||||
hd->primary = 1;
|
||||
|
||||
sh->unchecked_isa_dma = 0; /* We can only do PIO */
|
||||
|
||||
hd->next = NULL; /* build a linked list of all HBAs */
|
||||
hd->prev = last_HBA;
|
||||
if (hd->prev != NULL)
|
||||
|
|
|
@ -85,10 +85,10 @@
|
|||
|
||||
/* The meaning of the Scsi_Pointer members in this driver is as follows:
|
||||
* ptr: Chaining
|
||||
* this_residual: gdth_bufflen
|
||||
* buffer: gdth_sglist
|
||||
* this_residual: unused
|
||||
* buffer: unused
|
||||
* dma_handle: unused
|
||||
* buffers_residual: gdth_sg_count
|
||||
* buffers_residual: unused
|
||||
* Status: unused
|
||||
* Message: unused
|
||||
* have_data_in: unused
|
||||
|
@ -372,47 +372,6 @@ static const struct file_operations gdth_fops = {
|
|||
.release = gdth_close,
|
||||
};
|
||||
|
||||
/*
|
||||
* gdth scsi_command access wrappers.
|
||||
* below 6 functions are used throughout the driver to access scsi_command's
|
||||
* io parameters. The reason we do not use the regular accessors from
|
||||
* scsi_cmnd.h is because of gdth_execute(). Since it is unrecommended for
|
||||
* llds to directly set scsi_cmnd's IO members. This driver will use SCp
|
||||
* members for IO parameters, and will copy scsi_cmnd's members to Scp
|
||||
* members in queuecommand. For internal commands through gdth_execute()
|
||||
* SCp's members will be set directly.
|
||||
*/
|
||||
static inline unsigned gdth_bufflen(struct scsi_cmnd *cmd)
|
||||
{
|
||||
return (unsigned)cmd->SCp.this_residual;
|
||||
}
|
||||
|
||||
static inline void gdth_set_bufflen(struct scsi_cmnd *cmd, unsigned bufflen)
|
||||
{
|
||||
cmd->SCp.this_residual = bufflen;
|
||||
}
|
||||
|
||||
static inline unsigned gdth_sg_count(struct scsi_cmnd *cmd)
|
||||
{
|
||||
return (unsigned)cmd->SCp.buffers_residual;
|
||||
}
|
||||
|
||||
static inline void gdth_set_sg_count(struct scsi_cmnd *cmd, unsigned sg_count)
|
||||
{
|
||||
cmd->SCp.buffers_residual = sg_count;
|
||||
}
|
||||
|
||||
static inline struct scatterlist *gdth_sglist(struct scsi_cmnd *cmd)
|
||||
{
|
||||
return cmd->SCp.buffer;
|
||||
}
|
||||
|
||||
static inline void gdth_set_sglist(struct scsi_cmnd *cmd,
|
||||
struct scatterlist *sglist)
|
||||
{
|
||||
cmd->SCp.buffer = sglist;
|
||||
}
|
||||
|
||||
#include "gdth_proc.h"
|
||||
#include "gdth_proc.c"
|
||||
|
||||
|
@ -591,125 +550,111 @@ static int __init gdth_search_isa(ulong32 bios_adr)
|
|||
#endif /* CONFIG_ISA */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
|
||||
ushort vendor, ushort dev);
|
||||
static bool gdth_pci_registered;
|
||||
|
||||
static int __init gdth_search_pci(gdth_pci_str *pcistr)
|
||||
static bool gdth_search_vortex(ushort device)
|
||||
{
|
||||
ushort device, cnt;
|
||||
|
||||
TRACE(("gdth_search_pci()\n"));
|
||||
|
||||
cnt = 0;
|
||||
for (device = 0; device <= PCI_DEVICE_ID_VORTEX_GDT6555; ++device)
|
||||
gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
|
||||
for (device = PCI_DEVICE_ID_VORTEX_GDT6x17RP;
|
||||
device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; ++device)
|
||||
gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
|
||||
gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX,
|
||||
PCI_DEVICE_ID_VORTEX_GDTNEWRX);
|
||||
gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX,
|
||||
PCI_DEVICE_ID_VORTEX_GDTNEWRX2);
|
||||
gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_SRC);
|
||||
gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_SRC_XSCALE);
|
||||
return cnt;
|
||||
if (device <= PCI_DEVICE_ID_VORTEX_GDT6555)
|
||||
return true;
|
||||
if (device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP &&
|
||||
device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP)
|
||||
return true;
|
||||
if (device == PCI_DEVICE_ID_VORTEX_GDTNEWRX ||
|
||||
device == PCI_DEVICE_ID_VORTEX_GDTNEWRX2)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out);
|
||||
static int gdth_pci_init_one(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent);
|
||||
static void gdth_pci_remove_one(struct pci_dev *pdev);
|
||||
static void gdth_remove_one(gdth_ha_str *ha);
|
||||
|
||||
/* Vortex only makes RAID controllers.
|
||||
* We do not really want to specify all 550 ids here, so wildcard match.
|
||||
*/
|
||||
static struct pci_device_id gdthtable[] __maybe_unused = {
|
||||
{PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID},
|
||||
{PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID},
|
||||
{PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID},
|
||||
{0}
|
||||
static const struct pci_device_id gdthtable[] = {
|
||||
{ PCI_VDEVICE(VORTEX, PCI_ANY_ID) },
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC) },
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC_XSCALE) },
|
||||
{ } /* terminate list */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci,gdthtable);
|
||||
MODULE_DEVICE_TABLE(pci, gdthtable);
|
||||
|
||||
static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
|
||||
ushort vendor, ushort device)
|
||||
static struct pci_driver gdth_pci_driver = {
|
||||
.name = "gdth",
|
||||
.id_table = gdthtable,
|
||||
.probe = gdth_pci_init_one,
|
||||
.remove = gdth_pci_remove_one,
|
||||
};
|
||||
|
||||
static void gdth_pci_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
ulong base0, base1, base2;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
|
||||
*cnt, vendor, device));
|
||||
gdth_ha_str *ha = pci_get_drvdata(pdev);
|
||||
|
||||
pdev = NULL;
|
||||
while ((pdev = pci_get_device(vendor, device, pdev))
|
||||
!= NULL) {
|
||||
if (pci_enable_device(pdev))
|
||||
continue;
|
||||
if (*cnt >= MAXHA) {
|
||||
pci_dev_put(pdev);
|
||||
return;
|
||||
}
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
|
||||
list_del(&ha->list);
|
||||
gdth_remove_one(ha);
|
||||
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
static int gdth_pci_init_one(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
ushort vendor = pdev->vendor;
|
||||
ushort device = pdev->device;
|
||||
ulong base0, base1, base2;
|
||||
int rc;
|
||||
gdth_pci_str gdth_pcistr;
|
||||
gdth_ha_str *ha = NULL;
|
||||
|
||||
TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
|
||||
gdth_ctr_count, vendor, device));
|
||||
|
||||
memset(&gdth_pcistr, 0, sizeof(gdth_pcistr));
|
||||
|
||||
if (vendor == PCI_VENDOR_ID_VORTEX && !gdth_search_vortex(device))
|
||||
return -ENODEV;
|
||||
|
||||
rc = pci_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (gdth_ctr_count >= MAXHA)
|
||||
return -EBUSY;
|
||||
|
||||
/* GDT PCI controller found, resources are already in pdev */
|
||||
pcistr[*cnt].pdev = pdev;
|
||||
pcistr[*cnt].irq = pdev->irq;
|
||||
gdth_pcistr.pdev = pdev;
|
||||
base0 = pci_resource_flags(pdev, 0);
|
||||
base1 = pci_resource_flags(pdev, 1);
|
||||
base2 = pci_resource_flags(pdev, 2);
|
||||
if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */
|
||||
device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */
|
||||
if (!(base0 & IORESOURCE_MEM))
|
||||
continue;
|
||||
pcistr[*cnt].dpmem = pci_resource_start(pdev, 0);
|
||||
return -ENODEV;
|
||||
gdth_pcistr.dpmem = pci_resource_start(pdev, 0);
|
||||
} else { /* GDT6110, GDT6120, .. */
|
||||
if (!(base0 & IORESOURCE_MEM) ||
|
||||
!(base2 & IORESOURCE_MEM) ||
|
||||
!(base1 & IORESOURCE_IO))
|
||||
continue;
|
||||
pcistr[*cnt].dpmem = pci_resource_start(pdev, 2);
|
||||
pcistr[*cnt].io_mm = pci_resource_start(pdev, 0);
|
||||
pcistr[*cnt].io = pci_resource_start(pdev, 1);
|
||||
return -ENODEV;
|
||||
gdth_pcistr.dpmem = pci_resource_start(pdev, 2);
|
||||
gdth_pcistr.io = pci_resource_start(pdev, 1);
|
||||
}
|
||||
TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
|
||||
pcistr[*cnt].pdev->bus->number,
|
||||
PCI_SLOT(pcistr[*cnt].pdev->devfn),
|
||||
pcistr[*cnt].irq, pcistr[*cnt].dpmem));
|
||||
(*cnt)++;
|
||||
}
|
||||
}
|
||||
gdth_pcistr.pdev->bus->number,
|
||||
PCI_SLOT(gdth_pcistr.pdev->devfn),
|
||||
gdth_pcistr.irq,
|
||||
gdth_pcistr.dpmem));
|
||||
|
||||
static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt)
|
||||
{
|
||||
gdth_pci_str temp;
|
||||
int i, changed;
|
||||
|
||||
TRACE(("gdth_sort_pci() cnt %d\n",cnt));
|
||||
if (cnt == 0)
|
||||
return;
|
||||
rc = gdth_pci_probe_one(&gdth_pcistr, &ha);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
do {
|
||||
changed = FALSE;
|
||||
for (i = 0; i < cnt-1; ++i) {
|
||||
if (!reverse_scan) {
|
||||
if ((pcistr[i].pdev->bus->number > pcistr[i+1].pdev->bus->number) ||
|
||||
(pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number &&
|
||||
PCI_SLOT(pcistr[i].pdev->devfn) >
|
||||
PCI_SLOT(pcistr[i+1].pdev->devfn))) {
|
||||
temp = pcistr[i];
|
||||
pcistr[i] = pcistr[i+1];
|
||||
pcistr[i+1] = temp;
|
||||
changed = TRUE;
|
||||
}
|
||||
} else {
|
||||
if ((pcistr[i].pdev->bus->number < pcistr[i+1].pdev->bus->number) ||
|
||||
(pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number &&
|
||||
PCI_SLOT(pcistr[i].pdev->devfn) <
|
||||
PCI_SLOT(pcistr[i+1].pdev->devfn))) {
|
||||
temp = pcistr[i];
|
||||
pcistr[i] = pcistr[i+1];
|
||||
pcistr[i+1] = temp;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (changed);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
|
@ -909,7 +854,8 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha)
|
|||
#endif /* CONFIG_ISA */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
|
||||
static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
|
||||
gdth_ha_str *ha)
|
||||
{
|
||||
register gdt6_dpram_str __iomem *dp6_ptr;
|
||||
register gdt6c_dpram_str __iomem *dp6c_ptr;
|
||||
|
@ -921,14 +867,14 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
|
|||
|
||||
TRACE(("gdth_init_pci()\n"));
|
||||
|
||||
if (pcistr->pdev->vendor == PCI_VENDOR_ID_INTEL)
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL)
|
||||
ha->oem_id = OEM_ID_INTEL;
|
||||
else
|
||||
ha->oem_id = OEM_ID_ICP;
|
||||
ha->brd_phys = (pcistr->pdev->bus->number << 8) | (pcistr->pdev->devfn & 0xf8);
|
||||
ha->stype = (ulong32)pcistr->pdev->device;
|
||||
ha->irq = pcistr->irq;
|
||||
ha->pdev = pcistr->pdev;
|
||||
ha->brd_phys = (pdev->bus->number << 8) | (pdev->devfn & 0xf8);
|
||||
ha->stype = (ulong32)pdev->device;
|
||||
ha->irq = pdev->irq;
|
||||
ha->pdev = pdev;
|
||||
|
||||
if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */
|
||||
TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
|
||||
|
@ -956,8 +902,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
|
|||
continue;
|
||||
}
|
||||
iounmap(ha->brd);
|
||||
pci_write_config_dword(pcistr->pdev,
|
||||
PCI_BASE_ADDRESS_0, i);
|
||||
pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i);
|
||||
ha->brd = ioremap(i, sizeof(gdt6_dpram_str));
|
||||
if (ha->brd == NULL) {
|
||||
printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
|
||||
|
@ -1066,8 +1011,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
|
|||
continue;
|
||||
}
|
||||
iounmap(ha->brd);
|
||||
pci_write_config_dword(pcistr->pdev,
|
||||
PCI_BASE_ADDRESS_2, i);
|
||||
pci_write_config_dword(pdev, PCI_BASE_ADDRESS_2, i);
|
||||
ha->brd = ioremap(i, sizeof(gdt6c_dpram_str));
|
||||
if (ha->brd == NULL) {
|
||||
printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
|
||||
|
@ -1159,16 +1103,16 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
|
|||
}
|
||||
|
||||
/* manipulate config. space to enable DPMEM, start RP controller */
|
||||
pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command);
|
||||
pci_read_config_word(pdev, PCI_COMMAND, &command);
|
||||
command |= 6;
|
||||
pci_write_config_word(pcistr->pdev, PCI_COMMAND, command);
|
||||
if (pci_resource_start(pcistr->pdev, 8) == 1UL)
|
||||
pci_resource_start(pcistr->pdev, 8) = 0UL;
|
||||
pci_write_config_word(pdev, PCI_COMMAND, command);
|
||||
if (pci_resource_start(pdev, 8) == 1UL)
|
||||
pci_resource_start(pdev, 8) = 0UL;
|
||||
i = 0xFEFF0001UL;
|
||||
pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i);
|
||||
pci_write_config_dword(pdev, PCI_ROM_ADDRESS, i);
|
||||
gdth_delay(1);
|
||||
pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS,
|
||||
pci_resource_start(pcistr->pdev, 8));
|
||||
pci_write_config_dword(pdev, PCI_ROM_ADDRESS,
|
||||
pci_resource_start(pdev, 8));
|
||||
|
||||
dp6m_ptr = ha->brd;
|
||||
|
||||
|
@ -1195,8 +1139,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
|
|||
continue;
|
||||
}
|
||||
iounmap(ha->brd);
|
||||
pci_write_config_dword(pcistr->pdev,
|
||||
PCI_BASE_ADDRESS_0, i);
|
||||
pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i);
|
||||
ha->brd = ioremap(i, sizeof(gdt6m_dpram_str));
|
||||
if (ha->brd == NULL) {
|
||||
printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
|
||||
|
@ -2353,12 +2296,12 @@ static void gdth_next(gdth_ha_str *ha)
|
|||
static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
|
||||
char *buffer, ushort count)
|
||||
{
|
||||
ushort cpcount,i, max_sg = gdth_sg_count(scp);
|
||||
ushort cpcount,i, max_sg = scsi_sg_count(scp);
|
||||
ushort cpsum,cpnow;
|
||||
struct scatterlist *sl;
|
||||
char *address;
|
||||
|
||||
cpcount = min_t(ushort, count, gdth_bufflen(scp));
|
||||
cpcount = min_t(ushort, count, scsi_bufflen(scp));
|
||||
|
||||
if (cpcount) {
|
||||
cpsum=0;
|
||||
|
@ -2366,7 +2309,7 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
|
|||
unsigned long flags;
|
||||
cpnow = (ushort)sl->length;
|
||||
TRACE(("copy_internal() now %d sum %d count %d %d\n",
|
||||
cpnow, cpsum, cpcount, gdth_bufflen(scp)));
|
||||
cpnow, cpsum, cpcount, scsi_bufflen(scp)));
|
||||
if (cpsum+cpnow > cpcount)
|
||||
cpnow = cpcount - cpsum;
|
||||
cpsum += cpnow;
|
||||
|
@ -2589,10 +2532,10 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive)
|
|||
cmdp->u.cache.BlockCnt = blockcnt;
|
||||
}
|
||||
|
||||
if (gdth_bufflen(scp)) {
|
||||
if (scsi_bufflen(scp)) {
|
||||
cmndinfo->dma_dir = (read_write == 1 ?
|
||||
PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
|
||||
sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp),
|
||||
sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
|
||||
cmndinfo->dma_dir);
|
||||
if (mode64) {
|
||||
struct scatterlist *sl;
|
||||
|
@ -2739,7 +2682,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
|
|||
cmdp->u.raw64.lun = l;
|
||||
cmdp->u.raw64.bus = b;
|
||||
cmdp->u.raw64.priority = 0;
|
||||
cmdp->u.raw64.sdlen = gdth_bufflen(scp);
|
||||
cmdp->u.raw64.sdlen = scsi_bufflen(scp);
|
||||
cmdp->u.raw64.sense_len = 16;
|
||||
cmdp->u.raw64.sense_data = sense_paddr;
|
||||
cmdp->u.raw64.direction =
|
||||
|
@ -2756,7 +2699,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
|
|||
cmdp->u.raw.bus = b;
|
||||
cmdp->u.raw.priority = 0;
|
||||
cmdp->u.raw.link_p = 0;
|
||||
cmdp->u.raw.sdlen = gdth_bufflen(scp);
|
||||
cmdp->u.raw.sdlen = scsi_bufflen(scp);
|
||||
cmdp->u.raw.sense_len = 16;
|
||||
cmdp->u.raw.sense_data = sense_paddr;
|
||||
cmdp->u.raw.direction =
|
||||
|
@ -2765,9 +2708,9 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
|
|||
cmdp->u.raw.sg_ranz = 0;
|
||||
}
|
||||
|
||||
if (gdth_bufflen(scp)) {
|
||||
if (scsi_bufflen(scp)) {
|
||||
cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL;
|
||||
sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp),
|
||||
sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
|
||||
cmndinfo->dma_dir);
|
||||
if (mode64) {
|
||||
struct scatterlist *sl;
|
||||
|
@ -3388,8 +3331,8 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index,
|
|||
/* retry */
|
||||
return 2;
|
||||
}
|
||||
if (gdth_bufflen(scp))
|
||||
pci_unmap_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp),
|
||||
if (scsi_bufflen(scp))
|
||||
pci_unmap_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
|
||||
cmndinfo->dma_dir);
|
||||
|
||||
if (cmndinfo->sense_paddr)
|
||||
|
@ -4031,10 +3974,6 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
|
|||
gdth_update_timeout(scp, scp->timeout_per_command * 6);
|
||||
cmndinfo->priority = DEFAULT_PRI;
|
||||
|
||||
gdth_set_bufflen(scp, scsi_bufflen(scp));
|
||||
gdth_set_sg_count(scp, scsi_sg_count(scp));
|
||||
gdth_set_sglist(scp, scsi_sglist(scp));
|
||||
|
||||
return __gdth_queuecommand(ha, scp, cmndinfo);
|
||||
}
|
||||
|
||||
|
@ -4955,12 +4894,16 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot)
|
|||
#endif /* CONFIG_EISA */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
|
||||
static int gdth_pci_probe_one(gdth_pci_str *pcistr,
|
||||
gdth_ha_str **ha_out)
|
||||
{
|
||||
struct Scsi_Host *shp;
|
||||
gdth_ha_str *ha;
|
||||
dma_addr_t scratch_dma_handle = 0;
|
||||
int error, i;
|
||||
struct pci_dev *pdev = pcistr->pdev;
|
||||
|
||||
*ha_out = NULL;
|
||||
|
||||
shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str));
|
||||
if (!shp)
|
||||
|
@ -4968,13 +4911,13 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
|
|||
ha = shost_priv(shp);
|
||||
|
||||
error = -ENODEV;
|
||||
if (!gdth_init_pci(&pcistr[ctr],ha))
|
||||
if (!gdth_init_pci(pdev, pcistr, ha))
|
||||
goto out_host_put;
|
||||
|
||||
/* controller found and initialized */
|
||||
printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n",
|
||||
pcistr[ctr].pdev->bus->number,
|
||||
PCI_SLOT(pcistr[ctr].pdev->devfn),
|
||||
pdev->bus->number,
|
||||
PCI_SLOT(pdev->devfn),
|
||||
ha->irq);
|
||||
|
||||
error = request_irq(ha->irq, gdth_interrupt,
|
||||
|
@ -5019,7 +4962,7 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
|
|||
|
||||
ha->scratch_busy = FALSE;
|
||||
ha->req_first = NULL;
|
||||
ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES;
|
||||
ha->tid_cnt = pdev->device >= 0x200 ? MAXID : MAX_HDRIVES;
|
||||
if (max_ids > 0 && max_ids < ha->tid_cnt)
|
||||
ha->tid_cnt = max_ids;
|
||||
for (i = 0; i < GDTH_MAXCMDS; ++i)
|
||||
|
@ -5039,16 +4982,16 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
|
|||
/* 64-bit DMA only supported from FW >= x.43 */
|
||||
if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) ||
|
||||
!ha->dma64_support) {
|
||||
if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) {
|
||||
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
|
||||
printk(KERN_WARNING "GDT-PCI %d: "
|
||||
"Unable to set 32-bit DMA\n", ha->hanum);
|
||||
goto out_free_coal_stat;
|
||||
}
|
||||
} else {
|
||||
shp->max_cmd_len = 16;
|
||||
if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) {
|
||||
if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
|
||||
printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum);
|
||||
} else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) {
|
||||
} else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
|
||||
printk(KERN_WARNING "GDT-PCI %d: "
|
||||
"Unable to set 64/32-bit DMA\n", ha->hanum);
|
||||
goto out_free_coal_stat;
|
||||
|
@ -5062,13 +5005,17 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
|
|||
spin_lock_init(&ha->smp_lock);
|
||||
gdth_enable_int(ha);
|
||||
|
||||
error = scsi_add_host(shp, &pcistr[ctr].pdev->dev);
|
||||
error = scsi_add_host(shp, &pdev->dev);
|
||||
if (error)
|
||||
goto out_free_coal_stat;
|
||||
list_add_tail(&ha->list, &gdth_instances);
|
||||
|
||||
pci_set_drvdata(ha->pdev, ha);
|
||||
|
||||
scsi_scan_host(shp);
|
||||
|
||||
*ha_out = ha;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_coal_stat:
|
||||
|
@ -5185,16 +5132,8 @@ static int __init gdth_init(void)
|
|||
|
||||
#ifdef CONFIG_PCI
|
||||
/* scanning for PCI controllers */
|
||||
{
|
||||
gdth_pci_str pcistr[MAXHA];
|
||||
int cnt,ctr;
|
||||
|
||||
cnt = gdth_search_pci(pcistr);
|
||||
printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt);
|
||||
gdth_sort_pci(pcistr,cnt);
|
||||
for (ctr = 0; ctr < cnt; ++ctr)
|
||||
gdth_pci_probe_one(pcistr, ctr);
|
||||
}
|
||||
if (pci_register_driver(&gdth_pci_driver) == 0)
|
||||
gdth_pci_registered = true;
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count));
|
||||
|
@ -5227,6 +5166,11 @@ static void __exit gdth_exit(void)
|
|||
del_timer_sync(&gdth_timer);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
if (gdth_pci_registered)
|
||||
pci_unregister_driver(&gdth_pci_driver);
|
||||
#endif
|
||||
|
||||
list_for_each_entry(ha, &gdth_instances, list)
|
||||
gdth_remove_one(ha);
|
||||
}
|
||||
|
|
|
@ -839,8 +839,6 @@ typedef struct {
|
|||
struct pci_dev *pdev;
|
||||
ulong dpmem; /* DPRAM address */
|
||||
ulong io; /* IO address */
|
||||
ulong io_mm; /* IO address mem. mapped */
|
||||
unchar irq; /* IRQ */
|
||||
} gdth_pci_str;
|
||||
|
||||
|
||||
|
|
|
@ -322,6 +322,9 @@ int __init gvp11_detect(struct scsi_host_template *tpnt)
|
|||
*/
|
||||
regs.SASR = &(DMA(instance)->SASR);
|
||||
regs.SCMD = &(DMA(instance)->SCMD);
|
||||
HDATA(instance)->no_sync = 0xff;
|
||||
HDATA(instance)->fast = 0;
|
||||
HDATA(instance)->dma_mode = CTRL_DMA;
|
||||
wd33c93_init(instance, regs, dma_setup, dma_stop,
|
||||
(epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10
|
||||
: WD33C93_FS_12_15);
|
||||
|
|
|
@ -347,7 +347,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
|
|||
shost->unchecked_isa_dma = sht->unchecked_isa_dma;
|
||||
shost->use_clustering = sht->use_clustering;
|
||||
shost->ordered_tag = sht->ordered_tag;
|
||||
shost->active_mode = sht->supported_mode;
|
||||
|
||||
if (sht->supported_mode == MODE_UNKNOWN)
|
||||
/* means we didn't set it ... default to INITIATOR */
|
||||
|
|
|
@ -338,7 +338,8 @@ static int iop_get_config_mv(struct hptiop_hba *hba,
|
|||
req->header.size =
|
||||
cpu_to_le32(sizeof(struct hpt_iop_request_get_config));
|
||||
req->header.result = cpu_to_le32(IOP_RESULT_PENDING);
|
||||
req->header.context = cpu_to_le64(IOP_REQUEST_TYPE_GET_CONFIG<<5);
|
||||
req->header.context = cpu_to_le32(IOP_REQUEST_TYPE_GET_CONFIG<<5);
|
||||
req->header.context_hi32 = 0;
|
||||
|
||||
if (iop_send_sync_request_mv(hba, 0, 20000)) {
|
||||
dprintk("Get config send cmd failed\n");
|
||||
|
@ -392,7 +393,8 @@ static int iop_set_config_mv(struct hptiop_hba *hba,
|
|||
req->header.size =
|
||||
cpu_to_le32(sizeof(struct hpt_iop_request_set_config));
|
||||
req->header.result = cpu_to_le32(IOP_RESULT_PENDING);
|
||||
req->header.context = cpu_to_le64(IOP_REQUEST_TYPE_SET_CONFIG<<5);
|
||||
req->header.context = cpu_to_le32(IOP_REQUEST_TYPE_SET_CONFIG<<5);
|
||||
req->header.context_hi32 = 0;
|
||||
|
||||
if (iop_send_sync_request_mv(hba, 0, 20000)) {
|
||||
dprintk("Set config send cmd failed\n");
|
||||
|
@ -903,7 +905,6 @@ static struct scsi_host_template driver_template = {
|
|||
.eh_device_reset_handler = hptiop_reset,
|
||||
.eh_bus_reset_handler = hptiop_reset,
|
||||
.info = hptiop_info,
|
||||
.unchecked_isa_dma = 0,
|
||||
.emulated = 0,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.proc_name = driver_name,
|
||||
|
|
|
@ -2581,8 +2581,8 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
|
|||
/* Map the sense buffer into bus memory */
|
||||
dma_addr = dma_map_single(&host->pci_dev->dev, cmnd->sense_buffer,
|
||||
SENSE_SIZE, DMA_FROM_DEVICE);
|
||||
cblk->senseptr = cpu_to_le32((u32)dma_addr);
|
||||
cblk->senselen = cpu_to_le32(SENSE_SIZE);
|
||||
cblk->senseptr = (u32)dma_addr;
|
||||
cblk->senselen = SENSE_SIZE;
|
||||
cmnd->SCp.ptr = (char *)(unsigned long)dma_addr;
|
||||
cblk->cdblen = cmnd->cmd_len;
|
||||
|
||||
|
@ -2606,7 +2606,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
|
|||
dma_addr = dma_map_single(&host->pci_dev->dev, &cblk->sglist[0],
|
||||
sizeof(struct sg_entry) * TOTAL_SG_ENTRY,
|
||||
DMA_BIDIRECTIONAL);
|
||||
cblk->bufptr = cpu_to_le32((u32)dma_addr);
|
||||
cblk->bufptr = (u32)dma_addr;
|
||||
cmnd->SCp.dma_handle = dma_addr;
|
||||
|
||||
cblk->sglen = nseg;
|
||||
|
@ -2616,7 +2616,8 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
|
|||
sg = &cblk->sglist[0];
|
||||
scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) {
|
||||
sg->data = cpu_to_le32((u32)sg_dma_address(sglist));
|
||||
total_len += sg->len = cpu_to_le32((u32)sg_dma_len(sglist));
|
||||
sg->len = cpu_to_le32((u32)sg_dma_len(sglist));
|
||||
total_len += sg_dma_len(sglist);
|
||||
++sg;
|
||||
}
|
||||
|
||||
|
|
|
@ -2377,7 +2377,7 @@ ips_get_bios_version(ips_ha_t * ha, int intr)
|
|||
if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
|
||||
return;
|
||||
|
||||
outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
|
||||
outl(1, ha->io_addr + IPS_REG_FLAP);
|
||||
if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
|
||||
udelay(25); /* 25 us */
|
||||
|
||||
|
@ -2385,21 +2385,21 @@ ips_get_bios_version(ips_ha_t * ha, int intr)
|
|||
return;
|
||||
|
||||
/* Get Major version */
|
||||
outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP);
|
||||
outl(0x1FF, ha->io_addr + IPS_REG_FLAP);
|
||||
if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
|
||||
udelay(25); /* 25 us */
|
||||
|
||||
major = inb(ha->io_addr + IPS_REG_FLDP);
|
||||
|
||||
/* Get Minor version */
|
||||
outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP);
|
||||
outl(0x1FE, ha->io_addr + IPS_REG_FLAP);
|
||||
if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
|
||||
udelay(25); /* 25 us */
|
||||
|
||||
minor = inb(ha->io_addr + IPS_REG_FLDP);
|
||||
|
||||
/* Get SubMinor version */
|
||||
outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP);
|
||||
outl(0x1FD, ha->io_addr + IPS_REG_FLAP);
|
||||
if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
|
||||
udelay(25); /* 25 us */
|
||||
|
||||
|
@ -3502,27 +3502,11 @@ ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
|
|||
static void
|
||||
ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
|
||||
{
|
||||
int i;
|
||||
unsigned int min_cnt, xfer_cnt;
|
||||
char *cdata = (char *) data;
|
||||
unsigned char *buffer;
|
||||
unsigned long flags;
|
||||
struct scatterlist *sg = scsi_sglist(scmd);
|
||||
unsigned long flags;
|
||||
|
||||
for (i = 0, xfer_cnt = 0;
|
||||
(i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) {
|
||||
min_cnt = min(count - xfer_cnt, sg[i].length);
|
||||
|
||||
/* kmap_atomic() ensures addressability of the data buffer.*/
|
||||
/* local_irq_save() protects the KM_IRQ0 address slot. */
|
||||
local_irq_save(flags);
|
||||
buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
|
||||
memcpy(buffer, &cdata[xfer_cnt], min_cnt);
|
||||
kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
|
||||
local_irq_restore(flags);
|
||||
|
||||
xfer_cnt += min_cnt;
|
||||
}
|
||||
local_irq_save(flags);
|
||||
scsi_sg_copy_from_buffer(scmd, data, count);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -3535,27 +3519,11 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
|
|||
static void
|
||||
ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
|
||||
{
|
||||
int i;
|
||||
unsigned int min_cnt, xfer_cnt;
|
||||
char *cdata = (char *) data;
|
||||
unsigned char *buffer;
|
||||
unsigned long flags;
|
||||
struct scatterlist *sg = scsi_sglist(scmd);
|
||||
unsigned long flags;
|
||||
|
||||
for (i = 0, xfer_cnt = 0;
|
||||
(i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) {
|
||||
min_cnt = min(count - xfer_cnt, sg[i].length);
|
||||
|
||||
/* kmap_atomic() ensures addressability of the data buffer.*/
|
||||
/* local_irq_save() protects the KM_IRQ0 address slot. */
|
||||
local_irq_save(flags);
|
||||
buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
|
||||
memcpy(&cdata[xfer_cnt], buffer, min_cnt);
|
||||
kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
|
||||
local_irq_restore(flags);
|
||||
|
||||
xfer_cnt += min_cnt;
|
||||
}
|
||||
local_irq_save(flags);
|
||||
scsi_sg_copy_to_buffer(scmd, data, count);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -3696,9 +3664,7 @@ ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
|
|||
scb->cmd.basic_io.sg_count = scb->sg_len;
|
||||
|
||||
if (scb->cmd.basic_io.lba)
|
||||
scb->cmd.basic_io.lba =
|
||||
cpu_to_le32(le32_to_cpu
|
||||
(scb->cmd.basic_io.lba) +
|
||||
le32_add_cpu(&scb->cmd.basic_io.lba,
|
||||
le16_to_cpu(scb->cmd.basic_io.
|
||||
sector_count));
|
||||
else
|
||||
|
@ -3744,9 +3710,7 @@ ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
|
|||
scb->cmd.basic_io.sg_count = scb->sg_len;
|
||||
|
||||
if (scb->cmd.basic_io.lba)
|
||||
scb->cmd.basic_io.lba =
|
||||
cpu_to_le32(le32_to_cpu
|
||||
(scb->cmd.basic_io.lba) +
|
||||
le32_add_cpu(&scb->cmd.basic_io.lba,
|
||||
le16_to_cpu(scb->cmd.basic_io.
|
||||
sector_count));
|
||||
else
|
||||
|
@ -4888,7 +4852,7 @@ ips_init_copperhead(ips_ha_t * ha)
|
|||
return (0);
|
||||
|
||||
/* setup CCCR */
|
||||
outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR);
|
||||
outl(0x1010, ha->io_addr + IPS_REG_CCCR);
|
||||
|
||||
/* Enable busmastering */
|
||||
outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
|
||||
|
@ -5270,12 +5234,12 @@ ips_statinit(ips_ha_t * ha)
|
|||
ha->adapt->p_status_tail = ha->adapt->status;
|
||||
|
||||
phys_status_start = ha->adapt->hw_status_start;
|
||||
outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR);
|
||||
outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE),
|
||||
outl(phys_status_start, ha->io_addr + IPS_REG_SQSR);
|
||||
outl(phys_status_start + IPS_STATUS_Q_SIZE,
|
||||
ha->io_addr + IPS_REG_SQER);
|
||||
outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE),
|
||||
outl(phys_status_start + IPS_STATUS_SIZE,
|
||||
ha->io_addr + IPS_REG_SQHR);
|
||||
outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR);
|
||||
outl(phys_status_start, ha->io_addr + IPS_REG_SQTR);
|
||||
|
||||
ha->adapt->hw_status_tail = phys_status_start;
|
||||
}
|
||||
|
@ -5332,7 +5296,7 @@ ips_statupd_copperhead(ips_ha_t * ha)
|
|||
ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
|
||||
}
|
||||
|
||||
outl(cpu_to_le32(ha->adapt->hw_status_tail),
|
||||
outl(ha->adapt->hw_status_tail,
|
||||
ha->io_addr + IPS_REG_SQTR);
|
||||
|
||||
return (ha->adapt->p_status_tail->value);
|
||||
|
@ -5434,8 +5398,8 @@ ips_issue_copperhead(ips_ha_t * ha, ips_scb_t * scb)
|
|||
} /* end if */
|
||||
} /* end while */
|
||||
|
||||
outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR);
|
||||
outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR);
|
||||
outl(scb->scb_busaddr, ha->io_addr + IPS_REG_CCSAR);
|
||||
outw(IPS_BIT_START_CMD, ha->io_addr + IPS_REG_CCCR);
|
||||
|
||||
return (IPS_SUCCESS);
|
||||
}
|
||||
|
@ -5520,7 +5484,7 @@ ips_issue_i2o(ips_ha_t * ha, ips_scb_t * scb)
|
|||
ips_name, ha->host_num, scb->cmd.basic_io.command_id);
|
||||
}
|
||||
|
||||
outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ);
|
||||
outl(scb->scb_busaddr, ha->io_addr + IPS_REG_I2O_INMSGQ);
|
||||
|
||||
return (IPS_SUCCESS);
|
||||
}
|
||||
|
@ -6412,7 +6376,7 @@ ips_program_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
|
|||
|
||||
for (i = 0; i < buffersize; i++) {
|
||||
/* write a byte */
|
||||
outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
|
||||
outl(i + offset, ha->io_addr + IPS_REG_FLAP);
|
||||
if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
|
||||
udelay(25); /* 25 us */
|
||||
|
||||
|
@ -6597,7 +6561,7 @@ ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
|
|||
if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
|
||||
return (1);
|
||||
|
||||
outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
|
||||
outl(1, ha->io_addr + IPS_REG_FLAP);
|
||||
if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
|
||||
udelay(25); /* 25 us */
|
||||
if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
|
||||
|
@ -6606,7 +6570,7 @@ ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
|
|||
checksum = 0xff;
|
||||
for (i = 2; i < buffersize; i++) {
|
||||
|
||||
outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
|
||||
outl(i + offset, ha->io_addr + IPS_REG_FLAP);
|
||||
if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
|
||||
udelay(25); /* 25 us */
|
||||
|
||||
|
@ -6842,7 +6806,6 @@ ips_register_scsi(int index)
|
|||
sh->sg_tablesize = sh->hostt->sg_tablesize;
|
||||
sh->can_queue = sh->hostt->can_queue;
|
||||
sh->cmd_per_lun = sh->hostt->cmd_per_lun;
|
||||
sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
|
||||
sh->use_clustering = sh->hostt->use_clustering;
|
||||
sh->max_sectors = 128;
|
||||
|
||||
|
|
|
@ -528,6 +528,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||
struct iscsi_session *session = conn->session;
|
||||
struct scsi_cmnd *sc = ctask->sc;
|
||||
int datasn = be32_to_cpu(rhdr->datasn);
|
||||
unsigned total_in_length = scsi_in(sc)->length;
|
||||
|
||||
iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
|
||||
if (tcp_conn->in.datalen == 0)
|
||||
|
@ -542,10 +543,10 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||
tcp_ctask->exp_datasn++;
|
||||
|
||||
tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
|
||||
if (tcp_ctask->data_offset + tcp_conn->in.datalen > scsi_bufflen(sc)) {
|
||||
if (tcp_ctask->data_offset + tcp_conn->in.datalen > total_in_length) {
|
||||
debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n",
|
||||
__FUNCTION__, tcp_ctask->data_offset,
|
||||
tcp_conn->in.datalen, scsi_bufflen(sc));
|
||||
tcp_conn->in.datalen, total_in_length);
|
||||
return ISCSI_ERR_DATA_OFFSET;
|
||||
}
|
||||
|
||||
|
@ -558,8 +559,8 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||
|
||||
if (res_count > 0 &&
|
||||
(rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
|
||||
res_count <= scsi_bufflen(sc)))
|
||||
scsi_set_resid(sc, res_count);
|
||||
res_count <= total_in_length))
|
||||
scsi_in(sc)->resid = res_count;
|
||||
else
|
||||
sc->result = (DID_BAD_TARGET << 16) |
|
||||
rhdr->cmd_status;
|
||||
|
@ -670,11 +671,11 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||
r2t->data_length, session->max_burst);
|
||||
|
||||
r2t->data_offset = be32_to_cpu(rhdr->data_offset);
|
||||
if (r2t->data_offset + r2t->data_length > scsi_bufflen(ctask->sc)) {
|
||||
if (r2t->data_offset + r2t->data_length > scsi_out(ctask->sc)->length) {
|
||||
iscsi_conn_printk(KERN_ERR, conn,
|
||||
"invalid R2T with data len %u at offset %u "
|
||||
"and total length %d\n", r2t->data_length,
|
||||
r2t->data_offset, scsi_bufflen(ctask->sc));
|
||||
r2t->data_offset, scsi_out(ctask->sc)->length);
|
||||
__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
|
||||
sizeof(void*));
|
||||
return ISCSI_ERR_DATALEN;
|
||||
|
@ -771,6 +772,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
|
|||
if (tcp_conn->in.datalen) {
|
||||
struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
|
||||
struct hash_desc *rx_hash = NULL;
|
||||
struct scsi_data_buffer *sdb = scsi_in(ctask->sc);
|
||||
|
||||
/*
|
||||
* Setup copy of Data-In into the Scsi_Cmnd
|
||||
|
@ -788,8 +790,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
|
|||
tcp_ctask->data_offset,
|
||||
tcp_conn->in.datalen);
|
||||
return iscsi_segment_seek_sg(&tcp_conn->in.segment,
|
||||
scsi_sglist(ctask->sc),
|
||||
scsi_sg_count(ctask->sc),
|
||||
sdb->table.sgl,
|
||||
sdb->table.nents,
|
||||
tcp_ctask->data_offset,
|
||||
tcp_conn->in.datalen,
|
||||
iscsi_tcp_process_data_in,
|
||||
|
@ -1332,7 +1334,8 @@ iscsi_tcp_ctask_init(struct iscsi_cmd_task *ctask)
|
|||
return 0;
|
||||
|
||||
/* If we have immediate data, attach a payload */
|
||||
err = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc), scsi_sg_count(sc),
|
||||
err = iscsi_tcp_send_data_prep(conn, scsi_out(sc)->table.sgl,
|
||||
scsi_out(sc)->table.nents,
|
||||
0, ctask->imm_count);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -1386,6 +1389,7 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||
{
|
||||
struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
|
||||
struct scsi_cmnd *sc = ctask->sc;
|
||||
struct scsi_data_buffer *sdb = scsi_out(sc);
|
||||
int rc = 0;
|
||||
|
||||
flush:
|
||||
|
@ -1412,9 +1416,8 @@ flush:
|
|||
ctask->itt, tcp_ctask->sent, ctask->data_count);
|
||||
|
||||
iscsi_tcp_send_hdr_prep(conn, hdr, sizeof(*hdr));
|
||||
rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc),
|
||||
scsi_sg_count(sc),
|
||||
tcp_ctask->sent,
|
||||
rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl,
|
||||
sdb->table.nents, tcp_ctask->sent,
|
||||
ctask->data_count);
|
||||
if (rc)
|
||||
goto fail;
|
||||
|
@ -1460,8 +1463,8 @@ flush:
|
|||
iscsi_tcp_send_hdr_prep(conn, &r2t->dtask.hdr,
|
||||
sizeof(struct iscsi_hdr));
|
||||
|
||||
rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc),
|
||||
scsi_sg_count(sc),
|
||||
rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl,
|
||||
sdb->table.nents,
|
||||
r2t->data_offset + r2t->sent,
|
||||
r2t->data_count);
|
||||
if (rc)
|
||||
|
|
|
@ -137,6 +137,70 @@ static int iscsi_add_hdr(struct iscsi_cmd_task *ctask, unsigned len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* make an extended cdb AHS
|
||||
*/
|
||||
static int iscsi_prep_ecdb_ahs(struct iscsi_cmd_task *ctask)
|
||||
{
|
||||
struct scsi_cmnd *cmd = ctask->sc;
|
||||
unsigned rlen, pad_len;
|
||||
unsigned short ahslength;
|
||||
struct iscsi_ecdb_ahdr *ecdb_ahdr;
|
||||
int rc;
|
||||
|
||||
ecdb_ahdr = iscsi_next_hdr(ctask);
|
||||
rlen = cmd->cmd_len - ISCSI_CDB_SIZE;
|
||||
|
||||
BUG_ON(rlen > sizeof(ecdb_ahdr->ecdb));
|
||||
ahslength = rlen + sizeof(ecdb_ahdr->reserved);
|
||||
|
||||
pad_len = iscsi_padding(rlen);
|
||||
|
||||
rc = iscsi_add_hdr(ctask, sizeof(ecdb_ahdr->ahslength) +
|
||||
sizeof(ecdb_ahdr->ahstype) + ahslength + pad_len);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (pad_len)
|
||||
memset(&ecdb_ahdr->ecdb[rlen], 0, pad_len);
|
||||
|
||||
ecdb_ahdr->ahslength = cpu_to_be16(ahslength);
|
||||
ecdb_ahdr->ahstype = ISCSI_AHSTYPE_CDB;
|
||||
ecdb_ahdr->reserved = 0;
|
||||
memcpy(ecdb_ahdr->ecdb, cmd->cmnd + ISCSI_CDB_SIZE, rlen);
|
||||
|
||||
debug_scsi("iscsi_prep_ecdb_ahs: varlen_cdb_len %d "
|
||||
"rlen %d pad_len %d ahs_length %d iscsi_headers_size %u\n",
|
||||
cmd->cmd_len, rlen, pad_len, ahslength, ctask->hdr_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iscsi_prep_bidi_ahs(struct iscsi_cmd_task *ctask)
|
||||
{
|
||||
struct scsi_cmnd *sc = ctask->sc;
|
||||
struct iscsi_rlength_ahdr *rlen_ahdr;
|
||||
int rc;
|
||||
|
||||
rlen_ahdr = iscsi_next_hdr(ctask);
|
||||
rc = iscsi_add_hdr(ctask, sizeof(*rlen_ahdr));
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rlen_ahdr->ahslength =
|
||||
cpu_to_be16(sizeof(rlen_ahdr->read_length) +
|
||||
sizeof(rlen_ahdr->reserved));
|
||||
rlen_ahdr->ahstype = ISCSI_AHSTYPE_RLENGTH;
|
||||
rlen_ahdr->reserved = 0;
|
||||
rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length);
|
||||
|
||||
debug_scsi("bidi-in rlen_ahdr->read_length(%d) "
|
||||
"rlen_ahdr->ahslength(%d)\n",
|
||||
be32_to_cpu(rlen_ahdr->read_length),
|
||||
be16_to_cpu(rlen_ahdr->ahslength));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu
|
||||
* @ctask: iscsi cmd task
|
||||
|
@ -150,7 +214,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
|
|||
struct iscsi_session *session = conn->session;
|
||||
struct iscsi_cmd *hdr = ctask->hdr;
|
||||
struct scsi_cmnd *sc = ctask->sc;
|
||||
unsigned hdrlength;
|
||||
unsigned hdrlength, cmd_len;
|
||||
int rc;
|
||||
|
||||
ctask->hdr_len = 0;
|
||||
|
@ -161,17 +225,30 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
|
|||
hdr->flags = ISCSI_ATTR_SIMPLE;
|
||||
int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun);
|
||||
hdr->itt = build_itt(ctask->itt, session->age);
|
||||
hdr->data_length = cpu_to_be32(scsi_bufflen(sc));
|
||||
hdr->cmdsn = cpu_to_be32(session->cmdsn);
|
||||
session->cmdsn++;
|
||||
hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
|
||||
memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
|
||||
if (sc->cmd_len < MAX_COMMAND_SIZE)
|
||||
memset(&hdr->cdb[sc->cmd_len], 0,
|
||||
MAX_COMMAND_SIZE - sc->cmd_len);
|
||||
cmd_len = sc->cmd_len;
|
||||
if (cmd_len < ISCSI_CDB_SIZE)
|
||||
memset(&hdr->cdb[cmd_len], 0, ISCSI_CDB_SIZE - cmd_len);
|
||||
else if (cmd_len > ISCSI_CDB_SIZE) {
|
||||
rc = iscsi_prep_ecdb_ahs(ctask);
|
||||
if (rc)
|
||||
return rc;
|
||||
cmd_len = ISCSI_CDB_SIZE;
|
||||
}
|
||||
memcpy(hdr->cdb, sc->cmnd, cmd_len);
|
||||
|
||||
ctask->imm_count = 0;
|
||||
if (scsi_bidi_cmnd(sc)) {
|
||||
hdr->flags |= ISCSI_FLAG_CMD_READ;
|
||||
rc = iscsi_prep_bidi_ahs(ctask);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
if (sc->sc_data_direction == DMA_TO_DEVICE) {
|
||||
unsigned out_len = scsi_out(sc)->length;
|
||||
hdr->data_length = cpu_to_be32(out_len);
|
||||
hdr->flags |= ISCSI_FLAG_CMD_WRITE;
|
||||
/*
|
||||
* Write counters:
|
||||
|
@ -192,19 +269,19 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
|
|||
ctask->unsol_datasn = 0;
|
||||
|
||||
if (session->imm_data_en) {
|
||||
if (scsi_bufflen(sc) >= session->first_burst)
|
||||
if (out_len >= session->first_burst)
|
||||
ctask->imm_count = min(session->first_burst,
|
||||
conn->max_xmit_dlength);
|
||||
else
|
||||
ctask->imm_count = min(scsi_bufflen(sc),
|
||||
ctask->imm_count = min(out_len,
|
||||
conn->max_xmit_dlength);
|
||||
hton24(hdr->dlength, ctask->imm_count);
|
||||
} else
|
||||
zero_data(hdr->dlength);
|
||||
|
||||
if (!session->initial_r2t_en) {
|
||||
ctask->unsol_count = min((session->first_burst),
|
||||
(scsi_bufflen(sc))) - ctask->imm_count;
|
||||
ctask->unsol_count = min(session->first_burst, out_len)
|
||||
- ctask->imm_count;
|
||||
ctask->unsol_offset = ctask->imm_count;
|
||||
}
|
||||
|
||||
|
@ -214,6 +291,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
|
|||
} else {
|
||||
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
|
||||
zero_data(hdr->dlength);
|
||||
hdr->data_length = cpu_to_be32(scsi_in(sc)->length);
|
||||
|
||||
if (sc->sc_data_direction == DMA_FROM_DEVICE)
|
||||
hdr->flags |= ISCSI_FLAG_CMD_READ;
|
||||
|
@ -232,10 +310,12 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
|
|||
return EIO;
|
||||
|
||||
conn->scsicmd_pdus_cnt++;
|
||||
debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d "
|
||||
"cmdsn %d win %d]\n",
|
||||
sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
|
||||
conn->id, sc, sc->cmnd[0], ctask->itt, scsi_bufflen(sc),
|
||||
debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x "
|
||||
"len %d bidi_len %d cmdsn %d win %d]\n",
|
||||
scsi_bidi_cmnd(sc) ? "bidirectional" :
|
||||
sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
|
||||
conn->id, sc, sc->cmnd[0], ctask->itt,
|
||||
scsi_bufflen(sc), scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0,
|
||||
session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
|
||||
return 0;
|
||||
}
|
||||
|
@ -298,7 +378,12 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
|
|||
conn->session->tt->cleanup_cmd_task(conn, ctask);
|
||||
|
||||
sc->result = err;
|
||||
scsi_set_resid(sc, scsi_bufflen(sc));
|
||||
if (!scsi_bidi_cmnd(sc))
|
||||
scsi_set_resid(sc, scsi_bufflen(sc));
|
||||
else {
|
||||
scsi_out(sc)->resid = scsi_out(sc)->length;
|
||||
scsi_in(sc)->resid = scsi_in(sc)->length;
|
||||
}
|
||||
if (conn->ctask == ctask)
|
||||
conn->ctask = NULL;
|
||||
/* release ref from queuecommand */
|
||||
|
@ -433,6 +518,18 @@ invalid_datalen:
|
|||
min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE));
|
||||
}
|
||||
|
||||
if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
|
||||
ISCSI_FLAG_CMD_BIDI_OVERFLOW)) {
|
||||
int res_count = be32_to_cpu(rhdr->bi_residual_count);
|
||||
|
||||
if (scsi_bidi_cmnd(sc) && res_count > 0 &&
|
||||
(rhdr->flags & ISCSI_FLAG_CMD_BIDI_OVERFLOW ||
|
||||
res_count <= scsi_in(sc)->length))
|
||||
scsi_in(sc)->resid = res_count;
|
||||
else
|
||||
sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
|
||||
}
|
||||
|
||||
if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW |
|
||||
ISCSI_FLAG_CMD_OVERFLOW)) {
|
||||
int res_count = be32_to_cpu(rhdr->residual_count);
|
||||
|
@ -440,13 +537,11 @@ invalid_datalen:
|
|||
if (res_count > 0 &&
|
||||
(rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
|
||||
res_count <= scsi_bufflen(sc)))
|
||||
/* write side for bidi or uni-io set_resid */
|
||||
scsi_set_resid(sc, res_count);
|
||||
else
|
||||
sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
|
||||
} else if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
|
||||
ISCSI_FLAG_CMD_BIDI_OVERFLOW))
|
||||
sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
|
||||
|
||||
}
|
||||
out:
|
||||
debug_scsi("done [sc %lx res %d itt 0x%x]\n",
|
||||
(long)sc, sc->result, ctask->itt);
|
||||
|
@ -1102,7 +1197,12 @@ reject:
|
|||
fault:
|
||||
spin_unlock(&session->lock);
|
||||
debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason);
|
||||
scsi_set_resid(sc, scsi_bufflen(sc));
|
||||
if (!scsi_bidi_cmnd(sc))
|
||||
scsi_set_resid(sc, scsi_bufflen(sc));
|
||||
else {
|
||||
scsi_out(sc)->resid = scsi_out(sc)->length;
|
||||
scsi_in(sc)->resid = scsi_in(sc)->length;
|
||||
}
|
||||
sc->scsi_done(sc);
|
||||
spin_lock(host->host_lock);
|
||||
return 0;
|
||||
|
|
|
@ -691,7 +691,7 @@ static int sas_discover_sata_dev(struct domain_device *dev)
|
|||
/* incomplete response */
|
||||
SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to "
|
||||
"dev %llx\n", SAS_ADDR(dev->sas_addr));
|
||||
if (!le16_to_cpu(identify_x[83] & (1<<6)))
|
||||
if (!(identify_x[83] & cpu_to_le16(1<<6)))
|
||||
goto cont1;
|
||||
res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES,
|
||||
ATA_FEATURE_PUP_STBY_SPIN_UP,
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
*/
|
||||
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#include "sas_internal.h"
|
||||
|
||||
|
@ -1064,6 +1066,45 @@ void sas_target_destroy(struct scsi_target *starget)
|
|||
return;
|
||||
}
|
||||
|
||||
static void sas_parse_addr(u8 *sas_addr, const char *p)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SAS_ADDR_SIZE; i++) {
|
||||
u8 h, l;
|
||||
if (!*p)
|
||||
break;
|
||||
h = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10;
|
||||
p++;
|
||||
l = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10;
|
||||
p++;
|
||||
sas_addr[i] = (h<<4) | l;
|
||||
}
|
||||
}
|
||||
|
||||
#define SAS_STRING_ADDR_SIZE 16
|
||||
|
||||
int sas_request_addr(struct Scsi_Host *shost, u8 *addr)
|
||||
{
|
||||
int res;
|
||||
const struct firmware *fw;
|
||||
|
||||
res = request_firmware(&fw, "sas_addr", &shost->shost_gendev);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
if (fw->size < SAS_STRING_ADDR_SIZE) {
|
||||
res = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sas_parse_addr(addr, fw->data);
|
||||
|
||||
out:
|
||||
release_firmware(fw);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sas_request_addr);
|
||||
|
||||
EXPORT_SYMBOL_GPL(sas_queuecommand);
|
||||
EXPORT_SYMBOL_GPL(sas_target_alloc);
|
||||
EXPORT_SYMBOL_GPL(sas_slave_configure);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
struct lpfc_sli2_slim;
|
||||
|
||||
#define LPFC_MAX_TARGET 256 /* max number of targets supported */
|
||||
#define LPFC_MAX_TARGET 4096 /* max number of targets supported */
|
||||
#define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els
|
||||
requests */
|
||||
#define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact
|
||||
|
@ -268,7 +268,6 @@ struct lpfc_vport {
|
|||
#define FC_NLP_MORE 0x40 /* More node to process in node tbl */
|
||||
#define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */
|
||||
#define FC_FABRIC 0x100 /* We are fabric attached */
|
||||
#define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */
|
||||
#define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */
|
||||
#define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */
|
||||
#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */
|
||||
|
@ -433,8 +432,6 @@ struct lpfc_hba {
|
|||
|
||||
uint32_t fc_eventTag; /* event tag for link attention */
|
||||
|
||||
|
||||
struct timer_list fc_estabtmo; /* link establishment timer */
|
||||
/* These fields used to be binfo */
|
||||
uint32_t fc_pref_DID; /* preferred D_ID */
|
||||
uint8_t fc_pref_ALPA; /* preferred AL_PA */
|
||||
|
|
|
@ -1954,7 +1954,9 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
|
|||
(phba->sysfs_mbox.mbox->mb.mbxCommand !=
|
||||
MBX_DUMP_MEMORY &&
|
||||
phba->sysfs_mbox.mbox->mb.mbxCommand !=
|
||||
MBX_RESTART)) {
|
||||
MBX_RESTART &&
|
||||
phba->sysfs_mbox.mbox->mb.mbxCommand !=
|
||||
MBX_WRITE_VPARMS)) {
|
||||
sysfs_mbox_idle(phba);
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
return -EPERM;
|
||||
|
@ -1962,7 +1964,11 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
|
|||
|
||||
phba->sysfs_mbox.mbox->vport = vport;
|
||||
|
||||
if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
|
||||
/* Don't allow mailbox commands to be sent when blocked
|
||||
* or when in the middle of discovery
|
||||
*/
|
||||
if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO ||
|
||||
vport->fc_flag & FC_NDISC_ACTIVE) {
|
||||
sysfs_mbox_idle(phba);
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
return -EAGAIN;
|
||||
|
|
|
@ -63,7 +63,7 @@ lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
|
|||
{
|
||||
if (!mp) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||
"0146 Ignoring unsolicted CT No HBQ "
|
||||
"0146 Ignoring unsolicited CT No HBQ "
|
||||
"status = x%x\n",
|
||||
piocbq->iocb.ulpStatus);
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
|
|||
(!(vport->ct_flags & FC_CT_RFF_ID)) ||
|
||||
(!vport->cfg_restrict_login)) {
|
||||
ndlp = lpfc_setup_disc_node(vport, Did);
|
||||
if (ndlp) {
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
|
||||
lpfc_debugfs_disc_trc(vport,
|
||||
LPFC_DISC_TRC_CT,
|
||||
"Parse GID_FTrsp: "
|
||||
|
@ -543,7 +543,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
struct lpfc_dmabuf *outp;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
int rc, retry;
|
||||
int rc;
|
||||
|
||||
/* First save ndlp, before we overwrite it */
|
||||
ndlp = cmdiocb->context_un.ndlp;
|
||||
|
@ -563,45 +563,29 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
if (vport->load_flag & FC_UNLOADING)
|
||||
goto out;
|
||||
|
||||
if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) {
|
||||
if (lpfc_els_chk_latt(vport)) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||
"0216 Link event during NS query\n");
|
||||
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (lpfc_error_lost_link(irsp)) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||
"0226 NS query failed due to link event\n");
|
||||
goto out;
|
||||
}
|
||||
if (irsp->ulpStatus) {
|
||||
/* Check for retry */
|
||||
if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
|
||||
retry = 1;
|
||||
if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
|
||||
switch (irsp->un.ulpWord[4]) {
|
||||
case IOERR_NO_RESOURCES:
|
||||
/* We don't increment the retry
|
||||
* count for this case.
|
||||
*/
|
||||
break;
|
||||
case IOERR_LINK_DOWN:
|
||||
case IOERR_SLI_ABORTED:
|
||||
case IOERR_SLI_DOWN:
|
||||
retry = 0;
|
||||
break;
|
||||
default:
|
||||
vport->fc_ns_retry++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
|
||||
irsp->un.ulpWord[4] != IOERR_NO_RESOURCES)
|
||||
vport->fc_ns_retry++;
|
||||
|
||||
if (retry) {
|
||||
/* CT command is being retried */
|
||||
rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
|
||||
/* CT command is being retried */
|
||||
rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
|
||||
vport->fc_ns_retry, 0);
|
||||
if (rc == 0) {
|
||||
/* success */
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (rc == 0)
|
||||
goto out;
|
||||
}
|
||||
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
|
||||
|
@ -780,7 +764,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
|
||||
/* This is a target port, unregistered port, or the GFF_ID failed */
|
||||
ndlp = lpfc_setup_disc_node(vport, did);
|
||||
if (ndlp) {
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||
"0242 Process x%x GFF "
|
||||
"NameServer Rsp Data: x%x x%x x%x\n",
|
||||
|
|
|
@ -503,6 +503,8 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
|
|||
ndlp->nlp_sid);
|
||||
if (ndlp->nlp_type & NLP_FCP_INITIATOR)
|
||||
len += snprintf(buf+len, size-len, "FCP_INITIATOR ");
|
||||
len += snprintf(buf+len, size-len, "usgmap:%x ",
|
||||
ndlp->nlp_usg_map);
|
||||
len += snprintf(buf+len, size-len, "refcnt:%x",
|
||||
atomic_read(&ndlp->kref.refcount));
|
||||
len += snprintf(buf+len, size-len, "\n");
|
||||
|
|
|
@ -719,9 +719,9 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
|
|||
if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
|
||||
icmd->un.elsreq64.bdl.ulpIoTag32) {
|
||||
ndlp = (struct lpfc_nodelist *)(iocb->context1);
|
||||
if (ndlp && (ndlp->nlp_DID == Fabric_DID)) {
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
|
||||
(ndlp->nlp_DID == Fabric_DID))
|
||||
lpfc_sli_issue_abort_iotag(phba, pring, iocb);
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
@ -829,7 +829,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
|
|||
struct fc_rport *rport;
|
||||
struct serv_parm *sp;
|
||||
uint8_t name[sizeof(struct lpfc_name)];
|
||||
uint32_t rc;
|
||||
uint32_t rc, keepDID = 0;
|
||||
|
||||
/* Fabric nodes can have the same WWPN so we don't bother searching
|
||||
* by WWPN. Just return the ndlp that was given to us.
|
||||
|
@ -858,11 +858,17 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
|
|||
return ndlp;
|
||||
lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
|
||||
} else if (!NLP_CHK_NODE_ACT(new_ndlp)) {
|
||||
rc = memcmp(&ndlp->nlp_portname, name,
|
||||
sizeof(struct lpfc_name));
|
||||
if (!rc)
|
||||
return ndlp;
|
||||
new_ndlp = lpfc_enable_node(vport, new_ndlp,
|
||||
NLP_STE_UNUSED_NODE);
|
||||
if (!new_ndlp)
|
||||
return ndlp;
|
||||
}
|
||||
keepDID = new_ndlp->nlp_DID;
|
||||
} else
|
||||
keepDID = new_ndlp->nlp_DID;
|
||||
|
||||
lpfc_unreg_rpi(vport, new_ndlp);
|
||||
new_ndlp->nlp_DID = ndlp->nlp_DID;
|
||||
|
@ -893,12 +899,24 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
|
|||
}
|
||||
new_ndlp->nlp_type = ndlp->nlp_type;
|
||||
}
|
||||
/* We shall actually free the ndlp with both nlp_DID and
|
||||
* nlp_portname fields equals 0 to avoid any ndlp on the
|
||||
* nodelist never to be used.
|
||||
*/
|
||||
if (ndlp->nlp_DID == 0) {
|
||||
spin_lock_irq(&phba->ndlp_lock);
|
||||
NLP_SET_FREE_REQ(ndlp);
|
||||
spin_unlock_irq(&phba->ndlp_lock);
|
||||
}
|
||||
|
||||
/* Two ndlps cannot have the same did on the nodelist */
|
||||
ndlp->nlp_DID = keepDID;
|
||||
lpfc_drop_node(vport, ndlp);
|
||||
}
|
||||
else {
|
||||
lpfc_unreg_rpi(vport, ndlp);
|
||||
ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
|
||||
/* Two ndlps cannot have the same did */
|
||||
ndlp->nlp_DID = keepDID;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
||||
}
|
||||
return new_ndlp;
|
||||
|
@ -2091,7 +2109,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
}
|
||||
|
||||
phba->fc_stat.elsXmitRetry++;
|
||||
if (ndlp && delay) {
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp) && delay) {
|
||||
phba->fc_stat.elsDelayRetry++;
|
||||
ndlp->nlp_retry = cmdiocb->retry;
|
||||
|
||||
|
@ -2121,7 +2139,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry);
|
||||
return 1;
|
||||
case ELS_CMD_PLOGI:
|
||||
if (ndlp) {
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
|
||||
ndlp->nlp_prev_state = ndlp->nlp_state;
|
||||
lpfc_nlp_set_state(vport, ndlp,
|
||||
NLP_STE_PLOGI_ISSUE);
|
||||
|
@ -2302,7 +2320,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
mempool_free(pmb, phba->mbox_mem_pool);
|
||||
if (ndlp) {
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
|
||||
lpfc_nlp_put(ndlp);
|
||||
/* This is the end of the default RPI cleanup logic for this
|
||||
* ndlp. If no other discovery threads are using this ndlp.
|
||||
|
@ -2335,7 +2353,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
* function can have cmdiocb->contest1 (ndlp) field set to NULL.
|
||||
*/
|
||||
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
|
||||
if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
|
||||
(*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
|
||||
/* A LS_RJT associated with Default RPI cleanup has its own
|
||||
* seperate code path.
|
||||
*/
|
||||
|
@ -2344,7 +2363,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
}
|
||||
|
||||
/* Check to see if link went down during discovery */
|
||||
if (!ndlp || lpfc_els_chk_latt(vport)) {
|
||||
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || lpfc_els_chk_latt(vport)) {
|
||||
if (mbox) {
|
||||
mp = (struct lpfc_dmabuf *) mbox->context1;
|
||||
if (mp) {
|
||||
|
@ -2353,7 +2372,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
}
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
}
|
||||
if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
|
||||
(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
|
||||
if (lpfc_nlp_not_used(ndlp)) {
|
||||
ndlp = NULL;
|
||||
/* Indicate the node has already released,
|
||||
|
@ -2443,7 +2463,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
}
|
||||
out:
|
||||
if (ndlp) {
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
|
||||
spin_lock_irq(shost->host_lock);
|
||||
ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI);
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
@ -3139,6 +3159,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
/* Another thread is walking fc_rscn_id_list on this vport */
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
vport->fc_flag |= FC_RSCN_DISCOVERY;
|
||||
/* Send back ACC */
|
||||
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
|
||||
return 0;
|
||||
}
|
||||
/* Indicate we are walking fc_rscn_id_list on this vport */
|
||||
|
@ -3928,7 +3950,7 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
|
|||
else {
|
||||
struct lpfc_nodelist *ndlp;
|
||||
ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext);
|
||||
if (ndlp)
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp))
|
||||
remote_ID = ndlp->nlp_DID;
|
||||
}
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
|
||||
|
@ -4097,21 +4119,22 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|||
newnode = 1;
|
||||
if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
|
||||
ndlp->nlp_type |= NLP_FABRIC;
|
||||
} else {
|
||||
if (!NLP_CHK_NODE_ACT(ndlp)) {
|
||||
ndlp = lpfc_enable_node(vport, ndlp,
|
||||
NLP_STE_UNUSED_NODE);
|
||||
if (!ndlp)
|
||||
goto dropit;
|
||||
}
|
||||
if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
|
||||
/* This is simular to the new node path */
|
||||
ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!ndlp)
|
||||
goto dropit;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
||||
newnode = 1;
|
||||
}
|
||||
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
||||
ndlp = lpfc_enable_node(vport, ndlp,
|
||||
NLP_STE_UNUSED_NODE);
|
||||
if (!ndlp)
|
||||
goto dropit;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
||||
newnode = 1;
|
||||
if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
|
||||
ndlp->nlp_type |= NLP_FABRIC;
|
||||
} else if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
|
||||
/* This is similar to the new node path */
|
||||
ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!ndlp)
|
||||
goto dropit;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
||||
newnode = 1;
|
||||
}
|
||||
|
||||
phba->fc_stat.elsRcvFrame++;
|
||||
|
@ -4451,7 +4474,6 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
|
|||
return;
|
||||
}
|
||||
lpfc_nlp_init(vport, ndlp, NameServer_DID);
|
||||
ndlp->nlp_type |= NLP_FABRIC;
|
||||
} else if (!NLP_CHK_NODE_ACT(ndlp)) {
|
||||
ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
|
||||
if (!ndlp) {
|
||||
|
@ -4465,6 +4487,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
|
|||
return;
|
||||
}
|
||||
}
|
||||
ndlp->nlp_type |= NLP_FABRIC;
|
||||
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
|
||||
|
||||
|
@ -4481,8 +4504,8 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
|
|||
if (ndlp_fdmi) {
|
||||
lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
|
||||
ndlp_fdmi->nlp_type |= NLP_FABRIC;
|
||||
ndlp_fdmi->nlp_state =
|
||||
NLP_STE_PLOGI_ISSUE;
|
||||
lpfc_nlp_set_state(vport, ndlp_fdmi,
|
||||
NLP_STE_PLOGI_ISSUE);
|
||||
lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID,
|
||||
0);
|
||||
}
|
||||
|
@ -5074,39 +5097,3 @@ void lpfc_fabric_abort_hba(struct lpfc_hba *phba)
|
|||
(piocb->iocb_cmpl) (phba, piocb, piocb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void lpfc_fabric_abort_flogi(struct lpfc_hba *phba)
|
||||
{
|
||||
LIST_HEAD(completions);
|
||||
struct lpfc_iocbq *tmp_iocb, *piocb;
|
||||
IOCB_t *cmd;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
|
||||
list) {
|
||||
|
||||
cmd = &piocb->iocb;
|
||||
ndlp = (struct lpfc_nodelist *) piocb->context1;
|
||||
if (cmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
|
||||
ndlp != NULL &&
|
||||
ndlp->nlp_DID == Fabric_DID)
|
||||
list_move_tail(&piocb->list, &completions);
|
||||
}
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
||||
while (!list_empty(&completions)) {
|
||||
piocb = list_get_first(&completions, struct lpfc_iocbq, list);
|
||||
list_del_init(&piocb->list);
|
||||
|
||||
cmd = &piocb->iocb;
|
||||
cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
|
||||
cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
|
||||
(piocb->iocb_cmpl) (phba, piocb, piocb);
|
||||
}
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ lpfc_terminate_rport_io(struct fc_rport *rport)
|
|||
rdata = rport->dd_data;
|
||||
ndlp = rdata->pnode;
|
||||
|
||||
if (!ndlp) {
|
||||
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
|
||||
if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
|
||||
printk(KERN_ERR "Cannot find remote node"
|
||||
" to terminate I/O Data x%x\n",
|
||||
|
@ -114,7 +114,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
|
|||
|
||||
rdata = rport->dd_data;
|
||||
ndlp = rdata->pnode;
|
||||
if (!ndlp)
|
||||
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
|
||||
return;
|
||||
|
||||
vport = ndlp->vport;
|
||||
|
@ -243,8 +243,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
|
|||
if (warn_on) {
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
|
||||
"0203 Devloss timeout on "
|
||||
"WWPN %x:%x:%x:%x:%x:%x:%x:%x "
|
||||
"NPort x%x Data: x%x x%x x%x\n",
|
||||
"WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
|
||||
"NPort x%06x Data: x%x x%x x%x\n",
|
||||
*name, *(name+1), *(name+2), *(name+3),
|
||||
*(name+4), *(name+5), *(name+6), *(name+7),
|
||||
ndlp->nlp_DID, ndlp->nlp_flag,
|
||||
|
@ -252,8 +252,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
|
|||
} else {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||
"0204 Devloss timeout on "
|
||||
"WWPN %x:%x:%x:%x:%x:%x:%x:%x "
|
||||
"NPort x%x Data: x%x x%x x%x\n",
|
||||
"WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
|
||||
"NPort x%06x Data: x%x x%x x%x\n",
|
||||
*name, *(name+1), *(name+2), *(name+3),
|
||||
*(name+4), *(name+5), *(name+6), *(name+7),
|
||||
ndlp->nlp_DID, ndlp->nlp_flag,
|
||||
|
@ -399,7 +399,10 @@ lpfc_work_done(struct lpfc_hba *phba)
|
|||
vport = vports[i];
|
||||
if (vport == NULL)
|
||||
break;
|
||||
spin_lock_irq(&vport->work_port_lock);
|
||||
work_port_events = vport->work_port_events;
|
||||
vport->work_port_events &= ~work_port_events;
|
||||
spin_unlock_irq(&vport->work_port_lock);
|
||||
if (work_port_events & WORKER_DISC_TMO)
|
||||
lpfc_disc_timeout_handler(vport);
|
||||
if (work_port_events & WORKER_ELS_TMO)
|
||||
|
@ -416,9 +419,6 @@ lpfc_work_done(struct lpfc_hba *phba)
|
|||
lpfc_ramp_down_queue_handler(phba);
|
||||
if (work_port_events & WORKER_RAMP_UP_QUEUE)
|
||||
lpfc_ramp_up_queue_handler(phba);
|
||||
spin_lock_irq(&vport->work_port_lock);
|
||||
vport->work_port_events &= ~work_port_events;
|
||||
spin_unlock_irq(&vport->work_port_lock);
|
||||
}
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
|
||||
|
@ -430,10 +430,10 @@ lpfc_work_done(struct lpfc_hba *phba)
|
|||
if (pring->flag & LPFC_STOP_IOCB_EVENT) {
|
||||
pring->flag |= LPFC_DEFERRED_RING_EVENT;
|
||||
} else {
|
||||
pring->flag &= ~LPFC_DEFERRED_RING_EVENT;
|
||||
lpfc_sli_handle_slow_ring_event(phba, pring,
|
||||
(status &
|
||||
HA_RXMASK));
|
||||
pring->flag &= ~LPFC_DEFERRED_RING_EVENT;
|
||||
}
|
||||
/*
|
||||
* Turn on Ring interrupts
|
||||
|
@ -519,7 +519,9 @@ lpfc_do_work(void *p)
|
|||
schedule();
|
||||
}
|
||||
}
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
phba->work_wait = NULL;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -809,11 +811,9 @@ out:
|
|||
mempool_free(pmb, phba->mbox_mem_pool);
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK);
|
||||
vport->fc_flag &= ~FC_ABORT_DISCOVERY;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
del_timer_sync(&phba->fc_estabtmo);
|
||||
|
||||
lpfc_can_disctmo(vport);
|
||||
|
||||
/* turn on Link Attention interrupts */
|
||||
|
@ -1340,10 +1340,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
i++) {
|
||||
if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
|
||||
continue;
|
||||
if (phba->fc_topology == TOPOLOGY_LOOP) {
|
||||
lpfc_vport_set_state(vports[i],
|
||||
FC_VPORT_LINKDOWN);
|
||||
continue;
|
||||
}
|
||||
if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
|
||||
lpfc_initial_fdisc(vports[i]);
|
||||
else if (phba->sli3_options &
|
||||
LPFC_SLI3_NPIV_ENABLED) {
|
||||
else {
|
||||
lpfc_vport_set_state(vports[i],
|
||||
FC_VPORT_NO_FABRIC_SUPP);
|
||||
lpfc_printf_vlog(vport, KERN_ERR,
|
||||
|
@ -2190,10 +2194,6 @@ lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
if (did == Bcast_DID)
|
||||
return 0;
|
||||
|
||||
if (ndlp->nlp_DID == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* First check for Direct match */
|
||||
if (ndlp->nlp_DID == did)
|
||||
return 1;
|
||||
|
@ -2301,7 +2301,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
|
|||
return ndlp;
|
||||
}
|
||||
|
||||
if (vport->fc_flag & FC_RSCN_MODE) {
|
||||
if ((vport->fc_flag & FC_RSCN_MODE) &&
|
||||
!(vport->fc_flag & FC_NDISC_ACTIVE)) {
|
||||
if (lpfc_rscn_payload_check(vport, did)) {
|
||||
/* If we've already recieved a PLOGI from this NPort
|
||||
* we don't need to try to discover it again.
|
||||
|
@ -2947,24 +2948,6 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Search node lists for a remote port matching filter criteria
|
||||
* Caller needs to hold host_lock before calling this routine.
|
||||
*/
|
||||
struct lpfc_nodelist *
|
||||
lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
|
||||
{
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
struct lpfc_nodelist *ndlp;
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
ndlp = __lpfc_find_node(vport, filter, param);
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
return ndlp;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/*
|
||||
* This routine looks up the ndlp lists for the given RPI. If rpi found it
|
||||
* returns the node list element pointer else return NULL.
|
||||
|
@ -2975,20 +2958,6 @@ __lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
|
|||
return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi);
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct lpfc_nodelist *
|
||||
lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
|
||||
{
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
struct lpfc_nodelist *ndlp;
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
ndlp = __lpfc_findnode_rpi(vport, rpi);
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
return ndlp;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/*
|
||||
* This routine looks up the ndlp lists for the given WWPN. If WWPN found it
|
||||
* returns the node element list pointer else return NULL.
|
||||
|
|
|
@ -559,8 +559,10 @@ lpfc_hb_timeout(unsigned long ptr)
|
|||
phba->pport->work_port_events |= WORKER_HB_TMO;
|
||||
spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);
|
||||
|
||||
spin_lock_irqsave(&phba->hbalock, iflag);
|
||||
if (phba->work_wait)
|
||||
wake_up(phba->work_wait);
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflag);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -714,12 +716,10 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
|
|||
struct lpfc_vport *vport = phba->pport;
|
||||
struct lpfc_sli *psli = &phba->sli;
|
||||
struct lpfc_sli_ring *pring;
|
||||
struct lpfc_vport **vports;
|
||||
uint32_t event_data;
|
||||
unsigned long temperature;
|
||||
struct temp_event temp_event_data;
|
||||
struct Scsi_Host *shost;
|
||||
int i;
|
||||
|
||||
/* If the pci channel is offline, ignore possible errors,
|
||||
* since we cannot communicate with the pci card anyway. */
|
||||
|
@ -729,25 +729,14 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
|
|||
if (!phba->cfg_enable_hba_reset)
|
||||
return;
|
||||
|
||||
if (phba->work_hs & HS_FFER6 ||
|
||||
phba->work_hs & HS_FFER5) {
|
||||
if (phba->work_hs & HS_FFER6) {
|
||||
/* Re-establishing Link */
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
|
||||
"1301 Re-establishing Link "
|
||||
"Data: x%x x%x x%x\n",
|
||||
phba->work_hs,
|
||||
phba->work_status[0], phba->work_status[1]);
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0;
|
||||
i <= phba->max_vpi && vports[i] != NULL;
|
||||
i++){
|
||||
shost = lpfc_shost_from_vport(vports[i]);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vports[i]->fc_flag |= FC_ESTABLISH_LINK;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
@ -761,7 +750,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
|
|||
pring = &psli->ring[psli->fcp_ring];
|
||||
lpfc_sli_abort_iocb_ring(phba, pring);
|
||||
|
||||
|
||||
/*
|
||||
* There was a firmware error. Take the hba offline and then
|
||||
* attempt to restart it.
|
||||
|
@ -770,7 +758,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
|
|||
lpfc_offline(phba);
|
||||
lpfc_sli_brdrestart(phba);
|
||||
if (lpfc_online(phba) == 0) { /* Initialize the HBA */
|
||||
mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
|
||||
lpfc_unblock_mgmt_io(phba);
|
||||
return;
|
||||
}
|
||||
|
@ -1454,6 +1441,13 @@ lpfc_cleanup(struct lpfc_vport *vport)
|
|||
NLP_SET_FREE_REQ(ndlp);
|
||||
spin_unlock_irq(&phba->ndlp_lock);
|
||||
|
||||
if (vport->port_type != LPFC_PHYSICAL_PORT &&
|
||||
ndlp->nlp_DID == Fabric_DID) {
|
||||
/* Just free up ndlp with Fabric_DID for vports */
|
||||
lpfc_nlp_put(ndlp);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ndlp->nlp_type & NLP_FABRIC)
|
||||
lpfc_disc_state_machine(vport, ndlp, NULL,
|
||||
NLP_EVT_DEVICE_RECOVERY);
|
||||
|
@ -1491,31 +1485,6 @@ lpfc_cleanup(struct lpfc_vport *vport)
|
|||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_establish_link_tmo(unsigned long ptr)
|
||||
{
|
||||
struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
|
||||
struct lpfc_vport **vports;
|
||||
unsigned long iflag;
|
||||
int i;
|
||||
|
||||
/* Re-establishing Link, timer expired */
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
|
||||
"1300 Re-establishing Link, timer expired "
|
||||
"Data: x%x x%x\n",
|
||||
phba->pport->fc_flag, phba->pport->port_state);
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
||||
struct Scsi_Host *shost;
|
||||
shost = lpfc_shost_from_vport(vports[i]);
|
||||
spin_lock_irqsave(shost->host_lock, iflag);
|
||||
vports[i]->fc_flag &= ~FC_ESTABLISH_LINK;
|
||||
spin_unlock_irqrestore(shost->host_lock, iflag);
|
||||
}
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_stop_vport_timers(struct lpfc_vport *vport)
|
||||
{
|
||||
|
@ -1529,7 +1498,6 @@ static void
|
|||
lpfc_stop_phba_timers(struct lpfc_hba *phba)
|
||||
{
|
||||
del_timer_sync(&phba->fcp_poll_timer);
|
||||
del_timer_sync(&phba->fc_estabtmo);
|
||||
lpfc_stop_vport_timers(phba->pport);
|
||||
del_timer_sync(&phba->sli.mbox_tmo);
|
||||
del_timer_sync(&phba->fabric_block_timer);
|
||||
|
@ -2005,10 +1973,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
|
|||
phba->max_vpi = LPFC_MAX_VPI;
|
||||
|
||||
/* Initialize timers used by driver */
|
||||
init_timer(&phba->fc_estabtmo);
|
||||
phba->fc_estabtmo.function = lpfc_establish_link_tmo;
|
||||
phba->fc_estabtmo.data = (unsigned long)phba;
|
||||
|
||||
init_timer(&phba->hb_tmofunc);
|
||||
phba->hb_tmofunc.function = lpfc_hb_timeout;
|
||||
phba->hb_tmofunc.data = (unsigned long)phba;
|
||||
|
@ -2406,6 +2370,7 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
|
|||
struct Scsi_Host *shost = pci_get_drvdata(pdev);
|
||||
struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
|
||||
struct lpfc_sli *psli = &phba->sli;
|
||||
int error, retval;
|
||||
|
||||
dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n");
|
||||
if (pci_enable_device_mem(pdev)) {
|
||||
|
@ -2416,15 +2381,40 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
|
|||
|
||||
pci_set_master(pdev);
|
||||
|
||||
/* Re-establishing Link */
|
||||
spin_lock_irq(shost->host_lock);
|
||||
phba->pport->fc_flag |= FC_ESTABLISH_LINK;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
||||
/* Enable configured interrupt method */
|
||||
phba->intr_type = NONE;
|
||||
if (phba->cfg_use_msi == 2) {
|
||||
error = lpfc_enable_msix(phba);
|
||||
if (!error)
|
||||
phba->intr_type = MSIX;
|
||||
}
|
||||
|
||||
/* Fallback to MSI if MSI-X initialization failed */
|
||||
if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) {
|
||||
retval = pci_enable_msi(phba->pcidev);
|
||||
if (!retval)
|
||||
phba->intr_type = MSI;
|
||||
else
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
"0470 Enable MSI failed, continuing "
|
||||
"with IRQ\n");
|
||||
}
|
||||
|
||||
/* MSI-X is the only case the doesn't need to call request_irq */
|
||||
if (phba->intr_type != MSIX) {
|
||||
retval = request_irq(phba->pcidev->irq, lpfc_intr_handler,
|
||||
IRQF_SHARED, LPFC_DRIVER_NAME, phba);
|
||||
if (retval) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"0471 Enable interrupt handler "
|
||||
"failed\n");
|
||||
} else if (phba->intr_type != MSI)
|
||||
phba->intr_type = INTx;
|
||||
}
|
||||
|
||||
/* Take device offline; this will perform cleanup */
|
||||
lpfc_offline(phba);
|
||||
|
@ -2445,9 +2435,7 @@ static void lpfc_io_resume(struct pci_dev *pdev)
|
|||
struct Scsi_Host *shost = pci_get_drvdata(pdev);
|
||||
struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
|
||||
|
||||
if (lpfc_online(phba) == 0) {
|
||||
mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
|
||||
}
|
||||
lpfc_online(phba);
|
||||
}
|
||||
|
||||
static struct pci_device_id lpfc_id_table[] = {
|
||||
|
|
|
@ -451,7 +451,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
if ((ndlp->nlp_flag & NLP_ADISC_SND) &&
|
||||
(vport->num_disc_nodes)) {
|
||||
(vport->num_disc_nodes)) {
|
||||
/* Check to see if there are more
|
||||
* ADISCs to be sent
|
||||
*/
|
||||
|
@ -469,20 +469,23 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
lpfc_end_rscn(vport);
|
||||
}
|
||||
}
|
||||
else if (vport->num_disc_nodes) {
|
||||
/* Check to see if there are more
|
||||
* PLOGIs to be sent
|
||||
*/
|
||||
lpfc_more_plogi(vport);
|
||||
|
||||
if (vport->num_disc_nodes == 0) {
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
lpfc_can_disctmo(vport);
|
||||
lpfc_end_rscn(vport);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) &&
|
||||
(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
|
||||
(vport->num_disc_nodes)) {
|
||||
spin_lock_irq(shost->host_lock);
|
||||
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
/* Check to see if there are more
|
||||
* PLOGIs to be sent
|
||||
*/
|
||||
lpfc_more_plogi(vport);
|
||||
if (vport->num_disc_nodes == 0) {
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
lpfc_can_disctmo(vport);
|
||||
lpfc_end_rscn(vport);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -869,8 +872,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
|
|||
|
||||
lp = (uint32_t *) prsp->virt;
|
||||
sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
|
||||
if (wwn_to_u64(sp->portName.u.wwn) == 0 ||
|
||||
wwn_to_u64(sp->nodeName.u.wwn) == 0) {
|
||||
|
||||
/* Some switches have FDMI servers returning 0 for WWN */
|
||||
if ((ndlp->nlp_DID != FDMI_DID) &&
|
||||
(wwn_to_u64(sp->portName.u.wwn) == 0 ||
|
||||
wwn_to_u64(sp->nodeName.u.wwn) == 0)) {
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
|
||||
"0142 PLOGI RSP: Invalid WWN.\n");
|
||||
goto out;
|
||||
|
|
|
@ -169,6 +169,9 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
|
|||
for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
||||
shost = lpfc_shost_from_vport(vports[i]);
|
||||
shost_for_each_device(sdev, shost) {
|
||||
if (vports[i]->cfg_lun_queue_depth <=
|
||||
sdev->queue_depth)
|
||||
continue;
|
||||
if (sdev->ordered_tags)
|
||||
scsi_adjust_queue_depth(sdev,
|
||||
MSG_ORDERED_TAG,
|
||||
|
@ -578,14 +581,14 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
|||
lpfc_cmd->result == IOERR_NO_RESOURCES ||
|
||||
lpfc_cmd->result == RJT_LOGIN_REQUIRED) {
|
||||
cmd->result = ScsiResult(DID_REQUEUE, 0);
|
||||
break;
|
||||
} /* else: fall through */
|
||||
break;
|
||||
} /* else: fall through */
|
||||
default:
|
||||
cmd->result = ScsiResult(DID_ERROR, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((pnode == NULL )
|
||||
if (!pnode || !NLP_CHK_NODE_ACT(pnode)
|
||||
|| (pnode->nlp_state != NLP_STE_MAPPED_NODE))
|
||||
cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY);
|
||||
} else {
|
||||
|
@ -606,6 +609,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
|||
result = cmd->result;
|
||||
sdev = cmd->device;
|
||||
lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
|
||||
spin_lock_irqsave(sdev->host->host_lock, flags);
|
||||
lpfc_cmd->pCmd = NULL; /* This must be done before scsi_done */
|
||||
spin_unlock_irqrestore(sdev->host->host_lock, flags);
|
||||
cmd->scsi_done(cmd);
|
||||
|
||||
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
|
||||
|
@ -614,7 +620,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
|||
* wake up the thread.
|
||||
*/
|
||||
spin_lock_irqsave(sdev->host->host_lock, flags);
|
||||
lpfc_cmd->pCmd = NULL;
|
||||
if (lpfc_cmd->waitq)
|
||||
wake_up(lpfc_cmd->waitq);
|
||||
spin_unlock_irqrestore(sdev->host->host_lock, flags);
|
||||
|
@ -626,7 +631,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
|||
if (!result)
|
||||
lpfc_rampup_queue_depth(vport, sdev);
|
||||
|
||||
if (!result && pnode != NULL &&
|
||||
if (!result && pnode && NLP_CHK_NODE_ACT(pnode) &&
|
||||
((jiffies - pnode->last_ramp_up_time) >
|
||||
LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
|
||||
((jiffies - pnode->last_q_full_time) >
|
||||
|
@ -654,7 +659,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
|||
* Check for queue full. If the lun is reporting queue full, then
|
||||
* back off the lun queue depth to prevent target overloads.
|
||||
*/
|
||||
if (result == SAM_STAT_TASK_SET_FULL && pnode != NULL) {
|
||||
if (result == SAM_STAT_TASK_SET_FULL && pnode &&
|
||||
NLP_CHK_NODE_ACT(pnode)) {
|
||||
pnode->last_q_full_time = jiffies;
|
||||
|
||||
shost_for_each_device(tmp_sdev, sdev->host) {
|
||||
|
@ -684,7 +690,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
|||
* wake up the thread.
|
||||
*/
|
||||
spin_lock_irqsave(sdev->host->host_lock, flags);
|
||||
lpfc_cmd->pCmd = NULL;
|
||||
if (lpfc_cmd->waitq)
|
||||
wake_up(lpfc_cmd->waitq);
|
||||
spin_unlock_irqrestore(sdev->host->host_lock, flags);
|
||||
|
@ -704,6 +709,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
|
|||
int datadir = scsi_cmnd->sc_data_direction;
|
||||
char tag[2];
|
||||
|
||||
if (!pnode || !NLP_CHK_NODE_ACT(pnode))
|
||||
return;
|
||||
|
||||
lpfc_cmd->fcp_rsp->rspSnsLen = 0;
|
||||
/* clear task management bits */
|
||||
lpfc_cmd->fcp_cmnd->fcpCntl2 = 0;
|
||||
|
@ -785,9 +793,9 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport,
|
|||
struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
|
||||
struct lpfc_nodelist *ndlp = rdata->pnode;
|
||||
|
||||
if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
|
||||
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) ||
|
||||
ndlp->nlp_state != NLP_STE_MAPPED_NODE)
|
||||
return 0;
|
||||
}
|
||||
|
||||
piocbq = &(lpfc_cmd->cur_iocbq);
|
||||
piocbq->vport = vport;
|
||||
|
@ -842,7 +850,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport,
|
|||
struct lpfc_iocbq *iocbqrsp;
|
||||
int ret;
|
||||
|
||||
if (!rdata->pnode)
|
||||
if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode))
|
||||
return FAILED;
|
||||
|
||||
lpfc_cmd->rdata = rdata;
|
||||
|
@ -959,7 +967,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
|
|||
* Catch race where our node has transitioned, but the
|
||||
* transport is still transitioning.
|
||||
*/
|
||||
if (!ndlp) {
|
||||
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
|
||||
cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
|
||||
goto out_fail_command;
|
||||
}
|
||||
|
@ -1146,7 +1154,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
|
|||
* target is rediscovered or devloss timeout expires.
|
||||
*/
|
||||
while (1) {
|
||||
if (!pnode)
|
||||
if (!pnode || !NLP_CHK_NODE_ACT(pnode))
|
||||
goto out;
|
||||
|
||||
if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
|
||||
|
@ -1162,7 +1170,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
|
|||
goto out;
|
||||
}
|
||||
pnode = rdata->pnode;
|
||||
if (!pnode)
|
||||
if (!pnode || !NLP_CHK_NODE_ACT(pnode))
|
||||
goto out;
|
||||
}
|
||||
if (pnode->nlp_state == NLP_STE_MAPPED_NODE)
|
||||
|
|
|
@ -2648,7 +2648,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
|
|||
spin_unlock_irq(&phba->pport->work_port_lock);
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
phba->link_state = LPFC_LINK_UNKNOWN;
|
||||
phba->pport->fc_flag |= FC_ESTABLISH_LINK;
|
||||
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
||||
|
@ -2669,8 +2668,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
|
|||
lpfc_offline_prep(phba);
|
||||
lpfc_offline(phba);
|
||||
lpfc_sli_brdrestart(phba);
|
||||
if (lpfc_online(phba) == 0) /* Initialize the HBA */
|
||||
mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
|
||||
lpfc_online(phba);
|
||||
lpfc_unblock_mgmt_io(phba);
|
||||
return;
|
||||
}
|
||||
|
@ -2687,28 +2685,41 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
|
|||
unsigned long drvr_flag = 0;
|
||||
volatile uint32_t word0, ldata;
|
||||
void __iomem *to_slim;
|
||||
int processing_queue = 0;
|
||||
|
||||
spin_lock_irqsave(&phba->hbalock, drvr_flag);
|
||||
if (!pmbox) {
|
||||
/* processing mbox queue from intr_handler */
|
||||
processing_queue = 1;
|
||||
phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
||||
pmbox = lpfc_mbox_get(phba);
|
||||
if (!pmbox) {
|
||||
spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
|
||||
return MBX_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl &&
|
||||
pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) {
|
||||
if(!pmbox->vport) {
|
||||
spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
|
||||
lpfc_printf_log(phba, KERN_ERR,
|
||||
LOG_MBOX | LOG_VPORT,
|
||||
"1806 Mbox x%x failed. No vport\n",
|
||||
pmbox->mb.mbxCommand);
|
||||
dump_stack();
|
||||
return MBX_NOT_FINISHED;
|
||||
goto out_not_finished;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If the PCI channel is in offline state, do not post mbox. */
|
||||
if (unlikely(pci_channel_offline(phba->pcidev)))
|
||||
return MBX_NOT_FINISHED;
|
||||
if (unlikely(pci_channel_offline(phba->pcidev))) {
|
||||
spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
|
||||
goto out_not_finished;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&phba->hbalock, drvr_flag);
|
||||
psli = &phba->sli;
|
||||
|
||||
|
||||
mb = &pmbox->mb;
|
||||
status = MBX_SUCCESS;
|
||||
|
||||
|
@ -2717,14 +2728,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
|
|||
|
||||
/* Mbox command <mbxCommand> cannot issue */
|
||||
LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
|
||||
return MBX_NOT_FINISHED;
|
||||
goto out_not_finished;
|
||||
}
|
||||
|
||||
if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT &&
|
||||
!(readl(phba->HCregaddr) & HC_MBINT_ENA)) {
|
||||
spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
|
||||
LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
|
||||
return MBX_NOT_FINISHED;
|
||||
goto out_not_finished;
|
||||
}
|
||||
|
||||
if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) {
|
||||
|
@ -2738,14 +2749,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
|
|||
|
||||
/* Mbox command <mbxCommand> cannot issue */
|
||||
LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
|
||||
return MBX_NOT_FINISHED;
|
||||
goto out_not_finished;
|
||||
}
|
||||
|
||||
if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) {
|
||||
spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
|
||||
/* Mbox command <mbxCommand> cannot issue */
|
||||
LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
|
||||
return MBX_NOT_FINISHED;
|
||||
goto out_not_finished;
|
||||
}
|
||||
|
||||
/* Another mailbox command is still being processed, queue this
|
||||
|
@ -2792,7 +2803,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
|
|||
spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
|
||||
/* Mbox command <mbxCommand> cannot issue */
|
||||
LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
|
||||
return MBX_NOT_FINISHED;
|
||||
goto out_not_finished;
|
||||
}
|
||||
/* timeout active mbox command */
|
||||
mod_timer(&psli->mbox_tmo, (jiffies +
|
||||
|
@ -2900,7 +2911,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
|
|||
psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
||||
spin_unlock_irqrestore(&phba->hbalock,
|
||||
drvr_flag);
|
||||
return MBX_NOT_FINISHED;
|
||||
goto out_not_finished;
|
||||
}
|
||||
|
||||
/* Check if we took a mbox interrupt while we were
|
||||
|
@ -2967,6 +2978,13 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
|
|||
|
||||
spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
|
||||
return status;
|
||||
|
||||
out_not_finished:
|
||||
if (processing_queue) {
|
||||
pmbox->mb.mbxStatus = MBX_NOT_FINISHED;
|
||||
lpfc_mbox_cmpl_put(phba, pmbox);
|
||||
}
|
||||
return MBX_NOT_FINISHED;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3463,26 +3481,21 @@ lpfc_sli_hba_down(struct lpfc_hba *phba)
|
|||
phba->pport->work_port_events &= ~WORKER_MBOX_TMO;
|
||||
spin_unlock(&phba->pport->work_port_lock);
|
||||
|
||||
/* Return any pending or completed mbox cmds */
|
||||
list_splice_init(&phba->sli.mboxq, &completions);
|
||||
if (psli->mbox_active) {
|
||||
list_add_tail(&psli->mbox_active->list, &completions);
|
||||
psli->mbox_active = NULL;
|
||||
psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
||||
}
|
||||
|
||||
/* Return any pending or completed mbox cmds */
|
||||
list_splice_init(&phba->sli.mboxq, &completions);
|
||||
list_splice_init(&phba->sli.mboxq_cmpl, &completions);
|
||||
INIT_LIST_HEAD(&psli->mboxq);
|
||||
INIT_LIST_HEAD(&psli->mboxq_cmpl);
|
||||
|
||||
spin_unlock_irqrestore(&phba->hbalock, flags);
|
||||
|
||||
while (!list_empty(&completions)) {
|
||||
list_remove_head(&completions, pmb, LPFC_MBOXQ_t, list);
|
||||
pmb->mb.mbxStatus = MBX_NOT_FINISHED;
|
||||
if (pmb->mbox_cmpl) {
|
||||
if (pmb->mbox_cmpl)
|
||||
pmb->mbox_cmpl(phba,pmb);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -3612,6 +3625,15 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
abort_iocb, abort_iotag, abort_context,
|
||||
irsp->ulpStatus, irsp->un.ulpWord[4]);
|
||||
|
||||
/*
|
||||
* If the iocb is not found in Firmware queue the iocb
|
||||
* might have completed already. Do not free it again.
|
||||
*/
|
||||
if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
lpfc_sli_release_iocbq(phba, cmdiocb);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* make sure we have the right iocbq before taking it
|
||||
* off the txcmplq and try to call completion routine.
|
||||
|
@ -4174,6 +4196,7 @@ lpfc_intr_handler(int irq, void *dev_id)
|
|||
phba->pport->stopped = 1;
|
||||
}
|
||||
|
||||
spin_lock(&phba->hbalock);
|
||||
if ((work_ha_copy & HA_MBATT) &&
|
||||
(phba->sli.mbox_active)) {
|
||||
pmb = phba->sli.mbox_active;
|
||||
|
@ -4184,6 +4207,7 @@ lpfc_intr_handler(int irq, void *dev_id)
|
|||
/* First check out the status word */
|
||||
lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t));
|
||||
if (pmbox->mbxOwner != OWN_HOST) {
|
||||
spin_unlock(&phba->hbalock);
|
||||
/*
|
||||
* Stray Mailbox Interrupt, mbxCommand <cmd>
|
||||
* mbxStatus <status>
|
||||
|
@ -4199,10 +4223,10 @@ lpfc_intr_handler(int irq, void *dev_id)
|
|||
/* clear mailbox attention bit */
|
||||
work_ha_copy &= ~HA_MBATT;
|
||||
} else {
|
||||
phba->sli.mbox_active = NULL;
|
||||
spin_unlock(&phba->hbalock);
|
||||
phba->last_completion_time = jiffies;
|
||||
del_timer(&phba->sli.mbox_tmo);
|
||||
|
||||
phba->sli.mbox_active = NULL;
|
||||
if (pmb->mbox_cmpl) {
|
||||
lpfc_sli_pcimem_bcopy(mbox, pmbox,
|
||||
MAILBOX_CMD_SIZE);
|
||||
|
@ -4237,10 +4261,15 @@ lpfc_intr_handler(int irq, void *dev_id)
|
|||
pmb->context1 = mp;
|
||||
pmb->context2 = ndlp;
|
||||
pmb->vport = vport;
|
||||
spin_lock(&phba->hbalock);
|
||||
phba->sli.sli_flag &=
|
||||
~LPFC_SLI_MBOX_ACTIVE;
|
||||
spin_unlock(&phba->hbalock);
|
||||
rc = lpfc_sli_issue_mbox(phba,
|
||||
pmb,
|
||||
MBX_NOWAIT);
|
||||
if (rc != MBX_BUSY)
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_MBOX | LOG_SLI,
|
||||
"0306 rc should have"
|
||||
"been MBX_BUSY");
|
||||
goto send_current_mbox;
|
||||
}
|
||||
}
|
||||
|
@ -4250,25 +4279,20 @@ lpfc_intr_handler(int irq, void *dev_id)
|
|||
spin_unlock(&phba->pport->work_port_lock);
|
||||
lpfc_mbox_cmpl_put(phba, pmb);
|
||||
}
|
||||
}
|
||||
} else
|
||||
spin_unlock(&phba->hbalock);
|
||||
if ((work_ha_copy & HA_MBATT) &&
|
||||
(phba->sli.mbox_active == NULL)) {
|
||||
send_next_mbox:
|
||||
spin_lock(&phba->hbalock);
|
||||
phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
||||
pmb = lpfc_mbox_get(phba);
|
||||
spin_unlock(&phba->hbalock);
|
||||
send_current_mbox:
|
||||
/* Process next mailbox command if there is one */
|
||||
if (pmb != NULL) {
|
||||
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
|
||||
if (rc == MBX_NOT_FINISHED) {
|
||||
pmb->mb.mbxStatus = MBX_NOT_FINISHED;
|
||||
lpfc_mbox_cmpl_put(phba, pmb);
|
||||
goto send_next_mbox;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
rc = lpfc_sli_issue_mbox(phba, NULL,
|
||||
MBX_NOWAIT);
|
||||
} while (rc == MBX_NOT_FINISHED);
|
||||
if (rc != MBX_SUCCESS)
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX |
|
||||
LOG_SLI, "0349 rc should be "
|
||||
"MBX_SUCCESS");
|
||||
}
|
||||
|
||||
spin_lock(&phba->hbalock);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* included with this package. *
|
||||
*******************************************************************/
|
||||
|
||||
#define LPFC_DRIVER_VERSION "8.2.5"
|
||||
#define LPFC_DRIVER_VERSION "8.2.6"
|
||||
|
||||
#define LPFC_DRIVER_NAME "lpfc"
|
||||
|
||||
|
|
|
@ -538,7 +538,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
|
|||
/* Otherwise, we will perform fabric logo as needed */
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
|
||||
ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
|
||||
phba->link_state >= LPFC_LINK_UP) {
|
||||
phba->link_state >= LPFC_LINK_UP &&
|
||||
phba->fc_topology != TOPOLOGY_LOOP) {
|
||||
if (vport->cfg_enable_da_id) {
|
||||
timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
|
||||
if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0))
|
||||
|
|
|
@ -592,7 +592,6 @@ static struct scsi_host_template driver_template = {
|
|||
.this_id = 7,
|
||||
.sg_tablesize = SG_ALL,
|
||||
.cmd_per_lun = CMD_PER_LUN,
|
||||
.unchecked_isa_dma = 0,
|
||||
.use_clustering = DISABLE_CLUSTERING
|
||||
};
|
||||
|
||||
|
|
|
@ -68,6 +68,8 @@ static struct pci_device_id megasas_pci_table[] = {
|
|||
/* xscale IOP */
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)},
|
||||
/* ppc IOP */
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)},
|
||||
/* ppc IOP */
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
|
||||
/* xscale IOP, vega */
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
|
||||
|
@ -488,12 +490,13 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
|
|||
|
||||
/**
|
||||
* megasas_get_frame_count - Computes the number of frames
|
||||
* @frame_type : type of frame- io or pthru frame
|
||||
* @sge_count : number of sg elements
|
||||
*
|
||||
* Returns the number of frames required for numnber of sge's (sge_count)
|
||||
*/
|
||||
|
||||
static u32 megasas_get_frame_count(u8 sge_count)
|
||||
static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
|
||||
{
|
||||
int num_cnt;
|
||||
int sge_bytes;
|
||||
|
@ -504,13 +507,22 @@ static u32 megasas_get_frame_count(u8 sge_count)
|
|||
sizeof(struct megasas_sge32);
|
||||
|
||||
/*
|
||||
* Main frame can contain 2 SGEs for 64-bit SGLs and
|
||||
* 3 SGEs for 32-bit SGLs
|
||||
*/
|
||||
if (IS_DMA64)
|
||||
num_cnt = sge_count - 2;
|
||||
else
|
||||
num_cnt = sge_count - 3;
|
||||
* Main frame can contain 2 SGEs for 64-bit SGLs and
|
||||
* 3 SGEs for 32-bit SGLs for ldio &
|
||||
* 1 SGEs for 64-bit SGLs and
|
||||
* 2 SGEs for 32-bit SGLs for pthru frame
|
||||
*/
|
||||
if (unlikely(frame_type == PTHRU_FRAME)) {
|
||||
if (IS_DMA64)
|
||||
num_cnt = sge_count - 1;
|
||||
else
|
||||
num_cnt = sge_count - 2;
|
||||
} else {
|
||||
if (IS_DMA64)
|
||||
num_cnt = sge_count - 2;
|
||||
else
|
||||
num_cnt = sge_count - 3;
|
||||
}
|
||||
|
||||
if(num_cnt>0){
|
||||
sge_bytes = sge_sz * num_cnt;
|
||||
|
@ -592,7 +604,8 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
|
|||
* Compute the total number of frames this command consumes. FW uses
|
||||
* this number to pull sufficient number of frames from host memory.
|
||||
*/
|
||||
cmd->frame_count = megasas_get_frame_count(pthru->sge_count);
|
||||
cmd->frame_count = megasas_get_frame_count(pthru->sge_count,
|
||||
PTHRU_FRAME);
|
||||
|
||||
return cmd->frame_count;
|
||||
}
|
||||
|
@ -709,7 +722,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
|
|||
* Compute the total number of frames this command consumes. FW uses
|
||||
* this number to pull sufficient number of frames from host memory.
|
||||
*/
|
||||
cmd->frame_count = megasas_get_frame_count(ldio->sge_count);
|
||||
cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME);
|
||||
|
||||
return cmd->frame_count;
|
||||
}
|
||||
|
@ -1460,7 +1473,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
|
|||
instance->instancet->disable_intr(instance->reg_set);
|
||||
writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
|
||||
|
||||
max_wait = 10;
|
||||
max_wait = 60;
|
||||
cur_state = MFI_STATE_OPERATIONAL;
|
||||
break;
|
||||
|
||||
|
@ -1980,7 +1993,8 @@ static int megasas_init_mfi(struct megasas_instance *instance)
|
|||
|
||||
switch(instance->pdev->device)
|
||||
{
|
||||
case PCI_DEVICE_ID_LSI_SAS1078R:
|
||||
case PCI_DEVICE_ID_LSI_SAS1078R:
|
||||
case PCI_DEVICE_ID_LSI_SAS1078DE:
|
||||
instance->instancet = &megasas_instance_template_ppc;
|
||||
break;
|
||||
case PCI_DEVICE_ID_LSI_SAS1064R:
|
||||
|
@ -2909,7 +2923,6 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
|
|||
void *sense = NULL;
|
||||
dma_addr_t sense_handle;
|
||||
u32 *sense_ptr;
|
||||
unsigned long *sense_buff;
|
||||
|
||||
memset(kbuff_arr, 0, sizeof(kbuff_arr));
|
||||
|
||||
|
@ -3014,14 +3027,14 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
|
|||
*/
|
||||
if (ioc->sense_len) {
|
||||
/*
|
||||
* sense_buff points to the location that has the user
|
||||
* sense_ptr points to the location that has the user
|
||||
* sense buffer address
|
||||
*/
|
||||
sense_buff = (unsigned long *) ((unsigned long)ioc->frame.raw +
|
||||
ioc->sense_off);
|
||||
sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw +
|
||||
ioc->sense_off);
|
||||
|
||||
if (copy_to_user((void __user *)(unsigned long)(*sense_buff),
|
||||
sense, ioc->sense_len)) {
|
||||
if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
|
||||
sense, ioc->sense_len)) {
|
||||
printk(KERN_ERR "megasas: Failed to copy out to user "
|
||||
"sense data\n");
|
||||
error = -EFAULT;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
* Device IDs
|
||||
*/
|
||||
#define PCI_DEVICE_ID_LSI_SAS1078R 0x0060
|
||||
#define PCI_DEVICE_ID_LSI_SAS1078DE 0x007C
|
||||
#define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413
|
||||
|
||||
/*
|
||||
|
@ -542,6 +543,10 @@ struct megasas_ctrl_info {
|
|||
|
||||
#define MEGASAS_FW_BUSY 1
|
||||
|
||||
/* Frame Type */
|
||||
#define IO_FRAME 0
|
||||
#define PTHRU_FRAME 1
|
||||
|
||||
/*
|
||||
* When SCSI mid-layer calls driver's reset routine, driver waits for
|
||||
* MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note
|
||||
|
|
|
@ -82,6 +82,9 @@ int mvme147_detect(struct scsi_host_template *tpnt)
|
|||
mvme147_host->irq = MVME147_IRQ_SCSI_PORT;
|
||||
regs.SASR = (volatile unsigned char *)0xfffe4000;
|
||||
regs.SCMD = (volatile unsigned char *)0xfffe4001;
|
||||
HDATA(mvme147_host)->no_sync = 0xff;
|
||||
HDATA(mvme147_host)->fast = 0;
|
||||
HDATA(mvme147_host)->dma_mode = CTRL_DMA;
|
||||
wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
|
||||
|
||||
if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, "MVME147 SCSI PORT", mvme147_intr))
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <scsi/scsi_dbg.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_eh.h>
|
||||
|
||||
#include <asm/lv1call.h>
|
||||
#include <asm/ps3stor.h>
|
||||
|
@ -90,78 +91,6 @@ static int ps3rom_slave_configure(struct scsi_device *scsi_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy data from device into scatter/gather buffer
|
||||
*/
|
||||
static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf)
|
||||
{
|
||||
int k, req_len, act_len, len, active;
|
||||
void *kaddr;
|
||||
struct scatterlist *sgpnt;
|
||||
unsigned int buflen;
|
||||
|
||||
buflen = scsi_bufflen(cmd);
|
||||
if (!buflen)
|
||||
return 0;
|
||||
|
||||
if (!scsi_sglist(cmd))
|
||||
return -1;
|
||||
|
||||
active = 1;
|
||||
req_len = act_len = 0;
|
||||
scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
|
||||
if (active) {
|
||||
kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
|
||||
len = sgpnt->length;
|
||||
if ((req_len + len) > buflen) {
|
||||
active = 0;
|
||||
len = buflen - req_len;
|
||||
}
|
||||
memcpy(kaddr + sgpnt->offset, buf + req_len, len);
|
||||
flush_kernel_dcache_page(sg_page(sgpnt));
|
||||
kunmap_atomic(kaddr, KM_IRQ0);
|
||||
act_len += len;
|
||||
}
|
||||
req_len += sgpnt->length;
|
||||
}
|
||||
scsi_set_resid(cmd, buflen - act_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy data from scatter/gather into device's buffer
|
||||
*/
|
||||
static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf)
|
||||
{
|
||||
int k, req_len, len, fin;
|
||||
void *kaddr;
|
||||
struct scatterlist *sgpnt;
|
||||
unsigned int buflen;
|
||||
|
||||
buflen = scsi_bufflen(cmd);
|
||||
if (!buflen)
|
||||
return 0;
|
||||
|
||||
if (!scsi_sglist(cmd))
|
||||
return -1;
|
||||
|
||||
req_len = fin = 0;
|
||||
scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
|
||||
kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
|
||||
len = sgpnt->length;
|
||||
if ((req_len + len) > buflen) {
|
||||
len = buflen - req_len;
|
||||
fin = 1;
|
||||
}
|
||||
memcpy(buf + req_len, kaddr + sgpnt->offset, len);
|
||||
kunmap_atomic(kaddr, KM_IRQ0);
|
||||
if (fin)
|
||||
return req_len + len;
|
||||
req_len += sgpnt->length;
|
||||
}
|
||||
return req_len;
|
||||
}
|
||||
|
||||
static int ps3rom_atapi_request(struct ps3_storage_device *dev,
|
||||
struct scsi_cmnd *cmd)
|
||||
{
|
||||
|
@ -195,9 +124,7 @@ static int ps3rom_atapi_request(struct ps3_storage_device *dev,
|
|||
else
|
||||
atapi_cmnd.proto = PIO_DATA_OUT_PROTO;
|
||||
atapi_cmnd.in_out = DIR_WRITE;
|
||||
res = fetch_to_dev_buffer(cmd, dev->bounce_buf);
|
||||
if (res < 0)
|
||||
return DID_ERROR << 16;
|
||||
scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -269,9 +196,7 @@ static int ps3rom_write_request(struct ps3_storage_device *dev,
|
|||
dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n",
|
||||
__func__, __LINE__, sectors, start_sector);
|
||||
|
||||
res = fetch_to_dev_buffer(cmd, dev->bounce_buf);
|
||||
if (res < 0)
|
||||
return DID_ERROR << 16;
|
||||
scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size);
|
||||
|
||||
res = lv1_storage_write(dev->sbd.dev_id,
|
||||
dev->regions[dev->region_idx].id, start_sector,
|
||||
|
@ -381,11 +306,13 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data)
|
|||
if (!status) {
|
||||
/* OK, completed */
|
||||
if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
|
||||
res = fill_from_dev_buffer(cmd, dev->bounce_buf);
|
||||
if (res) {
|
||||
cmd->result = DID_ERROR << 16;
|
||||
goto done;
|
||||
}
|
||||
int len;
|
||||
|
||||
len = scsi_sg_copy_from_buffer(cmd,
|
||||
dev->bounce_buf,
|
||||
dev->bounce_size);
|
||||
|
||||
scsi_set_resid(cmd, scsi_bufflen(cmd) - len);
|
||||
}
|
||||
cmd->result = DID_OK << 16;
|
||||
goto done;
|
||||
|
@ -404,11 +331,7 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data)
|
|||
goto done;
|
||||
}
|
||||
|
||||
cmd->sense_buffer[0] = 0x70;
|
||||
cmd->sense_buffer[2] = sense_key;
|
||||
cmd->sense_buffer[7] = 16 - 6;
|
||||
cmd->sense_buffer[12] = asc;
|
||||
cmd->sense_buffer[13] = ascq;
|
||||
scsi_build_sense_buffer(0, cmd->sense_buffer, sense_key, asc, ascq);
|
||||
cmd->result = SAM_STAT_CHECK_CONDITION;
|
||||
|
||||
done:
|
||||
|
@ -427,7 +350,7 @@ static struct scsi_host_template ps3rom_host_template = {
|
|||
.cmd_per_lun = 1,
|
||||
.emulated = 1, /* only sg driver uses this */
|
||||
.max_sectors = PS3ROM_MAX_SECTORS,
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.module = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
|
|
@ -333,7 +333,6 @@
|
|||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
|
@ -367,10 +366,6 @@
|
|||
#include <asm/sn/io.h>
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020600
|
||||
#error "Kernels older than 2.6.0 are no longer supported"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Compile time Options:
|
||||
|
|
|
@ -16,7 +16,8 @@ config SCSI_QLA_FC
|
|||
22xx ql2200_fw.bin
|
||||
2300, 2312, 6312 ql2300_fw.bin
|
||||
2322, 6322 ql2322_fw.bin
|
||||
24xx ql2400_fw.bin
|
||||
24xx, 54xx ql2400_fw.bin
|
||||
25xx ql2500_fw.bin
|
||||
|
||||
Upon request, the driver caches the firmware image until
|
||||
the driver is unloaded.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
@ -849,20 +849,20 @@ static void
|
|||
qla2x00_get_host_speed(struct Scsi_Host *shost)
|
||||
{
|
||||
scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
|
||||
uint32_t speed = 0;
|
||||
u32 speed = FC_PORTSPEED_UNKNOWN;
|
||||
|
||||
switch (ha->link_data_rate) {
|
||||
case PORT_SPEED_1GB:
|
||||
speed = 1;
|
||||
speed = FC_PORTSPEED_1GBIT;
|
||||
break;
|
||||
case PORT_SPEED_2GB:
|
||||
speed = 2;
|
||||
speed = FC_PORTSPEED_2GBIT;
|
||||
break;
|
||||
case PORT_SPEED_4GB:
|
||||
speed = 4;
|
||||
speed = FC_PORTSPEED_4GBIT;
|
||||
break;
|
||||
case PORT_SPEED_8GB:
|
||||
speed = 8;
|
||||
speed = FC_PORTSPEED_8GBIT;
|
||||
break;
|
||||
}
|
||||
fc_host_speed(shost) = speed;
|
||||
|
@ -900,7 +900,8 @@ qla2x00_get_starget_node_name(struct scsi_target *starget)
|
|||
u64 node_name = 0;
|
||||
|
||||
list_for_each_entry(fcport, &ha->fcports, list) {
|
||||
if (starget->id == fcport->os_target_id) {
|
||||
if (fcport->rport &&
|
||||
starget->id == fcport->rport->scsi_target_id) {
|
||||
node_name = wwn_to_u64(fcport->node_name);
|
||||
break;
|
||||
}
|
||||
|
@ -918,7 +919,8 @@ qla2x00_get_starget_port_name(struct scsi_target *starget)
|
|||
u64 port_name = 0;
|
||||
|
||||
list_for_each_entry(fcport, &ha->fcports, list) {
|
||||
if (starget->id == fcport->os_target_id) {
|
||||
if (fcport->rport &&
|
||||
starget->id == fcport->rport->scsi_target_id) {
|
||||
port_name = wwn_to_u64(fcport->port_name);
|
||||
break;
|
||||
}
|
||||
|
@ -936,7 +938,8 @@ qla2x00_get_starget_port_id(struct scsi_target *starget)
|
|||
uint32_t port_id = ~0U;
|
||||
|
||||
list_for_each_entry(fcport, &ha->fcports, list) {
|
||||
if (starget->id == fcport->os_target_id) {
|
||||
if (fcport->rport &&
|
||||
starget->id == fcport->rport->scsi_target_id) {
|
||||
port_id = fcport->d_id.b.domain << 16 |
|
||||
fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
|
||||
break;
|
||||
|
@ -1196,6 +1199,7 @@ struct fc_function_template qla2xxx_transport_functions = {
|
|||
.show_host_node_name = 1,
|
||||
.show_host_port_name = 1,
|
||||
.show_host_supported_classes = 1,
|
||||
.show_host_supported_speeds = 1,
|
||||
|
||||
.get_host_port_id = qla2x00_get_host_port_id,
|
||||
.show_host_port_id = 1,
|
||||
|
@ -1276,9 +1280,23 @@ struct fc_function_template qla2xxx_transport_vport_functions = {
|
|||
void
|
||||
qla2x00_init_host_attr(scsi_qla_host_t *ha)
|
||||
{
|
||||
u32 speed = FC_PORTSPEED_UNKNOWN;
|
||||
|
||||
fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name);
|
||||
fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name);
|
||||
fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
|
||||
fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;;
|
||||
fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count;
|
||||
|
||||
if (IS_QLA25XX(ha))
|
||||
speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT |
|
||||
FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
|
||||
else if (IS_QLA24XX_TYPE(ha))
|
||||
speed = FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
|
||||
FC_PORTSPEED_1GBIT;
|
||||
else if (IS_QLA23XX(ha))
|
||||
speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
|
||||
else
|
||||
speed = FC_PORTSPEED_1GBIT;
|
||||
fc_host_supported_speeds(ha->host) = speed;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
@ -1410,125 +1410,3 @@ qla2x00_dump_buffer(uint8_t * b, uint32_t size)
|
|||
if (cnt % 16)
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* qla2x00_print_scsi_cmd
|
||||
* Dumps out info about the scsi cmd and srb.
|
||||
* Input
|
||||
* cmd : struct scsi_cmnd
|
||||
**************************************************************************/
|
||||
void
|
||||
qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd)
|
||||
{
|
||||
int i;
|
||||
struct scsi_qla_host *ha;
|
||||
srb_t *sp;
|
||||
|
||||
ha = shost_priv(cmd->device->host);
|
||||
|
||||
sp = (srb_t *) cmd->SCp.ptr;
|
||||
printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble);
|
||||
printk(" chan=0x%02x, target=0x%02x, lun=0x%02x, cmd_len=0x%02x\n",
|
||||
cmd->device->channel, cmd->device->id, cmd->device->lun,
|
||||
cmd->cmd_len);
|
||||
printk(" CDB: ");
|
||||
for (i = 0; i < cmd->cmd_len; i++) {
|
||||
printk("0x%02x ", cmd->cmnd[i]);
|
||||
}
|
||||
printk("\n seg_cnt=%d, allowed=%d, retries=%d\n",
|
||||
scsi_sg_count(cmd), cmd->allowed, cmd->retries);
|
||||
printk(" request buffer=0x%p, request buffer len=0x%x\n",
|
||||
scsi_sglist(cmd), scsi_bufflen(cmd));
|
||||
printk(" tag=%d, transfersize=0x%x\n",
|
||||
cmd->tag, cmd->transfersize);
|
||||
printk(" serial_number=%lx, SP=%p\n", cmd->serial_number, sp);
|
||||
printk(" data direction=%d\n", cmd->sc_data_direction);
|
||||
|
||||
if (!sp)
|
||||
return;
|
||||
|
||||
printk(" sp flags=0x%x\n", sp->flags);
|
||||
}
|
||||
|
||||
#if defined(QL_DEBUG_ROUTINES)
|
||||
/*
|
||||
* qla2x00_formatted_dump_buffer
|
||||
* Prints string plus buffer.
|
||||
*
|
||||
* Input:
|
||||
* string = Null terminated string (no newline at end).
|
||||
* buffer = buffer address.
|
||||
* wd_size = word size 8, 16, 32 or 64 bits
|
||||
* count = number of words.
|
||||
*/
|
||||
void
|
||||
qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer,
|
||||
uint8_t wd_size, uint32_t count)
|
||||
{
|
||||
uint32_t cnt;
|
||||
uint16_t *buf16;
|
||||
uint32_t *buf32;
|
||||
|
||||
if (strcmp(string, "") != 0)
|
||||
printk("%s\n",string);
|
||||
|
||||
switch (wd_size) {
|
||||
case 8:
|
||||
printk(" 0 1 2 3 4 5 6 7 "
|
||||
"8 9 Ah Bh Ch Dh Eh Fh\n");
|
||||
printk("-----------------------------------------"
|
||||
"-------------------------------------\n");
|
||||
|
||||
for (cnt = 1; cnt <= count; cnt++, buffer++) {
|
||||
printk("%02x",*buffer);
|
||||
if (cnt % 16 == 0)
|
||||
printk("\n");
|
||||
else
|
||||
printk(" ");
|
||||
}
|
||||
if (cnt % 16 != 0)
|
||||
printk("\n");
|
||||
break;
|
||||
case 16:
|
||||
printk(" 0 2 4 6 8 Ah "
|
||||
" Ch Eh\n");
|
||||
printk("-----------------------------------------"
|
||||
"-------------\n");
|
||||
|
||||
buf16 = (uint16_t *) buffer;
|
||||
for (cnt = 1; cnt <= count; cnt++, buf16++) {
|
||||
printk("%4x",*buf16);
|
||||
|
||||
if (cnt % 8 == 0)
|
||||
printk("\n");
|
||||
else if (*buf16 < 10)
|
||||
printk(" ");
|
||||
else
|
||||
printk(" ");
|
||||
}
|
||||
if (cnt % 8 != 0)
|
||||
printk("\n");
|
||||
break;
|
||||
case 32:
|
||||
printk(" 0 4 8 Ch\n");
|
||||
printk("------------------------------------------\n");
|
||||
|
||||
buf32 = (uint32_t *) buffer;
|
||||
for (cnt = 1; cnt <= count; cnt++, buf32++) {
|
||||
printk("%8x", *buf32);
|
||||
|
||||
if (cnt % 4 == 0)
|
||||
printk("\n");
|
||||
else if (*buf32 < 10)
|
||||
printk(" ");
|
||||
else
|
||||
printk(" ");
|
||||
}
|
||||
if (cnt % 4 != 0)
|
||||
printk("\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
@ -22,19 +22,7 @@
|
|||
/* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */
|
||||
/* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */
|
||||
/* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */
|
||||
/*
|
||||
* Local Macro Definitions.
|
||||
*/
|
||||
#if defined(QL_DEBUG_LEVEL_1) || defined(QL_DEBUG_LEVEL_2) || \
|
||||
defined(QL_DEBUG_LEVEL_3) || defined(QL_DEBUG_LEVEL_4) || \
|
||||
defined(QL_DEBUG_LEVEL_5) || defined(QL_DEBUG_LEVEL_6) || \
|
||||
defined(QL_DEBUG_LEVEL_7) || defined(QL_DEBUG_LEVEL_8) || \
|
||||
defined(QL_DEBUG_LEVEL_9) || defined(QL_DEBUG_LEVEL_10) || \
|
||||
defined(QL_DEBUG_LEVEL_11) || defined(QL_DEBUG_LEVEL_12) || \
|
||||
defined(QL_DEBUG_LEVEL_13) || defined(QL_DEBUG_LEVEL_14) || \
|
||||
defined(QL_DEBUG_LEVEL_15)
|
||||
#define QL_DEBUG_ROUTINES
|
||||
#endif
|
||||
/* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */
|
||||
|
||||
/*
|
||||
* Macros use for debugging the driver.
|
||||
|
@ -54,6 +42,7 @@
|
|||
#define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0)
|
||||
#define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0)
|
||||
#define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0)
|
||||
#define DEBUG2_16(x) do { if (ql2xextended_error_logging) { x; } } while (0)
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_3)
|
||||
#define DEBUG3(x) do {x;} while (0)
|
||||
|
@ -133,6 +122,12 @@
|
|||
#define DEBUG15(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_16)
|
||||
#define DEBUG16(x) do {x;} while (0)
|
||||
#else
|
||||
#define DEBUG16(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Firmware Dump structure definition
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
@ -24,6 +24,7 @@
|
|||
#include <linux/workqueue.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/aer.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/semaphore.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
|
@ -192,9 +193,6 @@ typedef struct srb {
|
|||
|
||||
uint16_t flags;
|
||||
|
||||
/* Single transfer DMA context */
|
||||
dma_addr_t dma_handle;
|
||||
|
||||
uint32_t request_sense_length;
|
||||
uint8_t *request_sense_ptr;
|
||||
} srb_t;
|
||||
|
@ -1542,8 +1540,6 @@ typedef struct fc_port {
|
|||
atomic_t state;
|
||||
uint32_t flags;
|
||||
|
||||
unsigned int os_target_id;
|
||||
|
||||
int port_login_retry_count;
|
||||
int login_retry;
|
||||
atomic_t port_down_timer;
|
||||
|
@ -1613,6 +1609,7 @@ typedef struct fc_port {
|
|||
#define CT_ACCEPT_RESPONSE 0x8002
|
||||
#define CT_REASON_INVALID_COMMAND_CODE 0x01
|
||||
#define CT_REASON_CANNOT_PERFORM 0x09
|
||||
#define CT_REASON_COMMAND_UNSUPPORTED 0x0b
|
||||
#define CT_EXPL_ALREADY_REGISTERED 0x10
|
||||
|
||||
#define NS_N_PORT_TYPE 0x01
|
||||
|
@ -2063,7 +2060,8 @@ struct isp_operations {
|
|||
void (*disable_intrs) (struct scsi_qla_host *);
|
||||
|
||||
int (*abort_command) (struct scsi_qla_host *, srb_t *);
|
||||
int (*abort_target) (struct fc_port *);
|
||||
int (*target_reset) (struct fc_port *, unsigned int);
|
||||
int (*lun_reset) (struct fc_port *, unsigned int);
|
||||
int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t,
|
||||
uint8_t, uint8_t, uint16_t *, uint8_t);
|
||||
int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t,
|
||||
|
@ -2117,6 +2115,46 @@ struct qla_msix_entry {
|
|||
|
||||
#define WATCH_INTERVAL 1 /* number of seconds */
|
||||
|
||||
/* Work events. */
|
||||
enum qla_work_type {
|
||||
QLA_EVT_AEN,
|
||||
QLA_EVT_HWE_LOG,
|
||||
};
|
||||
|
||||
|
||||
struct qla_work_evt {
|
||||
struct list_head list;
|
||||
enum qla_work_type type;
|
||||
u32 flags;
|
||||
#define QLA_EVT_FLAG_FREE 0x1
|
||||
|
||||
union {
|
||||
struct {
|
||||
enum fc_host_event_code code;
|
||||
u32 data;
|
||||
} aen;
|
||||
struct {
|
||||
uint16_t code;
|
||||
uint16_t d1, d2, d3;
|
||||
} hwe;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct qla_chip_state_84xx {
|
||||
struct list_head list;
|
||||
struct kref kref;
|
||||
|
||||
void *bus;
|
||||
spinlock_t access_lock;
|
||||
struct mutex fw_update_mutex;
|
||||
uint32_t fw_update;
|
||||
uint32_t op_fw_version;
|
||||
uint32_t op_fw_size;
|
||||
uint32_t op_fw_seq_size;
|
||||
uint32_t diag_fw_version;
|
||||
uint32_t gold_fw_version;
|
||||
};
|
||||
|
||||
/*
|
||||
* Linux Host Adapter structure
|
||||
*/
|
||||
|
@ -2155,6 +2193,7 @@ typedef struct scsi_qla_host {
|
|||
uint32_t vsan_enabled :1;
|
||||
uint32_t npiv_supported :1;
|
||||
uint32_t fce_enabled :1;
|
||||
uint32_t hw_event_marker_found :1;
|
||||
} flags;
|
||||
|
||||
atomic_t loop_state;
|
||||
|
@ -2204,6 +2243,7 @@ typedef struct scsi_qla_host {
|
|||
#define DFLG_NO_CABLE BIT_4
|
||||
|
||||
#define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532
|
||||
#define PCI_DEVICE_ID_QLOGIC_ISP8432 0x8432
|
||||
uint32_t device_type;
|
||||
#define DT_ISP2100 BIT_0
|
||||
#define DT_ISP2200 BIT_1
|
||||
|
@ -2217,7 +2257,8 @@ typedef struct scsi_qla_host {
|
|||
#define DT_ISP5422 BIT_9
|
||||
#define DT_ISP5432 BIT_10
|
||||
#define DT_ISP2532 BIT_11
|
||||
#define DT_ISP_LAST (DT_ISP2532 << 1)
|
||||
#define DT_ISP8432 BIT_12
|
||||
#define DT_ISP_LAST (DT_ISP8432 << 1)
|
||||
|
||||
#define DT_IIDMA BIT_26
|
||||
#define DT_FWI2 BIT_27
|
||||
|
@ -2239,12 +2280,16 @@ typedef struct scsi_qla_host {
|
|||
#define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422)
|
||||
#define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432)
|
||||
#define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532)
|
||||
#define IS_QLA8432(ha) (DT_MASK(ha) & DT_ISP8432)
|
||||
|
||||
#define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
|
||||
IS_QLA6312(ha) || IS_QLA6322(ha))
|
||||
#define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha))
|
||||
#define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha))
|
||||
#define IS_QLA25XX(ha) (IS_QLA2532(ha))
|
||||
#define IS_QLA84XX(ha) (IS_QLA8432(ha))
|
||||
#define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \
|
||||
IS_QLA84XX(ha))
|
||||
|
||||
#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA)
|
||||
#define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2)
|
||||
|
@ -2356,6 +2401,8 @@ typedef struct scsi_qla_host {
|
|||
uint32_t login_retry_count;
|
||||
int max_q_depth;
|
||||
|
||||
struct list_head work_list;
|
||||
|
||||
/* Fibre Channel Device List. */
|
||||
struct list_head fcports;
|
||||
|
||||
|
@ -2423,8 +2470,6 @@ typedef struct scsi_qla_host {
|
|||
#define MBX_TIMEDOUT BIT_5
|
||||
#define MBX_ACCESS_TIMEDOUT BIT_6
|
||||
|
||||
mbx_cmd_t mc;
|
||||
|
||||
/* Basic firmware related information. */
|
||||
uint16_t fw_major_version;
|
||||
uint16_t fw_minor_version;
|
||||
|
@ -2458,6 +2503,10 @@ typedef struct scsi_qla_host {
|
|||
uint64_t fce_wr, fce_rd;
|
||||
struct mutex fce_mutex;
|
||||
|
||||
uint32_t hw_event_start;
|
||||
uint32_t hw_event_ptr;
|
||||
uint32_t hw_event_pause_errors;
|
||||
|
||||
uint8_t host_str[16];
|
||||
uint32_t pci_attr;
|
||||
uint16_t chip_revision;
|
||||
|
@ -2493,6 +2542,13 @@ typedef struct scsi_qla_host {
|
|||
uint8_t fcode_revision[16];
|
||||
uint32_t fw_revision[4];
|
||||
|
||||
uint16_t fdt_odd_index;
|
||||
uint32_t fdt_wrt_disable;
|
||||
uint32_t fdt_erase_cmd;
|
||||
uint32_t fdt_block_size;
|
||||
uint32_t fdt_unprotect_sec_cmd;
|
||||
uint32_t fdt_protect_sec_cmd;
|
||||
|
||||
/* Needed for BEACON */
|
||||
uint16_t beacon_blink_led;
|
||||
uint8_t beacon_color_state;
|
||||
|
@ -2538,6 +2594,8 @@ typedef struct scsi_qla_host {
|
|||
#define VP_ERR_ADAP_NORESOURCES 5
|
||||
uint16_t max_npiv_vports; /* 63 or 125 per topoloty */
|
||||
int cur_vport_count;
|
||||
|
||||
struct qla_chip_state_84xx *cs84xx;
|
||||
} scsi_qla_host_t;
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
@ -719,7 +719,7 @@ struct tsk_mgmt_entry {
|
|||
|
||||
uint16_t timeout; /* Command timeout. */
|
||||
|
||||
uint8_t lun[8]; /* FCP LUN (BE). */
|
||||
struct scsi_lun lun; /* FCP LUN (BE). */
|
||||
|
||||
uint32_t control_flags; /* Control Flags. */
|
||||
#define TCF_NOTMCMD_TO_TARGET BIT_31
|
||||
|
@ -793,7 +793,19 @@ struct device_reg_24xx {
|
|||
#define FA_VPD_NVRAM_ADDR 0x48000
|
||||
#define FA_FEATURE_ADDR 0x4C000
|
||||
#define FA_FLASH_DESCR_ADDR 0x50000
|
||||
#define FA_HW_EVENT_ADDR 0x54000
|
||||
#define FA_HW_EVENT0_ADDR 0x54000
|
||||
#define FA_HW_EVENT1_ADDR 0x54200
|
||||
#define FA_HW_EVENT_SIZE 0x200
|
||||
#define FA_HW_EVENT_ENTRY_SIZE 4
|
||||
/*
|
||||
* Flash Error Log Event Codes.
|
||||
*/
|
||||
#define HW_EVENT_RESET_ERR 0xF00B
|
||||
#define HW_EVENT_ISP_ERR 0xF020
|
||||
#define HW_EVENT_PARITY_ERR 0xF022
|
||||
#define HW_EVENT_NVRAM_CHKSUM_ERR 0xF023
|
||||
#define HW_EVENT_FLASH_FW_ERR 0xF024
|
||||
|
||||
#define FA_BOOT_LOG_ADDR 0x58000
|
||||
#define FA_FW_DUMP0_ADDR 0x60000
|
||||
#define FA_FW_DUMP1_ADDR 0x70000
|
||||
|
@ -1174,4 +1186,159 @@ struct vf_evfp_entry_24xx {
|
|||
};
|
||||
|
||||
/* END MID Support ***********************************************************/
|
||||
|
||||
/* Flash Description Table ***************************************************/
|
||||
|
||||
struct qla_fdt_layout {
|
||||
uint8_t sig[4];
|
||||
uint16_t version;
|
||||
uint16_t len;
|
||||
uint16_t checksum;
|
||||
uint8_t unused1[2];
|
||||
uint8_t model[16];
|
||||
uint16_t man_id;
|
||||
uint16_t id;
|
||||
uint8_t flags;
|
||||
uint8_t erase_cmd;
|
||||
uint8_t alt_erase_cmd;
|
||||
uint8_t wrt_enable_cmd;
|
||||
uint8_t wrt_enable_bits;
|
||||
uint8_t wrt_sts_reg_cmd;
|
||||
uint8_t unprotect_sec_cmd;
|
||||
uint8_t read_man_id_cmd;
|
||||
uint32_t block_size;
|
||||
uint32_t alt_block_size;
|
||||
uint32_t flash_size;
|
||||
uint32_t wrt_enable_data;
|
||||
uint8_t read_id_addr_len;
|
||||
uint8_t wrt_disable_bits;
|
||||
uint8_t read_dev_id_len;
|
||||
uint8_t chip_erase_cmd;
|
||||
uint16_t read_timeout;
|
||||
uint8_t protect_sec_cmd;
|
||||
uint8_t unused2[65];
|
||||
};
|
||||
|
||||
/* 84XX Support **************************************************************/
|
||||
|
||||
#define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */
|
||||
#define A84_PANIC_RECOVERY 0x1
|
||||
#define A84_OP_LOGIN_COMPLETE 0x2
|
||||
#define A84_DIAG_LOGIN_COMPLETE 0x3
|
||||
#define A84_GOLD_LOGIN_COMPLETE 0x4
|
||||
|
||||
#define MBC_ISP84XX_RESET 0x3a /* Reset. */
|
||||
|
||||
#define FSTATE_REMOTE_FC_DOWN BIT_0
|
||||
#define FSTATE_NSL_LINK_DOWN BIT_1
|
||||
#define FSTATE_IS_DIAG_FW BIT_2
|
||||
#define FSTATE_LOGGED_IN BIT_3
|
||||
#define FSTATE_WAITING_FOR_VERIFY BIT_4
|
||||
|
||||
#define VERIFY_CHIP_IOCB_TYPE 0x1B
|
||||
struct verify_chip_entry_84xx {
|
||||
uint8_t entry_type;
|
||||
uint8_t entry_count;
|
||||
uint8_t sys_defined;
|
||||
uint8_t entry_status;
|
||||
|
||||
uint32_t handle;
|
||||
|
||||
uint16_t options;
|
||||
#define VCO_DONT_UPDATE_FW BIT_0
|
||||
#define VCO_FORCE_UPDATE BIT_1
|
||||
#define VCO_DONT_RESET_UPDATE BIT_2
|
||||
#define VCO_DIAG_FW BIT_3
|
||||
#define VCO_END_OF_DATA BIT_14
|
||||
#define VCO_ENABLE_DSD BIT_15
|
||||
|
||||
uint16_t reserved_1;
|
||||
|
||||
uint16_t data_seg_cnt;
|
||||
uint16_t reserved_2[3];
|
||||
|
||||
uint32_t fw_ver;
|
||||
uint32_t exchange_address;
|
||||
|
||||
uint32_t reserved_3[3];
|
||||
uint32_t fw_size;
|
||||
uint32_t fw_seq_size;
|
||||
uint32_t relative_offset;
|
||||
|
||||
uint32_t dseg_address[2];
|
||||
uint32_t dseg_length;
|
||||
};
|
||||
|
||||
struct verify_chip_rsp_84xx {
|
||||
uint8_t entry_type;
|
||||
uint8_t entry_count;
|
||||
uint8_t sys_defined;
|
||||
uint8_t entry_status;
|
||||
|
||||
uint32_t handle;
|
||||
|
||||
uint16_t comp_status;
|
||||
#define CS_VCS_CHIP_FAILURE 0x3
|
||||
#define CS_VCS_BAD_EXCHANGE 0x8
|
||||
#define CS_VCS_SEQ_COMPLETEi 0x40
|
||||
|
||||
uint16_t failure_code;
|
||||
#define VFC_CHECKSUM_ERROR 0x1
|
||||
#define VFC_INVALID_LEN 0x2
|
||||
#define VFC_ALREADY_IN_PROGRESS 0x8
|
||||
|
||||
uint16_t reserved_1[4];
|
||||
|
||||
uint32_t fw_ver;
|
||||
uint32_t exchange_address;
|
||||
|
||||
uint32_t reserved_2[6];
|
||||
};
|
||||
|
||||
#define ACCESS_CHIP_IOCB_TYPE 0x2B
|
||||
struct access_chip_84xx {
|
||||
uint8_t entry_type;
|
||||
uint8_t entry_count;
|
||||
uint8_t sys_defined;
|
||||
uint8_t entry_status;
|
||||
|
||||
uint32_t handle;
|
||||
|
||||
uint16_t options;
|
||||
#define ACO_DUMP_MEMORY 0x0
|
||||
#define ACO_LOAD_MEMORY 0x1
|
||||
#define ACO_CHANGE_CONFIG_PARAM 0x2
|
||||
#define ACO_REQUEST_INFO 0x3
|
||||
|
||||
uint16_t reserved1;
|
||||
|
||||
uint16_t dseg_count;
|
||||
uint16_t reserved2[3];
|
||||
|
||||
uint32_t parameter1;
|
||||
uint32_t parameter2;
|
||||
uint32_t parameter3;
|
||||
|
||||
uint32_t reserved3[3];
|
||||
uint32_t total_byte_cnt;
|
||||
uint32_t reserved4;
|
||||
|
||||
uint32_t dseg_address[2];
|
||||
uint32_t dseg_length;
|
||||
};
|
||||
|
||||
struct access_chip_rsp_84xx {
|
||||
uint8_t entry_type;
|
||||
uint8_t entry_count;
|
||||
uint8_t sys_defined;
|
||||
uint8_t entry_status;
|
||||
|
||||
uint32_t handle;
|
||||
|
||||
uint16_t comp_status;
|
||||
uint16_t failure_code;
|
||||
uint32_t residual_count;
|
||||
|
||||
uint32_t reserved[12];
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
@ -38,9 +38,6 @@ extern int qla2x00_loop_resync(scsi_qla_host_t *);
|
|||
extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
|
||||
extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
|
||||
|
||||
extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t);
|
||||
|
||||
extern void qla2x00_rescan_fcports(scsi_qla_host_t *);
|
||||
extern void qla2x00_update_fcports(scsi_qla_host_t *);
|
||||
|
||||
extern int qla2x00_abort_isp(scsi_qla_host_t *);
|
||||
|
@ -50,6 +47,8 @@ extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
|
|||
extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
|
||||
extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
|
||||
|
||||
extern void qla84xx_put_chip(struct scsi_qla_host *);
|
||||
|
||||
/*
|
||||
* Global Data in qla_os.c source file.
|
||||
*/
|
||||
|
@ -67,6 +66,10 @@ extern int num_hosts;
|
|||
|
||||
extern int qla2x00_loop_reset(scsi_qla_host_t *);
|
||||
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
|
||||
extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
|
||||
fc_host_event_code, u32);
|
||||
extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t,
|
||||
uint16_t, uint16_t);
|
||||
|
||||
/*
|
||||
* Global Functions in qla_mid.c source file.
|
||||
|
@ -148,13 +151,18 @@ qla2x00_verify_checksum(scsi_qla_host_t *, uint32_t);
|
|||
extern int
|
||||
qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t);
|
||||
|
||||
extern int
|
||||
qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *, dma_addr_t, size_t,
|
||||
uint32_t);
|
||||
|
||||
extern int
|
||||
qla2x00_abort_command(scsi_qla_host_t *, srb_t *);
|
||||
|
||||
#if USE_ABORT_TGT
|
||||
extern int
|
||||
qla2x00_abort_target(fc_port_t *);
|
||||
#endif
|
||||
qla2x00_abort_target(struct fc_port *, unsigned int);
|
||||
|
||||
extern int
|
||||
qla2x00_lun_reset(struct fc_port *, unsigned int);
|
||||
|
||||
extern int
|
||||
qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
|
||||
|
@ -220,7 +228,8 @@ qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *,
|
|||
dma_addr_t);
|
||||
|
||||
extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *);
|
||||
extern int qla24xx_abort_target(fc_port_t *);
|
||||
extern int qla24xx_abort_target(struct fc_port *, unsigned int);
|
||||
extern int qla24xx_lun_reset(struct fc_port *, unsigned int);
|
||||
|
||||
extern int
|
||||
qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
|
||||
|
@ -246,6 +255,8 @@ qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
|
|||
extern int
|
||||
qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
|
||||
|
||||
extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *);
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_isr.c source file.
|
||||
*/
|
||||
|
@ -298,6 +309,11 @@ extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
|
|||
extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *);
|
||||
extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
|
||||
|
||||
extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t,
|
||||
uint16_t, uint16_t);
|
||||
|
||||
extern void qla2xxx_get_flash_info(scsi_qla_host_t *);
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_dbg.c source file.
|
||||
*/
|
||||
|
@ -307,7 +323,6 @@ extern void qla24xx_fw_dump(scsi_qla_host_t *, int);
|
|||
extern void qla25xx_fw_dump(scsi_qla_host_t *, int);
|
||||
extern void qla2x00_dump_regs(scsi_qla_host_t *);
|
||||
extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
|
||||
extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *);
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_gs.c source file.
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
#include "qla_def.h"
|
||||
|
||||
static inline struct ct_sns_req *
|
||||
qla2x00_prep_ct_req(struct ct_sns_req *, uint16_t, uint16_t);
|
||||
|
||||
static inline struct sns_cmd_pkt *
|
||||
qla2x00_prep_sns_cmd(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
|
||||
|
||||
static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
|
||||
static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
|
||||
static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
|
||||
|
@ -1538,7 +1532,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
|
|||
eiter->a.sup_speed = __constant_cpu_to_be32(
|
||||
FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
|
||||
FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB);
|
||||
else if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||
else if (IS_QLA24XX_TYPE(ha))
|
||||
eiter->a.sup_speed = __constant_cpu_to_be32(
|
||||
FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
|
||||
FDMI_PORT_SPEED_4GB);
|
||||
|
@ -1847,8 +1841,10 @@ qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list)
|
|||
"GPSC")) != QLA_SUCCESS) {
|
||||
/* FM command unsupported? */
|
||||
if (rval == QLA_INVALID_COMMAND &&
|
||||
ct_rsp->header.reason_code ==
|
||||
CT_REASON_INVALID_COMMAND_CODE) {
|
||||
(ct_rsp->header.reason_code ==
|
||||
CT_REASON_INVALID_COMMAND_CODE ||
|
||||
ct_rsp->header.reason_code ==
|
||||
CT_REASON_COMMAND_UNSUPPORTED)) {
|
||||
DEBUG2(printk("scsi(%ld): GPSC command "
|
||||
"unsupported, disabling query...\n",
|
||||
ha->host_no));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
@ -15,14 +15,6 @@
|
|||
#include <asm/prom.h>
|
||||
#endif
|
||||
|
||||
/* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */
|
||||
#ifndef EXT_IS_LUN_BIT_SET
|
||||
#define EXT_IS_LUN_BIT_SET(P,L) \
|
||||
(((P)->mask[L/8] & (0x80 >> (L%8)))?1:0)
|
||||
#define EXT_SET_LUN_BIT(P,L) \
|
||||
((P)->mask[L/8] |= (0x80 >> (L%8)))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* QLogic ISP2x00 Hardware Support Function Prototypes.
|
||||
*/
|
||||
|
@ -45,6 +37,9 @@ static int qla2x00_restart_isp(scsi_qla_host_t *);
|
|||
|
||||
static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev);
|
||||
|
||||
static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
|
||||
static int qla84xx_init_chip(scsi_qla_host_t *);
|
||||
|
||||
/****************************************************************************/
|
||||
/* QLogic ISP2x00 Hardware Support Functions. */
|
||||
/****************************************************************************/
|
||||
|
@ -114,6 +109,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
|
|||
rval = qla2x00_setup_chip(ha);
|
||||
if (rval)
|
||||
return (rval);
|
||||
qla2xxx_get_flash_info(ha);
|
||||
}
|
||||
if (IS_QLA84XX(ha)) {
|
||||
ha->cs84xx = qla84xx_get_chip(ha);
|
||||
if (!ha->cs84xx) {
|
||||
qla_printk(KERN_ERR, ha,
|
||||
"Unable to configure ISP84XX.\n");
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
}
|
||||
rval = qla2x00_init_rings(ha);
|
||||
|
||||
|
@ -500,6 +504,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha)
|
|||
static inline void
|
||||
qla24xx_reset_risc(scsi_qla_host_t *ha)
|
||||
{
|
||||
int hw_evt = 0;
|
||||
unsigned long flags = 0;
|
||||
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
|
||||
uint32_t cnt, d2;
|
||||
|
@ -528,6 +533,8 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
|
|||
d2 = (uint32_t) RD_REG_WORD(®->mailbox0);
|
||||
barrier();
|
||||
}
|
||||
if (cnt == 0)
|
||||
hw_evt = 1;
|
||||
|
||||
/* Wait for soft-reset to complete. */
|
||||
d2 = RD_REG_DWORD(®->ctrl_status);
|
||||
|
@ -536,6 +543,10 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
|
|||
d2 = RD_REG_DWORD(®->ctrl_status);
|
||||
barrier();
|
||||
}
|
||||
if (cnt == 0 || hw_evt)
|
||||
qla2xxx_hw_event_log(ha, HW_EVENT_RESET_ERR,
|
||||
RD_REG_WORD(®->mailbox1), RD_REG_WORD(®->mailbox2),
|
||||
RD_REG_WORD(®->mailbox3));
|
||||
|
||||
WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET);
|
||||
RD_REG_DWORD(®->hccr);
|
||||
|
@ -1243,10 +1254,10 @@ static int
|
|||
qla2x00_fw_ready(scsi_qla_host_t *ha)
|
||||
{
|
||||
int rval;
|
||||
unsigned long wtime, mtime;
|
||||
unsigned long wtime, mtime, cs84xx_time;
|
||||
uint16_t min_wait; /* Minimum wait time if loop is down */
|
||||
uint16_t wait_time; /* Wait time if loop is coming ready */
|
||||
uint16_t fw_state;
|
||||
uint16_t state[3];
|
||||
|
||||
rval = QLA_SUCCESS;
|
||||
|
||||
|
@ -1275,12 +1286,34 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
|
|||
ha->host_no));
|
||||
|
||||
do {
|
||||
rval = qla2x00_get_firmware_state(ha, &fw_state);
|
||||
rval = qla2x00_get_firmware_state(ha, state);
|
||||
if (rval == QLA_SUCCESS) {
|
||||
if (fw_state < FSTATE_LOSS_OF_SYNC) {
|
||||
if (state[0] < FSTATE_LOSS_OF_SYNC) {
|
||||
ha->device_flags &= ~DFLG_NO_CABLE;
|
||||
}
|
||||
if (fw_state == FSTATE_READY) {
|
||||
if (IS_QLA84XX(ha) && state[0] != FSTATE_READY) {
|
||||
DEBUG16(printk("scsi(%ld): fw_state=%x "
|
||||
"84xx=%x.\n", ha->host_no, state[0],
|
||||
state[2]));
|
||||
if ((state[2] & FSTATE_LOGGED_IN) &&
|
||||
(state[2] & FSTATE_WAITING_FOR_VERIFY)) {
|
||||
DEBUG16(printk("scsi(%ld): Sending "
|
||||
"verify iocb.\n", ha->host_no));
|
||||
|
||||
cs84xx_time = jiffies;
|
||||
rval = qla84xx_init_chip(ha);
|
||||
if (rval != QLA_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Add time taken to initialize. */
|
||||
cs84xx_time = jiffies - cs84xx_time;
|
||||
wtime += cs84xx_time;
|
||||
mtime += cs84xx_time;
|
||||
DEBUG16(printk("scsi(%ld): Increasing "
|
||||
"wait time by %ld. New time %ld\n",
|
||||
ha->host_no, cs84xx_time, wtime));
|
||||
}
|
||||
} else if (state[0] == FSTATE_READY) {
|
||||
DEBUG(printk("scsi(%ld): F/W Ready - OK \n",
|
||||
ha->host_no));
|
||||
|
||||
|
@ -1294,7 +1327,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
|
|||
rval = QLA_FUNCTION_FAILED;
|
||||
|
||||
if (atomic_read(&ha->loop_down_timer) &&
|
||||
fw_state != FSTATE_READY) {
|
||||
state[0] != FSTATE_READY) {
|
||||
/* Loop down. Timeout on min_wait for states
|
||||
* other than Wait for Login.
|
||||
*/
|
||||
|
@ -1319,11 +1352,11 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
|
|||
msleep(500);
|
||||
|
||||
DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n",
|
||||
ha->host_no, fw_state, jiffies));
|
||||
ha->host_no, state[0], jiffies));
|
||||
} while (1);
|
||||
|
||||
DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n",
|
||||
ha->host_no, fw_state, jiffies));
|
||||
ha->host_no, state[0], jiffies));
|
||||
|
||||
if (rval) {
|
||||
DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n",
|
||||
|
@ -1555,6 +1588,10 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
|
|||
qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet "
|
||||
"invalid -- WWPN) defaults.\n");
|
||||
|
||||
if (chksum)
|
||||
qla2xxx_hw_event_log(ha, HW_EVENT_NVRAM_CHKSUM_ERR, 0,
|
||||
MSW(chksum), LSW(chksum));
|
||||
|
||||
/*
|
||||
* Set default initialization control block.
|
||||
*/
|
||||
|
@ -2164,20 +2201,6 @@ cleanup_allocation:
|
|||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
|
||||
{
|
||||
fc_port_t *fcport;
|
||||
|
||||
qla2x00_mark_all_devices_lost(ha, 0);
|
||||
list_for_each_entry(fcport, &ha->fcports, list) {
|
||||
if (fcport->port_type != FCT_TARGET)
|
||||
continue;
|
||||
|
||||
qla2x00_update_fcport(ha, fcport);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
|
||||
{
|
||||
|
@ -2251,10 +2274,6 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
|
|||
if (fcport->port_type == FCT_TARGET)
|
||||
rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
|
||||
fc_remote_port_rolechg(rport, rport_ids.roles);
|
||||
|
||||
if (rport->scsi_target_id != -1 &&
|
||||
rport->scsi_target_id < ha->host->max_id)
|
||||
fcport->os_target_id = rport->scsi_target_id;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2434,7 +2453,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
|
|||
|
||||
if (fcport->loop_id == FC_NO_LOOP_ID) {
|
||||
fcport->loop_id = next_loopid;
|
||||
rval = qla2x00_find_new_loop_id(ha, fcport);
|
||||
rval = qla2x00_find_new_loop_id(
|
||||
to_qla_parent(ha), fcport);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
/* Ran out of IDs to use */
|
||||
break;
|
||||
|
@ -2459,7 +2479,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
|
|||
|
||||
/* Find a new loop ID to use. */
|
||||
fcport->loop_id = next_loopid;
|
||||
rval = qla2x00_find_new_loop_id(ha, fcport);
|
||||
rval = qla2x00_find_new_loop_id(to_qla_parent(ha),
|
||||
fcport);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
/* Ran out of IDs to use */
|
||||
break;
|
||||
|
@ -3192,25 +3213,6 @@ qla2x00_loop_resync(scsi_qla_host_t *ha)
|
|||
return (rval);
|
||||
}
|
||||
|
||||
void
|
||||
qla2x00_rescan_fcports(scsi_qla_host_t *ha)
|
||||
{
|
||||
int rescan_done;
|
||||
fc_port_t *fcport;
|
||||
|
||||
rescan_done = 0;
|
||||
list_for_each_entry(fcport, &ha->fcports, list) {
|
||||
if ((fcport->flags & FCF_RESCAN_NEEDED) == 0)
|
||||
continue;
|
||||
|
||||
qla2x00_update_fcport(ha, fcport);
|
||||
fcport->flags &= ~FCF_RESCAN_NEEDED;
|
||||
|
||||
rescan_done = 1;
|
||||
}
|
||||
qla2x00_probe_for_all_luns(ha);
|
||||
}
|
||||
|
||||
void
|
||||
qla2x00_update_fcports(scsi_qla_host_t *ha)
|
||||
{
|
||||
|
@ -4044,16 +4046,16 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha)
|
|||
if (!ha->parent)
|
||||
return -EINVAL;
|
||||
|
||||
rval = qla2x00_fw_ready(ha);
|
||||
rval = qla2x00_fw_ready(ha->parent);
|
||||
if (rval == QLA_SUCCESS) {
|
||||
clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
|
||||
qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
|
||||
qla2x00_marker(ha->parent, 0, 0, MK_SYNC_ALL);
|
||||
}
|
||||
|
||||
ha->flags.management_server_logged_in = 0;
|
||||
|
||||
/* Login to SNS first */
|
||||
qla24xx_login_fabric(ha, NPH_SNS, 0xff, 0xff, 0xfc,
|
||||
qla24xx_login_fabric(ha->parent, NPH_SNS, 0xff, 0xff, 0xfc,
|
||||
mb, BIT_1);
|
||||
if (mb[0] != MBS_COMMAND_COMPLETE) {
|
||||
DEBUG15(qla_printk(KERN_INFO, ha,
|
||||
|
@ -4067,7 +4069,77 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha)
|
|||
atomic_set(&ha->loop_state, LOOP_UP);
|
||||
set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
|
||||
set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
|
||||
rval = qla2x00_loop_resync(ha);
|
||||
rval = qla2x00_loop_resync(ha->parent);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* 84XX Support **************************************************************/
|
||||
|
||||
static LIST_HEAD(qla_cs84xx_list);
|
||||
static DEFINE_MUTEX(qla_cs84xx_mutex);
|
||||
|
||||
static struct qla_chip_state_84xx *
|
||||
qla84xx_get_chip(struct scsi_qla_host *ha)
|
||||
{
|
||||
struct qla_chip_state_84xx *cs84xx;
|
||||
|
||||
mutex_lock(&qla_cs84xx_mutex);
|
||||
|
||||
/* Find any shared 84xx chip. */
|
||||
list_for_each_entry(cs84xx, &qla_cs84xx_list, list) {
|
||||
if (cs84xx->bus == ha->pdev->bus) {
|
||||
kref_get(&cs84xx->kref);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
cs84xx = kzalloc(sizeof(*cs84xx), GFP_KERNEL);
|
||||
if (!cs84xx)
|
||||
goto done;
|
||||
|
||||
kref_init(&cs84xx->kref);
|
||||
spin_lock_init(&cs84xx->access_lock);
|
||||
mutex_init(&cs84xx->fw_update_mutex);
|
||||
cs84xx->bus = ha->pdev->bus;
|
||||
|
||||
list_add_tail(&cs84xx->list, &qla_cs84xx_list);
|
||||
done:
|
||||
mutex_unlock(&qla_cs84xx_mutex);
|
||||
return cs84xx;
|
||||
}
|
||||
|
||||
static void
|
||||
__qla84xx_chip_release(struct kref *kref)
|
||||
{
|
||||
struct qla_chip_state_84xx *cs84xx =
|
||||
container_of(kref, struct qla_chip_state_84xx, kref);
|
||||
|
||||
mutex_lock(&qla_cs84xx_mutex);
|
||||
list_del(&cs84xx->list);
|
||||
mutex_unlock(&qla_cs84xx_mutex);
|
||||
kfree(cs84xx);
|
||||
}
|
||||
|
||||
void
|
||||
qla84xx_put_chip(struct scsi_qla_host *ha)
|
||||
{
|
||||
if (ha->cs84xx)
|
||||
kref_put(&ha->cs84xx->kref, __qla84xx_chip_release);
|
||||
}
|
||||
|
||||
static int
|
||||
qla84xx_init_chip(scsi_qla_host_t *ha)
|
||||
{
|
||||
int rval;
|
||||
uint16_t status[2];
|
||||
|
||||
mutex_lock(&ha->cs84xx->fw_update_mutex);
|
||||
|
||||
rval = qla84xx_verify_chip(ha, status);
|
||||
|
||||
mutex_unlock(&ha->cs84xx->fw_update_mutex);
|
||||
|
||||
return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED:
|
||||
QLA_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
||||
static __inline__ uint16_t qla2x00_debounce_register(volatile uint16_t __iomem *);
|
||||
/*
|
||||
* qla2x00_debounce_register
|
||||
* Debounce register.
|
||||
|
@ -32,94 +31,12 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr)
|
|||
return (first);
|
||||
}
|
||||
|
||||
static __inline__ int qla2x00_normalize_dma_addr(
|
||||
dma_addr_t *e_addr, uint32_t *e_len,
|
||||
dma_addr_t *ne_addr, uint32_t *ne_len);
|
||||
|
||||
/**
|
||||
* qla2x00_normalize_dma_addr() - Normalize an DMA address.
|
||||
* @e_addr: Raw DMA address
|
||||
* @e_len: Raw DMA length
|
||||
* @ne_addr: Normalized second DMA address
|
||||
* @ne_len: Normalized second DMA length
|
||||
*
|
||||
* If the address does not span a 4GB page boundary, the contents of @ne_addr
|
||||
* and @ne_len are undefined. @e_len is updated to reflect a normalization.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ffffabc0ffffeeee (e_addr) start of DMA address
|
||||
* 0000000020000000 (e_len) length of DMA transfer
|
||||
* ffffabc11fffeeed end of DMA transfer
|
||||
*
|
||||
* Is the 4GB boundary crossed?
|
||||
*
|
||||
* ffffabc0ffffeeee (e_addr)
|
||||
* ffffabc11fffeeed (e_addr + e_len - 1)
|
||||
* 00000001e0000003 ((e_addr ^ (e_addr + e_len - 1))
|
||||
* 0000000100000000 ((e_addr ^ (e_addr + e_len - 1)) & ~(0xffffffff)
|
||||
*
|
||||
* Compute start of second DMA segment:
|
||||
*
|
||||
* ffffabc0ffffeeee (e_addr)
|
||||
* ffffabc1ffffeeee (0x100000000 + e_addr)
|
||||
* ffffabc100000000 (0x100000000 + e_addr) & ~(0xffffffff)
|
||||
* ffffabc100000000 (ne_addr)
|
||||
*
|
||||
* Compute length of second DMA segment:
|
||||
*
|
||||
* 00000000ffffeeee (e_addr & 0xffffffff)
|
||||
* 0000000000001112 (0x100000000 - (e_addr & 0xffffffff))
|
||||
* 000000001fffeeee (e_len - (0x100000000 - (e_addr & 0xffffffff))
|
||||
* 000000001fffeeee (ne_len)
|
||||
*
|
||||
* Adjust length of first DMA segment
|
||||
*
|
||||
* 0000000020000000 (e_len)
|
||||
* 0000000000001112 (e_len - ne_len)
|
||||
* 0000000000001112 (e_len)
|
||||
*
|
||||
* Returns non-zero if the specified address was normalized, else zero.
|
||||
*/
|
||||
static __inline__ int
|
||||
qla2x00_normalize_dma_addr(
|
||||
dma_addr_t *e_addr, uint32_t *e_len,
|
||||
dma_addr_t *ne_addr, uint32_t *ne_len)
|
||||
{
|
||||
int normalized;
|
||||
|
||||
normalized = 0;
|
||||
if ((*e_addr ^ (*e_addr + *e_len - 1)) & ~(0xFFFFFFFFULL)) {
|
||||
/* Compute normalized crossed address and len */
|
||||
*ne_addr = (0x100000000ULL + *e_addr) & ~(0xFFFFFFFFULL);
|
||||
*ne_len = *e_len - (0x100000000ULL - (*e_addr & 0xFFFFFFFFULL));
|
||||
*e_len -= *ne_len;
|
||||
|
||||
normalized++;
|
||||
}
|
||||
return (normalized);
|
||||
}
|
||||
|
||||
static __inline__ void qla2x00_poll(scsi_qla_host_t *);
|
||||
static inline void
|
||||
qla2x00_poll(scsi_qla_host_t *ha)
|
||||
{
|
||||
ha->isp_ops->intr_handler(0, ha);
|
||||
}
|
||||
|
||||
static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *);
|
||||
/*
|
||||
* This routine will wait for fabric devices for
|
||||
* the reset delay.
|
||||
*/
|
||||
static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *ha)
|
||||
{
|
||||
uint16_t fw_state;
|
||||
|
||||
qla2x00_get_firmware_state(ha, &fw_state);
|
||||
}
|
||||
|
||||
static __inline__ scsi_qla_host_t * to_qla_parent(scsi_qla_host_t *);
|
||||
static __inline__ scsi_qla_host_t *
|
||||
to_qla_parent(scsi_qla_host_t *ha)
|
||||
{
|
||||
|
@ -152,7 +69,6 @@ qla2x00_issue_marker(scsi_qla_host_t *ha, int ha_locked)
|
|||
return (QLA_SUCCESS);
|
||||
}
|
||||
|
||||
static inline uint8_t *host_to_fcp_swap(uint8_t *, uint32_t);
|
||||
static inline uint8_t *
|
||||
host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
|
||||
{
|
||||
|
@ -166,7 +82,6 @@ host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
|
|||
return fcp;
|
||||
}
|
||||
|
||||
static inline int qla2x00_is_reserved_id(scsi_qla_host_t *, uint16_t);
|
||||
static inline int
|
||||
qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
@ -11,9 +11,6 @@
|
|||
|
||||
#include <scsi/scsi_tcq.h>
|
||||
|
||||
static inline uint16_t qla2x00_get_cmd_direction(struct scsi_cmnd *cmd);
|
||||
static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *);
|
||||
static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *);
|
||||
static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
|
||||
static void qla2x00_isp_cmd(scsi_qla_host_t *ha);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
@ -14,9 +14,6 @@ static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
|
|||
static void qla2x00_status_entry(scsi_qla_host_t *, void *);
|
||||
static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
|
||||
static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
|
||||
static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);
|
||||
|
||||
static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *);
|
||||
|
||||
/**
|
||||
* qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
|
||||
|
@ -33,7 +30,6 @@ qla2100_intr_handler(int irq, void *dev_id)
|
|||
scsi_qla_host_t *ha;
|
||||
struct device_reg_2xxx __iomem *reg;
|
||||
int status;
|
||||
unsigned long flags;
|
||||
unsigned long iter;
|
||||
uint16_t hccr;
|
||||
uint16_t mb[4];
|
||||
|
@ -48,7 +44,7 @@ qla2100_intr_handler(int irq, void *dev_id)
|
|||
reg = &ha->iobase->isp;
|
||||
status = 0;
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
spin_lock(&ha->hardware_lock);
|
||||
for (iter = 50; iter--; ) {
|
||||
hccr = RD_REG_WORD(®->hccr);
|
||||
if (hccr & HCCR_RISC_PAUSE) {
|
||||
|
@ -99,7 +95,7 @@ qla2100_intr_handler(int irq, void *dev_id)
|
|||
RD_REG_WORD(®->hccr);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
spin_unlock(&ha->hardware_lock);
|
||||
|
||||
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
|
||||
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
|
||||
|
@ -125,7 +121,6 @@ qla2300_intr_handler(int irq, void *dev_id)
|
|||
scsi_qla_host_t *ha;
|
||||
struct device_reg_2xxx __iomem *reg;
|
||||
int status;
|
||||
unsigned long flags;
|
||||
unsigned long iter;
|
||||
uint32_t stat;
|
||||
uint16_t hccr;
|
||||
|
@ -141,7 +136,7 @@ qla2300_intr_handler(int irq, void *dev_id)
|
|||
reg = &ha->iobase->isp;
|
||||
status = 0;
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
spin_lock(&ha->hardware_lock);
|
||||
for (iter = 50; iter--; ) {
|
||||
stat = RD_REG_DWORD(®->u.isp2300.host_status);
|
||||
if (stat & HSR_RISC_PAUSED) {
|
||||
|
@ -211,7 +206,7 @@ qla2300_intr_handler(int irq, void *dev_id)
|
|||
WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT);
|
||||
RD_REG_WORD_RELAXED(®->hccr);
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
spin_unlock(&ha->hardware_lock);
|
||||
|
||||
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
|
||||
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
|
||||
|
@ -276,6 +271,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
|
||||
uint32_t rscn_entry, host_pid;
|
||||
uint8_t rscn_queue_index;
|
||||
unsigned long flags;
|
||||
scsi_qla_host_t *vha;
|
||||
int i;
|
||||
|
||||
/* Setup to process RIO completion. */
|
||||
handle_cnt = 0;
|
||||
|
@ -351,6 +349,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
"ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
|
||||
mb[1], mb[2], mb[3]);
|
||||
|
||||
qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]);
|
||||
ha->isp_ops->fw_dump(ha, 1);
|
||||
|
||||
if (IS_FWI2_CAPABLE(ha)) {
|
||||
|
@ -375,6 +374,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
ha->host_no));
|
||||
qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n");
|
||||
|
||||
qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]);
|
||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||
break;
|
||||
|
||||
|
@ -383,6 +383,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
ha->host_no));
|
||||
qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n");
|
||||
|
||||
qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]);
|
||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||
break;
|
||||
|
||||
|
@ -410,6 +411,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
|
||||
|
||||
ha->flags.management_server_logged_in = 0;
|
||||
qla2x00_post_aen_work(ha, FCH_EVT_LIP, mb[1]);
|
||||
break;
|
||||
|
||||
case MBA_LOOP_UP: /* Loop Up Event */
|
||||
|
@ -429,12 +431,14 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
link_speed);
|
||||
|
||||
ha->flags.management_server_logged_in = 0;
|
||||
qla2x00_post_aen_work(ha, FCH_EVT_LINKUP, ha->link_data_rate);
|
||||
break;
|
||||
|
||||
case MBA_LOOP_DOWN: /* Loop Down Event */
|
||||
DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n",
|
||||
ha->host_no, mb[1]));
|
||||
qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]);
|
||||
DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN "
|
||||
"(%x %x %x).\n", ha->host_no, mb[1], mb[2], mb[3]));
|
||||
qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n",
|
||||
mb[1], mb[2], mb[3]);
|
||||
|
||||
if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
|
||||
atomic_set(&ha->loop_state, LOOP_DOWN);
|
||||
|
@ -452,6 +456,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
ha->link_data_rate = PORT_SPEED_UNKNOWN;
|
||||
if (ql2xfdmienable)
|
||||
set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
|
||||
qla2x00_post_aen_work(ha, FCH_EVT_LINKDOWN, 0);
|
||||
break;
|
||||
|
||||
case MBA_LIP_RESET: /* LIP reset occurred */
|
||||
|
@ -475,6 +480,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
|
||||
ha->operating_mode = LOOP;
|
||||
ha->flags.management_server_logged_in = 0;
|
||||
qla2x00_post_aen_work(ha, FCH_EVT_LIPRESET, mb[1]);
|
||||
break;
|
||||
|
||||
case MBA_POINT_TO_POINT: /* Point-to-Point */
|
||||
|
@ -538,6 +544,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
break;
|
||||
|
||||
case MBA_PORT_UPDATE: /* Port database update */
|
||||
if ((ha->flags.npiv_supported) && (ha->num_vhosts)) {
|
||||
for_each_mapped_vp_idx(ha, i) {
|
||||
list_for_each_entry(vha, &ha->vp_list,
|
||||
vp_list) {
|
||||
if ((mb[3] & 0xff)
|
||||
== vha->vp_idx) {
|
||||
ha = vha;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
|
||||
* event etc. earlier indicating loop is down) then process
|
||||
|
@ -572,12 +590,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
break;
|
||||
|
||||
case MBA_RSCN_UPDATE: /* State Change Registration */
|
||||
/* Check if the Vport has issued a SCR */
|
||||
if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags))
|
||||
break;
|
||||
/* Only handle SCNs for our Vport index. */
|
||||
if (ha->flags.npiv_supported && ha->vp_idx != mb[3])
|
||||
break;
|
||||
if ((ha->flags.npiv_supported) && (ha->num_vhosts)) {
|
||||
for_each_mapped_vp_idx(ha, i) {
|
||||
list_for_each_entry(vha, &ha->vp_list,
|
||||
vp_list) {
|
||||
if ((mb[3] & 0xff)
|
||||
== vha->vp_idx) {
|
||||
ha = vha;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
|
||||
ha->host_no));
|
||||
|
@ -612,6 +636,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
|
||||
set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
|
||||
set_bit(RSCN_UPDATE, &ha->dpc_flags);
|
||||
qla2x00_post_aen_work(ha, FCH_EVT_RSCN, rscn_entry);
|
||||
break;
|
||||
|
||||
/* case MBA_RIO_RESPONSE: */
|
||||
|
@ -637,6 +662,42 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n",
|
||||
ha->host_no, mb[1], mb[2]));
|
||||
break;
|
||||
|
||||
case MBA_ISP84XX_ALERT:
|
||||
DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- "
|
||||
"%04x %04x %04x\n", ha->host_no, mb[1], mb[2], mb[3]));
|
||||
|
||||
spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
|
||||
switch (mb[1]) {
|
||||
case A84_PANIC_RECOVERY:
|
||||
qla_printk(KERN_INFO, ha, "Alert 84XX: panic recovery "
|
||||
"%04x %04x\n", mb[2], mb[3]);
|
||||
break;
|
||||
case A84_OP_LOGIN_COMPLETE:
|
||||
ha->cs84xx->op_fw_version = mb[3] << 16 | mb[2];
|
||||
DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:"
|
||||
"firmware version %x\n", ha->cs84xx->op_fw_version));
|
||||
break;
|
||||
case A84_DIAG_LOGIN_COMPLETE:
|
||||
ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2];
|
||||
DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:"
|
||||
"diagnostic firmware version %x\n",
|
||||
ha->cs84xx->diag_fw_version));
|
||||
break;
|
||||
case A84_GOLD_LOGIN_COMPLETE:
|
||||
ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2];
|
||||
ha->cs84xx->fw_update = 1;
|
||||
DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX: gold "
|
||||
"firmware version %x\n",
|
||||
ha->cs84xx->gold_fw_version));
|
||||
break;
|
||||
default:
|
||||
qla_printk(KERN_ERR, ha,
|
||||
"Alert 84xx: Invalid Alert %04x %04x %04x\n",
|
||||
mb[1], mb[2], mb[3]);
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->cs84xx->access_lock, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ha->parent && ha->num_vhosts)
|
||||
|
@ -803,9 +864,6 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha)
|
|||
case STATUS_CONT_TYPE:
|
||||
qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
|
||||
break;
|
||||
case MS_IOCB_TYPE:
|
||||
qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt);
|
||||
break;
|
||||
default:
|
||||
/* Type Not Supported. */
|
||||
DEBUG4(printk(KERN_WARNING
|
||||
|
@ -1339,44 +1397,6 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* qla2x00_ms_entry() - Process a Management Server entry.
|
||||
* @ha: SCSI driver HA context
|
||||
* @index: Response queue out pointer
|
||||
*/
|
||||
static void
|
||||
qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
|
||||
{
|
||||
srb_t *sp;
|
||||
|
||||
DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
|
||||
__func__, ha->host_no, pkt, pkt->handle1));
|
||||
|
||||
/* Validate handle. */
|
||||
if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS)
|
||||
sp = ha->outstanding_cmds[pkt->handle1];
|
||||
else
|
||||
sp = NULL;
|
||||
|
||||
if (sp == NULL) {
|
||||
DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
|
||||
ha->host_no));
|
||||
qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n");
|
||||
|
||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||
return;
|
||||
}
|
||||
|
||||
CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status);
|
||||
CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
|
||||
|
||||
/* Free outstanding command slot. */
|
||||
ha->outstanding_cmds[pkt->handle1] = NULL;
|
||||
|
||||
qla2x00_sp_compl(ha, sp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* qla24xx_mbx_completion() - Process mailbox command completions.
|
||||
* @ha: SCSI driver HA context
|
||||
|
@ -1449,9 +1469,6 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha)
|
|||
case STATUS_CONT_TYPE:
|
||||
qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
|
||||
break;
|
||||
case MS_IOCB_TYPE:
|
||||
qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt);
|
||||
break;
|
||||
case VP_RPT_ID_IOCB_TYPE:
|
||||
qla24xx_report_id_acquisition(ha,
|
||||
(struct vp_rpt_id_entry_24xx *)pkt);
|
||||
|
@ -1533,7 +1550,6 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
|||
scsi_qla_host_t *ha;
|
||||
struct device_reg_24xx __iomem *reg;
|
||||
int status;
|
||||
unsigned long flags;
|
||||
unsigned long iter;
|
||||
uint32_t stat;
|
||||
uint32_t hccr;
|
||||
|
@ -1549,13 +1565,19 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
|||
reg = &ha->iobase->isp24;
|
||||
status = 0;
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
spin_lock(&ha->hardware_lock);
|
||||
for (iter = 50; iter--; ) {
|
||||
stat = RD_REG_DWORD(®->host_status);
|
||||
if (stat & HSRX_RISC_PAUSED) {
|
||||
if (pci_channel_offline(ha->pdev))
|
||||
break;
|
||||
|
||||
if (ha->hw_event_pause_errors == 0)
|
||||
qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR,
|
||||
0, MSW(stat), LSW(stat));
|
||||
else if (ha->hw_event_pause_errors < 0xffffffff)
|
||||
ha->hw_event_pause_errors++;
|
||||
|
||||
hccr = RD_REG_DWORD(®->hccr);
|
||||
|
||||
qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
|
||||
|
@ -1597,7 +1619,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
|||
WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT);
|
||||
RD_REG_DWORD_RELAXED(®->hccr);
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
spin_unlock(&ha->hardware_lock);
|
||||
|
||||
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
|
||||
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
|
||||
|
@ -1608,66 +1630,21 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* qla24xx_ms_entry() - Process a Management Server entry.
|
||||
* @ha: SCSI driver HA context
|
||||
* @index: Response queue out pointer
|
||||
*/
|
||||
static void
|
||||
qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt)
|
||||
{
|
||||
srb_t *sp;
|
||||
|
||||
DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
|
||||
__func__, ha->host_no, pkt, pkt->handle));
|
||||
|
||||
DEBUG9(printk("%s: ct pkt dump:\n", __func__));
|
||||
DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx)));
|
||||
|
||||
/* Validate handle. */
|
||||
if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
|
||||
sp = ha->outstanding_cmds[pkt->handle];
|
||||
else
|
||||
sp = NULL;
|
||||
|
||||
if (sp == NULL) {
|
||||
DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
|
||||
ha->host_no));
|
||||
DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n",
|
||||
ha->host_no));
|
||||
qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n",
|
||||
pkt->handle);
|
||||
|
||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||
return;
|
||||
}
|
||||
|
||||
CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status);
|
||||
CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
|
||||
|
||||
/* Free outstanding command slot. */
|
||||
ha->outstanding_cmds[pkt->handle] = NULL;
|
||||
|
||||
qla2x00_sp_compl(ha, sp);
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
qla24xx_msix_rsp_q(int irq, void *dev_id)
|
||||
{
|
||||
scsi_qla_host_t *ha;
|
||||
struct device_reg_24xx __iomem *reg;
|
||||
unsigned long flags;
|
||||
|
||||
ha = dev_id;
|
||||
reg = &ha->iobase->isp24;
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
spin_lock(&ha->hardware_lock);
|
||||
|
||||
qla24xx_process_response_queue(ha);
|
||||
|
||||
WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT);
|
||||
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
spin_unlock(&ha->hardware_lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -1678,7 +1655,6 @@ qla24xx_msix_default(int irq, void *dev_id)
|
|||
scsi_qla_host_t *ha;
|
||||
struct device_reg_24xx __iomem *reg;
|
||||
int status;
|
||||
unsigned long flags;
|
||||
uint32_t stat;
|
||||
uint32_t hccr;
|
||||
uint16_t mb[4];
|
||||
|
@ -1687,13 +1663,19 @@ qla24xx_msix_default(int irq, void *dev_id)
|
|||
reg = &ha->iobase->isp24;
|
||||
status = 0;
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
spin_lock(&ha->hardware_lock);
|
||||
do {
|
||||
stat = RD_REG_DWORD(®->host_status);
|
||||
if (stat & HSRX_RISC_PAUSED) {
|
||||
if (pci_channel_offline(ha->pdev))
|
||||
break;
|
||||
|
||||
if (ha->hw_event_pause_errors == 0)
|
||||
qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR,
|
||||
0, MSW(stat), LSW(stat));
|
||||
else if (ha->hw_event_pause_errors < 0xffffffff)
|
||||
ha->hw_event_pause_errors++;
|
||||
|
||||
hccr = RD_REG_DWORD(®->hccr);
|
||||
|
||||
qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
|
||||
|
@ -1734,7 +1716,7 @@ qla24xx_msix_default(int irq, void *dev_id)
|
|||
}
|
||||
WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT);
|
||||
} while (0);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
spin_unlock(&ha->hardware_lock);
|
||||
|
||||
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
|
||||
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
|
||||
|
@ -1821,10 +1803,9 @@ qla2x00_request_irqs(scsi_qla_host_t *ha)
|
|||
{
|
||||
int ret;
|
||||
device_reg_t __iomem *reg = ha->iobase;
|
||||
unsigned long flags;
|
||||
|
||||
/* If possible, enable MSI-X. */
|
||||
if (!IS_QLA2432(ha) && !IS_QLA2532(ha))
|
||||
if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha))
|
||||
goto skip_msix;
|
||||
|
||||
if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX ||
|
||||
|
@ -1859,7 +1840,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha)
|
|||
"MSI-X: Falling back-to INTa mode -- %d.\n", ret);
|
||||
skip_msix:
|
||||
|
||||
if (!IS_QLA24XX(ha) && !IS_QLA2532(ha))
|
||||
if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha))
|
||||
goto skip_msi;
|
||||
|
||||
ret = pci_enable_msi(ha->pdev);
|
||||
|
@ -1882,7 +1863,7 @@ skip_msi:
|
|||
clear_risc_ints:
|
||||
|
||||
ha->isp_ops->disable_intrs(ha);
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
spin_lock_irq(&ha->hardware_lock);
|
||||
if (IS_FWI2_CAPABLE(ha)) {
|
||||
WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT);
|
||||
WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT);
|
||||
|
@ -1891,7 +1872,7 @@ clear_risc_ints:
|
|||
WRT_REG_WORD(®->isp.hccr, HCCR_CLR_RISC_INT);
|
||||
WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT);
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
spin_unlock_irq(&ha->hardware_lock);
|
||||
ha->isp_ops->enable_intrs(ha);
|
||||
|
||||
fail:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
@ -310,7 +310,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr,
|
|||
}
|
||||
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -367,7 +367,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr)
|
|||
}
|
||||
}
|
||||
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -417,7 +417,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor,
|
|||
mcp->out_mb = MBX_0;
|
||||
mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->flags = 0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
/* Return mailbox data. */
|
||||
|
@ -466,7 +466,7 @@ qla2x00_get_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
|
|||
mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
|
||||
mcp->out_mb = MBX_0;
|
||||
mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -524,7 +524,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
|
|||
mcp->mb[12] = 0; /* Undocumented, but used */
|
||||
mcp->out_mb |= MBX_12|MBX_11|MBX_10;
|
||||
}
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -576,7 +576,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha)
|
|||
mcp->mb[7] = 0x2525;
|
||||
mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -587,6 +587,14 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha)
|
|||
if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
|
||||
mcp->mb[7] != 0x2525)
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
if (rval == QLA_FUNCTION_FAILED) {
|
||||
struct device_reg_24xx __iomem *reg =
|
||||
&ha->iobase->isp24;
|
||||
|
||||
qla2xxx_hw_event_log(ha, HW_EVENT_ISP_ERR, 0,
|
||||
LSW(RD_REG_DWORD(®->hccr)),
|
||||
LSW(RD_REG_DWORD(®->istatus)));
|
||||
}
|
||||
}
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
|
@ -640,7 +648,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr)
|
|||
mcp->in_mb |= MBX_1;
|
||||
}
|
||||
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -674,8 +682,8 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr)
|
|||
* Kernel context.
|
||||
*/
|
||||
int
|
||||
qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr,
|
||||
size_t size)
|
||||
qla2x00_issue_iocb_timeout(scsi_qla_host_t *ha, void *buffer,
|
||||
dma_addr_t phys_addr, size_t size, uint32_t tov)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
|
@ -689,7 +697,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr,
|
|||
mcp->mb[7] = LSW(MSD(phys_addr));
|
||||
mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_2|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = tov;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -710,6 +718,14 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr,
|
|||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_issue_iocb(scsi_qla_host_t *ha, void *buffer, dma_addr_t phys_addr,
|
||||
size_t size)
|
||||
{
|
||||
return qla2x00_issue_iocb_timeout(ha, buffer, phys_addr, size,
|
||||
MBX_TOV_SECONDS);
|
||||
}
|
||||
|
||||
/*
|
||||
* qla2x00_abort_command
|
||||
* Abort command aborts a specified IOCB.
|
||||
|
@ -760,7 +776,7 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp)
|
|||
mcp->mb[6] = (uint16_t)sp->cmd->device->lun;
|
||||
mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -776,36 +792,20 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp)
|
|||
return rval;
|
||||
}
|
||||
|
||||
#if USE_ABORT_TGT
|
||||
/*
|
||||
* qla2x00_abort_target
|
||||
* Issue abort target mailbox command.
|
||||
*
|
||||
* Input:
|
||||
* ha = adapter block pointer.
|
||||
*
|
||||
* Returns:
|
||||
* qla2x00 local function return status code.
|
||||
*
|
||||
* Context:
|
||||
* Kernel context.
|
||||
*/
|
||||
int
|
||||
qla2x00_abort_target(fc_port_t *fcport)
|
||||
qla2x00_abort_target(struct fc_port *fcport, unsigned int l)
|
||||
{
|
||||
int rval;
|
||||
int rval, rval2;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
scsi_qla_host_t *ha;
|
||||
|
||||
if (fcport == NULL)
|
||||
return 0;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
|
||||
|
||||
l = l;
|
||||
ha = fcport->ha;
|
||||
mcp->mb[0] = MBC_ABORT_TARGET;
|
||||
mcp->out_mb = MBX_2|MBX_1|MBX_0;
|
||||
mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
|
||||
if (HAS_EXTENDED_IDS(ha)) {
|
||||
mcp->mb[1] = fcport->loop_id;
|
||||
mcp->mb[10] = 0;
|
||||
|
@ -814,27 +814,70 @@ qla2x00_abort_target(fc_port_t *fcport)
|
|||
mcp->mb[1] = fcport->loop_id << 8;
|
||||
}
|
||||
mcp->mb[2] = ha->loop_reset_delay;
|
||||
mcp->mb[9] = ha->vp_idx;
|
||||
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
/* Issue marker command. */
|
||||
ha->marker_needed = 1;
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n",
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
|
||||
ha->host_no, rval));
|
||||
}
|
||||
|
||||
/* Issue marker IOCB. */
|
||||
rval2 = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID);
|
||||
if (rval2 != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
|
||||
"(%x).\n", __func__, ha->host_no, rval2));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("qla2x00_abort_target(%ld): done.\n",
|
||||
ha->host_no));
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_lun_reset(struct fc_port *fcport, unsigned int l)
|
||||
{
|
||||
int rval, rval2;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
scsi_qla_host_t *ha;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
|
||||
|
||||
ha = fcport->ha;
|
||||
mcp->mb[0] = MBC_LUN_RESET;
|
||||
mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
if (HAS_EXTENDED_IDS(ha))
|
||||
mcp->mb[1] = fcport->loop_id;
|
||||
else
|
||||
mcp->mb[1] = fcport->loop_id << 8;
|
||||
mcp->mb[2] = l;
|
||||
mcp->mb[3] = 0;
|
||||
mcp->mb[9] = ha->vp_idx;
|
||||
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
|
||||
ha->host_no, rval));
|
||||
}
|
||||
|
||||
/* Issue marker IOCB. */
|
||||
rval2 = qla2x00_marker(ha, fcport->loop_id, l, MK_SYNC_ID_LUN);
|
||||
if (rval2 != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
|
||||
"(%x).\n", __func__, ha->host_no, rval2));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* qla2x00_get_adapter_id
|
||||
|
@ -871,7 +914,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
|
|||
mcp->mb[9] = ha->vp_idx;
|
||||
mcp->out_mb = MBX_9|MBX_0;
|
||||
mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
if (mcp->mb[0] == MBS_COMMAND_ERROR)
|
||||
|
@ -928,7 +971,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov,
|
|||
mcp->mb[0] = MBC_GET_RETRY_COUNT;
|
||||
mcp->out_mb = MBX_0;
|
||||
mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -995,7 +1038,7 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size)
|
|||
mcp->in_mb = MBX_5|MBX_4|MBX_0;
|
||||
mcp->buf_size = size;
|
||||
mcp->flags = MBX_DMA_OUT;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
|
@ -1173,7 +1216,7 @@ gpd_error_out:
|
|||
* Kernel context.
|
||||
*/
|
||||
int
|
||||
qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr)
|
||||
qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *states)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
|
@ -1184,13 +1227,15 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr)
|
|||
|
||||
mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
|
||||
mcp->out_mb = MBX_0;
|
||||
mcp->in_mb = MBX_2|MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
/* Return firmware state. */
|
||||
*dptr = mcp->mb[1];
|
||||
/* Return firmware states. */
|
||||
states[0] = mcp->mb[1];
|
||||
states[1] = mcp->mb[2];
|
||||
states[2] = mcp->mb[3];
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
|
@ -1246,7 +1291,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name,
|
|||
}
|
||||
|
||||
mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -1318,7 +1363,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha)
|
|||
mcp->mb[3] = 0;
|
||||
}
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -1743,7 +1788,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
|||
}
|
||||
|
||||
mcp->in_mb = MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -1791,7 +1836,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha)
|
|||
mcp->mb[3] = 0;
|
||||
mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -1852,7 +1897,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma,
|
|||
mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
|
||||
}
|
||||
mcp->in_mb = MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -1896,7 +1941,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt,
|
|||
mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
|
||||
mcp->out_mb = MBX_0;
|
||||
mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -2036,7 +2081,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
|
|||
mcp->mb[1] = loop_id << 8;
|
||||
mcp->out_mb |= MBX_1;
|
||||
}
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = IOCTL_CMD;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -2082,7 +2127,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, struct link_statistics *stats,
|
|||
mcp->mb[10] = 0;
|
||||
mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
|
||||
mcp->in_mb = MBX_2|MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = IOCTL_CMD;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -2180,17 +2225,15 @@ struct tsk_mgmt_cmd {
|
|||
} p;
|
||||
};
|
||||
|
||||
int
|
||||
qla24xx_abort_target(fc_port_t *fcport)
|
||||
static int
|
||||
__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
|
||||
unsigned int l)
|
||||
{
|
||||
int rval;
|
||||
int rval, rval2;
|
||||
struct tsk_mgmt_cmd *tsk;
|
||||
dma_addr_t tsk_dma;
|
||||
scsi_qla_host_t *ha, *pha;
|
||||
|
||||
if (fcport == NULL)
|
||||
return 0;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
|
||||
|
||||
ha = fcport->ha;
|
||||
|
@ -2207,47 +2250,61 @@ qla24xx_abort_target(fc_port_t *fcport)
|
|||
tsk->p.tsk.entry_count = 1;
|
||||
tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
|
||||
tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
|
||||
tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET);
|
||||
tsk->p.tsk.control_flags = cpu_to_le32(type);
|
||||
tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
|
||||
tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
|
||||
tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
|
||||
tsk->p.tsk.vp_index = fcport->vp_idx;
|
||||
if (type == TCF_LUN_RESET) {
|
||||
int_to_scsilun(l, &tsk->p.tsk.lun);
|
||||
host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
|
||||
sizeof(tsk->p.tsk.lun));
|
||||
}
|
||||
|
||||
rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB "
|
||||
"(%x).\n", __func__, ha->host_no, rval));
|
||||
goto atarget_done;
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB "
|
||||
"(%x).\n", __func__, ha->host_no, name, rval));
|
||||
} else if (tsk->p.sts.entry_status != 0) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
|
||||
"-- error status (%x).\n", __func__, ha->host_no,
|
||||
tsk->p.sts.entry_status));
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
goto atarget_done;
|
||||
} else if (tsk->p.sts.comp_status !=
|
||||
__constant_cpu_to_le16(CS_COMPLETE)) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
|
||||
"-- completion status (%x).\n", __func__,
|
||||
ha->host_no, le16_to_cpu(tsk->p.sts.comp_status)));
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
goto atarget_done;
|
||||
}
|
||||
|
||||
/* Issue marker IOCB. */
|
||||
rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
rval2 = qla2x00_marker(ha, fcport->loop_id, l,
|
||||
type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
|
||||
if (rval2 != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
|
||||
"(%x).\n", __func__, ha->host_no, rval));
|
||||
"(%x).\n", __func__, ha->host_no, rval2));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
atarget_done:
|
||||
dma_pool_free(pha->s_dma_pool, tsk, tsk_dma);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla24xx_abort_target(struct fc_port *fcport, unsigned int l)
|
||||
{
|
||||
return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l);
|
||||
}
|
||||
|
||||
int
|
||||
qla24xx_lun_reset(struct fc_port *fcport, unsigned int l)
|
||||
{
|
||||
return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
int
|
||||
|
@ -2304,7 +2361,7 @@ qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g,
|
|||
mcp->mb[4] = sw_em_4g | BIT_15;
|
||||
mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -2372,7 +2429,7 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *ha, dma_addr_t eft_dma,
|
|||
mcp->mb[7] = TC_AEN_DISABLE;
|
||||
mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
|
@ -2401,7 +2458,7 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *ha)
|
|||
mcp->mb[1] = TC_EFT_DISABLE;
|
||||
mcp->out_mb = MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
|
@ -2441,7 +2498,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *ha, dma_addr_t fce_dma,
|
|||
mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
|
||||
MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
|
@ -2477,7 +2534,7 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *ha, uint64_t *wr, uint64_t *rd)
|
|||
mcp->out_mb = MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
|
||||
MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
|
@ -2525,7 +2582,7 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr,
|
|||
mcp->mb[10] = 0;
|
||||
mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -2559,7 +2616,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id,
|
|||
mcp->mb[4] = mcp->mb[5] = 0;
|
||||
mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -2877,7 +2934,7 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr,
|
|||
}
|
||||
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
|
@ -2890,3 +2947,104 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr,
|
|||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* 84XX Support **************************************************************/
|
||||
|
||||
struct cs84xx_mgmt_cmd {
|
||||
union {
|
||||
struct verify_chip_entry_84xx req;
|
||||
struct verify_chip_rsp_84xx rsp;
|
||||
} p;
|
||||
};
|
||||
|
||||
int
|
||||
qla84xx_verify_chip(struct scsi_qla_host *ha, uint16_t *status)
|
||||
{
|
||||
int rval, retry;
|
||||
struct cs84xx_mgmt_cmd *mn;
|
||||
dma_addr_t mn_dma;
|
||||
uint16_t options;
|
||||
unsigned long flags;
|
||||
|
||||
DEBUG16(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
|
||||
if (mn == NULL) {
|
||||
DEBUG2_3(printk("%s(%ld): failed to allocate Verify ISP84XX "
|
||||
"IOCB.\n", __func__, ha->host_no));
|
||||
return QLA_MEMORY_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
/* Force Update? */
|
||||
options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
|
||||
/* Diagnostic firmware? */
|
||||
/* options |= MENLO_DIAG_FW; */
|
||||
/* We update the firmware with only one data sequence. */
|
||||
options |= VCO_END_OF_DATA;
|
||||
|
||||
retry = 0;
|
||||
do {
|
||||
memset(mn, 0, sizeof(*mn));
|
||||
mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
|
||||
mn->p.req.entry_count = 1;
|
||||
mn->p.req.options = cpu_to_le16(options);
|
||||
|
||||
DEBUG16(printk("%s(%ld): Dump of Verify Request.\n", __func__,
|
||||
ha->host_no));
|
||||
DEBUG16(qla2x00_dump_buffer((uint8_t *)mn,
|
||||
sizeof(*mn)));
|
||||
|
||||
rval = qla2x00_issue_iocb_timeout(ha, mn, mn_dma, 0, 120);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_16(printk("%s(%ld): failed to issue Verify "
|
||||
"IOCB (%x).\n", __func__, ha->host_no, rval));
|
||||
goto verify_done;
|
||||
}
|
||||
|
||||
DEBUG16(printk("%s(%ld): Dump of Verify Response.\n", __func__,
|
||||
ha->host_no));
|
||||
DEBUG16(qla2x00_dump_buffer((uint8_t *)mn,
|
||||
sizeof(*mn)));
|
||||
|
||||
status[0] = le16_to_cpu(mn->p.rsp.comp_status);
|
||||
status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
|
||||
le16_to_cpu(mn->p.rsp.failure_code) : 0;
|
||||
DEBUG2_16(printk("%s(%ld): cs=%x fc=%x\n", __func__,
|
||||
ha->host_no, status[0], status[1]));
|
||||
|
||||
if (status[0] != CS_COMPLETE) {
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
if (!(options & VCO_DONT_UPDATE_FW)) {
|
||||
DEBUG2_16(printk("%s(%ld): Firmware update "
|
||||
"failed. Retrying without update "
|
||||
"firmware.\n", __func__, ha->host_no));
|
||||
options |= VCO_DONT_UPDATE_FW;
|
||||
options &= ~VCO_FORCE_UPDATE;
|
||||
retry = 1;
|
||||
}
|
||||
} else {
|
||||
DEBUG2_16(printk("%s(%ld): firmware updated to %x.\n",
|
||||
__func__, ha->host_no,
|
||||
le32_to_cpu(mn->p.rsp.fw_ver)));
|
||||
|
||||
/* NOTE: we only update OP firmware. */
|
||||
spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
|
||||
ha->cs84xx->op_fw_version =
|
||||
le32_to_cpu(mn->p.rsp.fw_ver);
|
||||
spin_unlock_irqrestore(&ha->cs84xx->access_lock,
|
||||
flags);
|
||||
}
|
||||
} while (retry);
|
||||
|
||||
verify_done:
|
||||
dma_pool_free(ha->s_dma_pool, mn, mn_dma);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_16(printk("%s(%ld): failed=%x.\n", __func__,
|
||||
ha->host_no, rval));
|
||||
} else {
|
||||
DEBUG16(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
|
|
@ -1,20 +1,8 @@
|
|||
/*
|
||||
* QLOGIC LINUX SOFTWARE
|
||||
*
|
||||
* QLogic ISP2x00 device driver for Linux 2.6.x
|
||||
* Copyright (C) 2003-2005 QLogic Corporation
|
||||
* (www.qlogic.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
#include "qla_def.h"
|
||||
|
||||
|
@ -28,8 +16,6 @@
|
|||
#include <scsi/scsicam.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
void qla2x00_vp_stop_timer(scsi_qla_host_t *);
|
||||
|
||||
void
|
||||
qla2x00_vp_stop_timer(scsi_qla_host_t *vha)
|
||||
{
|
||||
|
@ -268,9 +254,17 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
|
|||
static int
|
||||
qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
|
||||
{
|
||||
scsi_qla_host_t *ha = vha->parent;
|
||||
|
||||
if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
|
||||
/* VP acquired. complete port configuration */
|
||||
qla24xx_configure_vp(vha);
|
||||
if (atomic_read(&ha->loop_state) == LOOP_READY) {
|
||||
qla24xx_configure_vp(vha);
|
||||
} else {
|
||||
set_bit(VP_IDX_ACQUIRED, &vha->vp_flags);
|
||||
set_bit(VP_DPC_NEEDED, &ha->dpc_flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
|
@ -26,9 +26,6 @@ char qla2x00_version_str[40];
|
|||
*/
|
||||
static struct kmem_cache *srb_cachep;
|
||||
|
||||
/*
|
||||
* Ioctl related information.
|
||||
*/
|
||||
int num_hosts;
|
||||
int ql2xlogintimeout = 20;
|
||||
module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
|
||||
|
@ -103,9 +100,9 @@ static int qla24xx_queuecommand(struct scsi_cmnd *cmd,
|
|||
void (*fn)(struct scsi_cmnd *));
|
||||
static int qla2xxx_eh_abort(struct scsi_cmnd *);
|
||||
static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
|
||||
static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
|
||||
static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
|
||||
static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
|
||||
static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *);
|
||||
|
||||
static int qla2x00_change_queue_depth(struct scsi_device *, int);
|
||||
static int qla2x00_change_queue_type(struct scsi_device *, int);
|
||||
|
@ -117,6 +114,7 @@ static struct scsi_host_template qla2x00_driver_template = {
|
|||
|
||||
.eh_abort_handler = qla2xxx_eh_abort,
|
||||
.eh_device_reset_handler = qla2xxx_eh_device_reset,
|
||||
.eh_target_reset_handler = qla2xxx_eh_target_reset,
|
||||
.eh_bus_reset_handler = qla2xxx_eh_bus_reset,
|
||||
.eh_host_reset_handler = qla2xxx_eh_host_reset,
|
||||
|
||||
|
@ -148,6 +146,7 @@ struct scsi_host_template qla24xx_driver_template = {
|
|||
|
||||
.eh_abort_handler = qla2xxx_eh_abort,
|
||||
.eh_device_reset_handler = qla2xxx_eh_device_reset,
|
||||
.eh_target_reset_handler = qla2xxx_eh_target_reset,
|
||||
.eh_bus_reset_handler = qla2xxx_eh_bus_reset,
|
||||
.eh_host_reset_handler = qla2xxx_eh_host_reset,
|
||||
|
||||
|
@ -253,9 +252,9 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str)
|
|||
|
||||
strcpy(str, "PCIe (");
|
||||
if (lspeed == 1)
|
||||
strcat(str, "2.5Gb/s ");
|
||||
strcat(str, "2.5GT/s ");
|
||||
else if (lspeed == 2)
|
||||
strcat(str, "5.0Gb/s ");
|
||||
strcat(str, "5.0GT/s ");
|
||||
else
|
||||
strcat(str, "<unknown> ");
|
||||
snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth);
|
||||
|
@ -340,6 +339,8 @@ qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str)
|
|||
strcat(str, "[T10 CRC] ");
|
||||
if (ha->fw_attributes & BIT_5)
|
||||
strcat(str, "[VI] ");
|
||||
if (ha->fw_attributes & BIT_10)
|
||||
strcat(str, "[84XX] ");
|
||||
if (ha->fw_attributes & BIT_13)
|
||||
strcat(str, "[Experimental]");
|
||||
return str;
|
||||
|
@ -570,8 +571,6 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha)
|
|||
else
|
||||
return_status = QLA_FUNCTION_FAILED;
|
||||
|
||||
DEBUG2(printk("%s return_status=%d\n",__func__,return_status));
|
||||
|
||||
return (return_status);
|
||||
}
|
||||
|
||||
|
@ -685,7 +684,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||
|
||||
DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n",
|
||||
__func__, ha->host_no, sp, serial));
|
||||
DEBUG3(qla2x00_print_scsi_cmd(cmd));
|
||||
|
||||
spin_unlock_irqrestore(&pha->hardware_lock, flags);
|
||||
if (ha->isp_ops->abort_command(ha, sp)) {
|
||||
|
@ -719,190 +717,122 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* qla2x00_eh_wait_for_pending_target_commands
|
||||
*
|
||||
* Description:
|
||||
* Waits for all the commands to come back from the specified target.
|
||||
*
|
||||
* Input:
|
||||
* ha - pointer to scsi_qla_host structure.
|
||||
* t - target
|
||||
* Returns:
|
||||
* Either SUCCESS or FAILED.
|
||||
*
|
||||
* Note:
|
||||
**************************************************************************/
|
||||
enum nexus_wait_type {
|
||||
WAIT_HOST = 0,
|
||||
WAIT_TARGET,
|
||||
WAIT_LUN,
|
||||
};
|
||||
|
||||
static int
|
||||
qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
|
||||
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t,
|
||||
unsigned int l, enum nexus_wait_type type)
|
||||
{
|
||||
int cnt;
|
||||
int status;
|
||||
srb_t *sp;
|
||||
struct scsi_cmnd *cmd;
|
||||
int cnt, match, status;
|
||||
srb_t *sp;
|
||||
unsigned long flags;
|
||||
scsi_qla_host_t *pha = to_qla_parent(ha);
|
||||
|
||||
status = 0;
|
||||
|
||||
/*
|
||||
* Waiting for all commands for the designated target in the active
|
||||
* array
|
||||
*/
|
||||
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
|
||||
spin_lock_irqsave(&pha->hardware_lock, flags);
|
||||
status = QLA_SUCCESS;
|
||||
spin_lock_irqsave(&pha->hardware_lock, flags);
|
||||
for (cnt = 1; status == QLA_SUCCESS && cnt < MAX_OUTSTANDING_COMMANDS;
|
||||
cnt++) {
|
||||
sp = pha->outstanding_cmds[cnt];
|
||||
if (sp) {
|
||||
cmd = sp->cmd;
|
||||
spin_unlock_irqrestore(&pha->hardware_lock, flags);
|
||||
if (cmd->device->id == t &&
|
||||
ha->vp_idx == sp->ha->vp_idx) {
|
||||
if (!qla2x00_eh_wait_on_command(ha, cmd)) {
|
||||
status = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
spin_unlock_irqrestore(&pha->hardware_lock, flags);
|
||||
if (!sp)
|
||||
continue;
|
||||
if (ha->vp_idx != sp->ha->vp_idx)
|
||||
continue;
|
||||
match = 0;
|
||||
switch (type) {
|
||||
case WAIT_HOST:
|
||||
match = 1;
|
||||
break;
|
||||
case WAIT_TARGET:
|
||||
match = sp->cmd->device->id == t;
|
||||
break;
|
||||
case WAIT_LUN:
|
||||
match = (sp->cmd->device->id == t &&
|
||||
sp->cmd->device->lun == l);
|
||||
break;
|
||||
}
|
||||
if (!match)
|
||||
continue;
|
||||
|
||||
spin_unlock_irqrestore(&pha->hardware_lock, flags);
|
||||
status = qla2x00_eh_wait_on_command(ha, sp->cmd);
|
||||
spin_lock_irqsave(&pha->hardware_lock, flags);
|
||||
}
|
||||
return (status);
|
||||
spin_unlock_irqrestore(&pha->hardware_lock, flags);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static char *reset_errors[] = {
|
||||
"HBA not online",
|
||||
"HBA not ready",
|
||||
"Task management failed",
|
||||
"Waiting for command completions",
|
||||
};
|
||||
|
||||
static int
|
||||
__qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
|
||||
struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int))
|
||||
{
|
||||
scsi_qla_host_t *ha = shost_priv(cmd->device->host);
|
||||
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
|
||||
int err;
|
||||
|
||||
qla2x00_block_error_handler(cmd);
|
||||
|
||||
if (!fcport)
|
||||
return FAILED;
|
||||
|
||||
qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET ISSUED.\n",
|
||||
ha->host_no, cmd->device->id, cmd->device->lun, name);
|
||||
|
||||
err = 0;
|
||||
if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)
|
||||
goto eh_reset_failed;
|
||||
err = 1;
|
||||
if (qla2x00_wait_for_loop_ready(ha) != QLA_SUCCESS)
|
||||
goto eh_reset_failed;
|
||||
err = 2;
|
||||
if (do_reset(fcport, cmd->device->lun) != QLA_SUCCESS)
|
||||
goto eh_reset_failed;
|
||||
err = 3;
|
||||
if (qla2x00_eh_wait_for_pending_commands(ha, cmd->device->id,
|
||||
cmd->device->lun, type) != QLA_SUCCESS)
|
||||
goto eh_reset_failed;
|
||||
|
||||
qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n",
|
||||
ha->host_no, cmd->device->id, cmd->device->lun, name);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
eh_reset_failed:
|
||||
qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET FAILED: %s.\n",
|
||||
ha->host_no, cmd->device->id, cmd->device->lun, name,
|
||||
reset_errors[err]);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* qla2xxx_eh_device_reset
|
||||
*
|
||||
* Description:
|
||||
* The device reset function will reset the target and abort any
|
||||
* executing commands.
|
||||
*
|
||||
* NOTE: The use of SP is undefined within this context. Do *NOT*
|
||||
* attempt to use this value, even if you determine it is
|
||||
* non-null.
|
||||
*
|
||||
* Input:
|
||||
* cmd = Linux SCSI command packet of the command that cause the
|
||||
* bus device reset.
|
||||
*
|
||||
* Returns:
|
||||
* SUCCESS/FAILURE (defined as macro in scsi.h).
|
||||
*
|
||||
**************************************************************************/
|
||||
static int
|
||||
qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
|
||||
{
|
||||
scsi_qla_host_t *ha = shost_priv(cmd->device->host);
|
||||
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
|
||||
int ret = FAILED;
|
||||
unsigned int id, lun;
|
||||
unsigned long serial;
|
||||
|
||||
qla2x00_block_error_handler(cmd);
|
||||
|
||||
id = cmd->device->id;
|
||||
lun = cmd->device->lun;
|
||||
serial = cmd->serial_number;
|
||||
|
||||
if (!fcport)
|
||||
return ret;
|
||||
|
||||
qla_printk(KERN_INFO, ha,
|
||||
"scsi(%ld:%d:%d): DEVICE RESET ISSUED.\n", ha->host_no, id, lun);
|
||||
|
||||
if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)
|
||||
goto eh_dev_reset_done;
|
||||
|
||||
if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) {
|
||||
if (qla2x00_device_reset(ha, fcport) == 0)
|
||||
ret = SUCCESS;
|
||||
|
||||
#if defined(LOGOUT_AFTER_DEVICE_RESET)
|
||||
if (ret == SUCCESS) {
|
||||
if (fcport->flags & FC_FABRIC_DEVICE) {
|
||||
ha->isp_ops->fabric_logout(ha, fcport->loop_id);
|
||||
qla2x00_mark_device_lost(ha, fcport, 0, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
DEBUG2(printk(KERN_INFO
|
||||
"%s failed: loop not ready\n",__func__));
|
||||
}
|
||||
|
||||
if (ret == FAILED) {
|
||||
DEBUG3(printk("%s(%ld): device reset failed\n",
|
||||
__func__, ha->host_no));
|
||||
qla_printk(KERN_INFO, ha, "%s: device reset failed\n",
|
||||
__func__);
|
||||
|
||||
goto eh_dev_reset_done;
|
||||
}
|
||||
|
||||
/* Flush outstanding commands. */
|
||||
if (qla2x00_eh_wait_for_pending_target_commands(ha, id))
|
||||
ret = FAILED;
|
||||
if (ret == FAILED) {
|
||||
DEBUG3(printk("%s(%ld): failed while waiting for commands\n",
|
||||
__func__, ha->host_no));
|
||||
qla_printk(KERN_INFO, ha,
|
||||
"%s: failed while waiting for commands\n", __func__);
|
||||
} else
|
||||
qla_printk(KERN_INFO, ha,
|
||||
"scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no,
|
||||
id, lun);
|
||||
eh_dev_reset_done:
|
||||
return ret;
|
||||
return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd,
|
||||
ha->isp_ops->lun_reset);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* qla2x00_eh_wait_for_pending_commands
|
||||
*
|
||||
* Description:
|
||||
* Waits for all the commands to come back from the specified host.
|
||||
*
|
||||
* Input:
|
||||
* ha - pointer to scsi_qla_host structure.
|
||||
*
|
||||
* Returns:
|
||||
* 1 : SUCCESS
|
||||
* 0 : FAILED
|
||||
*
|
||||
* Note:
|
||||
**************************************************************************/
|
||||
static int
|
||||
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
|
||||
qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
|
||||
{
|
||||
int cnt;
|
||||
int status;
|
||||
srb_t *sp;
|
||||
struct scsi_cmnd *cmd;
|
||||
unsigned long flags;
|
||||
scsi_qla_host_t *ha = shost_priv(cmd->device->host);
|
||||
|
||||
status = 1;
|
||||
|
||||
/*
|
||||
* Waiting for all commands for the designated target in the active
|
||||
* array
|
||||
*/
|
||||
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
sp = ha->outstanding_cmds[cnt];
|
||||
if (sp) {
|
||||
cmd = sp->cmd;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
status = qla2x00_eh_wait_on_command(ha, cmd);
|
||||
if (status == 0)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
}
|
||||
}
|
||||
return (status);
|
||||
return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd,
|
||||
ha->isp_ops->target_reset);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* qla2xxx_eh_bus_reset
|
||||
*
|
||||
|
@ -953,7 +883,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
|
|||
goto eh_bus_reset_done;
|
||||
|
||||
/* Flush outstanding commands. */
|
||||
if (!qla2x00_eh_wait_for_pending_commands(pha))
|
||||
if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) !=
|
||||
QLA_SUCCESS)
|
||||
ret = FAILED;
|
||||
|
||||
eh_bus_reset_done:
|
||||
|
@ -1024,7 +955,8 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
|
|||
clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags);
|
||||
|
||||
/* Waiting for our command in done_queue to be returned to OS.*/
|
||||
if (qla2x00_eh_wait_for_pending_commands(pha))
|
||||
if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) ==
|
||||
QLA_SUCCESS)
|
||||
ret = SUCCESS;
|
||||
|
||||
if (ha->parent)
|
||||
|
@ -1080,7 +1012,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha)
|
|||
if (fcport->port_type != FCT_TARGET)
|
||||
continue;
|
||||
|
||||
ret = qla2x00_device_reset(ha, fcport);
|
||||
ret = ha->isp_ops->target_reset(fcport, 0);
|
||||
if (ret != QLA_SUCCESS) {
|
||||
DEBUG2_3(printk("%s(%ld): bus_reset failed: "
|
||||
"target_reset=%d d_id=%x.\n", __func__,
|
||||
|
@ -1095,26 +1027,6 @@ qla2x00_loop_reset(scsi_qla_host_t *ha)
|
|||
return QLA_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* qla2x00_device_reset
|
||||
* Issue bus device reset message to the target.
|
||||
*
|
||||
* Input:
|
||||
* ha = adapter block pointer.
|
||||
* t = SCSI ID.
|
||||
* TARGET_QUEUE_LOCK must be released.
|
||||
* ADAPTER_STATE_LOCK must be released.
|
||||
*
|
||||
* Context:
|
||||
* Kernel context.
|
||||
*/
|
||||
static int
|
||||
qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport)
|
||||
{
|
||||
/* Abort Target command will clear Reservation */
|
||||
return ha->isp_ops->abort_target(reset_fcport);
|
||||
}
|
||||
|
||||
void
|
||||
qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res)
|
||||
{
|
||||
|
@ -1292,7 +1204,8 @@ static struct isp_operations qla2100_isp_ops = {
|
|||
.enable_intrs = qla2x00_enable_intrs,
|
||||
.disable_intrs = qla2x00_disable_intrs,
|
||||
.abort_command = qla2x00_abort_command,
|
||||
.abort_target = qla2x00_abort_target,
|
||||
.target_reset = qla2x00_abort_target,
|
||||
.lun_reset = qla2x00_lun_reset,
|
||||
.fabric_login = qla2x00_login_fabric,
|
||||
.fabric_logout = qla2x00_fabric_logout,
|
||||
.calc_req_entries = qla2x00_calc_iocbs_32,
|
||||
|
@ -1325,7 +1238,8 @@ static struct isp_operations qla2300_isp_ops = {
|
|||
.enable_intrs = qla2x00_enable_intrs,
|
||||
.disable_intrs = qla2x00_disable_intrs,
|
||||
.abort_command = qla2x00_abort_command,
|
||||
.abort_target = qla2x00_abort_target,
|
||||
.target_reset = qla2x00_abort_target,
|
||||
.lun_reset = qla2x00_lun_reset,
|
||||
.fabric_login = qla2x00_login_fabric,
|
||||
.fabric_logout = qla2x00_fabric_logout,
|
||||
.calc_req_entries = qla2x00_calc_iocbs_32,
|
||||
|
@ -1358,7 +1272,8 @@ static struct isp_operations qla24xx_isp_ops = {
|
|||
.enable_intrs = qla24xx_enable_intrs,
|
||||
.disable_intrs = qla24xx_disable_intrs,
|
||||
.abort_command = qla24xx_abort_command,
|
||||
.abort_target = qla24xx_abort_target,
|
||||
.target_reset = qla24xx_abort_target,
|
||||
.lun_reset = qla24xx_lun_reset,
|
||||
.fabric_login = qla24xx_login_fabric,
|
||||
.fabric_logout = qla24xx_fabric_logout,
|
||||
.calc_req_entries = NULL,
|
||||
|
@ -1391,7 +1306,8 @@ static struct isp_operations qla25xx_isp_ops = {
|
|||
.enable_intrs = qla24xx_enable_intrs,
|
||||
.disable_intrs = qla24xx_disable_intrs,
|
||||
.abort_command = qla24xx_abort_command,
|
||||
.abort_target = qla24xx_abort_target,
|
||||
.target_reset = qla24xx_abort_target,
|
||||
.lun_reset = qla24xx_lun_reset,
|
||||
.fabric_login = qla24xx_login_fabric,
|
||||
.fabric_logout = qla24xx_fabric_logout,
|
||||
.calc_req_entries = NULL,
|
||||
|
@ -1464,6 +1380,13 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha)
|
|||
ha->device_type |= DT_IIDMA;
|
||||
ha->fw_srisc_address = RISC_START_ADDRESS_2400;
|
||||
break;
|
||||
case PCI_DEVICE_ID_QLOGIC_ISP8432:
|
||||
ha->device_type |= DT_ISP8432;
|
||||
ha->device_type |= DT_ZIO_SUPPORTED;
|
||||
ha->device_type |= DT_FWI2;
|
||||
ha->device_type |= DT_IIDMA;
|
||||
ha->fw_srisc_address = RISC_START_ADDRESS_2400;
|
||||
break;
|
||||
case PCI_DEVICE_ID_QLOGIC_ISP5422:
|
||||
ha->device_type |= DT_ISP5422;
|
||||
ha->device_type |= DT_FWI2;
|
||||
|
@ -1587,6 +1510,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
sht = &qla2x00_driver_template;
|
||||
if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
|
||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
|
||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 ||
|
||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 ||
|
||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 ||
|
||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) {
|
||||
|
@ -1677,7 +1601,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
if (IS_QLA2322(ha) || IS_QLA6322(ha))
|
||||
ha->optrom_size = OPTROM_SIZE_2322;
|
||||
ha->isp_ops = &qla2300_isp_ops;
|
||||
} else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||
} else if (IS_QLA24XX_TYPE(ha)) {
|
||||
host->max_id = MAX_TARGETS_2200;
|
||||
ha->mbx_count = MAILBOX_REGISTER_COUNT;
|
||||
ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
|
||||
|
@ -1699,6 +1623,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
ha->gid_list_info_size = 8;
|
||||
ha->optrom_size = OPTROM_SIZE_25XX;
|
||||
ha->isp_ops = &qla25xx_isp_ops;
|
||||
ha->hw_event_start = PCI_FUNC(pdev->devfn) ?
|
||||
FA_HW_EVENT1_ADDR: FA_HW_EVENT0_ADDR;
|
||||
}
|
||||
host->can_queue = ha->request_q_length + 128;
|
||||
|
||||
|
@ -1713,6 +1639,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
INIT_LIST_HEAD(&ha->list);
|
||||
INIT_LIST_HEAD(&ha->fcports);
|
||||
INIT_LIST_HEAD(&ha->vp_list);
|
||||
INIT_LIST_HEAD(&ha->work_list);
|
||||
|
||||
set_bit(0, (unsigned long *) ha->vp_idx_map);
|
||||
|
||||
|
@ -1819,6 +1746,8 @@ qla2x00_remove_one(struct pci_dev *pdev)
|
|||
|
||||
qla2x00_dfs_remove(ha);
|
||||
|
||||
qla84xx_put_chip(ha);
|
||||
|
||||
qla2x00_free_sysfs_attr(ha);
|
||||
|
||||
fc_remove_host(ha->host);
|
||||
|
@ -2206,6 +2135,97 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
|||
kfree(ha->nvram);
|
||||
}
|
||||
|
||||
struct qla_work_evt *
|
||||
qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type,
|
||||
int locked)
|
||||
{
|
||||
struct qla_work_evt *e;
|
||||
|
||||
e = kzalloc(sizeof(struct qla_work_evt), locked ? GFP_ATOMIC:
|
||||
GFP_KERNEL);
|
||||
if (!e)
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&e->list);
|
||||
e->type = type;
|
||||
e->flags = QLA_EVT_FLAG_FREE;
|
||||
return e;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!locked)
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
list_add_tail(&e->list, &ha->work_list);
|
||||
qla2xxx_wake_dpc(ha);
|
||||
if (!locked)
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
return QLA_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_post_aen_work(struct scsi_qla_host *ha, enum fc_host_event_code code,
|
||||
u32 data)
|
||||
{
|
||||
struct qla_work_evt *e;
|
||||
|
||||
e = qla2x00_alloc_work(ha, QLA_EVT_AEN, 1);
|
||||
if (!e)
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
||||
e->u.aen.code = code;
|
||||
e->u.aen.data = data;
|
||||
return qla2x00_post_work(ha, e, 1);
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_post_hwe_work(struct scsi_qla_host *ha, uint16_t code, uint16_t d1,
|
||||
uint16_t d2, uint16_t d3)
|
||||
{
|
||||
struct qla_work_evt *e;
|
||||
|
||||
e = qla2x00_alloc_work(ha, QLA_EVT_HWE_LOG, 1);
|
||||
if (!e)
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
||||
e->u.hwe.code = code;
|
||||
e->u.hwe.d1 = d1;
|
||||
e->u.hwe.d2 = d2;
|
||||
e->u.hwe.d3 = d3;
|
||||
return qla2x00_post_work(ha, e, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
qla2x00_do_work(struct scsi_qla_host *ha)
|
||||
{
|
||||
struct qla_work_evt *e;
|
||||
|
||||
spin_lock_irq(&ha->hardware_lock);
|
||||
while (!list_empty(&ha->work_list)) {
|
||||
e = list_entry(ha->work_list.next, struct qla_work_evt, list);
|
||||
list_del_init(&e->list);
|
||||
spin_unlock_irq(&ha->hardware_lock);
|
||||
|
||||
switch (e->type) {
|
||||
case QLA_EVT_AEN:
|
||||
fc_host_post_event(ha->host, fc_get_event_number(),
|
||||
e->u.aen.code, e->u.aen.data);
|
||||
break;
|
||||
case QLA_EVT_HWE_LOG:
|
||||
qla2xxx_hw_event_log(ha, e->u.hwe.code, e->u.hwe.d1,
|
||||
e->u.hwe.d2, e->u.hwe.d3);
|
||||
break;
|
||||
}
|
||||
if (e->flags & QLA_EVT_FLAG_FREE)
|
||||
kfree(e);
|
||||
spin_lock_irq(&ha->hardware_lock);
|
||||
}
|
||||
spin_unlock_irq(&ha->hardware_lock);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* qla2x00_do_dpc
|
||||
* This kernel thread is a task that is schedule by the interrupt handler
|
||||
|
@ -2257,6 +2277,8 @@ qla2x00_do_dpc(void *data)
|
|||
continue;
|
||||
}
|
||||
|
||||
qla2x00_do_work(ha);
|
||||
|
||||
if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) {
|
||||
|
||||
DEBUG(printk("scsi(%ld): dpc: sched "
|
||||
|
@ -2291,12 +2313,6 @@ qla2x00_do_dpc(void *data)
|
|||
if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags))
|
||||
qla2x00_update_fcports(ha);
|
||||
|
||||
if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) {
|
||||
DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n",
|
||||
ha->host_no));
|
||||
qla2x00_loop_reset(ha);
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) &&
|
||||
(!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) {
|
||||
|
||||
|
@ -2367,19 +2383,6 @@ qla2x00_do_dpc(void *data)
|
|||
ha->host_no));
|
||||
}
|
||||
|
||||
if ((test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags)) &&
|
||||
atomic_read(&ha->loop_state) != LOOP_DOWN) {
|
||||
|
||||
clear_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags);
|
||||
DEBUG(printk("scsi(%ld): qla2x00_login_retry()\n",
|
||||
ha->host_no));
|
||||
|
||||
set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
|
||||
|
||||
DEBUG(printk("scsi(%ld): qla2x00_login_retry - end\n",
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
|
||||
|
||||
DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n",
|
||||
|
@ -2397,18 +2400,6 @@ qla2x00_do_dpc(void *data)
|
|||
ha->host_no));
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags)) {
|
||||
|
||||
DEBUG(printk("scsi(%ld): Rescan flagged fcports...\n",
|
||||
ha->host_no));
|
||||
|
||||
qla2x00_rescan_fcports(ha);
|
||||
|
||||
DEBUG(printk("scsi(%ld): Rescan flagged fcports..."
|
||||
"end.\n",
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
if (!ha->interrupts_on)
|
||||
ha->isp_ops->enable_intrs(ha);
|
||||
|
||||
|
@ -2586,7 +2577,8 @@ qla2x00_timer(scsi_qla_host_t *ha)
|
|||
set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags);
|
||||
start_dpc++;
|
||||
|
||||
if (!(ha->device_flags & DFLG_NO_CABLE)) {
|
||||
if (!(ha->device_flags & DFLG_NO_CABLE) &&
|
||||
!ha->parent) {
|
||||
DEBUG(printk("scsi(%ld): Loop down - "
|
||||
"aborting ISP.\n",
|
||||
ha->host_no));
|
||||
|
@ -2610,10 +2602,8 @@ qla2x00_timer(scsi_qla_host_t *ha)
|
|||
/* Schedule the DPC routine if needed */
|
||||
if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
|
||||
test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
|
||||
test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
|
||||
test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) ||
|
||||
start_dpc ||
|
||||
test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
|
||||
test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
|
||||
test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
|
||||
test_bit(VP_DPC_NEEDED, &ha->dpc_flags) ||
|
||||
|
@ -2665,7 +2655,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha)
|
|||
blob = &qla_fw_blobs[FW_ISP2300];
|
||||
} else if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
|
||||
blob = &qla_fw_blobs[FW_ISP2322];
|
||||
} else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||
} else if (IS_QLA24XX_TYPE(ha)) {
|
||||
blob = &qla_fw_blobs[FW_ISP24XX];
|
||||
} else if (IS_QLA25XX(ha)) {
|
||||
blob = &qla_fw_blobs[FW_ISP25XX];
|
||||
|
@ -2815,6 +2805,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
|
|||
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8432) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) },
|
||||
|
|
|
@ -1,26 +1,12 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
* Copyright (c) 2003-2008 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
/*
|
||||
* Compile time Options:
|
||||
* 0 - Disable and 1 - Enable
|
||||
*/
|
||||
#define DEBUG_QLA2100 0 /* For Debug of qla2x00 */
|
||||
|
||||
#define USE_ABORT_TGT 1 /* Use Abort Target mbx cmd */
|
||||
|
||||
#define MAX_RETRIES_OF_ISP_ABORT 5
|
||||
|
||||
/* Max time to wait for the loop to be in LOOP_READY state */
|
||||
#define MAX_LOOP_TIMEOUT (60 * 5)
|
||||
|
||||
/*
|
||||
* Some vendor subsystems do not recover properly after a device reset. Define
|
||||
* the following to force a logout after a successful device reset.
|
||||
*/
|
||||
#undef LOGOUT_AFTER_DEVICE_RESET
|
||||
|
||||
#include "qla_version.h"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue