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:
Linus Torvalds 2008-04-18 11:25:31 -07:00
commit 2cca775bae
133 changed files with 4890 additions and 4406 deletions

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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);
}
/**

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View 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 */

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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"

View file

@ -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);

View file

@ -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))

View file

@ -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);

View file

@ -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) {

View file

@ -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;

View file

@ -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;

View file

@ -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;
/*

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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_ */

View file

@ -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) {

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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 ---------- */
/**

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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",
};

View file

@ -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",
};

View file

@ -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) {

View file

@ -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,
};

View file

@ -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)

View file

@ -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);
}

View file

@ -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;

View file

@ -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);

View file

@ -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 */

View file

@ -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,

View file

@ -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;
}

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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,

View file

@ -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);

View file

@ -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 */

View file

@ -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;

View file

@ -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",

View file

@ -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");

View file

@ -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 */

View file

@ -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.

View file

@ -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[] = {

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -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"

View file

@ -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))

View file

@ -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
};

View file

@ -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;

View file

@ -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

View file

@ -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))

View file

@ -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,
};

View file

@ -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:

View file

@ -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.

View file

@ -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;
}

View file

@ -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

View file

@ -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
*/

View file

@ -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;

View file

@ -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.
*/

View file

@ -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

View file

@ -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.

View 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));

View file

@ -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(&reg->mailbox0);
barrier();
}
if (cnt == 0)
hw_evt = 1;
/* Wait for soft-reset to complete. */
d2 = RD_REG_DWORD(&reg->ctrl_status);
@ -536,6 +543,10 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
d2 = RD_REG_DWORD(&reg->ctrl_status);
barrier();
}
if (cnt == 0 || hw_evt)
qla2xxx_hw_event_log(ha, HW_EVENT_RESET_ERR,
RD_REG_WORD(&reg->mailbox1), RD_REG_WORD(&reg->mailbox2),
RD_REG_WORD(&reg->mailbox3));
WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
RD_REG_DWORD(&reg->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;
}

View file

@ -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)
{

View file

@ -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);

View file

@ -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(&reg->hccr);
if (hccr & HCCR_RISC_PAUSE) {
@ -99,7 +95,7 @@ qla2100_intr_handler(int irq, void *dev_id)
RD_REG_WORD(&reg->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(&reg->u.isp2300.host_status);
if (stat & HSR_RISC_PAUSED) {
@ -211,7 +206,7 @@ qla2300_intr_handler(int irq, void *dev_id)
WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
RD_REG_WORD_RELAXED(&reg->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(&reg->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(&reg->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(&reg->hccr, HCCRX_CLR_RISC_INT);
RD_REG_DWORD_RELAXED(&reg->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(&reg->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(&reg->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(&reg->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(&reg->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(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
@ -1891,7 +1872,7 @@ clear_risc_ints:
WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_RISC_INT);
WRT_REG_WORD(&reg->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:

View file

@ -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(&reg->hccr)),
LSW(RD_REG_DWORD(&reg->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;
}

View file

@ -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;
}

View file

@ -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) },

View file

@ -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