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: (38 commits)
  fusion: mptsas, fix lock imbalance
  [SCSI] scsi_transport_fc: replace BUS_ID_SIZE by fixed count
  sd, sr: fix Driver 'sd' needs updating message
  scsi_transport_iscsi: return -EOVERFLOW for Too many iscsi targets
  fc_transport: Selective return value from BSG timeout function
  fc_transport: The softirq_done function registration for BSG request
  sym53c8xx: ratelimit parity errors
  explain the hidden scsi_wait_scan Kconfig variable
  ibmvfc: Fix endless PRLI loop in discovery
  ibmvfc: Process async events before command responses
  libfc: Add runtime debugging with debug_logging module parameter
  libfcoe: Add runtime debugging with module param debug_logging
  fcoe: Add runtime debug logging with module parameter debug_logging
  scsi_debug: Add support for physical block exponent and alignment
  cnic: add NETDEV_1000 and NETDEVICES to Kconfig select
  cnic: Fix __symbol_get() build error.
  Revert "[SCSI] cnic: fix error: implicit declaration of function ‘__symbol_get’"
  ipr: differentiate pci-x and pci-e based adapters
  ipr: add test for MSI interrupt support
  scsi_transport_spi: Blacklist Ultrium-3 tape for IU transfers
  ...
This commit is contained in:
Linus Torvalds 2009-06-23 11:35:37 -07:00
commit f5bcf5f447
46 changed files with 1246 additions and 605 deletions

View file

@ -315,7 +315,6 @@ out:
blk_put_request(rq); blk_put_request(rq);
if (next_rq) { if (next_rq) {
blk_rq_unmap_user(next_rq->bio); blk_rq_unmap_user(next_rq->bio);
next_rq->bio = NULL;
blk_put_request(next_rq); blk_put_request(next_rq);
} }
return ERR_PTR(ret); return ERR_PTR(ret);
@ -449,7 +448,6 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
hdr->dout_resid = rq->resid_len; hdr->dout_resid = rq->resid_len;
hdr->din_resid = rq->next_rq->resid_len; hdr->din_resid = rq->next_rq->resid_len;
blk_rq_unmap_user(bidi_bio); blk_rq_unmap_user(bidi_bio);
rq->next_rq->bio = NULL;
blk_put_request(rq->next_rq); blk_put_request(rq->next_rq);
} else if (rq_data_dir(rq) == READ) } else if (rq_data_dir(rq) == READ)
hdr->din_resid = rq->resid_len; hdr->din_resid = rq->resid_len;
@ -468,7 +466,6 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
blk_rq_unmap_user(bio); blk_rq_unmap_user(bio);
if (rq->cmd != rq->__cmd) if (rq->cmd != rq->__cmd)
kfree(rq->cmd); kfree(rq->cmd);
rq->bio = NULL;
blk_put_request(rq); blk_put_request(rq);
return ret; return ret;

View file

@ -3518,7 +3518,7 @@ retry_page:
} else } else
mptsas_volume_delete(ioc, sas_info->fw.id); mptsas_volume_delete(ioc, sas_info->fw.id);
} }
mutex_lock(&ioc->sas_device_info_mutex); mutex_unlock(&ioc->sas_device_info_mutex);
/* expanders */ /* expanders */
mutex_lock(&ioc->sas_topology_mutex); mutex_lock(&ioc->sas_topology_mutex);
@ -3549,7 +3549,7 @@ retry_page:
goto redo_expander_scan; goto redo_expander_scan;
} }
} }
mutex_lock(&ioc->sas_topology_mutex); mutex_unlock(&ioc->sas_topology_mutex);
} }
/** /**

View file

@ -25,8 +25,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/module.h>
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
#define BCM_VLAN 1 #define BCM_VLAN 1
#endif #endif
@ -2521,9 +2519,9 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev)
struct cnic_dev *cdev; struct cnic_dev *cdev;
struct cnic_local *cp; struct cnic_local *cp;
struct cnic_eth_dev *ethdev = NULL; struct cnic_eth_dev *ethdev = NULL;
struct cnic_eth_dev *(*probe)(void *) = NULL; struct cnic_eth_dev *(*probe)(struct net_device *) = NULL;
probe = __symbol_get("bnx2_cnic_probe"); probe = symbol_get(bnx2_cnic_probe);
if (probe) { if (probe) {
ethdev = (*probe)(dev); ethdev = (*probe)(dev);
symbol_put_addr(probe); symbol_put_addr(probe);

View file

@ -296,4 +296,6 @@ extern int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops);
extern int cnic_unregister_driver(int ulp_type); extern int cnic_unregister_driver(int ulp_type);
extern struct cnic_eth_dev *bnx2_cnic_probe(struct net_device *dev);
#endif #endif

View file

@ -258,10 +258,21 @@ config SCSI_SCAN_ASYNC
or async on the kernel's command line. or async on the kernel's command line.
config SCSI_WAIT_SCAN config SCSI_WAIT_SCAN
tristate tristate # No prompt here, this is an invisible symbol.
default m default m
depends on SCSI depends on SCSI
depends on MODULES depends on MODULES
# scsi_wait_scan is a loadable module which waits until all the async scans are
# complete. The idea is to use it in initrd/ initramfs scripts. You modprobe
# it after all the modprobes of the root SCSI drivers and it will wait until
# they have all finished scanning their buses before allowing the boot to
# proceed. (This method is not applicable if targets boot independently in
# parallel with the initiator, or with transports with non-deterministic target
# discovery schemes, or if a transport driver does not support scsi_wait_scan.)
#
# This symbol is not exposed as a prompt because little is to be gained by
# disabling it, whereas people who accidentally switch it off may wonder why
# their mkinitrd gets into trouble.
menu "SCSI Transports" menu "SCSI Transports"
depends on SCSI depends on SCSI

View file

@ -1,6 +1,8 @@
config SCSI_BNX2_ISCSI config SCSI_BNX2_ISCSI
tristate "Broadcom NetXtreme II iSCSI support" tristate "Broadcom NetXtreme II iSCSI support"
select SCSI_ISCSI_ATTRS select SCSI_ISCSI_ATTRS
select NETDEVICES
select NETDEV_1000
select CNIC select CNIC
depends on PCI depends on PCI
---help--- ---help---

View file

@ -206,6 +206,31 @@ int cxgb3i_ddp_find_page_index(unsigned long pgsz)
return DDP_PGIDX_MAX; return DDP_PGIDX_MAX;
} }
/**
* cxgb3i_ddp_adjust_page_table - adjust page table with PAGE_SIZE
* return the ddp page index, if no match is found return DDP_PGIDX_MAX.
*/
int cxgb3i_ddp_adjust_page_table(void)
{
int i;
unsigned int base_order, order;
if (PAGE_SIZE < (1UL << ddp_page_shift[0])) {
ddp_log_info("PAGE_SIZE 0x%lx too small, min. 0x%lx.\n",
PAGE_SIZE, 1UL << ddp_page_shift[0]);
return -EINVAL;
}
base_order = get_order(1UL << ddp_page_shift[0]);
order = get_order(1 << PAGE_SHIFT);
for (i = 0; i < DDP_PGIDX_MAX; i++) {
/* first is the kernel page size, then just doubling the size */
ddp_page_order[i] = order - base_order + i;
ddp_page_shift[i] = PAGE_SHIFT + i;
}
return 0;
}
static inline void ddp_gl_unmap(struct pci_dev *pdev, static inline void ddp_gl_unmap(struct pci_dev *pdev,
struct cxgb3i_gather_list *gl) struct cxgb3i_gather_list *gl)
{ {
@ -598,22 +623,24 @@ int cxgb3i_adapter_ddp_info(struct t3cdev *tdev,
* release all the resource held by the ddp pagepod manager for a given * release all the resource held by the ddp pagepod manager for a given
* adapter if needed * adapter if needed
*/ */
void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
static void ddp_cleanup(struct kref *kref)
{ {
struct cxgb3i_ddp_info *ddp = container_of(kref,
struct cxgb3i_ddp_info,
refcnt);
int i = 0; int i = 0;
struct cxgb3i_ddp_info *ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
ddp_log_info("t3dev 0x%p, release ddp 0x%p.\n", tdev, ddp); ddp_log_info("kref release ddp 0x%p, t3dev 0x%p.\n", ddp, ddp->tdev);
if (ddp) { ddp->tdev->ulp_iscsi = NULL;
tdev->ulp_iscsi = NULL;
while (i < ddp->nppods) { while (i < ddp->nppods) {
struct cxgb3i_gather_list *gl = ddp->gl_map[i]; struct cxgb3i_gather_list *gl = ddp->gl_map[i];
if (gl) { if (gl) {
int npods = (gl->nelem + PPOD_PAGES_MAX - 1) int npods = (gl->nelem + PPOD_PAGES_MAX - 1)
>> PPOD_PAGES_SHIFT; >> PPOD_PAGES_SHIFT;
ddp_log_info("t3dev 0x%p, ddp %d + %d.\n", ddp_log_info("t3dev 0x%p, ddp %d + %d.\n",
tdev, i, npods); ddp->tdev, i, npods);
kfree(gl); kfree(gl);
ddp_free_gl_skb(ddp, i, npods); ddp_free_gl_skb(ddp, i, npods);
i += npods; i += npods;
@ -622,6 +649,14 @@ void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
} }
cxgb3i_free_big_mem(ddp); cxgb3i_free_big_mem(ddp);
} }
void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
{
struct cxgb3i_ddp_info *ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
ddp_log_info("t3dev 0x%p, release ddp 0x%p.\n", tdev, ddp);
if (ddp)
kref_put(&ddp->refcnt, ddp_cleanup);
} }
/** /**
@ -631,12 +666,13 @@ void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
*/ */
static void ddp_init(struct t3cdev *tdev) static void ddp_init(struct t3cdev *tdev)
{ {
struct cxgb3i_ddp_info *ddp; struct cxgb3i_ddp_info *ddp = tdev->ulp_iscsi;
struct ulp_iscsi_info uinfo; struct ulp_iscsi_info uinfo;
unsigned int ppmax, bits; unsigned int ppmax, bits;
int i, err; int i, err;
if (tdev->ulp_iscsi) { if (ddp) {
kref_get(&ddp->refcnt);
ddp_log_warn("t3dev 0x%p, ddp 0x%p already set up.\n", ddp_log_warn("t3dev 0x%p, ddp 0x%p already set up.\n",
tdev, tdev->ulp_iscsi); tdev, tdev->ulp_iscsi);
return; return;
@ -670,6 +706,7 @@ static void ddp_init(struct t3cdev *tdev)
ppmax * ppmax *
sizeof(struct cxgb3i_gather_list *)); sizeof(struct cxgb3i_gather_list *));
spin_lock_init(&ddp->map_lock); spin_lock_init(&ddp->map_lock);
kref_init(&ddp->refcnt);
ddp->tdev = tdev; ddp->tdev = tdev;
ddp->pdev = uinfo.pdev; ddp->pdev = uinfo.pdev;
@ -715,6 +752,17 @@ void cxgb3i_ddp_init(struct t3cdev *tdev)
{ {
if (page_idx == DDP_PGIDX_MAX) { if (page_idx == DDP_PGIDX_MAX) {
page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE); page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE);
if (page_idx == DDP_PGIDX_MAX) {
ddp_log_info("system PAGE_SIZE %lu, update hw.\n",
PAGE_SIZE);
if (cxgb3i_ddp_adjust_page_table() < 0) {
ddp_log_info("PAGE_SIZE %lu, ddp disabled.\n",
PAGE_SIZE);
return;
}
page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE);
}
ddp_log_info("system PAGE_SIZE %lu, ddp idx %u.\n", ddp_log_info("system PAGE_SIZE %lu, ddp idx %u.\n",
PAGE_SIZE, page_idx); PAGE_SIZE, page_idx);
} }

View file

@ -54,6 +54,7 @@ struct cxgb3i_gather_list {
* struct cxgb3i_ddp_info - cxgb3i direct data placement for pdu payload * struct cxgb3i_ddp_info - cxgb3i direct data placement for pdu payload
* *
* @list: list head to link elements * @list: list head to link elements
* @refcnt: ref. count
* @tdev: pointer to t3cdev used by cxgb3 driver * @tdev: pointer to t3cdev used by cxgb3 driver
* @max_txsz: max tx packet size for ddp * @max_txsz: max tx packet size for ddp
* @max_rxsz: max rx packet size for ddp * @max_rxsz: max rx packet size for ddp
@ -70,6 +71,7 @@ struct cxgb3i_gather_list {
*/ */
struct cxgb3i_ddp_info { struct cxgb3i_ddp_info {
struct list_head list; struct list_head list;
struct kref refcnt;
struct t3cdev *tdev; struct t3cdev *tdev;
struct pci_dev *pdev; struct pci_dev *pdev;
unsigned int max_txsz; unsigned int max_txsz;

View file

@ -45,8 +45,6 @@
#include "fcoe.h" #include "fcoe.h"
static int debug_fcoe;
MODULE_AUTHOR("Open-FCoE.org"); MODULE_AUTHOR("Open-FCoE.org");
MODULE_DESCRIPTION("FCoE"); MODULE_DESCRIPTION("FCoE");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
@ -305,23 +303,22 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
#ifdef NETIF_F_FCOE_CRC #ifdef NETIF_F_FCOE_CRC
if (netdev->features & NETIF_F_FCOE_CRC) { if (netdev->features & NETIF_F_FCOE_CRC) {
lp->crc_offload = 1; lp->crc_offload = 1;
printk(KERN_DEBUG "fcoe:%s supports FCCRC offload\n", FCOE_NETDEV_DBG(netdev, "Supports FCCRC offload\n");
netdev->name);
} }
#endif #endif
#ifdef NETIF_F_FSO #ifdef NETIF_F_FSO
if (netdev->features & NETIF_F_FSO) { if (netdev->features & NETIF_F_FSO) {
lp->seq_offload = 1; lp->seq_offload = 1;
lp->lso_max = netdev->gso_max_size; lp->lso_max = netdev->gso_max_size;
printk(KERN_DEBUG "fcoe:%s supports LSO for max len 0x%x\n", FCOE_NETDEV_DBG(netdev, "Supports LSO for max len 0x%x\n",
netdev->name, lp->lso_max); lp->lso_max);
} }
#endif #endif
if (netdev->fcoe_ddp_xid) { if (netdev->fcoe_ddp_xid) {
lp->lro_enabled = 1; lp->lro_enabled = 1;
lp->lro_xid = netdev->fcoe_ddp_xid; lp->lro_xid = netdev->fcoe_ddp_xid;
printk(KERN_DEBUG "fcoe:%s supports LRO for max xid 0x%x\n", FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n",
netdev->name, lp->lro_xid); lp->lro_xid);
} }
skb_queue_head_init(&fc->fcoe_pending_queue); skb_queue_head_init(&fc->fcoe_pending_queue);
fc->fcoe_pending_queue_active = 0; fc->fcoe_pending_queue_active = 0;
@ -407,7 +404,8 @@ static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
/* add the new host to the SCSI-ml */ /* add the new host to the SCSI-ml */
rc = scsi_add_host(lp->host, dev); rc = scsi_add_host(lp->host, dev);
if (rc) { if (rc) {
FC_DBG("fcoe_shost_config:error on scsi_add_host\n"); FCOE_NETDEV_DBG(fcoe_netdev(lp), "fcoe_shost_config: "
"error on scsi_add_host\n");
return rc; return rc;
} }
sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s", sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
@ -448,8 +446,7 @@ static int fcoe_if_destroy(struct net_device *netdev)
BUG_ON(!netdev); BUG_ON(!netdev);
printk(KERN_DEBUG "fcoe_if_destroy:interface on %s\n", FCOE_NETDEV_DBG(netdev, "Destroying interface\n");
netdev->name);
lp = fcoe_hostlist_lookup(netdev); lp = fcoe_hostlist_lookup(netdev);
if (!lp) if (!lp)
@ -560,8 +557,7 @@ static int fcoe_if_create(struct net_device *netdev)
BUG_ON(!netdev); BUG_ON(!netdev);
printk(KERN_DEBUG "fcoe_if_create:interface on %s\n", FCOE_NETDEV_DBG(netdev, "Create Interface\n");
netdev->name);
lp = fcoe_hostlist_lookup(netdev); lp = fcoe_hostlist_lookup(netdev);
if (lp) if (lp)
@ -570,7 +566,7 @@ static int fcoe_if_create(struct net_device *netdev)
shost = libfc_host_alloc(&fcoe_shost_template, shost = libfc_host_alloc(&fcoe_shost_template,
sizeof(struct fcoe_softc)); sizeof(struct fcoe_softc));
if (!shost) { if (!shost) {
FC_DBG("Could not allocate host structure\n"); FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n");
return -ENOMEM; return -ENOMEM;
} }
lp = shost_priv(shost); lp = shost_priv(shost);
@ -579,7 +575,8 @@ static int fcoe_if_create(struct net_device *netdev)
/* configure fc_lport, e.g., em */ /* configure fc_lport, e.g., em */
rc = fcoe_lport_config(lp); rc = fcoe_lport_config(lp);
if (rc) { if (rc) {
FC_DBG("Could not configure lport\n"); FCOE_NETDEV_DBG(netdev, "Could not configure lport for the "
"interface\n");
goto out_host_put; goto out_host_put;
} }
@ -593,28 +590,32 @@ static int fcoe_if_create(struct net_device *netdev)
/* configure lport network properties */ /* configure lport network properties */
rc = fcoe_netdev_config(lp, netdev); rc = fcoe_netdev_config(lp, netdev);
if (rc) { if (rc) {
FC_DBG("Could not configure netdev for the interface\n"); FCOE_NETDEV_DBG(netdev, "Could not configure netdev for the "
"interface\n");
goto out_netdev_cleanup; goto out_netdev_cleanup;
} }
/* configure lport scsi host properties */ /* configure lport scsi host properties */
rc = fcoe_shost_config(lp, shost, &netdev->dev); rc = fcoe_shost_config(lp, shost, &netdev->dev);
if (rc) { if (rc) {
FC_DBG("Could not configure shost for lport\n"); FCOE_NETDEV_DBG(netdev, "Could not configure shost for the "
"interface\n");
goto out_netdev_cleanup; goto out_netdev_cleanup;
} }
/* lport exch manager allocation */ /* lport exch manager allocation */
rc = fcoe_em_config(lp); rc = fcoe_em_config(lp);
if (rc) { if (rc) {
FC_DBG("Could not configure em for lport\n"); FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the "
"interface\n");
goto out_netdev_cleanup; goto out_netdev_cleanup;
} }
/* Initialize the library */ /* Initialize the library */
rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ); rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ);
if (rc) { if (rc) {
FC_DBG("Could not configure libfc for lport!\n"); FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the "
"interface\n");
goto out_lp_destroy; goto out_lp_destroy;
} }
@ -653,7 +654,7 @@ static int __init fcoe_if_init(void)
fc_attach_transport(&fcoe_transport_function); fc_attach_transport(&fcoe_transport_function);
if (!scsi_transport_fcoe_sw) { if (!scsi_transport_fcoe_sw) {
printk(KERN_ERR "fcoe_init:fc_attach_transport() failed\n"); printk(KERN_ERR "fcoe: Failed to attach to the FC transport\n");
return -ENODEV; return -ENODEV;
} }
@ -714,7 +715,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu)
unsigned targ_cpu = smp_processor_id(); unsigned targ_cpu = smp_processor_id();
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
printk(KERN_DEBUG "fcoe: Destroying receive thread for CPU %d\n", cpu); FCOE_DBG("Destroying receive thread for CPU %d\n", cpu);
/* Prevent any new skbs from being queued for this CPU. */ /* Prevent any new skbs from being queued for this CPU. */
p = &per_cpu(fcoe_percpu, cpu); p = &per_cpu(fcoe_percpu, cpu);
@ -736,7 +737,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu)
p0 = &per_cpu(fcoe_percpu, targ_cpu); p0 = &per_cpu(fcoe_percpu, targ_cpu);
spin_lock_bh(&p0->fcoe_rx_list.lock); spin_lock_bh(&p0->fcoe_rx_list.lock);
if (p0->thread) { if (p0->thread) {
FC_DBG("Moving frames from CPU %d to CPU %d\n", FCOE_DBG("Moving frames from CPU %d to CPU %d\n",
cpu, targ_cpu); cpu, targ_cpu);
while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL) while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
@ -803,12 +804,12 @@ static int fcoe_cpu_callback(struct notifier_block *nfb,
switch (action) { switch (action) {
case CPU_ONLINE: case CPU_ONLINE:
case CPU_ONLINE_FROZEN: case CPU_ONLINE_FROZEN:
FC_DBG("CPU %x online: Create Rx thread\n", cpu); FCOE_DBG("CPU %x online: Create Rx thread\n", cpu);
fcoe_percpu_thread_create(cpu); fcoe_percpu_thread_create(cpu);
break; break;
case CPU_DEAD: case CPU_DEAD:
case CPU_DEAD_FROZEN: case CPU_DEAD_FROZEN:
FC_DBG("CPU %x offline: Remove Rx thread\n", cpu); FCOE_DBG("CPU %x offline: Remove Rx thread\n", cpu);
fcoe_percpu_thread_destroy(cpu); fcoe_percpu_thread_destroy(cpu);
break; break;
default: default:
@ -846,24 +847,21 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type); fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type);
lp = fc->ctlr.lp; lp = fc->ctlr.lp;
if (unlikely(lp == NULL)) { if (unlikely(lp == NULL)) {
FC_DBG("cannot find hba structure"); FCOE_NETDEV_DBG(dev, "Cannot find hba structure");
goto err2; goto err2;
} }
if (!lp->link_up) if (!lp->link_up)
goto err2; goto err2;
if (unlikely(debug_fcoe)) { FCOE_NETDEV_DBG(dev, "skb_info: len:%d data_len:%d head:%p "
FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p tail:%p " "data:%p tail:%p end:%p sum:%d dev:%s",
"end:%p sum:%d dev:%s", skb->len, skb->data_len, skb->len, skb->data_len, skb->head, skb->data,
skb->head, skb->data, skb_tail_pointer(skb), skb_tail_pointer(skb), skb_end_pointer(skb),
skb_end_pointer(skb), skb->csum, skb->csum, skb->dev ? skb->dev->name : "<NULL>");
skb->dev ? skb->dev->name : "<NULL>");
}
/* check for FCOE packet type */ /* check for FCOE packet type */
if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) { if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
FC_DBG("wrong FC type frame"); FCOE_NETDEV_DBG(dev, "Wrong FC type frame");
goto err; goto err;
} }
@ -901,8 +899,9 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
* the first CPU now. For non-SMP systems this * the first CPU now. For non-SMP systems this
* will check the same CPU twice. * will check the same CPU twice.
*/ */
FC_DBG("CPU is online, but no receive thread ready " FCOE_NETDEV_DBG(dev, "CPU is online, but no receive thread "
"for incoming skb- using first online CPU.\n"); "ready for incoming skb- using first online "
"CPU.\n");
spin_unlock_bh(&fps->fcoe_rx_list.lock); spin_unlock_bh(&fps->fcoe_rx_list.lock);
cpu = first_cpu(cpu_online_map); cpu = first_cpu(cpu_online_map);
@ -1201,19 +1200,17 @@ int fcoe_percpu_receive_thread(void *arg)
fr = fcoe_dev_from_skb(skb); fr = fcoe_dev_from_skb(skb);
lp = fr->fr_dev; lp = fr->fr_dev;
if (unlikely(lp == NULL)) { if (unlikely(lp == NULL)) {
FC_DBG("invalid HBA Structure"); FCOE_NETDEV_DBG(skb->dev, "Invalid HBA Structure");
kfree_skb(skb); kfree_skb(skb);
continue; continue;
} }
if (unlikely(debug_fcoe)) { FCOE_NETDEV_DBG(skb->dev, "skb_info: len:%d data_len:%d "
FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p " "head:%p data:%p tail:%p end:%p sum:%d dev:%s",
"tail:%p end:%p sum:%d dev:%s",
skb->len, skb->data_len, skb->len, skb->data_len,
skb->head, skb->data, skb_tail_pointer(skb), skb->head, skb->data, skb_tail_pointer(skb),
skb_end_pointer(skb), skb->csum, skb_end_pointer(skb), skb->csum,
skb->dev ? skb->dev->name : "<NULL>"); skb->dev ? skb->dev->name : "<NULL>");
}
/* /*
* Save source MAC address before discarding header. * Save source MAC address before discarding header.
@ -1233,7 +1230,7 @@ int fcoe_percpu_receive_thread(void *arg)
stats = fc_lport_get_stats(lp); stats = fc_lport_get_stats(lp);
if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
if (stats->ErrorFrames < 5) if (stats->ErrorFrames < 5)
printk(KERN_WARNING "FCoE version " printk(KERN_WARNING "fcoe: FCoE version "
"mismatch: The frame has " "mismatch: The frame has "
"version %x, but the " "version %x, but the "
"initiator supports version " "initiator supports version "
@ -1286,7 +1283,7 @@ int fcoe_percpu_receive_thread(void *arg)
if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) { if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
if (le32_to_cpu(fr_crc(fp)) != if (le32_to_cpu(fr_crc(fp)) !=
~crc32(~0, skb->data, fr_len)) { ~crc32(~0, skb->data, fr_len)) {
if (debug_fcoe || stats->InvalidCRCCount < 5) if (stats->InvalidCRCCount < 5)
printk(KERN_WARNING "fcoe: dropping " printk(KERN_WARNING "fcoe: dropping "
"frame with CRC error\n"); "frame with CRC error\n");
stats->InvalidCRCCount++; stats->InvalidCRCCount++;
@ -1432,7 +1429,8 @@ static int fcoe_device_notification(struct notifier_block *notifier,
case NETDEV_REGISTER: case NETDEV_REGISTER:
break; break;
default: default:
FC_DBG("Unknown event %ld from netdev netlink\n", event); FCOE_NETDEV_DBG(real_dev, "Unknown event %ld "
"from netdev netlink\n", event);
} }
if (link_possible && !fcoe_link_ok(lp)) if (link_possible && !fcoe_link_ok(lp))
fcoe_ctlr_link_up(&fc->ctlr); fcoe_ctlr_link_up(&fc->ctlr);
@ -1505,8 +1503,8 @@ static int fcoe_ethdrv_get(const struct net_device *netdev)
owner = fcoe_netdev_to_module_owner(netdev); owner = fcoe_netdev_to_module_owner(netdev);
if (owner) { if (owner) {
printk(KERN_DEBUG "fcoe:hold driver module %s for %s\n", FCOE_NETDEV_DBG(netdev, "Hold driver module %s\n",
module_name(owner), netdev->name); module_name(owner));
return try_module_get(owner); return try_module_get(owner);
} }
return -ENODEV; return -ENODEV;
@ -1527,8 +1525,8 @@ static int fcoe_ethdrv_put(const struct net_device *netdev)
owner = fcoe_netdev_to_module_owner(netdev); owner = fcoe_netdev_to_module_owner(netdev);
if (owner) { if (owner) {
printk(KERN_DEBUG "fcoe:release driver module %s for %s\n", FCOE_NETDEV_DBG(netdev, "Release driver module %s\n",
module_name(owner), netdev->name); module_name(owner));
module_put(owner); module_put(owner);
return 0; return 0;
} }
@ -1559,7 +1557,7 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
} }
rc = fcoe_if_destroy(netdev); rc = fcoe_if_destroy(netdev);
if (rc) { if (rc) {
printk(KERN_ERR "fcoe: fcoe_if_destroy(%s) failed\n", printk(KERN_ERR "fcoe: Failed to destroy interface (%s)\n",
netdev->name); netdev->name);
rc = -EIO; rc = -EIO;
goto out_putdev; goto out_putdev;
@ -1598,7 +1596,7 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
rc = fcoe_if_create(netdev); rc = fcoe_if_create(netdev);
if (rc) { if (rc) {
printk(KERN_ERR "fcoe: fcoe_if_create(%s) failed\n", printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
netdev->name); netdev->name);
fcoe_ethdrv_put(netdev); fcoe_ethdrv_put(netdev);
rc = -EIO; rc = -EIO;

View file

@ -40,6 +40,30 @@
#define FCOE_MIN_XID 0x0001 /* the min xid supported by fcoe_sw */ #define FCOE_MIN_XID 0x0001 /* the min xid supported by fcoe_sw */
#define FCOE_MAX_XID 0x07ef /* the max xid supported by fcoe_sw */ #define FCOE_MAX_XID 0x07ef /* the max xid supported by fcoe_sw */
unsigned int fcoe_debug_logging;
module_param_named(debug_logging, fcoe_debug_logging, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
#define FCOE_LOGGING 0x01 /* General logging, not categorized */
#define FCOE_NETDEV_LOGGING 0x02 /* Netdevice logging */
#define FCOE_CHECK_LOGGING(LEVEL, CMD) \
do { \
if (unlikely(fcoe_debug_logging & LEVEL)) \
do { \
CMD; \
} while (0); \
} while (0);
#define FCOE_DBG(fmt, args...) \
FCOE_CHECK_LOGGING(FCOE_LOGGING, \
printk(KERN_INFO "fcoe: " fmt, ##args);)
#define FCOE_NETDEV_DBG(netdev, fmt, args...) \
FCOE_CHECK_LOGGING(FCOE_NETDEV_LOGGING, \
printk(KERN_INFO "fcoe: %s" fmt, \
netdev->name, ##args);)
/* /*
* this percpu struct for fcoe * this percpu struct for fcoe
*/ */

View file

@ -56,15 +56,28 @@ static void fcoe_ctlr_recv_work(struct work_struct *);
static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS; static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS;
static u32 fcoe_ctlr_debug; /* 1 for basic, 2 for noisy debug */ unsigned int libfcoe_debug_logging;
module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
#define FIP_DBG_LVL(level, fmt, args...) \ #define LIBFCOE_LOGGING 0x01 /* General logging, not categorized */
#define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */
#define LIBFCOE_CHECK_LOGGING(LEVEL, CMD) \
do { \ do { \
if (fcoe_ctlr_debug >= (level)) \ if (unlikely(libfcoe_debug_logging & LEVEL)) \
FC_DBG(fmt, ##args); \ do { \
} while (0) CMD; \
} while (0); \
} while (0);
#define FIP_DBG(fmt, args...) FIP_DBG_LVL(1, fmt, ##args) #define LIBFCOE_DBG(fmt, args...) \
LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING, \
printk(KERN_INFO "libfcoe: " fmt, ##args);)
#define LIBFCOE_FIP_DBG(fmt, args...) \
LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING, \
printk(KERN_INFO "fip: " fmt, ##args);)
/* /*
* Return non-zero if FCF fcoe_size has been validated. * Return non-zero if FCF fcoe_size has been validated.
@ -243,7 +256,7 @@ void fcoe_ctlr_link_up(struct fcoe_ctlr *fip)
fip->last_link = 1; fip->last_link = 1;
fip->link = 1; fip->link = 1;
spin_unlock_bh(&fip->lock); spin_unlock_bh(&fip->lock);
FIP_DBG("%s", "setting AUTO mode.\n"); LIBFCOE_FIP_DBG("%s", "setting AUTO mode.\n");
fc_linkup(fip->lp); fc_linkup(fip->lp);
fcoe_ctlr_solicit(fip, NULL); fcoe_ctlr_solicit(fip, NULL);
} else } else
@ -614,7 +627,8 @@ static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf)
((struct fip_mac_desc *)desc)->fd_mac, ((struct fip_mac_desc *)desc)->fd_mac,
ETH_ALEN); ETH_ALEN);
if (!is_valid_ether_addr(fcf->fcf_mac)) { if (!is_valid_ether_addr(fcf->fcf_mac)) {
FIP_DBG("invalid MAC addr in FIP adv\n"); LIBFCOE_FIP_DBG("Invalid MAC address "
"in FIP adv\n");
return -EINVAL; return -EINVAL;
} }
break; break;
@ -647,8 +661,8 @@ static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf)
case FIP_DT_LOGO: case FIP_DT_LOGO:
case FIP_DT_ELP: case FIP_DT_ELP:
default: default:
FIP_DBG("unexpected descriptor type %x in FIP adv\n", LIBFCOE_FIP_DBG("unexpected descriptor type %x "
desc->fip_dtype); "in FIP adv\n", desc->fip_dtype);
/* standard says ignore unknown descriptors >= 128 */ /* standard says ignore unknown descriptors >= 128 */
if (desc->fip_dtype < FIP_DT_VENDOR_BASE) if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
return -EINVAL; return -EINVAL;
@ -664,7 +678,7 @@ static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf)
return 0; return 0;
len_err: len_err:
FIP_DBG("FIP length error in descriptor type %x len %zu\n", LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n",
desc->fip_dtype, dlen); desc->fip_dtype, dlen);
return -EINVAL; return -EINVAL;
} }
@ -728,9 +742,10 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
} }
mtu_valid = fcoe_ctlr_mtu_valid(fcf); mtu_valid = fcoe_ctlr_mtu_valid(fcf);
fcf->time = jiffies; fcf->time = jiffies;
FIP_DBG_LVL(found ? 2 : 1, "%s FCF for fab %llx map %x val %d\n", if (!found) {
found ? "old" : "new", LIBFCOE_FIP_DBG("New FCF for fab %llx map %x val %d\n",
fcf->fabric_name, fcf->fc_map, mtu_valid); fcf->fabric_name, fcf->fc_map, mtu_valid);
}
/* /*
* If this advertisement is not solicited and our max receive size * If this advertisement is not solicited and our max receive size
@ -807,7 +822,8 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
((struct fip_mac_desc *)desc)->fd_mac, ((struct fip_mac_desc *)desc)->fd_mac,
ETH_ALEN); ETH_ALEN);
if (!is_valid_ether_addr(granted_mac)) { if (!is_valid_ether_addr(granted_mac)) {
FIP_DBG("invalid MAC addrs in FIP ELS\n"); LIBFCOE_FIP_DBG("Invalid MAC address "
"in FIP ELS\n");
goto drop; goto drop;
} }
break; break;
@ -825,7 +841,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
els_dtype = desc->fip_dtype; els_dtype = desc->fip_dtype;
break; break;
default: default:
FIP_DBG("unexpected descriptor type %x " LIBFCOE_FIP_DBG("unexpected descriptor type %x "
"in FIP adv\n", desc->fip_dtype); "in FIP adv\n", desc->fip_dtype);
/* standard says ignore unknown descriptors >= 128 */ /* standard says ignore unknown descriptors >= 128 */
if (desc->fip_dtype < FIP_DT_VENDOR_BASE) if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
@ -867,7 +883,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
return; return;
len_err: len_err:
FIP_DBG("FIP length error in descriptor type %x len %zu\n", LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n",
desc->fip_dtype, dlen); desc->fip_dtype, dlen);
drop: drop:
kfree_skb(skb); kfree_skb(skb);
@ -894,7 +910,7 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
struct fc_lport *lp = fip->lp; struct fc_lport *lp = fip->lp;
u32 desc_mask; u32 desc_mask;
FIP_DBG("Clear Virtual Link received\n"); LIBFCOE_FIP_DBG("Clear Virtual Link received\n");
if (!fcf) if (!fcf)
return; return;
if (!fcf || !fc_host_port_id(lp->host)) if (!fcf || !fc_host_port_id(lp->host))
@ -952,9 +968,9 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
* reset only if all required descriptors were present and valid. * reset only if all required descriptors were present and valid.
*/ */
if (desc_mask) { if (desc_mask) {
FIP_DBG("missing descriptors mask %x\n", desc_mask); LIBFCOE_FIP_DBG("missing descriptors mask %x\n", desc_mask);
} else { } else {
FIP_DBG("performing Clear Virtual Link\n"); LIBFCOE_FIP_DBG("performing Clear Virtual Link\n");
fcoe_ctlr_reset(fip, FIP_ST_ENABLED); fcoe_ctlr_reset(fip, FIP_ST_ENABLED);
} }
} }
@ -1002,10 +1018,6 @@ static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb)
op = ntohs(fiph->fip_op); op = ntohs(fiph->fip_op);
sub = fiph->fip_subcode; sub = fiph->fip_subcode;
FIP_DBG_LVL(2, "ver %x op %x/%x dl %x fl %x\n",
FIP_VER_DECAPS(fiph->fip_ver), op, sub,
ntohs(fiph->fip_dl_len), ntohs(fiph->fip_flags));
if (FIP_VER_DECAPS(fiph->fip_ver) != FIP_VER) if (FIP_VER_DECAPS(fiph->fip_ver) != FIP_VER)
goto drop; goto drop;
if (ntohs(fiph->fip_dl_len) * FIP_BPW + sizeof(*fiph) > skb->len) if (ntohs(fiph->fip_dl_len) * FIP_BPW + sizeof(*fiph) > skb->len)
@ -1017,7 +1029,7 @@ static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb)
fip->map_dest = 0; fip->map_dest = 0;
fip->state = FIP_ST_ENABLED; fip->state = FIP_ST_ENABLED;
state = FIP_ST_ENABLED; state = FIP_ST_ENABLED;
FIP_DBG("using FIP mode\n"); LIBFCOE_FIP_DBG("Using FIP mode\n");
} }
spin_unlock_bh(&fip->lock); spin_unlock_bh(&fip->lock);
if (state != FIP_ST_ENABLED) if (state != FIP_ST_ENABLED)
@ -1052,14 +1064,15 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
struct fcoe_fcf *best = NULL; struct fcoe_fcf *best = NULL;
list_for_each_entry(fcf, &fip->fcfs, list) { list_for_each_entry(fcf, &fip->fcfs, list) {
FIP_DBG("consider FCF for fab %llx VFID %d map %x val %d\n", LIBFCOE_FIP_DBG("consider FCF for fab %llx VFID %d map %x "
fcf->fabric_name, fcf->vfid, "val %d\n", fcf->fabric_name, fcf->vfid,
fcf->fc_map, fcoe_ctlr_mtu_valid(fcf)); fcf->fc_map, fcoe_ctlr_mtu_valid(fcf));
if (!fcoe_ctlr_fcf_usable(fcf)) { if (!fcoe_ctlr_fcf_usable(fcf)) {
FIP_DBG("FCF for fab %llx map %x %svalid %savailable\n", LIBFCOE_FIP_DBG("FCF for fab %llx map %x %svalid "
fcf->fabric_name, fcf->fc_map, "%savailable\n", fcf->fabric_name,
(fcf->flags & FIP_FL_SOL) ? "" : "in", fcf->fc_map, (fcf->flags & FIP_FL_SOL)
(fcf->flags & FIP_FL_AVAIL) ? "" : "un"); ? "" : "in", (fcf->flags & FIP_FL_AVAIL)
? "" : "un");
continue; continue;
} }
if (!best) { if (!best) {
@ -1069,7 +1082,8 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
if (fcf->fabric_name != best->fabric_name || if (fcf->fabric_name != best->fabric_name ||
fcf->vfid != best->vfid || fcf->vfid != best->vfid ||
fcf->fc_map != best->fc_map) { fcf->fc_map != best->fc_map) {
FIP_DBG("conflicting fabric, VFID, or FC-MAP\n"); LIBFCOE_FIP_DBG("Conflicting fabric, VFID, "
"or FC-MAP\n");
return; return;
} }
if (fcf->pri < best->pri) if (fcf->pri < best->pri)
@ -1113,7 +1127,7 @@ static void fcoe_ctlr_timeout(unsigned long arg)
if (sel != fcf) { if (sel != fcf) {
fcf = sel; /* the old FCF may have been freed */ fcf = sel; /* the old FCF may have been freed */
if (sel) { if (sel) {
printk(KERN_INFO "host%d: FIP selected " printk(KERN_INFO "libfcoe: host%d: FIP selected "
"Fibre-Channel Forwarder MAC %s\n", "Fibre-Channel Forwarder MAC %s\n",
fip->lp->host->host_no, fip->lp->host->host_no,
print_mac(buf, sel->fcf_mac)); print_mac(buf, sel->fcf_mac));
@ -1123,7 +1137,7 @@ static void fcoe_ctlr_timeout(unsigned long arg)
fip->ctlr_ka_time = jiffies + sel->fka_period; fip->ctlr_ka_time = jiffies + sel->fka_period;
fip->link = 1; fip->link = 1;
} else { } else {
printk(KERN_NOTICE "host%d: " printk(KERN_NOTICE "libfcoe: host%d: "
"FIP Fibre-Channel Forwarder timed out. " "FIP Fibre-Channel Forwarder timed out. "
"Starting FCF discovery.\n", "Starting FCF discovery.\n",
fip->lp->host->host_no); fip->lp->host->host_no);
@ -1247,7 +1261,7 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa)
return -EINVAL; return -EINVAL;
} }
fip->state = FIP_ST_NON_FIP; fip->state = FIP_ST_NON_FIP;
FIP_DBG("received FLOGI LS_ACC using non-FIP mode\n"); LIBFCOE_FIP_DBG("received FLOGI LS_ACC using non-FIP mode\n");
/* /*
* FLOGI accepted. * FLOGI accepted.
@ -1276,7 +1290,7 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa)
memcpy(fip->dest_addr, sa, ETH_ALEN); memcpy(fip->dest_addr, sa, ETH_ALEN);
fip->map_dest = 0; fip->map_dest = 0;
if (fip->state == FIP_ST_NON_FIP) if (fip->state == FIP_ST_NON_FIP)
FIP_DBG("received FLOGI REQ, " LIBFCOE_FIP_DBG("received FLOGI REQ, "
"using non-FIP mode\n"); "using non-FIP mode\n");
fip->state = FIP_ST_NON_FIP; fip->state = FIP_ST_NON_FIP;
} }

View file

@ -40,7 +40,7 @@
#include "scsi_logging.h" #include "scsi_logging.h"
static int scsi_host_next_hn; /* host_no for next new host */ static atomic_t scsi_host_next_hn; /* host_no for next new host */
static void scsi_host_cls_release(struct device *dev) static void scsi_host_cls_release(struct device *dev)
@ -333,7 +333,11 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
mutex_init(&shost->scan_mutex); mutex_init(&shost->scan_mutex);
shost->host_no = scsi_host_next_hn++; /* XXX(hch): still racy */ /*
* subtract one because we increment first then return, but we need to
* know what the next host number was before increment
*/
shost->host_no = atomic_inc_return(&scsi_host_next_hn) - 1;
shost->dma_channel = 0xff; shost->dma_channel = 0xff;
/* These three are default values which can be overridden */ /* These three are default values which can be overridden */

View file

@ -2254,10 +2254,13 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
continue; continue;
if (crq->node_name && tgt->ids.node_name != crq->node_name) if (crq->node_name && tgt->ids.node_name != crq->node_name)
continue; continue;
if (tgt->need_login && crq->event == IBMVFC_AE_ELS_LOGO)
tgt->logo_rcvd = 1;
if (!tgt->need_login || crq->event == IBMVFC_AE_ELS_PLOGI) {
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
}
ibmvfc_reinit_host(vhost); ibmvfc_reinit_host(vhost);
}
}
break; break;
case IBMVFC_AE_LINK_DOWN: case IBMVFC_AE_LINK_DOWN:
case IBMVFC_AE_ADAPTER_FAILED: case IBMVFC_AE_ADAPTER_FAILED:
@ -2783,27 +2786,27 @@ static void ibmvfc_tasklet(void *data)
spin_lock_irqsave(vhost->host->host_lock, flags); spin_lock_irqsave(vhost->host->host_lock, flags);
while (!done) { while (!done) {
/* Pull all the valid messages off the CRQ */
while ((crq = ibmvfc_next_crq(vhost)) != NULL) {
ibmvfc_handle_crq(crq, vhost);
crq->valid = 0;
}
/* Pull all the valid messages off the async CRQ */ /* Pull all the valid messages off the async CRQ */
while ((async = ibmvfc_next_async_crq(vhost)) != NULL) { while ((async = ibmvfc_next_async_crq(vhost)) != NULL) {
ibmvfc_handle_async(async, vhost); ibmvfc_handle_async(async, vhost);
async->valid = 0; async->valid = 0;
} }
vio_enable_interrupts(vdev); /* Pull all the valid messages off the CRQ */
if ((crq = ibmvfc_next_crq(vhost)) != NULL) { while ((crq = ibmvfc_next_crq(vhost)) != NULL) {
vio_disable_interrupts(vdev);
ibmvfc_handle_crq(crq, vhost); ibmvfc_handle_crq(crq, vhost);
crq->valid = 0; crq->valid = 0;
} else if ((async = ibmvfc_next_async_crq(vhost)) != NULL) { }
vio_enable_interrupts(vdev);
if ((async = ibmvfc_next_async_crq(vhost)) != NULL) {
vio_disable_interrupts(vdev); vio_disable_interrupts(vdev);
ibmvfc_handle_async(async, vhost); ibmvfc_handle_async(async, vhost);
async->valid = 0; async->valid = 0;
} else if ((crq = ibmvfc_next_crq(vhost)) != NULL) {
vio_disable_interrupts(vdev);
ibmvfc_handle_crq(crq, vhost);
crq->valid = 0;
} else } else
done = 1; done = 1;
} }
@ -2927,7 +2930,11 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
break; break;
case IBMVFC_MAD_FAILED: case IBMVFC_MAD_FAILED:
default: default:
if (ibmvfc_retry_cmd(rsp->status, rsp->error)) if ((rsp->status & IBMVFC_VIOS_FAILURE) && rsp->error == IBMVFC_PLOGI_REQUIRED)
level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi);
else if (tgt->logo_rcvd)
level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi);
else if (ibmvfc_retry_cmd(rsp->status, rsp->error))
level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli); level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
else else
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
@ -3054,6 +3061,7 @@ static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt)
return; return;
kref_get(&tgt->kref); kref_get(&tgt->kref);
tgt->logo_rcvd = 0;
evt = ibmvfc_get_event(vhost); evt = ibmvfc_get_event(vhost);
vhost->discovery_threads++; vhost->discovery_threads++;
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);

View file

@ -605,6 +605,7 @@ struct ibmvfc_target {
int need_login; int need_login;
int add_rport; int add_rport;
int init_retries; int init_retries;
int logo_rcvd;
u32 cancel_key; u32 cancel_key;
struct ibmvfc_service_parms service_parms; struct ibmvfc_service_parms service_parms;
struct ibmvfc_service_parms service_parms_change; struct ibmvfc_service_parms service_parms_change;

View file

@ -131,13 +131,13 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
}; };
static const struct ipr_chip_t ipr_chip[] = { static const struct ipr_chip_t ipr_chip[] = {
{ PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, &ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, &ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, &ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, &ipr_chip_cfg[1] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, &ipr_chip_cfg[1] },
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, &ipr_chip_cfg[1] } { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, &ipr_chip_cfg[1] }
}; };
static int ipr_max_bus_speeds [] = { static int ipr_max_bus_speeds [] = {
@ -7367,6 +7367,7 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
INIT_LIST_HEAD(&ioa_cfg->used_res_q); INIT_LIST_HEAD(&ioa_cfg->used_res_q);
INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread); INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread);
init_waitqueue_head(&ioa_cfg->reset_wait_q); init_waitqueue_head(&ioa_cfg->reset_wait_q);
init_waitqueue_head(&ioa_cfg->msi_wait_q);
ioa_cfg->sdt_state = INACTIVE; ioa_cfg->sdt_state = INACTIVE;
if (ipr_enable_cache) if (ipr_enable_cache)
ioa_cfg->cache_state = CACHE_ENABLED; ioa_cfg->cache_state = CACHE_ENABLED;
@ -7398,24 +7399,107 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
} }
/** /**
* ipr_get_chip_cfg - Find adapter chip configuration * ipr_get_chip_info - Find adapter chip information
* @dev_id: PCI device id struct * @dev_id: PCI device id struct
* *
* Return value: * Return value:
* ptr to chip config on success / NULL on failure * ptr to chip information on success / NULL on failure
**/ **/
static const struct ipr_chip_cfg_t * __devinit static const struct ipr_chip_t * __devinit
ipr_get_chip_cfg(const struct pci_device_id *dev_id) ipr_get_chip_info(const struct pci_device_id *dev_id)
{ {
int i; int i;
for (i = 0; i < ARRAY_SIZE(ipr_chip); i++) for (i = 0; i < ARRAY_SIZE(ipr_chip); i++)
if (ipr_chip[i].vendor == dev_id->vendor && if (ipr_chip[i].vendor == dev_id->vendor &&
ipr_chip[i].device == dev_id->device) ipr_chip[i].device == dev_id->device)
return ipr_chip[i].cfg; return &ipr_chip[i];
return NULL; return NULL;
} }
/**
* ipr_test_intr - Handle the interrupt generated in ipr_test_msi().
* @pdev: PCI device struct
*
* Description: Simply set the msi_received flag to 1 indicating that
* Message Signaled Interrupts are supported.
*
* Return value:
* 0 on success / non-zero on failure
**/
static irqreturn_t __devinit ipr_test_intr(int irq, void *devp)
{
struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)devp;
unsigned long lock_flags = 0;
irqreturn_t rc = IRQ_HANDLED;
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
ioa_cfg->msi_received = 1;
wake_up(&ioa_cfg->msi_wait_q);
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
return rc;
}
/**
* ipr_test_msi - Test for Message Signaled Interrupt (MSI) support.
* @pdev: PCI device struct
*
* Description: The return value from pci_enable_msi() can not always be
* trusted. This routine sets up and initiates a test interrupt to determine
* if the interrupt is received via the ipr_test_intr() service routine.
* If the tests fails, the driver will fall back to LSI.
*
* Return value:
* 0 on success / non-zero on failure
**/
static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg,
struct pci_dev *pdev)
{
int rc;
volatile u32 int_reg;
unsigned long lock_flags = 0;
ENTER;
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
init_waitqueue_head(&ioa_cfg->msi_wait_q);
ioa_cfg->msi_received = 0;
ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg);
int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
rc = request_irq(pdev->irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg);
if (rc) {
dev_err(&pdev->dev, "Can not assign irq %d\n", pdev->irq);
return rc;
} else if (ipr_debug)
dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq);
writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg);
int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ);
ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
if (!ioa_cfg->msi_received) {
/* MSI test failed */
dev_info(&pdev->dev, "MSI test failed. Falling back to LSI.\n");
rc = -EOPNOTSUPP;
} else if (ipr_debug)
dev_info(&pdev->dev, "MSI test succeeded.\n");
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
free_irq(pdev->irq, ioa_cfg);
LEAVE;
return rc;
}
/** /**
* ipr_probe_ioa - Allocates memory and does first stage of initialization * ipr_probe_ioa - Allocates memory and does first stage of initialization
* @pdev: PCI device struct * @pdev: PCI device struct
@ -7441,11 +7525,6 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
goto out; goto out;
} }
if (!(rc = pci_enable_msi(pdev)))
dev_info(&pdev->dev, "MSI enabled\n");
else if (ipr_debug)
dev_info(&pdev->dev, "Cannot enable MSI\n");
dev_info(&pdev->dev, "Found IOA with IRQ: %d\n", pdev->irq); dev_info(&pdev->dev, "Found IOA with IRQ: %d\n", pdev->irq);
host = scsi_host_alloc(&driver_template, sizeof(*ioa_cfg)); host = scsi_host_alloc(&driver_template, sizeof(*ioa_cfg));
@ -7461,14 +7540,16 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
ata_host_init(&ioa_cfg->ata_host, &pdev->dev, ata_host_init(&ioa_cfg->ata_host, &pdev->dev,
sata_port_info.flags, &ipr_sata_ops); sata_port_info.flags, &ipr_sata_ops);
ioa_cfg->chip_cfg = ipr_get_chip_cfg(dev_id); ioa_cfg->ipr_chip = ipr_get_chip_info(dev_id);
if (!ioa_cfg->chip_cfg) { if (!ioa_cfg->ipr_chip) {
dev_err(&pdev->dev, "Unknown adapter chipset 0x%04X 0x%04X\n", dev_err(&pdev->dev, "Unknown adapter chipset 0x%04X 0x%04X\n",
dev_id->vendor, dev_id->device); dev_id->vendor, dev_id->device);
goto out_scsi_host_put; goto out_scsi_host_put;
} }
ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg;
if (ipr_transop_timeout) if (ipr_transop_timeout)
ioa_cfg->transop_timeout = ipr_transop_timeout; ioa_cfg->transop_timeout = ipr_transop_timeout;
else if (dev_id->driver_data & IPR_USE_LONG_TRANSOP_TIMEOUT) else if (dev_id->driver_data & IPR_USE_LONG_TRANSOP_TIMEOUT)
@ -7519,6 +7600,18 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
goto cleanup_nomem; goto cleanup_nomem;
} }
/* Enable MSI style interrupts if they are supported. */
if (ioa_cfg->ipr_chip->intr_type == IPR_USE_MSI && !pci_enable_msi(pdev)) {
rc = ipr_test_msi(ioa_cfg, pdev);
if (rc == -EOPNOTSUPP)
pci_disable_msi(pdev);
else if (rc)
goto out_msi_disable;
else
dev_info(&pdev->dev, "MSI enabled with IRQ: %d\n", pdev->irq);
} else if (ipr_debug)
dev_info(&pdev->dev, "Cannot enable MSI.\n");
/* Save away PCI config space for use following IOA reset */ /* Save away PCI config space for use following IOA reset */
rc = pci_save_state(pdev); rc = pci_save_state(pdev);
@ -7556,7 +7649,9 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
ioa_cfg->ioa_unit_checked = 1; ioa_cfg->ioa_unit_checked = 1;
ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
rc = request_irq(pdev->irq, ipr_isr, IRQF_SHARED, IPR_NAME, ioa_cfg); rc = request_irq(pdev->irq, ipr_isr,
ioa_cfg->msi_received ? 0 : IRQF_SHARED,
IPR_NAME, ioa_cfg);
if (rc) { if (rc) {
dev_err(&pdev->dev, "Couldn't register IRQ %d! rc=%d\n", dev_err(&pdev->dev, "Couldn't register IRQ %d! rc=%d\n",
@ -7583,12 +7678,13 @@ cleanup_nolog:
ipr_free_mem(ioa_cfg); ipr_free_mem(ioa_cfg);
cleanup_nomem: cleanup_nomem:
iounmap(ipr_regs); iounmap(ipr_regs);
out_msi_disable:
pci_disable_msi(pdev);
out_release_regions: out_release_regions:
pci_release_regions(pdev); pci_release_regions(pdev);
out_scsi_host_put: out_scsi_host_put:
scsi_host_put(host); scsi_host_put(host);
out_disable: out_disable:
pci_disable_msi(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
goto out; goto out;
} }

View file

@ -37,8 +37,8 @@
/* /*
* Literals * Literals
*/ */
#define IPR_DRIVER_VERSION "2.4.2" #define IPR_DRIVER_VERSION "2.4.3"
#define IPR_DRIVER_DATE "(January 21, 2009)" #define IPR_DRIVER_DATE "(June 10, 2009)"
/* /*
* IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@ -1025,6 +1025,9 @@ struct ipr_chip_cfg_t {
struct ipr_chip_t { struct ipr_chip_t {
u16 vendor; u16 vendor;
u16 device; u16 device;
u16 intr_type;
#define IPR_USE_LSI 0x00
#define IPR_USE_MSI 0x01
const struct ipr_chip_cfg_t *cfg; const struct ipr_chip_cfg_t *cfg;
}; };
@ -1094,6 +1097,7 @@ struct ipr_ioa_cfg {
u8 needs_hard_reset:1; u8 needs_hard_reset:1;
u8 dual_raid:1; u8 dual_raid:1;
u8 needs_warm_reset:1; u8 needs_warm_reset:1;
u8 msi_received:1;
u8 revid; u8 revid;
@ -1159,6 +1163,7 @@ struct ipr_ioa_cfg {
unsigned int transop_timeout; unsigned int transop_timeout;
const struct ipr_chip_cfg_t *chip_cfg; const struct ipr_chip_cfg_t *chip_cfg;
const struct ipr_chip_t *ipr_chip;
void __iomem *hdw_dma_regs; /* iomapped PCI memory space */ void __iomem *hdw_dma_regs; /* iomapped PCI memory space */
unsigned long hdw_dma_regs_pci; /* raw PCI memory space */ unsigned long hdw_dma_regs_pci; /* raw PCI memory space */
@ -1179,6 +1184,7 @@ struct ipr_ioa_cfg {
struct work_struct work_q; struct work_struct work_q;
wait_queue_head_t reset_wait_q; wait_queue_head_t reset_wait_q;
wait_queue_head_t msi_wait_q;
struct ipr_dump *dump; struct ipr_dump *dump;
enum ipr_sdt_state sdt_state; enum ipr_sdt_state sdt_state;

View file

@ -253,8 +253,6 @@ static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn,
if (r < 0) { if (r < 0) {
iscsi_tcp_segment_unmap(segment); iscsi_tcp_segment_unmap(segment);
if (copied || r == -EAGAIN)
break;
return r; return r;
} }
copied += r; copied += r;
@ -275,11 +273,17 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn)
while (1) { while (1) {
rc = iscsi_sw_tcp_xmit_segment(tcp_conn, segment); rc = iscsi_sw_tcp_xmit_segment(tcp_conn, segment);
if (rc < 0) { /*
* We may not have been able to send data because the conn
* is getting stopped. libiscsi will know so propogate err
* for it to do the right thing.
*/
if (rc == -EAGAIN)
return rc;
else if (rc < 0) {
rc = ISCSI_ERR_XMIT_FAILED; rc = ISCSI_ERR_XMIT_FAILED;
goto error; goto error;
} } else if (rc == 0)
if (rc == 0)
break; break;
consumed += rc; consumed += rc;

View file

@ -45,14 +45,6 @@
#define FC_DISC_DELAY 3 #define FC_DISC_DELAY 3
static int fc_disc_debug;
#define FC_DEBUG_DISC(fmt...) \
do { \
if (fc_disc_debug) \
FC_DBG(fmt); \
} while (0)
static void fc_disc_gpn_ft_req(struct fc_disc *); static void fc_disc_gpn_ft_req(struct fc_disc *);
static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *); static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *);
static int fc_disc_new_target(struct fc_disc *, struct fc_rport *, static int fc_disc_new_target(struct fc_disc *, struct fc_rport *,
@ -137,7 +129,7 @@ static void fc_disc_rport_callback(struct fc_lport *lport,
struct fc_rport_libfc_priv *rdata = rport->dd_data; struct fc_rport_libfc_priv *rdata = rport->dd_data;
struct fc_disc *disc = &lport->disc; struct fc_disc *disc = &lport->disc;
FC_DEBUG_DISC("Received a %d event for port (%6x)\n", event, FC_DISC_DBG(disc, "Received a %d event for port (%6x)\n", event,
rport->port_id); rport->port_id);
switch (event) { switch (event) {
@ -191,8 +183,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
lport = disc->lport; lport = disc->lport;
FC_DEBUG_DISC("Received an RSCN event on port (%6x)\n", FC_DISC_DBG(disc, "Received an RSCN event\n");
fc_host_port_id(lport->host));
/* make sure the frame contains an RSCN message */ /* make sure the frame contains an RSCN message */
rp = fc_frame_payload_get(fp, sizeof(*rp)); rp = fc_frame_payload_get(fp, sizeof(*rp));
@ -225,8 +216,8 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
*/ */
switch (fmt) { switch (fmt) {
case ELS_ADDR_FMT_PORT: case ELS_ADDR_FMT_PORT:
FC_DEBUG_DISC("Port address format for port (%6x)\n", FC_DISC_DBG(disc, "Port address format for port "
ntoh24(pp->rscn_fid)); "(%6x)\n", ntoh24(pp->rscn_fid));
dp = kzalloc(sizeof(*dp), GFP_KERNEL); dp = kzalloc(sizeof(*dp), GFP_KERNEL);
if (!dp) { if (!dp) {
redisc = 1; redisc = 1;
@ -243,17 +234,17 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
case ELS_ADDR_FMT_DOM: case ELS_ADDR_FMT_DOM:
case ELS_ADDR_FMT_FAB: case ELS_ADDR_FMT_FAB:
default: default:
FC_DEBUG_DISC("Address format is (%d)\n", fmt); FC_DISC_DBG(disc, "Address format is (%d)\n", fmt);
redisc = 1; redisc = 1;
break; break;
} }
} }
lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
if (redisc) { if (redisc) {
FC_DEBUG_DISC("RSCN received: rediscovering\n"); FC_DISC_DBG(disc, "RSCN received: rediscovering\n");
fc_disc_restart(disc); fc_disc_restart(disc);
} else { } else {
FC_DEBUG_DISC("RSCN received: not rediscovering. " FC_DISC_DBG(disc, "RSCN received: not rediscovering. "
"redisc %d state %d in_prog %d\n", "redisc %d state %d in_prog %d\n",
redisc, lport->state, disc->pending); redisc, lport->state, disc->pending);
list_for_each_entry_safe(dp, next, &disc_ports, peers) { list_for_each_entry_safe(dp, next, &disc_ports, peers) {
@ -270,7 +261,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
fc_frame_free(fp); fc_frame_free(fp);
return; return;
reject: reject:
FC_DEBUG_DISC("Received a bad RSCN frame\n"); FC_DISC_DBG(disc, "Received a bad RSCN frame\n");
rjt_data.fp = NULL; rjt_data.fp = NULL;
rjt_data.reason = ELS_RJT_LOGIC; rjt_data.reason = ELS_RJT_LOGIC;
rjt_data.explan = ELS_EXPL_NONE; rjt_data.explan = ELS_EXPL_NONE;
@ -302,7 +293,8 @@ static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp,
mutex_unlock(&disc->disc_mutex); mutex_unlock(&disc->disc_mutex);
break; break;
default: default:
FC_DBG("Received an unsupported request. opcode (%x)\n", op); FC_DISC_DBG(disc, "Received an unsupported request, "
"the opcode is (%x)\n", op);
break; break;
} }
} }
@ -320,12 +312,10 @@ static void fc_disc_restart(struct fc_disc *disc)
struct fc_rport_libfc_priv *rdata, *next; struct fc_rport_libfc_priv *rdata, *next;
struct fc_lport *lport = disc->lport; struct fc_lport *lport = disc->lport;
FC_DEBUG_DISC("Restarting discovery for port (%6x)\n", FC_DISC_DBG(disc, "Restarting discovery\n");
fc_host_port_id(lport->host));
list_for_each_entry_safe(rdata, next, &disc->rports, peers) { list_for_each_entry_safe(rdata, next, &disc->rports, peers) {
rport = PRIV_TO_RPORT(rdata); rport = PRIV_TO_RPORT(rdata);
FC_DEBUG_DISC("list_del(%6x)\n", rport->port_id);
list_del(&rdata->peers); list_del(&rdata->peers);
lport->tt.rport_logoff(rport); lport->tt.rport_logoff(rport);
} }
@ -485,8 +475,7 @@ static void fc_disc_done(struct fc_disc *disc)
struct fc_lport *lport = disc->lport; struct fc_lport *lport = disc->lport;
enum fc_disc_event event; enum fc_disc_event event;
FC_DEBUG_DISC("Discovery complete for port (%6x)\n", FC_DISC_DBG(disc, "Discovery complete\n");
fc_host_port_id(lport->host));
event = disc->event; event = disc->event;
disc->event = DISC_EV_NONE; disc->event = DISC_EV_NONE;
@ -510,8 +499,8 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp)
{ {
struct fc_lport *lport = disc->lport; struct fc_lport *lport = disc->lport;
unsigned long delay = 0; unsigned long delay = 0;
if (fc_disc_debug)
FC_DBG("Error %ld, retries %d/%d\n", FC_DISC_DBG(disc, "Error %ld, retries %d/%d\n",
PTR_ERR(fp), disc->retry_count, PTR_ERR(fp), disc->retry_count,
FC_DISC_RETRY_LIMIT); FC_DISC_RETRY_LIMIT);
@ -649,9 +638,9 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
&disc->rogue_rports); &disc->rogue_rports);
lport->tt.rport_login(rport); lport->tt.rport_login(rport);
} else } else
FC_DBG("Failed to allocate memory for " printk(KERN_WARNING "libfc: Failed to allocate "
"the newly discovered port (%6x)\n", "memory for the newly discovered port "
dp.ids.port_id); "(%6x)\n", dp.ids.port_id);
} }
if (np->fp_flags & FC_NS_FID_LAST) { if (np->fp_flags & FC_NS_FID_LAST) {
@ -671,9 +660,8 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
*/ */
if (error == 0 && len > 0 && len < sizeof(*np)) { if (error == 0 && len > 0 && len < sizeof(*np)) {
if (np != &disc->partial_buf) { if (np != &disc->partial_buf) {
FC_DEBUG_DISC("Partial buffer remains " FC_DISC_DBG(disc, "Partial buffer remains "
"for discovery by (%6x)\n", "for discovery\n");
fc_host_port_id(lport->host));
memcpy(&disc->partial_buf, np, len); memcpy(&disc->partial_buf, np, len);
} }
disc->buf_len = (unsigned char) len; disc->buf_len = (unsigned char) len;
@ -721,8 +709,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
int error; int error;
mutex_lock(&disc->disc_mutex); mutex_lock(&disc->disc_mutex);
FC_DEBUG_DISC("Received a GPN_FT response on port (%6x)\n", FC_DISC_DBG(disc, "Received a GPN_FT response\n");
fc_host_port_id(disc->lport->host));
if (IS_ERR(fp)) { if (IS_ERR(fp)) {
fc_disc_error(disc, fp); fc_disc_error(disc, fp);
@ -738,7 +725,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
disc->seq_count == 0) { disc->seq_count == 0) {
cp = fc_frame_payload_get(fp, sizeof(*cp)); cp = fc_frame_payload_get(fp, sizeof(*cp));
if (!cp) { if (!cp) {
FC_DBG("GPN_FT response too short, len %d\n", FC_DISC_DBG(disc, "GPN_FT response too short, len %d\n",
fr_len(fp)); fr_len(fp));
} else if (ntohs(cp->ct_cmd) == FC_FS_ACC) { } else if (ntohs(cp->ct_cmd) == FC_FS_ACC) {
@ -746,20 +733,20 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
buf = cp + 1; buf = cp + 1;
len -= sizeof(*cp); len -= sizeof(*cp);
} else if (ntohs(cp->ct_cmd) == FC_FS_RJT) { } else if (ntohs(cp->ct_cmd) == FC_FS_RJT) {
FC_DBG("GPN_FT rejected reason %x exp %x " FC_DISC_DBG(disc, "GPN_FT rejected reason %x exp %x "
"(check zoning)\n", cp->ct_reason, "(check zoning)\n", cp->ct_reason,
cp->ct_explan); cp->ct_explan);
disc->event = DISC_EV_FAILED; disc->event = DISC_EV_FAILED;
fc_disc_done(disc); fc_disc_done(disc);
} else { } else {
FC_DBG("GPN_FT unexpected response code %x\n", FC_DISC_DBG(disc, "GPN_FT unexpected response code "
ntohs(cp->ct_cmd)); "%x\n", ntohs(cp->ct_cmd));
} }
} else if (fr_sof(fp) == FC_SOF_N3 && } else if (fr_sof(fp) == FC_SOF_N3 &&
seq_cnt == disc->seq_count) { seq_cnt == disc->seq_count) {
buf = fh + 1; buf = fh + 1;
} else { } else {
FC_DBG("GPN_FT unexpected frame - out of sequence? " FC_DISC_DBG(disc, "GPN_FT unexpected frame - out of sequence? "
"seq_cnt %x expected %x sof %x eof %x\n", "seq_cnt %x expected %x sof %x eof %x\n",
seq_cnt, disc->seq_count, fr_sof(fp), fr_eof(fp)); seq_cnt, disc->seq_count, fr_sof(fp), fr_eof(fp));
} }

View file

@ -32,17 +32,6 @@
#include <scsi/libfc.h> #include <scsi/libfc.h>
#include <scsi/fc_encode.h> #include <scsi/fc_encode.h>
/*
* fc_exch_debug can be set in debugger or at compile time to get more logs.
*/
static int fc_exch_debug;
#define FC_DEBUG_EXCH(fmt...) \
do { \
if (fc_exch_debug) \
FC_DBG(fmt); \
} while (0)
static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ static struct kmem_cache *fc_em_cachep; /* cache for exchanges */
/* /*
@ -333,8 +322,8 @@ static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
return; return;
FC_DEBUG_EXCH("Exchange (%4x) timed out, notifying the upper layer\n", FC_EXCH_DBG(ep, "Exchange timed out, notifying the upper layer\n");
ep->xid);
if (schedule_delayed_work(&ep->timeout_work, if (schedule_delayed_work(&ep->timeout_work,
msecs_to_jiffies(timer_msec))) msecs_to_jiffies(timer_msec)))
fc_exch_hold(ep); /* hold for timer */ fc_exch_hold(ep); /* hold for timer */
@ -545,7 +534,7 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
/* alloc a new xid */ /* alloc a new xid */
xid = fc_em_alloc_xid(mp, fp); xid = fc_em_alloc_xid(mp, fp);
if (!xid) { if (!xid) {
printk(KERN_ERR "fc_em_alloc_xid() failed\n"); printk(KERN_WARNING "libfc: Failed to allocate an exhange\n");
goto err; goto err;
} }
} }
@ -820,8 +809,8 @@ static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp)
struct fc_exch *ep = fc_seq_exch(sp); struct fc_exch *ep = fc_seq_exch(sp);
sp = fc_seq_alloc(ep, ep->seq_id++); sp = fc_seq_alloc(ep, ep->seq_id++);
FC_DEBUG_EXCH("exch %4x f_ctl %6x seq %2x\n", FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n",
ep->xid, ep->f_ctl, sp->id); ep->f_ctl, sp->id);
return sp; return sp;
} }
/* /*
@ -901,7 +890,7 @@ void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd,
fc_exch_els_rec(sp, els_data->fp); fc_exch_els_rec(sp, els_data->fp);
break; break;
default: default:
FC_DBG("Invalid ELS CMD:%x\n", els_cmd); FC_EXCH_DBG(fc_seq_exch(sp), "Invalid ELS CMD:%x\n", els_cmd);
} }
} }
EXPORT_SYMBOL(fc_seq_els_rsp_send); EXPORT_SYMBOL(fc_seq_els_rsp_send);
@ -1134,7 +1123,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp,
lp->tt.lport_recv(lp, sp, fp); lp->tt.lport_recv(lp, sp, fp);
fc_exch_release(ep); /* release from lookup */ fc_exch_release(ep); /* release from lookup */
} else { } else {
FC_DEBUG_EXCH("exch/seq lookup failed: reject %x\n", reject); FC_EM_DBG(mp, "exch/seq lookup failed: reject %x\n", reject);
fc_frame_free(fp); fc_frame_free(fp);
} }
} }
@ -1242,10 +1231,10 @@ static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */ sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */
if (!sp) { if (!sp) {
atomic_inc(&mp->stats.xid_not_found); atomic_inc(&mp->stats.xid_not_found);
FC_DEBUG_EXCH("seq lookup failed\n"); FC_EM_DBG(mp, "seq lookup failed\n");
} else { } else {
atomic_inc(&mp->stats.non_bls_resp); atomic_inc(&mp->stats.non_bls_resp);
FC_DEBUG_EXCH("non-BLS response to sequence"); FC_EM_DBG(mp, "non-BLS response to sequence");
} }
fc_frame_free(fp); fc_frame_free(fp);
} }
@ -1266,8 +1255,8 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
int rc = 1, has_rec = 0; int rc = 1, has_rec = 0;
fh = fc_frame_header_get(fp); fh = fc_frame_header_get(fp);
FC_DEBUG_EXCH("exch: BLS rctl %x - %s\n", FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl,
fh->fh_r_ctl, fc_exch_rctl_name(fh->fh_r_ctl)); fc_exch_rctl_name(fh->fh_r_ctl));
if (cancel_delayed_work_sync(&ep->timeout_work)) if (cancel_delayed_work_sync(&ep->timeout_work))
fc_exch_release(ep); /* release from pending timer hold */ fc_exch_release(ep); /* release from pending timer hold */
@ -1359,7 +1348,7 @@ static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp)
case FC_RCTL_ACK_0: case FC_RCTL_ACK_0:
break; break;
default: default:
FC_DEBUG_EXCH("BLS rctl %x - %s received", FC_EXCH_DBG(ep, "BLS rctl %x - %s received",
fh->fh_r_ctl, fh->fh_r_ctl,
fc_exch_rctl_name(fh->fh_r_ctl)); fc_exch_rctl_name(fh->fh_r_ctl));
break; break;
@ -1599,7 +1588,8 @@ static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg)
if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT) if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT)
goto cleanup; goto cleanup;
FC_DBG("Cannot process RRQ, because of frame error %d\n", err); FC_EXCH_DBG(aborted_ep, "Cannot process RRQ, "
"frame error %d\n", err);
return; return;
} }
@ -1608,12 +1598,13 @@ static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg)
switch (op) { switch (op) {
case ELS_LS_RJT: case ELS_LS_RJT:
FC_DBG("LS_RJT for RRQ"); FC_EXCH_DBG(aborted_ep, "LS_RJT for RRQ");
/* fall through */ /* fall through */
case ELS_LS_ACC: case ELS_LS_ACC:
goto cleanup; goto cleanup;
default: default:
FC_DBG("unexpected response op %x for RRQ", op); FC_EXCH_DBG(aborted_ep, "unexpected response op %x "
"for RRQ", op);
return; return;
} }
@ -1740,7 +1731,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
size_t len; size_t len;
if (max_xid <= min_xid || min_xid == 0 || max_xid == FC_XID_UNKNOWN) { if (max_xid <= min_xid || min_xid == 0 || max_xid == FC_XID_UNKNOWN) {
FC_DBG("Invalid min_xid 0x:%x and max_xid 0x:%x\n", FC_LPORT_DBG(lp, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
min_xid, max_xid); min_xid, max_xid);
return NULL; return NULL;
} }
@ -1878,7 +1869,8 @@ void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp,
/* lport lock ? */ /* lport lock ? */
if (!lp || !mp || (lp->state == LPORT_ST_NONE)) { if (!lp || !mp || (lp->state == LPORT_ST_NONE)) {
FC_DBG("fc_lport or EM is not allocated and configured"); FC_LPORT_DBG(lp, "Receiving frames for an lport that "
"has not been initialized correctly\n");
fc_frame_free(fp); fc_frame_free(fp);
return; return;
} }
@ -1904,7 +1896,7 @@ void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp,
fc_exch_recv_req(lp, mp, fp); fc_exch_recv_req(lp, mp, fp);
break; break;
default: default:
FC_DBG("dropping invalid frame (eof %x)", fr_eof(fp)); FC_EM_DBG(mp, "dropping invalid frame (eof %x)", fr_eof(fp));
fc_frame_free(fp); fc_frame_free(fp);
break; break;
} }

View file

@ -43,13 +43,9 @@ MODULE_AUTHOR("Open-FCoE.org");
MODULE_DESCRIPTION("libfc"); MODULE_DESCRIPTION("libfc");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
static int fc_fcp_debug; unsigned int fc_debug_logging;
module_param_named(debug_logging, fc_debug_logging, int, S_IRUGO|S_IWUSR);
#define FC_DEBUG_FCP(fmt...) \ MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
do { \
if (fc_fcp_debug) \
FC_DBG(fmt); \
} while (0)
static struct kmem_cache *scsi_pkt_cachep; static struct kmem_cache *scsi_pkt_cachep;
@ -347,7 +343,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) &&
fc_frame_crc_check(fp)) fc_frame_crc_check(fp))
goto crc_err; goto crc_err;
FC_DEBUG_FCP("data received past end. len %zx offset %zx " FC_FCP_DBG(fsp, "data received past end. len %zx offset %zx "
"data_len %x\n", len, offset, fsp->data_len); "data_len %x\n", len, offset, fsp->data_len);
fc_fcp_retry_cmd(fsp); fc_fcp_retry_cmd(fsp);
return; return;
@ -411,7 +407,8 @@ crc_err:
stats->ErrorFrames++; stats->ErrorFrames++;
/* FIXME - per cpu count, not total count! */ /* FIXME - per cpu count, not total count! */
if (stats->InvalidCRCCount++ < 5) if (stats->InvalidCRCCount++ < 5)
printk(KERN_WARNING "CRC error on data frame for port (%6x)\n", printk(KERN_WARNING "libfc: CRC error on data "
"frame for port (%6x)\n",
fc_host_port_id(lp->host)); fc_host_port_id(lp->host));
/* /*
* Assume the frame is total garbage. * Assume the frame is total garbage.
@ -475,13 +472,13 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
WARN_ON(seq_blen <= 0); WARN_ON(seq_blen <= 0);
if (unlikely(offset + seq_blen > fsp->data_len)) { if (unlikely(offset + seq_blen > fsp->data_len)) {
/* this should never happen */ /* this should never happen */
FC_DEBUG_FCP("xfer-ready past end. seq_blen %zx offset %zx\n", FC_FCP_DBG(fsp, "xfer-ready past end. seq_blen %zx "
seq_blen, offset); "offset %zx\n", seq_blen, offset);
fc_fcp_send_abort(fsp); fc_fcp_send_abort(fsp);
return 0; return 0;
} else if (offset != fsp->xfer_len) { } else if (offset != fsp->xfer_len) {
/* Out of Order Data Request - no problem, but unexpected. */ /* Out of Order Data Request - no problem, but unexpected. */
FC_DEBUG_FCP("xfer-ready non-contiguous. " FC_FCP_DBG(fsp, "xfer-ready non-contiguous. "
"seq_blen %zx offset %zx\n", seq_blen, offset); "seq_blen %zx offset %zx\n", seq_blen, offset);
} }
@ -493,7 +490,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
t_blen = fsp->max_payload; t_blen = fsp->max_payload;
if (lp->seq_offload) { if (lp->seq_offload) {
t_blen = min(seq_blen, (size_t)lp->lso_max); t_blen = min(seq_blen, (size_t)lp->lso_max);
FC_DEBUG_FCP("fsp=%p:lso:blen=%zx lso_max=0x%x t_blen=%zx\n", FC_FCP_DBG(fsp, "fsp=%p:lso:blen=%zx lso_max=0x%x t_blen=%zx\n",
fsp, seq_blen, lp->lso_max, t_blen); fsp, seq_blen, lp->lso_max, t_blen);
} }
@ -694,7 +691,7 @@ static void fc_fcp_reduce_can_queue(struct fc_lport *lp)
if (!can_queue) if (!can_queue)
can_queue = 1; can_queue = 1;
lp->host->can_queue = can_queue; lp->host->can_queue = can_queue;
shost_printk(KERN_ERR, lp->host, "Could not allocate frame.\n" shost_printk(KERN_ERR, lp->host, "libfc: Could not allocate frame.\n"
"Reducing can_queue to %d.\n", can_queue); "Reducing can_queue to %d.\n", can_queue);
done: done:
spin_unlock_irqrestore(lp->host->host_lock, flags); spin_unlock_irqrestore(lp->host->host_lock, flags);
@ -768,7 +765,7 @@ static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg)
fc_fcp_resp(fsp, fp); fc_fcp_resp(fsp, fp);
} else { } else {
FC_DBG("unexpected frame. r_ctl %x\n", r_ctl); FC_FCP_DBG(fsp, "unexpected frame. r_ctl %x\n", r_ctl);
} }
unlock: unlock:
fc_fcp_unlock_pkt(fsp); fc_fcp_unlock_pkt(fsp);
@ -877,8 +874,8 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
return; return;
} }
fsp->status_code = FC_DATA_OVRRUN; fsp->status_code = FC_DATA_OVRRUN;
FC_DBG("tgt %6x xfer len %zx greater than expected len %x. " FC_FCP_DBG(fsp, "tgt %6x xfer len %zx greater than expected, "
"data len %x\n", "len %x, data len %x\n",
fsp->rport->port_id, fsp->rport->port_id,
fsp->xfer_len, expected_len, fsp->data_len); fsp->xfer_len, expected_len, fsp->data_len);
} }
@ -886,8 +883,8 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
return; return;
len_err: len_err:
FC_DBG("short FCP response. flags 0x%x len %u respl %u snsl %u\n", FC_FCP_DBG(fsp, "short FCP response. flags 0x%x len %u respl %u "
flags, fr_len(fp), respl, snsl); "snsl %u\n", flags, fr_len(fp), respl, snsl);
err: err:
fsp->status_code = FC_ERROR; fsp->status_code = FC_ERROR;
fc_fcp_complete_locked(fsp); fc_fcp_complete_locked(fsp);
@ -1107,13 +1104,11 @@ static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
if (fc_fcp_lock_pkt(fsp)) if (fc_fcp_lock_pkt(fsp))
return; return;
switch (error) { if (error == -FC_EX_CLOSED) {
case -FC_EX_CLOSED:
fc_fcp_retry_cmd(fsp); fc_fcp_retry_cmd(fsp);
goto unlock; goto unlock;
default:
FC_DBG("unknown error %ld\n", PTR_ERR(fp));
} }
/* /*
* clear abort pending, because the lower layer * clear abort pending, because the lower layer
* decided to force completion. * decided to force completion.
@ -1145,10 +1140,10 @@ static int fc_fcp_pkt_abort(struct fc_lport *lp, struct fc_fcp_pkt *fsp)
fsp->wait_for_comp = 0; fsp->wait_for_comp = 0;
if (!rc) { if (!rc) {
FC_DBG("target abort cmd failed\n"); FC_FCP_DBG(fsp, "target abort cmd failed\n");
rc = FAILED; rc = FAILED;
} else if (fsp->state & FC_SRB_ABORTED) { } else if (fsp->state & FC_SRB_ABORTED) {
FC_DBG("target abort cmd passed\n"); FC_FCP_DBG(fsp, "target abort cmd passed\n");
rc = SUCCESS; rc = SUCCESS;
fc_fcp_complete_locked(fsp); fc_fcp_complete_locked(fsp);
} }
@ -1213,7 +1208,7 @@ static int fc_lun_reset(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
spin_unlock_bh(&fsp->scsi_pkt_lock); spin_unlock_bh(&fsp->scsi_pkt_lock);
if (!rc) { if (!rc) {
FC_DBG("lun reset failed\n"); FC_SCSI_DBG(lp, "lun reset failed\n");
return FAILED; return FAILED;
} }
@ -1221,7 +1216,7 @@ static int fc_lun_reset(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
if (fsp->cdb_status != FCP_TMF_CMPL) if (fsp->cdb_status != FCP_TMF_CMPL)
return FAILED; return FAILED;
FC_DBG("lun reset to lun %u completed\n", lun); FC_SCSI_DBG(lp, "lun reset to lun %u completed\n", lun);
fc_fcp_cleanup_each_cmd(lp, id, lun, FC_CMD_ABORTED); fc_fcp_cleanup_each_cmd(lp, id, lun, FC_CMD_ABORTED);
return SUCCESS; return SUCCESS;
} }
@ -1388,13 +1383,13 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
rjt = fc_frame_payload_get(fp, sizeof(*rjt)); rjt = fc_frame_payload_get(fp, sizeof(*rjt));
switch (rjt->er_reason) { switch (rjt->er_reason) {
default: default:
FC_DEBUG_FCP("device %x unexpected REC reject " FC_FCP_DBG(fsp, "device %x unexpected REC reject "
"reason %d expl %d\n", "reason %d expl %d\n",
fsp->rport->port_id, rjt->er_reason, fsp->rport->port_id, rjt->er_reason,
rjt->er_explan); rjt->er_explan);
/* fall through */ /* fall through */
case ELS_RJT_UNSUP: case ELS_RJT_UNSUP:
FC_DEBUG_FCP("device does not support REC\n"); FC_FCP_DBG(fsp, "device does not support REC\n");
rp = fsp->rport->dd_data; rp = fsp->rport->dd_data;
/* /*
* if we do not spport RECs or got some bogus * if we do not spport RECs or got some bogus
@ -1514,7 +1509,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
break; break;
default: default:
FC_DBG("REC %p fid %x error unexpected error %d\n", FC_FCP_DBG(fsp, "REC %p fid %x error unexpected error %d\n",
fsp, fsp->rport->port_id, error); fsp, fsp->rport->port_id, error);
fsp->status_code = FC_CMD_PLOGO; fsp->status_code = FC_CMD_PLOGO;
/* fall through */ /* fall through */
@ -1524,7 +1519,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
* Assume REC or LS_ACC was lost. * Assume REC or LS_ACC was lost.
* The exchange manager will have aborted REC, so retry. * The exchange manager will have aborted REC, so retry.
*/ */
FC_DBG("REC fid %x error error %d retry %d/%d\n", FC_FCP_DBG(fsp, "REC fid %x error error %d retry %d/%d\n",
fsp->rport->port_id, error, fsp->recov_retry, fsp->rport->port_id, error, fsp->recov_retry,
FC_MAX_RECOV_RETRY); FC_MAX_RECOV_RETRY);
if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
@ -2011,9 +2006,11 @@ int fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
if (lp->state != LPORT_ST_READY) if (lp->state != LPORT_ST_READY)
return rc; return rc;
FC_SCSI_DBG(lp, "Resetting rport (%6x)\n", rport->port_id);
fsp = fc_fcp_pkt_alloc(lp, GFP_NOIO); fsp = fc_fcp_pkt_alloc(lp, GFP_NOIO);
if (fsp == NULL) { if (fsp == NULL) {
FC_DBG("could not allocate scsi_pkt\n"); printk(KERN_WARNING "libfc: could not allocate scsi_pkt\n");
sc_cmd->result = DID_NO_CONNECT << 16; sc_cmd->result = DID_NO_CONNECT << 16;
goto out; goto out;
} }
@ -2048,17 +2045,21 @@ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd)
struct fc_lport *lp = shost_priv(shost); struct fc_lport *lp = shost_priv(shost);
unsigned long wait_tmo; unsigned long wait_tmo;
FC_SCSI_DBG(lp, "Resetting host\n");
lp->tt.lport_reset(lp); lp->tt.lport_reset(lp);
wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT; wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT;
while (!fc_fcp_lport_queue_ready(lp) && time_before(jiffies, wait_tmo)) while (!fc_fcp_lport_queue_ready(lp) && time_before(jiffies, wait_tmo))
msleep(1000); msleep(1000);
if (fc_fcp_lport_queue_ready(lp)) { if (fc_fcp_lport_queue_ready(lp)) {
shost_printk(KERN_INFO, shost, "Host reset succeeded.\n"); shost_printk(KERN_INFO, shost, "libfc: Host reset succeeded "
"on port (%6x)\n", fc_host_port_id(lp->host));
return SUCCESS; return SUCCESS;
} else { } else {
shost_printk(KERN_INFO, shost, "Host reset failed. " shost_printk(KERN_INFO, shost, "libfc: Host reset failed, "
"lport not ready.\n"); "port (%6x) is not ready.\n",
fc_host_port_id(lp->host));
return FAILED; return FAILED;
} }
} }
@ -2117,7 +2118,8 @@ void fc_fcp_destroy(struct fc_lport *lp)
struct fc_fcp_internal *si = fc_get_scsi_internal(lp); struct fc_fcp_internal *si = fc_get_scsi_internal(lp);
if (!list_empty(&si->scsi_pkt_queue)) if (!list_empty(&si->scsi_pkt_queue))
printk(KERN_ERR "Leaked scsi packets.\n"); printk(KERN_ERR "libfc: Leaked SCSI packets when destroying "
"port (%6x)\n", fc_host_port_id(lp->host));
mempool_destroy(si->scsi_pkt_pool); mempool_destroy(si->scsi_pkt_pool);
kfree(si); kfree(si);
@ -2166,7 +2168,8 @@ static int __init libfc_init(void)
sizeof(struct fc_fcp_pkt), sizeof(struct fc_fcp_pkt),
0, SLAB_HWCACHE_ALIGN, NULL); 0, SLAB_HWCACHE_ALIGN, NULL);
if (scsi_pkt_cachep == NULL) { if (scsi_pkt_cachep == NULL) {
FC_DBG("Unable to allocate SRB cache...module load failed!"); printk(KERN_ERR "libfc: Unable to allocate SRB cache, "
"module load failed!");
return -ENOMEM; return -ENOMEM;
} }

View file

@ -101,14 +101,6 @@
#define DNS_DELAY 3 /* Discovery delay after RSCN (in seconds)*/ #define DNS_DELAY 3 /* Discovery delay after RSCN (in seconds)*/
static int fc_lport_debug;
#define FC_DEBUG_LPORT(fmt...) \
do { \
if (fc_lport_debug) \
FC_DBG(fmt); \
} while (0)
static void fc_lport_error(struct fc_lport *, struct fc_frame *); static void fc_lport_error(struct fc_lport *, struct fc_frame *);
static void fc_lport_enter_reset(struct fc_lport *); static void fc_lport_enter_reset(struct fc_lport *);
@ -151,7 +143,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
struct fc_rport *rport, struct fc_rport *rport,
enum fc_rport_event event) enum fc_rport_event event)
{ {
FC_DEBUG_LPORT("Received a %d event for port (%6x)\n", event, FC_LPORT_DBG(lport, "Received a %d event for port (%6x)\n", event,
rport->port_id); rport->port_id);
switch (event) { switch (event) {
@ -162,8 +154,8 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
lport->dns_rp = rport; lport->dns_rp = rport;
fc_lport_enter_rpn_id(lport); fc_lport_enter_rpn_id(lport);
} else { } else {
FC_DEBUG_LPORT("Received an CREATED event on " FC_LPORT_DBG(lport, "Received an CREATED event "
"port (%6x) for the directory " "on port (%6x) for the directory "
"server, but the lport is not " "server, but the lport is not "
"in the DNS state, it's in the " "in the DNS state, it's in the "
"%d state", rport->port_id, "%d state", rport->port_id,
@ -172,7 +164,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
} }
mutex_unlock(&lport->lp_mutex); mutex_unlock(&lport->lp_mutex);
} else } else
FC_DEBUG_LPORT("Received an event for port (%6x) " FC_LPORT_DBG(lport, "Received an event for port (%6x) "
"which is not the directory server\n", "which is not the directory server\n",
rport->port_id); rport->port_id);
break; break;
@ -185,7 +177,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
mutex_unlock(&lport->lp_mutex); mutex_unlock(&lport->lp_mutex);
} else } else
FC_DEBUG_LPORT("Received an event for port (%6x) " FC_LPORT_DBG(lport, "Received an event for port (%6x) "
"which is not the directory server\n", "which is not the directory server\n",
rport->port_id); rport->port_id);
break; break;
@ -363,7 +355,7 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp, static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
struct fc_lport *lport) struct fc_lport *lport)
{ {
FC_DEBUG_LPORT("Received RLIR request while in state %s\n", FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n",
fc_lport_state(lport)); fc_lport_state(lport));
lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
@ -389,7 +381,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
void *dp; void *dp;
u32 f_ctl; u32 f_ctl;
FC_DEBUG_LPORT("Received RLIR request while in state %s\n", FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n",
fc_lport_state(lport)); fc_lport_state(lport));
len = fr_len(in_fp) - sizeof(struct fc_frame_header); len = fr_len(in_fp) - sizeof(struct fc_frame_header);
@ -437,7 +429,7 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
size_t len; size_t len;
u32 f_ctl; u32 f_ctl;
FC_DEBUG_LPORT("Received RNID request while in state %s\n", FC_LPORT_DBG(lport, "Received RNID request while in state %s\n",
fc_lport_state(lport)); fc_lport_state(lport));
req = fc_frame_payload_get(in_fp, sizeof(*req)); req = fc_frame_payload_get(in_fp, sizeof(*req));
@ -498,7 +490,7 @@ static void fc_lport_recv_adisc_req(struct fc_seq *sp, struct fc_frame *in_fp,
size_t len; size_t len;
u32 f_ctl; u32 f_ctl;
FC_DEBUG_LPORT("Received ADISC request while in state %s\n", FC_LPORT_DBG(lport, "Received ADISC request while in state %s\n",
fc_lport_state(lport)); fc_lport_state(lport));
req = fc_frame_payload_get(in_fp, sizeof(*req)); req = fc_frame_payload_get(in_fp, sizeof(*req));
@ -574,7 +566,7 @@ EXPORT_SYMBOL(fc_fabric_login);
*/ */
void fc_linkup(struct fc_lport *lport) void fc_linkup(struct fc_lport *lport)
{ {
FC_DEBUG_LPORT("Link is up for port (%6x)\n", printk(KERN_INFO "libfc: Link up on port (%6x)\n",
fc_host_port_id(lport->host)); fc_host_port_id(lport->host));
mutex_lock(&lport->lp_mutex); mutex_lock(&lport->lp_mutex);
@ -595,7 +587,7 @@ EXPORT_SYMBOL(fc_linkup);
void fc_linkdown(struct fc_lport *lport) void fc_linkdown(struct fc_lport *lport)
{ {
mutex_lock(&lport->lp_mutex); mutex_lock(&lport->lp_mutex);
FC_DEBUG_LPORT("Link is down for port (%6x)\n", printk(KERN_INFO "libfc: Link down on port (%6x)\n",
fc_host_port_id(lport->host)); fc_host_port_id(lport->host));
if (lport->link_up) { if (lport->link_up) {
@ -701,11 +693,10 @@ void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event)
{ {
switch (event) { switch (event) {
case DISC_EV_SUCCESS: case DISC_EV_SUCCESS:
FC_DEBUG_LPORT("Got a SUCCESS event for port (%6x)\n", FC_LPORT_DBG(lport, "Discovery succeeded\n");
fc_host_port_id(lport->host));
break; break;
case DISC_EV_FAILED: case DISC_EV_FAILED:
FC_DEBUG_LPORT("Got a FAILED event for port (%6x)\n", printk(KERN_ERR "libfc: Discovery failed for port (%6x)\n",
fc_host_port_id(lport->host)); fc_host_port_id(lport->host));
mutex_lock(&lport->lp_mutex); mutex_lock(&lport->lp_mutex);
fc_lport_enter_reset(lport); fc_lport_enter_reset(lport);
@ -726,8 +717,8 @@ void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event)
*/ */
static void fc_lport_enter_ready(struct fc_lport *lport) static void fc_lport_enter_ready(struct fc_lport *lport)
{ {
FC_DEBUG_LPORT("Port (%6x) entered Ready from state %s\n", FC_LPORT_DBG(lport, "Entered READY from state %s\n",
fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state(lport));
fc_lport_state_enter(lport, LPORT_ST_READY); fc_lport_state_enter(lport, LPORT_ST_READY);
@ -762,7 +753,7 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
u32 local_fid; u32 local_fid;
u32 f_ctl; u32 f_ctl;
FC_DEBUG_LPORT("Received FLOGI request while in state %s\n", FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n",
fc_lport_state(lport)); fc_lport_state(lport));
fh = fc_frame_header_get(rx_fp); fh = fc_frame_header_get(rx_fp);
@ -772,12 +763,11 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
goto out; goto out;
remote_wwpn = get_unaligned_be64(&flp->fl_wwpn); remote_wwpn = get_unaligned_be64(&flp->fl_wwpn);
if (remote_wwpn == lport->wwpn) { if (remote_wwpn == lport->wwpn) {
FC_DBG("FLOGI from port with same WWPN %llx " printk(KERN_WARNING "libfc: Received FLOGI from port "
"possible configuration error\n", "with same WWPN %llx\n", remote_wwpn);
(unsigned long long)remote_wwpn);
goto out; goto out;
} }
FC_DBG("FLOGI from port WWPN %llx\n", (unsigned long long)remote_wwpn); FC_LPORT_DBG(lport, "FLOGI from port WWPN %llx\n", remote_wwpn);
/* /*
* XXX what is the right thing to do for FIDs? * XXX what is the right thing to do for FIDs?
@ -909,7 +899,8 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
} }
} }
} else { } else {
FC_DBG("dropping invalid frame (eof %x)\n", fr_eof(fp)); FC_LPORT_DBG(lport, "dropping invalid frame (eof %x)\n",
fr_eof(fp));
fc_frame_free(fp); fc_frame_free(fp);
} }
mutex_unlock(&lport->lp_mutex); mutex_unlock(&lport->lp_mutex);
@ -947,8 +938,8 @@ EXPORT_SYMBOL(fc_lport_reset);
*/ */
static void fc_lport_enter_reset(struct fc_lport *lport) static void fc_lport_enter_reset(struct fc_lport *lport)
{ {
FC_DEBUG_LPORT("Port (%6x) entered RESET state from %s state\n", FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state(lport));
fc_lport_state_enter(lport, LPORT_ST_RESET); fc_lport_state_enter(lport, LPORT_ST_RESET);
@ -982,7 +973,7 @@ static void fc_lport_enter_reset(struct fc_lport *lport)
static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp) static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
{ {
unsigned long delay = 0; unsigned long delay = 0;
FC_DEBUG_LPORT("Error %ld in state %s, retries %d\n", FC_LPORT_DBG(lport, "Error %ld in state %s, retries %d\n",
PTR_ERR(fp), fc_lport_state(lport), PTR_ERR(fp), fc_lport_state(lport),
lport->retry_count); lport->retry_count);
@ -1040,11 +1031,11 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
mutex_lock(&lport->lp_mutex); mutex_lock(&lport->lp_mutex);
FC_DEBUG_LPORT("Received a RFT_ID response\n"); FC_LPORT_DBG(lport, "Received a RFT_ID response\n");
if (lport->state != LPORT_ST_RFT_ID) { if (lport->state != LPORT_ST_RFT_ID) {
FC_DBG("Received a RFT_ID response, but in state %s\n", FC_LPORT_DBG(lport, "Received a RFT_ID response, but in state "
fc_lport_state(lport)); "%s\n", fc_lport_state(lport));
if (IS_ERR(fp)) if (IS_ERR(fp))
goto err; goto err;
goto out; goto out;
@ -1094,11 +1085,11 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
mutex_lock(&lport->lp_mutex); mutex_lock(&lport->lp_mutex);
FC_DEBUG_LPORT("Received a RPN_ID response\n"); FC_LPORT_DBG(lport, "Received a RPN_ID response\n");
if (lport->state != LPORT_ST_RPN_ID) { if (lport->state != LPORT_ST_RPN_ID) {
FC_DBG("Received a RPN_ID response, but in state %s\n", FC_LPORT_DBG(lport, "Received a RPN_ID response, but in state "
fc_lport_state(lport)); "%s\n", fc_lport_state(lport));
if (IS_ERR(fp)) if (IS_ERR(fp))
goto err; goto err;
goto out; goto out;
@ -1146,11 +1137,11 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
mutex_lock(&lport->lp_mutex); mutex_lock(&lport->lp_mutex);
FC_DEBUG_LPORT("Received a SCR response\n"); FC_LPORT_DBG(lport, "Received a SCR response\n");
if (lport->state != LPORT_ST_SCR) { if (lport->state != LPORT_ST_SCR) {
FC_DBG("Received a SCR response, but in state %s\n", FC_LPORT_DBG(lport, "Received a SCR response, but in state "
fc_lport_state(lport)); "%s\n", fc_lport_state(lport));
if (IS_ERR(fp)) if (IS_ERR(fp))
goto err; goto err;
goto out; goto out;
@ -1184,8 +1175,8 @@ static void fc_lport_enter_scr(struct fc_lport *lport)
{ {
struct fc_frame *fp; struct fc_frame *fp;
FC_DEBUG_LPORT("Port (%6x) entered SCR state from %s state\n", FC_LPORT_DBG(lport, "Entered SCR state from %s state\n",
fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state(lport));
fc_lport_state_enter(lport, LPORT_ST_SCR); fc_lport_state_enter(lport, LPORT_ST_SCR);
@ -1213,8 +1204,8 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport)
struct fc_ns_fts *lps; struct fc_ns_fts *lps;
int i; int i;
FC_DEBUG_LPORT("Port (%6x) entered RFT_ID state from %s state\n", FC_LPORT_DBG(lport, "Entered RFT_ID state from %s state\n",
fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state(lport));
fc_lport_state_enter(lport, LPORT_ST_RFT_ID); fc_lport_state_enter(lport, LPORT_ST_RFT_ID);
@ -1253,8 +1244,8 @@ static void fc_lport_enter_rpn_id(struct fc_lport *lport)
{ {
struct fc_frame *fp; struct fc_frame *fp;
FC_DEBUG_LPORT("Port (%6x) entered RPN_ID state from %s state\n", FC_LPORT_DBG(lport, "Entered RPN_ID state from %s state\n",
fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state(lport));
fc_lport_state_enter(lport, LPORT_ST_RPN_ID); fc_lport_state_enter(lport, LPORT_ST_RPN_ID);
@ -1294,8 +1285,8 @@ static void fc_lport_enter_dns(struct fc_lport *lport)
dp.ids.roles = FC_RPORT_ROLE_UNKNOWN; dp.ids.roles = FC_RPORT_ROLE_UNKNOWN;
dp.lp = lport; dp.lp = lport;
FC_DEBUG_LPORT("Port (%6x) entered DNS state from %s state\n", FC_LPORT_DBG(lport, "Entered DNS state from %s state\n",
fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state(lport));
fc_lport_state_enter(lport, LPORT_ST_DNS); fc_lport_state_enter(lport, LPORT_ST_DNS);
@ -1374,11 +1365,11 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
mutex_lock(&lport->lp_mutex); mutex_lock(&lport->lp_mutex);
FC_DEBUG_LPORT("Received a LOGO response\n"); FC_LPORT_DBG(lport, "Received a LOGO response\n");
if (lport->state != LPORT_ST_LOGO) { if (lport->state != LPORT_ST_LOGO) {
FC_DBG("Received a LOGO response, but in state %s\n", FC_LPORT_DBG(lport, "Received a LOGO response, but in state "
fc_lport_state(lport)); "%s\n", fc_lport_state(lport));
if (IS_ERR(fp)) if (IS_ERR(fp))
goto err; goto err;
goto out; goto out;
@ -1413,8 +1404,8 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
struct fc_frame *fp; struct fc_frame *fp;
struct fc_els_logo *logo; struct fc_els_logo *logo;
FC_DEBUG_LPORT("Port (%6x) entered LOGO state from %s state\n", FC_LPORT_DBG(lport, "Entered LOGO state from %s state\n",
fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state(lport));
fc_lport_state_enter(lport, LPORT_ST_LOGO); fc_lport_state_enter(lport, LPORT_ST_LOGO);
@ -1456,11 +1447,11 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
mutex_lock(&lport->lp_mutex); mutex_lock(&lport->lp_mutex);
FC_DEBUG_LPORT("Received a FLOGI response\n"); FC_LPORT_DBG(lport, "Received a FLOGI response\n");
if (lport->state != LPORT_ST_FLOGI) { if (lport->state != LPORT_ST_FLOGI) {
FC_DBG("Received a FLOGI response, but in state %s\n", FC_LPORT_DBG(lport, "Received a FLOGI response, but in state "
fc_lport_state(lport)); "%s\n", fc_lport_state(lport));
if (IS_ERR(fp)) if (IS_ERR(fp))
goto err; goto err;
goto out; goto out;
@ -1475,7 +1466,8 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
did = ntoh24(fh->fh_d_id); did = ntoh24(fh->fh_d_id);
if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) {
FC_DEBUG_LPORT("Assigned fid %x\n", did); printk(KERN_INFO "libfc: Assigned FID (%6x) in FLOGI response\n",
did);
fc_host_port_id(lport->host) = did; fc_host_port_id(lport->host) = did;
flp = fc_frame_payload_get(fp, sizeof(*flp)); flp = fc_frame_payload_get(fp, sizeof(*flp));
@ -1494,7 +1486,8 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
if (e_d_tov > lport->e_d_tov) if (e_d_tov > lport->e_d_tov)
lport->e_d_tov = e_d_tov; lport->e_d_tov = e_d_tov;
lport->r_a_tov = 2 * e_d_tov; lport->r_a_tov = 2 * e_d_tov;
FC_DBG("Point-to-Point mode\n"); printk(KERN_INFO "libfc: Port (%6x) entered "
"point to point mode\n", did);
fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id), fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id),
get_unaligned_be64( get_unaligned_be64(
&flp->fl_wwpn), &flp->fl_wwpn),
@ -1517,7 +1510,7 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
} }
} }
} else { } else {
FC_DBG("bad FLOGI response\n"); FC_LPORT_DBG(lport, "Bad FLOGI response\n");
} }
out: out:
@ -1537,7 +1530,8 @@ void fc_lport_enter_flogi(struct fc_lport *lport)
{ {
struct fc_frame *fp; struct fc_frame *fp;
FC_DEBUG_LPORT("Processing FLOGI state\n"); FC_LPORT_DBG(lport, "Entered FLOGI state from %s state\n",
fc_lport_state(lport));
fc_lport_state_enter(lport, LPORT_ST_FLOGI); fc_lport_state_enter(lport, LPORT_ST_FLOGI);

View file

@ -55,14 +55,6 @@
#include <scsi/libfc.h> #include <scsi/libfc.h>
#include <scsi/fc_encode.h> #include <scsi/fc_encode.h>
static int fc_rport_debug;
#define FC_DEBUG_RPORT(fmt...) \
do { \
if (fc_rport_debug) \
FC_DBG(fmt); \
} while (0)
struct workqueue_struct *rport_event_queue; struct workqueue_struct *rport_event_queue;
static void fc_rport_enter_plogi(struct fc_rport *); static void fc_rport_enter_plogi(struct fc_rport *);
@ -97,7 +89,7 @@ static const char *fc_rport_state_names[] = {
static void fc_rport_rogue_destroy(struct device *dev) static void fc_rport_rogue_destroy(struct device *dev)
{ {
struct fc_rport *rport = dev_to_rport(dev); struct fc_rport *rport = dev_to_rport(dev);
FC_DEBUG_RPORT("Destroying rogue rport (%6x)\n", rport->port_id); FC_RPORT_DBG(rport, "Destroying rogue rport\n");
kfree(rport); kfree(rport);
} }
@ -263,8 +255,8 @@ static void fc_rport_work(struct work_struct *work)
fc_rport_state_enter(new_rport, RPORT_ST_READY); fc_rport_state_enter(new_rport, RPORT_ST_READY);
} else { } else {
FC_DBG("Failed to create the rport for port " printk(KERN_WARNING "libfc: Failed to allocate "
"(%6x).\n", ids.port_id); " memory for rport (%6x)\n", ids.port_id);
event = RPORT_EV_FAILED; event = RPORT_EV_FAILED;
} }
if (rport->port_id != FC_FID_DIR_SERV) if (rport->port_id != FC_FID_DIR_SERV)
@ -309,7 +301,7 @@ int fc_rport_login(struct fc_rport *rport)
mutex_lock(&rdata->rp_mutex); mutex_lock(&rdata->rp_mutex);
FC_DEBUG_RPORT("Login to port (%6x)\n", rport->port_id); FC_RPORT_DBG(rport, "Login to port\n");
fc_rport_enter_plogi(rport); fc_rport_enter_plogi(rport);
@ -329,16 +321,13 @@ int fc_rport_login(struct fc_rport *rport)
int fc_rport_logoff(struct fc_rport *rport) int fc_rport_logoff(struct fc_rport *rport)
{ {
struct fc_rport_libfc_priv *rdata = rport->dd_data; struct fc_rport_libfc_priv *rdata = rport->dd_data;
struct fc_lport *lport = rdata->local_port;
mutex_lock(&rdata->rp_mutex); mutex_lock(&rdata->rp_mutex);
FC_DEBUG_RPORT("Remove port (%6x)\n", rport->port_id); FC_RPORT_DBG(rport, "Remove port\n");
if (rdata->rp_state == RPORT_ST_NONE) { if (rdata->rp_state == RPORT_ST_NONE) {
FC_DEBUG_RPORT("(%6x): Port (%6x) in NONE state," FC_RPORT_DBG(rport, "Port in NONE state, not removing\n");
" not removing", fc_host_port_id(lport->host),
rport->port_id);
mutex_unlock(&rdata->rp_mutex); mutex_unlock(&rdata->rp_mutex);
goto out; goto out;
} }
@ -379,7 +368,7 @@ static void fc_rport_enter_ready(struct fc_rport *rport)
fc_rport_state_enter(rport, RPORT_ST_READY); fc_rport_state_enter(rport, RPORT_ST_READY);
FC_DEBUG_RPORT("Port (%6x) is Ready\n", rport->port_id); FC_RPORT_DBG(rport, "Port is Ready\n");
rdata->event = RPORT_EV_CREATED; rdata->event = RPORT_EV_CREATED;
queue_work(rport_event_queue, &rdata->event_work); queue_work(rport_event_queue, &rdata->event_work);
@ -436,7 +425,7 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
{ {
struct fc_rport_libfc_priv *rdata = rport->dd_data; struct fc_rport_libfc_priv *rdata = rport->dd_data;
FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n", FC_RPORT_DBG(rport, "Error %ld in state %s, retries %d\n",
PTR_ERR(fp), fc_rport_state(rport), rdata->retries); PTR_ERR(fp), fc_rport_state(rport), rdata->retries);
switch (rdata->rp_state) { switch (rdata->rp_state) {
@ -479,7 +468,7 @@ static void fc_rport_error_retry(struct fc_rport *rport, struct fc_frame *fp)
return fc_rport_error(rport, fp); return fc_rport_error(rport, fp);
if (rdata->retries < rdata->local_port->max_rport_retry_count) { if (rdata->retries < rdata->local_port->max_rport_retry_count) {
FC_DEBUG_RPORT("Error %ld in state %s, retrying\n", FC_RPORT_DBG(rport, "Error %ld in state %s, retrying\n",
PTR_ERR(fp), fc_rport_state(rport)); PTR_ERR(fp), fc_rport_state(rport));
rdata->retries++; rdata->retries++;
/* no additional delay on exchange timeouts */ /* no additional delay on exchange timeouts */
@ -517,12 +506,11 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
mutex_lock(&rdata->rp_mutex); mutex_lock(&rdata->rp_mutex);
FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n", FC_RPORT_DBG(rport, "Received a PLOGI response\n");
rport->port_id);
if (rdata->rp_state != RPORT_ST_PLOGI) { if (rdata->rp_state != RPORT_ST_PLOGI) {
FC_DBG("Received a PLOGI response, but in state %s\n", FC_RPORT_DBG(rport, "Received a PLOGI response, but in state "
fc_rport_state(rport)); "%s\n", fc_rport_state(rport));
if (IS_ERR(fp)) if (IS_ERR(fp))
goto err; goto err;
goto out; goto out;
@ -583,8 +571,8 @@ static void fc_rport_enter_plogi(struct fc_rport *rport)
struct fc_lport *lport = rdata->local_port; struct fc_lport *lport = rdata->local_port;
struct fc_frame *fp; struct fc_frame *fp;
FC_DEBUG_RPORT("Port (%6x) entered PLOGI state from %s state\n", FC_RPORT_DBG(rport, "Port entered PLOGI state from %s state\n",
rport->port_id, fc_rport_state(rport)); fc_rport_state(rport));
fc_rport_state_enter(rport, RPORT_ST_PLOGI); fc_rport_state_enter(rport, RPORT_ST_PLOGI);
@ -628,12 +616,11 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
mutex_lock(&rdata->rp_mutex); mutex_lock(&rdata->rp_mutex);
FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n", FC_RPORT_DBG(rport, "Received a PRLI response\n");
rport->port_id);
if (rdata->rp_state != RPORT_ST_PRLI) { if (rdata->rp_state != RPORT_ST_PRLI) {
FC_DBG("Received a PRLI response, but in state %s\n", FC_RPORT_DBG(rport, "Received a PRLI response, but in state "
fc_rport_state(rport)); "%s\n", fc_rport_state(rport));
if (IS_ERR(fp)) if (IS_ERR(fp))
goto err; goto err;
goto out; goto out;
@ -663,7 +650,7 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
fc_rport_enter_rtv(rport); fc_rport_enter_rtv(rport);
} else { } else {
FC_DBG("Bad ELS response\n"); FC_RPORT_DBG(rport, "Bad ELS response for PRLI command\n");
rdata->event = RPORT_EV_FAILED; rdata->event = RPORT_EV_FAILED;
fc_rport_state_enter(rport, RPORT_ST_NONE); fc_rport_state_enter(rport, RPORT_ST_NONE);
queue_work(rport_event_queue, &rdata->event_work); queue_work(rport_event_queue, &rdata->event_work);
@ -695,12 +682,11 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
mutex_lock(&rdata->rp_mutex); mutex_lock(&rdata->rp_mutex);
FC_DEBUG_RPORT("Received a LOGO response from port (%6x)\n", FC_RPORT_DBG(rport, "Received a LOGO response\n");
rport->port_id);
if (rdata->rp_state != RPORT_ST_LOGO) { if (rdata->rp_state != RPORT_ST_LOGO) {
FC_DEBUG_RPORT("Received a LOGO response, but in state %s\n", FC_RPORT_DBG(rport, "Received a LOGO response, but in state "
fc_rport_state(rport)); "%s\n", fc_rport_state(rport));
if (IS_ERR(fp)) if (IS_ERR(fp))
goto err; goto err;
goto out; goto out;
@ -715,7 +701,7 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
if (op == ELS_LS_ACC) { if (op == ELS_LS_ACC) {
fc_rport_enter_rtv(rport); fc_rport_enter_rtv(rport);
} else { } else {
FC_DBG("Bad ELS response\n"); FC_RPORT_DBG(rport, "Bad ELS response for LOGO command\n");
rdata->event = RPORT_EV_LOGO; rdata->event = RPORT_EV_LOGO;
fc_rport_state_enter(rport, RPORT_ST_NONE); fc_rport_state_enter(rport, RPORT_ST_NONE);
queue_work(rport_event_queue, &rdata->event_work); queue_work(rport_event_queue, &rdata->event_work);
@ -745,8 +731,8 @@ static void fc_rport_enter_prli(struct fc_rport *rport)
} *pp; } *pp;
struct fc_frame *fp; struct fc_frame *fp;
FC_DEBUG_RPORT("Port (%6x) entered PRLI state from %s state\n", FC_RPORT_DBG(rport, "Port entered PRLI state from %s state\n",
rport->port_id, fc_rport_state(rport)); fc_rport_state(rport));
fc_rport_state_enter(rport, RPORT_ST_PRLI); fc_rport_state_enter(rport, RPORT_ST_PRLI);
@ -784,12 +770,11 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
mutex_lock(&rdata->rp_mutex); mutex_lock(&rdata->rp_mutex);
FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n", FC_RPORT_DBG(rport, "Received a RTV response\n");
rport->port_id);
if (rdata->rp_state != RPORT_ST_RTV) { if (rdata->rp_state != RPORT_ST_RTV) {
FC_DBG("Received a RTV response, but in state %s\n", FC_RPORT_DBG(rport, "Received a RTV response, but in state "
fc_rport_state(rport)); "%s\n", fc_rport_state(rport));
if (IS_ERR(fp)) if (IS_ERR(fp))
goto err; goto err;
goto out; goto out;
@ -844,8 +829,8 @@ static void fc_rport_enter_rtv(struct fc_rport *rport)
struct fc_rport_libfc_priv *rdata = rport->dd_data; struct fc_rport_libfc_priv *rdata = rport->dd_data;
struct fc_lport *lport = rdata->local_port; struct fc_lport *lport = rdata->local_port;
FC_DEBUG_RPORT("Port (%6x) entered RTV state from %s state\n", FC_RPORT_DBG(rport, "Port entered RTV state from %s state\n",
rport->port_id, fc_rport_state(rport)); fc_rport_state(rport));
fc_rport_state_enter(rport, RPORT_ST_RTV); fc_rport_state_enter(rport, RPORT_ST_RTV);
@ -875,8 +860,8 @@ static void fc_rport_enter_logo(struct fc_rport *rport)
struct fc_lport *lport = rdata->local_port; struct fc_lport *lport = rdata->local_port;
struct fc_frame *fp; struct fc_frame *fp;
FC_DEBUG_RPORT("Port (%6x) entered LOGO state from %s state\n", FC_RPORT_DBG(rport, "Port entered LOGO state from %s state\n",
rport->port_id, fc_rport_state(rport)); fc_rport_state(rport));
fc_rport_state_enter(rport, RPORT_ST_LOGO); fc_rport_state_enter(rport, RPORT_ST_LOGO);
@ -983,14 +968,13 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport,
fh = fc_frame_header_get(fp); fh = fc_frame_header_get(fp);
FC_DEBUG_RPORT("Received PLOGI request from port (%6x) " FC_RPORT_DBG(rport, "Received PLOGI request while in state %s\n",
"while in state %s\n", ntoh24(fh->fh_s_id),
fc_rport_state(rport)); fc_rport_state(rport));
sid = ntoh24(fh->fh_s_id); sid = ntoh24(fh->fh_s_id);
pl = fc_frame_payload_get(fp, sizeof(*pl)); pl = fc_frame_payload_get(fp, sizeof(*pl));
if (!pl) { if (!pl) {
FC_DBG("incoming PLOGI from %x too short\n", sid); FC_RPORT_DBG(rport, "Received PLOGI too short\n");
WARN_ON(1); WARN_ON(1);
/* XXX TBD: send reject? */ /* XXX TBD: send reject? */
fc_frame_free(fp); fc_frame_free(fp);
@ -1012,26 +996,26 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport,
*/ */
switch (rdata->rp_state) { switch (rdata->rp_state) {
case RPORT_ST_INIT: case RPORT_ST_INIT:
FC_DEBUG_RPORT("incoming PLOGI from %6x wwpn %llx state INIT " FC_RPORT_DBG(rport, "Received PLOGI, wwpn %llx state INIT "
"- reject\n", sid, (unsigned long long)wwpn); "- reject\n", (unsigned long long)wwpn);
reject = ELS_RJT_UNSUP; reject = ELS_RJT_UNSUP;
break; break;
case RPORT_ST_PLOGI: case RPORT_ST_PLOGI:
FC_DEBUG_RPORT("incoming PLOGI from %x in PLOGI state %d\n", FC_RPORT_DBG(rport, "Received PLOGI in PLOGI state %d\n",
sid, rdata->rp_state); rdata->rp_state);
if (wwpn < lport->wwpn) if (wwpn < lport->wwpn)
reject = ELS_RJT_INPROG; reject = ELS_RJT_INPROG;
break; break;
case RPORT_ST_PRLI: case RPORT_ST_PRLI:
case RPORT_ST_READY: case RPORT_ST_READY:
FC_DEBUG_RPORT("incoming PLOGI from %x in logged-in state %d " FC_RPORT_DBG(rport, "Received PLOGI in logged-in state %d "
"- ignored for now\n", sid, rdata->rp_state); "- ignored for now\n", rdata->rp_state);
/* XXX TBD - should reset */ /* XXX TBD - should reset */
break; break;
case RPORT_ST_NONE: case RPORT_ST_NONE:
default: default:
FC_DEBUG_RPORT("incoming PLOGI from %x in unexpected " FC_RPORT_DBG(rport, "Received PLOGI in unexpected "
"state %d\n", sid, rdata->rp_state); "state %d\n", rdata->rp_state);
fc_frame_free(fp); fc_frame_free(fp);
return; return;
break; break;
@ -1115,8 +1099,7 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport,
fh = fc_frame_header_get(rx_fp); fh = fc_frame_header_get(rx_fp);
FC_DEBUG_RPORT("Received PRLI request from port (%6x) " FC_RPORT_DBG(rport, "Received PRLI request while in state %s\n",
"while in state %s\n", ntoh24(fh->fh_s_id),
fc_rport_state(rport)); fc_rport_state(rport));
switch (rdata->rp_state) { switch (rdata->rp_state) {
@ -1252,8 +1235,7 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp,
fh = fc_frame_header_get(fp); fh = fc_frame_header_get(fp);
FC_DEBUG_RPORT("Received PRLO request from port (%6x) " FC_RPORT_DBG(rport, "Received PRLO request while in state %s\n",
"while in state %s\n", ntoh24(fh->fh_s_id),
fc_rport_state(rport)); fc_rport_state(rport));
if (rdata->rp_state == RPORT_ST_NONE) { if (rdata->rp_state == RPORT_ST_NONE) {
@ -1286,8 +1268,7 @@ static void fc_rport_recv_logo_req(struct fc_rport *rport, struct fc_seq *sp,
fh = fc_frame_header_get(fp); fh = fc_frame_header_get(fp);
FC_DEBUG_RPORT("Received LOGO request from port (%6x) " FC_RPORT_DBG(rport, "Received LOGO request while in state %s\n",
"while in state %s\n", ntoh24(fh->fh_s_id),
fc_rport_state(rport)); fc_rport_state(rport));
if (rdata->rp_state == RPORT_ST_NONE) { if (rdata->rp_state == RPORT_ST_NONE) {
@ -1308,7 +1289,6 @@ static void fc_rport_flush_queue(void)
flush_workqueue(rport_event_queue); flush_workqueue(rport_event_queue);
} }
int fc_rport_init(struct fc_lport *lport) int fc_rport_init(struct fc_lport *lport)
{ {
if (!lport->tt.rport_create) if (!lport->tt.rport_create)

View file

@ -38,15 +38,30 @@
#include <scsi/scsi_transport_iscsi.h> #include <scsi/scsi_transport_iscsi.h>
#include <scsi/libiscsi.h> #include <scsi/libiscsi.h>
static int iscsi_dbg_lib; static int iscsi_dbg_lib_conn;
module_param_named(debug_libiscsi, iscsi_dbg_lib, int, S_IRUGO | S_IWUSR); module_param_named(debug_libiscsi_conn, iscsi_dbg_lib_conn, int,
MODULE_PARM_DESC(debug_libiscsi, "Turn on debugging for libiscsi module. " S_IRUGO | S_IWUSR);
"Set to 1 to turn on, and zero to turn off. Default " MODULE_PARM_DESC(debug_libiscsi_conn,
"is off."); "Turn on debugging for connections in libiscsi module. "
"Set to 1 to turn on, and zero to turn off. Default is off.");
static int iscsi_dbg_lib_session;
module_param_named(debug_libiscsi_session, iscsi_dbg_lib_session, int,
S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug_libiscsi_session,
"Turn on debugging for sessions in libiscsi module. "
"Set to 1 to turn on, and zero to turn off. Default is off.");
static int iscsi_dbg_lib_eh;
module_param_named(debug_libiscsi_eh, iscsi_dbg_lib_eh, int,
S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug_libiscsi_eh,
"Turn on debugging for error handling in libiscsi module. "
"Set to 1 to turn on, and zero to turn off. Default is off.");
#define ISCSI_DBG_CONN(_conn, dbg_fmt, arg...) \ #define ISCSI_DBG_CONN(_conn, dbg_fmt, arg...) \
do { \ do { \
if (iscsi_dbg_lib) \ if (iscsi_dbg_lib_conn) \
iscsi_conn_printk(KERN_INFO, _conn, \ iscsi_conn_printk(KERN_INFO, _conn, \
"%s " dbg_fmt, \ "%s " dbg_fmt, \
__func__, ##arg); \ __func__, ##arg); \
@ -54,7 +69,15 @@ MODULE_PARM_DESC(debug_libiscsi, "Turn on debugging for libiscsi module. "
#define ISCSI_DBG_SESSION(_session, dbg_fmt, arg...) \ #define ISCSI_DBG_SESSION(_session, dbg_fmt, arg...) \
do { \ do { \
if (iscsi_dbg_lib) \ if (iscsi_dbg_lib_session) \
iscsi_session_printk(KERN_INFO, _session, \
"%s " dbg_fmt, \
__func__, ##arg); \
} while (0);
#define ISCSI_DBG_EH(_session, dbg_fmt, arg...) \
do { \
if (iscsi_dbg_lib_eh) \
iscsi_session_printk(KERN_INFO, _session, \ iscsi_session_printk(KERN_INFO, _session, \
"%s " dbg_fmt, \ "%s " dbg_fmt, \
__func__, ##arg); \ __func__, ##arg); \
@ -954,6 +977,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
task = iscsi_itt_to_ctask(conn, hdr->itt); task = iscsi_itt_to_ctask(conn, hdr->itt);
if (!task) if (!task)
return ISCSI_ERR_BAD_ITT; return ISCSI_ERR_BAD_ITT;
task->last_xfer = jiffies;
break; break;
case ISCSI_OP_R2T: case ISCSI_OP_R2T:
/* /*
@ -1192,10 +1216,12 @@ static int iscsi_xmit_task(struct iscsi_conn *conn)
spin_unlock_bh(&conn->session->lock); spin_unlock_bh(&conn->session->lock);
rc = conn->session->tt->xmit_task(task); rc = conn->session->tt->xmit_task(task);
spin_lock_bh(&conn->session->lock); spin_lock_bh(&conn->session->lock);
__iscsi_put_task(task); if (!rc) {
if (!rc)
/* done with this task */ /* done with this task */
task->last_xfer = jiffies;
conn->task = NULL; conn->task = NULL;
}
__iscsi_put_task(task);
return rc; return rc;
} }
@ -1361,6 +1387,9 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn,
task->state = ISCSI_TASK_PENDING; task->state = ISCSI_TASK_PENDING;
task->conn = conn; task->conn = conn;
task->sc = sc; task->sc = sc;
task->have_checked_conn = false;
task->last_timeout = jiffies;
task->last_xfer = jiffies;
INIT_LIST_HEAD(&task->running); INIT_LIST_HEAD(&task->running);
return task; return task;
} }
@ -1555,9 +1584,9 @@ int iscsi_eh_target_reset(struct scsi_cmnd *sc)
spin_lock_bh(&session->lock); spin_lock_bh(&session->lock);
if (session->state == ISCSI_STATE_TERMINATE) { if (session->state == ISCSI_STATE_TERMINATE) {
failed: failed:
iscsi_session_printk(KERN_INFO, session, ISCSI_DBG_EH(session,
"failing target reset: Could not log " "failing target reset: Could not log back into "
"back into target [age %d]\n", "target [age %d]\n",
session->age); session->age);
spin_unlock_bh(&session->lock); spin_unlock_bh(&session->lock);
mutex_unlock(&session->eh_mutex); mutex_unlock(&session->eh_mutex);
@ -1572,7 +1601,7 @@ failed:
*/ */
iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
ISCSI_DBG_SESSION(session, "wait for relogin\n"); ISCSI_DBG_EH(session, "wait for relogin\n");
wait_event_interruptible(conn->ehwait, wait_event_interruptible(conn->ehwait,
session->state == ISCSI_STATE_TERMINATE || session->state == ISCSI_STATE_TERMINATE ||
session->state == ISCSI_STATE_LOGGED_IN || session->state == ISCSI_STATE_LOGGED_IN ||
@ -1582,10 +1611,10 @@ failed:
mutex_lock(&session->eh_mutex); mutex_lock(&session->eh_mutex);
spin_lock_bh(&session->lock); spin_lock_bh(&session->lock);
if (session->state == ISCSI_STATE_LOGGED_IN) if (session->state == ISCSI_STATE_LOGGED_IN) {
iscsi_session_printk(KERN_INFO, session, ISCSI_DBG_EH(session,
"target reset succeeded\n"); "target reset succeeded\n");
else } else
goto failed; goto failed;
spin_unlock_bh(&session->lock); spin_unlock_bh(&session->lock);
mutex_unlock(&session->eh_mutex); mutex_unlock(&session->eh_mutex);
@ -1601,7 +1630,7 @@ static void iscsi_tmf_timedout(unsigned long data)
spin_lock(&session->lock); spin_lock(&session->lock);
if (conn->tmf_state == TMF_QUEUED) { if (conn->tmf_state == TMF_QUEUED) {
conn->tmf_state = TMF_TIMEDOUT; conn->tmf_state = TMF_TIMEDOUT;
ISCSI_DBG_SESSION(session, "tmf timedout\n"); ISCSI_DBG_EH(session, "tmf timedout\n");
/* unblock eh_abort() */ /* unblock eh_abort() */
wake_up(&conn->ehwait); wake_up(&conn->ehwait);
} }
@ -1621,7 +1650,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
spin_unlock_bh(&session->lock); spin_unlock_bh(&session->lock);
iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
spin_lock_bh(&session->lock); spin_lock_bh(&session->lock);
ISCSI_DBG_SESSION(session, "tmf exec failure\n"); ISCSI_DBG_EH(session, "tmf exec failure\n");
return -EPERM; return -EPERM;
} }
conn->tmfcmd_pdus_cnt++; conn->tmfcmd_pdus_cnt++;
@ -1629,7 +1658,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
conn->tmf_timer.function = iscsi_tmf_timedout; conn->tmf_timer.function = iscsi_tmf_timedout;
conn->tmf_timer.data = (unsigned long)conn; conn->tmf_timer.data = (unsigned long)conn;
add_timer(&conn->tmf_timer); add_timer(&conn->tmf_timer);
ISCSI_DBG_SESSION(session, "tmf set timeout\n"); ISCSI_DBG_EH(session, "tmf set timeout\n");
spin_unlock_bh(&session->lock); spin_unlock_bh(&session->lock);
mutex_unlock(&session->eh_mutex); mutex_unlock(&session->eh_mutex);
@ -1716,17 +1745,18 @@ static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
return 0; return 0;
} }
static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
{ {
enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
struct iscsi_task *task = NULL;
struct iscsi_cls_session *cls_session; struct iscsi_cls_session *cls_session;
struct iscsi_session *session; struct iscsi_session *session;
struct iscsi_conn *conn; struct iscsi_conn *conn;
enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
cls_session = starget_to_session(scsi_target(scmd->device)); cls_session = starget_to_session(scsi_target(sc->device));
session = cls_session->dd_data; session = cls_session->dd_data;
ISCSI_DBG_SESSION(session, "scsi cmd %p timedout\n", scmd); ISCSI_DBG_EH(session, "scsi cmd %p timedout\n", sc);
spin_lock(&session->lock); spin_lock(&session->lock);
if (session->state != ISCSI_STATE_LOGGED_IN) { if (session->state != ISCSI_STATE_LOGGED_IN) {
@ -1745,6 +1775,26 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
goto done; goto done;
} }
task = (struct iscsi_task *)sc->SCp.ptr;
if (!task)
goto done;
/*
* If we have sent (at least queued to the network layer) a pdu or
* recvd one for the task since the last timeout ask for
* more time. If on the next timeout we have not made progress
* we can check if it is the task or connection when we send the
* nop as a ping.
*/
if (time_after_eq(task->last_xfer, task->last_timeout)) {
ISCSI_DBG_EH(session, "Command making progress. Asking "
"scsi-ml for more time to complete. "
"Last data recv at %lu. Last timeout was at "
"%lu\n.", task->last_xfer, task->last_timeout);
task->have_checked_conn = false;
rc = BLK_EH_RESET_TIMER;
goto done;
}
if (!conn->recv_timeout && !conn->ping_timeout) if (!conn->recv_timeout && !conn->ping_timeout)
goto done; goto done;
/* /*
@ -1755,22 +1805,31 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
rc = BLK_EH_RESET_TIMER; rc = BLK_EH_RESET_TIMER;
goto done; goto done;
} }
/* Assumes nop timeout is shorter than scsi cmd timeout */
if (task->have_checked_conn)
goto done;
/* /*
* if we are about to check the transport then give the command * Checking the transport already or nop from a cmd timeout still
* more time * running
*/ */
if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ), if (conn->ping_task) {
jiffies)) { task->have_checked_conn = true;
rc = BLK_EH_RESET_TIMER; rc = BLK_EH_RESET_TIMER;
goto done; goto done;
} }
/* if in the middle of checking the transport then give us more time */ /* Make sure there is a transport check done */
if (conn->ping_task) iscsi_send_nopout(conn, NULL);
task->have_checked_conn = true;
rc = BLK_EH_RESET_TIMER; rc = BLK_EH_RESET_TIMER;
done: done:
if (task)
task->last_timeout = jiffies;
spin_unlock(&session->lock); spin_unlock(&session->lock);
ISCSI_DBG_SESSION(session, "return %s\n", rc == BLK_EH_RESET_TIMER ? ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ?
"timer reset" : "nh"); "timer reset" : "nh");
return rc; return rc;
} }
@ -1841,7 +1900,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
cls_session = starget_to_session(scsi_target(sc->device)); cls_session = starget_to_session(scsi_target(sc->device));
session = cls_session->dd_data; session = cls_session->dd_data;
ISCSI_DBG_SESSION(session, "aborting sc %p\n", sc); ISCSI_DBG_EH(session, "aborting sc %p\n", sc);
mutex_lock(&session->eh_mutex); mutex_lock(&session->eh_mutex);
spin_lock_bh(&session->lock); spin_lock_bh(&session->lock);
@ -1850,7 +1909,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
* got the command. * got the command.
*/ */
if (!sc->SCp.ptr) { if (!sc->SCp.ptr) {
ISCSI_DBG_SESSION(session, "sc never reached iscsi layer or " ISCSI_DBG_EH(session, "sc never reached iscsi layer or "
"it completed.\n"); "it completed.\n");
spin_unlock_bh(&session->lock); spin_unlock_bh(&session->lock);
mutex_unlock(&session->eh_mutex); mutex_unlock(&session->eh_mutex);
@ -1865,7 +1924,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
sc->SCp.phase != session->age) { sc->SCp.phase != session->age) {
spin_unlock_bh(&session->lock); spin_unlock_bh(&session->lock);
mutex_unlock(&session->eh_mutex); mutex_unlock(&session->eh_mutex);
ISCSI_DBG_SESSION(session, "failing abort due to dropped " ISCSI_DBG_EH(session, "failing abort due to dropped "
"session.\n"); "session.\n");
return FAILED; return FAILED;
} }
@ -1875,13 +1934,12 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
age = session->age; age = session->age;
task = (struct iscsi_task *)sc->SCp.ptr; task = (struct iscsi_task *)sc->SCp.ptr;
ISCSI_DBG_SESSION(session, "aborting [sc %p itt 0x%x]\n", ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n",
sc, task->itt); sc, task->itt);
/* task completed before time out */ /* task completed before time out */
if (!task->sc) { if (!task->sc) {
ISCSI_DBG_SESSION(session, "sc completed while abort in " ISCSI_DBG_EH(session, "sc completed while abort in progress\n");
"progress\n");
goto success; goto success;
} }
@ -1930,8 +1988,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
if (!sc->SCp.ptr) { if (!sc->SCp.ptr) {
conn->tmf_state = TMF_INITIAL; conn->tmf_state = TMF_INITIAL;
/* task completed before tmf abort response */ /* task completed before tmf abort response */
ISCSI_DBG_SESSION(session, "sc completed while abort " ISCSI_DBG_EH(session, "sc completed while abort in "
"in progress\n"); "progress\n");
goto success; goto success;
} }
/* fall through */ /* fall through */
@ -1943,7 +2001,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
success: success:
spin_unlock_bh(&session->lock); spin_unlock_bh(&session->lock);
success_unlocked: success_unlocked:
ISCSI_DBG_SESSION(session, "abort success [sc %p itt 0x%x]\n", ISCSI_DBG_EH(session, "abort success [sc %p itt 0x%x]\n",
sc, task->itt); sc, task->itt);
mutex_unlock(&session->eh_mutex); mutex_unlock(&session->eh_mutex);
return SUCCESS; return SUCCESS;
@ -1951,7 +2009,7 @@ success_unlocked:
failed: failed:
spin_unlock_bh(&session->lock); spin_unlock_bh(&session->lock);
failed_unlocked: failed_unlocked:
ISCSI_DBG_SESSION(session, "abort failed [sc %p itt 0x%x]\n", sc, ISCSI_DBG_EH(session, "abort failed [sc %p itt 0x%x]\n", sc,
task ? task->itt : 0); task ? task->itt : 0);
mutex_unlock(&session->eh_mutex); mutex_unlock(&session->eh_mutex);
return FAILED; return FAILED;
@ -1979,8 +2037,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
cls_session = starget_to_session(scsi_target(sc->device)); cls_session = starget_to_session(scsi_target(sc->device));
session = cls_session->dd_data; session = cls_session->dd_data;
ISCSI_DBG_SESSION(session, "LU Reset [sc %p lun %u]\n", ISCSI_DBG_EH(session, "LU Reset [sc %p lun %u]\n", sc, sc->device->lun);
sc, sc->device->lun);
mutex_lock(&session->eh_mutex); mutex_lock(&session->eh_mutex);
spin_lock_bh(&session->lock); spin_lock_bh(&session->lock);
@ -2034,7 +2091,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
unlock: unlock:
spin_unlock_bh(&session->lock); spin_unlock_bh(&session->lock);
done: done:
ISCSI_DBG_SESSION(session, "dev reset result = %s\n", ISCSI_DBG_EH(session, "dev reset result = %s\n",
rc == SUCCESS ? "SUCCESS" : "FAILED"); rc == SUCCESS ? "SUCCESS" : "FAILED");
mutex_unlock(&session->eh_mutex); mutex_unlock(&session->eh_mutex);
return rc; return rc;

View file

@ -686,6 +686,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
"offset=%d, datalen=%d)\n", "offset=%d, datalen=%d)\n",
tcp_task->data_offset, tcp_task->data_offset,
tcp_conn->in.datalen); tcp_conn->in.datalen);
task->last_xfer = jiffies;
rc = iscsi_segment_seek_sg(&tcp_conn->in.segment, rc = iscsi_segment_seek_sg(&tcp_conn->in.segment,
sdb->table.sgl, sdb->table.sgl,
sdb->table.nents, sdb->table.nents,
@ -713,9 +714,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
rc = ISCSI_ERR_BAD_ITT; rc = ISCSI_ERR_BAD_ITT;
else if (ahslen) else if (ahslen)
rc = ISCSI_ERR_AHSLEN; rc = ISCSI_ERR_AHSLEN;
else if (task->sc->sc_data_direction == DMA_TO_DEVICE) else if (task->sc->sc_data_direction == DMA_TO_DEVICE) {
task->last_xfer = jiffies;
rc = iscsi_tcp_r2t_rsp(conn, task); rc = iscsi_tcp_r2t_rsp(conn, task);
else } else
rc = ISCSI_ERR_PROTO; rc = ISCSI_ERR_PROTO;
spin_unlock(&conn->session->lock); spin_unlock(&conn->session->lock);
break; break;

View file

@ -216,7 +216,7 @@ qla24xx_soft_reset(struct qla_hw_data *ha)
static int static int
qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram, qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram,
uint16_t ram_words, void **nxt) uint32_t ram_words, void **nxt)
{ {
int rval; int rval;
uint32_t cnt, stat, timer, words, idx; uint32_t cnt, stat, timer, words, idx;

View file

@ -2301,7 +2301,7 @@ qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
static char *link_speeds[] = { "1", "2", "?", "4", "8", "10" }; static char *link_speeds[] = { "1", "2", "?", "4", "8", "10" };
char *link_speed; char *link_speed;
int rval; int rval;
uint16_t mb[6]; uint16_t mb[4];
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
if (!IS_IIDMA_CAPABLE(ha)) if (!IS_IIDMA_CAPABLE(ha))

View file

@ -1267,17 +1267,22 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
mcp->mb[0] = MBC_GET_FIRMWARE_STATE; mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
mcp->out_mb = MBX_0; mcp->out_mb = MBX_0;
if (IS_FWI2_CAPABLE(vha->hw))
mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
else
mcp->in_mb = MBX_1|MBX_0;
mcp->tov = MBX_TOV_SECONDS; mcp->tov = MBX_TOV_SECONDS;
mcp->flags = 0; mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp); rval = qla2x00_mailbox_command(vha, mcp);
/* Return firmware states. */ /* Return firmware states. */
states[0] = mcp->mb[1]; states[0] = mcp->mb[1];
if (IS_FWI2_CAPABLE(vha->hw)) {
states[1] = mcp->mb[2]; states[1] = mcp->mb[2];
states[2] = mcp->mb[3]; states[2] = mcp->mb[3];
states[3] = mcp->mb[4]; states[3] = mcp->mb[4];
states[4] = mcp->mb[5]; states[4] = mcp->mb[5];
}
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
/*EMPTY*/ /*EMPTY*/
@ -2697,10 +2702,13 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
mcp->mb[0] = MBC_PORT_PARAMS; mcp->mb[0] = MBC_PORT_PARAMS;
mcp->mb[1] = loop_id; mcp->mb[1] = loop_id;
mcp->mb[2] = BIT_0; mcp->mb[2] = BIT_0;
if (IS_QLA81XX(vha->hw))
mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
else
mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0); mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
mcp->mb[4] = mcp->mb[5] = 0; mcp->mb[9] = vha->vp_idx;
mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; mcp->in_mb = MBX_3|MBX_1|MBX_0;
mcp->tov = MBX_TOV_SECONDS; mcp->tov = MBX_TOV_SECONDS;
mcp->flags = 0; mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp); rval = qla2x00_mailbox_command(vha, mcp);
@ -2710,8 +2718,6 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
mb[0] = mcp->mb[0]; mb[0] = mcp->mb[0];
mb[1] = mcp->mb[1]; mb[1] = mcp->mb[1];
mb[3] = mcp->mb[3]; mb[3] = mcp->mb[3];
mb[4] = mcp->mb[4];
mb[5] = mcp->mb[5];
} }
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {

View file

@ -1663,7 +1663,7 @@ skip_pio:
/* queue 0 uses two msix vectors */ /* queue 0 uses two msix vectors */
if (ql2xmultique_tag) { if (ql2xmultique_tag) {
cpus = num_online_cpus(); cpus = num_online_cpus();
ha->max_rsp_queues = (ha->msix_count - 1 - cpus) ? ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ?
(cpus + 1) : (ha->msix_count - 1); (cpus + 1) : (ha->msix_count - 1);
ha->max_req_queues = 2; ha->max_req_queues = 2;
} else if (ql2xmaxqueues > 1) { } else if (ql2xmaxqueues > 1) {

View file

@ -7,7 +7,7 @@
/* /*
* Driver version * Driver version
*/ */
#define QLA2XXX_VERSION "8.03.01-k3" #define QLA2XXX_VERSION "8.03.01-k4"
#define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3 #define QLA_DRIVER_MINOR_VER 3

View file

@ -101,6 +101,8 @@ static const char * scsi_debug_version_date = "20070104";
#define DEF_DIF 0 #define DEF_DIF 0
#define DEF_GUARD 0 #define DEF_GUARD 0
#define DEF_ATO 1 #define DEF_ATO 1
#define DEF_PHYSBLK_EXP 0
#define DEF_LOWEST_ALIGNED 0
/* bit mask values for scsi_debug_opts */ /* bit mask values for scsi_debug_opts */
#define SCSI_DEBUG_OPT_NOISE 1 #define SCSI_DEBUG_OPT_NOISE 1
@ -156,6 +158,8 @@ static int scsi_debug_dix = DEF_DIX;
static int scsi_debug_dif = DEF_DIF; static int scsi_debug_dif = DEF_DIF;
static int scsi_debug_guard = DEF_GUARD; static int scsi_debug_guard = DEF_GUARD;
static int scsi_debug_ato = DEF_ATO; static int scsi_debug_ato = DEF_ATO;
static int scsi_debug_physblk_exp = DEF_PHYSBLK_EXP;
static int scsi_debug_lowest_aligned = DEF_LOWEST_ALIGNED;
static int scsi_debug_cmnd_count = 0; static int scsi_debug_cmnd_count = 0;
@ -657,7 +661,12 @@ static unsigned char vpdb0_data[] = {
static int inquiry_evpd_b0(unsigned char * arr) static int inquiry_evpd_b0(unsigned char * arr)
{ {
unsigned int gran;
memcpy(arr, vpdb0_data, sizeof(vpdb0_data)); memcpy(arr, vpdb0_data, sizeof(vpdb0_data));
gran = 1 << scsi_debug_physblk_exp;
arr[2] = (gran >> 8) & 0xff;
arr[3] = gran & 0xff;
if (sdebug_store_sectors > 0x400) { if (sdebug_store_sectors > 0x400) {
arr[4] = (sdebug_store_sectors >> 24) & 0xff; arr[4] = (sdebug_store_sectors >> 24) & 0xff;
arr[5] = (sdebug_store_sectors >> 16) & 0xff; arr[5] = (sdebug_store_sectors >> 16) & 0xff;
@ -945,6 +954,9 @@ static int resp_readcap16(struct scsi_cmnd * scp,
arr[9] = (scsi_debug_sector_size >> 16) & 0xff; arr[9] = (scsi_debug_sector_size >> 16) & 0xff;
arr[10] = (scsi_debug_sector_size >> 8) & 0xff; arr[10] = (scsi_debug_sector_size >> 8) & 0xff;
arr[11] = scsi_debug_sector_size & 0xff; arr[11] = scsi_debug_sector_size & 0xff;
arr[13] = scsi_debug_physblk_exp & 0xf;
arr[14] = (scsi_debug_lowest_aligned >> 8) & 0x3f;
arr[15] = scsi_debug_lowest_aligned & 0xff;
if (scsi_debug_dif) { if (scsi_debug_dif) {
arr[12] = (scsi_debug_dif - 1) << 1; /* P_TYPE */ arr[12] = (scsi_debug_dif - 1) << 1; /* P_TYPE */
@ -2380,6 +2392,8 @@ module_param_named(dix, scsi_debug_dix, int, S_IRUGO);
module_param_named(dif, scsi_debug_dif, int, S_IRUGO); module_param_named(dif, scsi_debug_dif, int, S_IRUGO);
module_param_named(guard, scsi_debug_guard, int, S_IRUGO); module_param_named(guard, scsi_debug_guard, int, S_IRUGO);
module_param_named(ato, scsi_debug_ato, int, S_IRUGO); module_param_named(ato, scsi_debug_ato, int, S_IRUGO);
module_param_named(physblk_exp, scsi_debug_physblk_exp, int, S_IRUGO);
module_param_named(lowest_aligned, scsi_debug_lowest_aligned, int, S_IRUGO);
MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
MODULE_DESCRIPTION("SCSI debug adapter driver"); MODULE_DESCRIPTION("SCSI debug adapter driver");
@ -2401,7 +2415,9 @@ MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])");
MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)");
MODULE_PARM_DESC(vpd_use_hostno, "0 -> dev ids ignore hostno (def=1 -> unique dev ids)"); MODULE_PARM_DESC(vpd_use_hostno, "0 -> dev ids ignore hostno (def=1 -> unique dev ids)");
MODULE_PARM_DESC(sector_size, "hardware sector size in bytes (def=512)"); MODULE_PARM_DESC(sector_size, "logical block size in bytes (def=512)");
MODULE_PARM_DESC(physblk_exp, "physical block exponent (def=0)");
MODULE_PARM_DESC(lowest_aligned, "lowest aligned lba (def=0)");
MODULE_PARM_DESC(dix, "data integrity extensions mask (def=0)"); MODULE_PARM_DESC(dix, "data integrity extensions mask (def=0)");
MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)"); MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)");
MODULE_PARM_DESC(guard, "protection checksum: 0=crc, 1=ip (def=0)"); MODULE_PARM_DESC(guard, "protection checksum: 0=crc, 1=ip (def=0)");
@ -2874,6 +2890,18 @@ static int __init scsi_debug_init(void)
return -EINVAL; return -EINVAL;
} }
if (scsi_debug_physblk_exp > 15) {
printk(KERN_ERR "scsi_debug_init: invalid physblk_exp %u\n",
scsi_debug_physblk_exp);
return -EINVAL;
}
if (scsi_debug_lowest_aligned > 0x3fff) {
printk(KERN_ERR "scsi_debug_init: lowest_aligned too big: %u\n",
scsi_debug_lowest_aligned);
return -EINVAL;
}
if (scsi_debug_dev_size_mb < 1) if (scsi_debug_dev_size_mb < 1)
scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */
sz = (unsigned long)scsi_debug_dev_size_mb * 1048576; sz = (unsigned long)scsi_debug_dev_size_mb * 1048576;

View file

@ -24,6 +24,13 @@ struct scsi_dev_info_list {
unsigned compatible; /* for use with scsi_static_device_list entries */ unsigned compatible; /* for use with scsi_static_device_list entries */
}; };
struct scsi_dev_info_list_table {
struct list_head node; /* our node for being on the master list */
struct list_head scsi_dev_info_list; /* head of dev info list */
const char *name; /* name of list for /proc (NULL for global) */
int key; /* unique numeric identifier */
};
static const char spaces[] = " "; /* 16 of them */ static const char spaces[] = " "; /* 16 of them */
static unsigned scsi_default_dev_flags; static unsigned scsi_default_dev_flags;
@ -247,6 +254,22 @@ static struct {
{ NULL, NULL, NULL, 0 }, { NULL, NULL, NULL, 0 },
}; };
static struct scsi_dev_info_list_table *scsi_devinfo_lookup_by_key(int key)
{
struct scsi_dev_info_list_table *devinfo_table;
int found = 0;
list_for_each_entry(devinfo_table, &scsi_dev_info_list, node)
if (devinfo_table->key == key) {
found = 1;
break;
}
if (!found)
return ERR_PTR(-EINVAL);
return devinfo_table;
}
/* /*
* scsi_strcpy_devinfo: called from scsi_dev_info_list_add to copy into * scsi_strcpy_devinfo: called from scsi_dev_info_list_add to copy into
* devinfo vendor and model strings. * devinfo vendor and model strings.
@ -295,8 +318,39 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length,
**/ **/
static int scsi_dev_info_list_add(int compatible, char *vendor, char *model, static int scsi_dev_info_list_add(int compatible, char *vendor, char *model,
char *strflags, int flags) char *strflags, int flags)
{
return scsi_dev_info_list_add_keyed(compatible, vendor, model,
strflags, flags,
SCSI_DEVINFO_GLOBAL);
}
/**
* scsi_dev_info_list_add_keyed - add one dev_info list entry.
* @compatible: if true, null terminate short strings. Otherwise space pad.
* @vendor: vendor string
* @model: model (product) string
* @strflags: integer string
* @flags: if strflags NULL, use this flag value
* @key: specify list to use
*
* Description:
* Create and add one dev_info entry for @vendor, @model,
* @strflags or @flag in list specified by @key. If @compatible,
* add to the tail of the list, do not space pad, and set
* devinfo->compatible. The scsi_static_device_list entries are
* added with @compatible 1 and @clfags NULL.
*
* Returns: 0 OK, -error on failure.
**/
int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model,
char *strflags, int flags, int key)
{ {
struct scsi_dev_info_list *devinfo; struct scsi_dev_info_list *devinfo;
struct scsi_dev_info_list_table *devinfo_table =
scsi_devinfo_lookup_by_key(key);
if (IS_ERR(devinfo_table))
return PTR_ERR(devinfo_table);
devinfo = kmalloc(sizeof(*devinfo), GFP_KERNEL); devinfo = kmalloc(sizeof(*devinfo), GFP_KERNEL);
if (!devinfo) { if (!devinfo) {
@ -317,12 +371,15 @@ static int scsi_dev_info_list_add(int compatible, char *vendor, char *model,
devinfo->compatible = compatible; devinfo->compatible = compatible;
if (compatible) if (compatible)
list_add_tail(&devinfo->dev_info_list, &scsi_dev_info_list); list_add_tail(&devinfo->dev_info_list,
&devinfo_table->scsi_dev_info_list);
else else
list_add(&devinfo->dev_info_list, &scsi_dev_info_list); list_add(&devinfo->dev_info_list,
&devinfo_table->scsi_dev_info_list);
return 0; return 0;
} }
EXPORT_SYMBOL(scsi_dev_info_list_add_keyed);
/** /**
* scsi_dev_info_list_add_str - parse dev_list and add to the scsi_dev_info_list. * scsi_dev_info_list_add_str - parse dev_list and add to the scsi_dev_info_list.
@ -382,22 +439,48 @@ static int scsi_dev_info_list_add_str(char *dev_list)
* @model: model name * @model: model name
* *
* Description: * Description:
* Search the scsi_dev_info_list for an entry matching @vendor and * Search the global scsi_dev_info_list (specified by list zero)
* @model, if found, return the matching flags value, else return * for an entry matching @vendor and @model, if found, return the
* the host or global default settings. Called during scan time. * matching flags value, else return the host or global default
* settings. Called during scan time.
**/ **/
int scsi_get_device_flags(struct scsi_device *sdev, int scsi_get_device_flags(struct scsi_device *sdev,
const unsigned char *vendor, const unsigned char *vendor,
const unsigned char *model) const unsigned char *model)
{
return scsi_get_device_flags_keyed(sdev, vendor, model,
SCSI_DEVINFO_GLOBAL);
}
/**
* get_device_flags_keyed - get device specific flags from the dynamic device list.
* @sdev: &scsi_device to get flags for
* @vendor: vendor name
* @model: model name
* @key: list to look up
*
* Description:
* Search the scsi_dev_info_list specified by @key for an entry
* matching @vendor and @model, if found, return the matching
* flags value, else return the host or global default settings.
* Called during scan time.
**/
int scsi_get_device_flags_keyed(struct scsi_device *sdev,
const unsigned char *vendor,
const unsigned char *model,
int key)
{ {
struct scsi_dev_info_list *devinfo; struct scsi_dev_info_list *devinfo;
unsigned int bflags; struct scsi_dev_info_list_table *devinfo_table;
bflags = sdev->sdev_bflags; devinfo_table = scsi_devinfo_lookup_by_key(key);
if (!bflags)
bflags = scsi_default_dev_flags;
list_for_each_entry(devinfo, &scsi_dev_info_list, dev_info_list) { if (IS_ERR(devinfo_table))
return PTR_ERR(devinfo_table);
list_for_each_entry(devinfo, &devinfo_table->scsi_dev_info_list,
dev_info_list) {
if (devinfo->compatible) { if (devinfo->compatible) {
/* /*
* Behave like the older version of get_device_flags. * Behave like the older version of get_device_flags.
@ -447,32 +530,89 @@ int scsi_get_device_flags(struct scsi_device *sdev,
return devinfo->flags; return devinfo->flags;
} }
} }
return bflags; /* nothing found, return nothing */
if (key != SCSI_DEVINFO_GLOBAL)
return 0;
/* except for the global list, where we have an exception */
if (sdev->sdev_bflags)
return sdev->sdev_bflags;
return scsi_default_dev_flags;
} }
EXPORT_SYMBOL(scsi_get_device_flags_keyed);
#ifdef CONFIG_SCSI_PROC_FS #ifdef CONFIG_SCSI_PROC_FS
struct double_list {
struct list_head *top;
struct list_head *bottom;
};
static int devinfo_seq_show(struct seq_file *m, void *v) static int devinfo_seq_show(struct seq_file *m, void *v)
{ {
struct double_list *dl = v;
struct scsi_dev_info_list_table *devinfo_table =
list_entry(dl->top, struct scsi_dev_info_list_table, node);
struct scsi_dev_info_list *devinfo = struct scsi_dev_info_list *devinfo =
list_entry(v, struct scsi_dev_info_list, dev_info_list); list_entry(dl->bottom, struct scsi_dev_info_list,
dev_info_list);
if (devinfo_table->scsi_dev_info_list.next == dl->bottom &&
devinfo_table->name)
seq_printf(m, "[%s]:\n", devinfo_table->name);
seq_printf(m, "'%.8s' '%.16s' 0x%x\n", seq_printf(m, "'%.8s' '%.16s' 0x%x\n",
devinfo->vendor, devinfo->model, devinfo->flags); devinfo->vendor, devinfo->model, devinfo->flags);
return 0; return 0;
} }
static void * devinfo_seq_start(struct seq_file *m, loff_t *pos) static void *devinfo_seq_start(struct seq_file *m, loff_t *ppos)
{ {
return seq_list_start(&scsi_dev_info_list, *pos); struct double_list *dl = kmalloc(sizeof(*dl), GFP_KERNEL);
loff_t pos = *ppos;
if (!dl)
return NULL;
list_for_each(dl->top, &scsi_dev_info_list) {
struct scsi_dev_info_list_table *devinfo_table =
list_entry(dl->top, struct scsi_dev_info_list_table,
node);
list_for_each(dl->bottom, &devinfo_table->scsi_dev_info_list)
if (pos-- == 0)
return dl;
} }
static void * devinfo_seq_next(struct seq_file *m, void *v, loff_t *pos) kfree(dl);
return NULL;
}
static void *devinfo_seq_next(struct seq_file *m, void *v, loff_t *ppos)
{ {
return seq_list_next(v, &scsi_dev_info_list, pos); struct double_list *dl = v;
struct scsi_dev_info_list_table *devinfo_table =
list_entry(dl->top, struct scsi_dev_info_list_table, node);
++*ppos;
dl->bottom = dl->bottom->next;
while (&devinfo_table->scsi_dev_info_list == dl->bottom) {
dl->top = dl->top->next;
if (dl->top == &scsi_dev_info_list) {
kfree(dl);
return NULL;
}
devinfo_table = list_entry(dl->top,
struct scsi_dev_info_list_table,
node);
dl->bottom = devinfo_table->scsi_dev_info_list.next;
}
return dl;
} }
static void devinfo_seq_stop(struct seq_file *m, void *v) static void devinfo_seq_stop(struct seq_file *m, void *v)
{ {
kfree(v);
} }
static const struct seq_operations scsi_devinfo_seq_ops = { static const struct seq_operations scsi_devinfo_seq_ops = {
@ -549,19 +689,78 @@ MODULE_PARM_DESC(default_dev_flags,
**/ **/
void scsi_exit_devinfo(void) void scsi_exit_devinfo(void)
{ {
struct list_head *lh, *lh_next;
struct scsi_dev_info_list *devinfo;
#ifdef CONFIG_SCSI_PROC_FS #ifdef CONFIG_SCSI_PROC_FS
remove_proc_entry("scsi/device_info", NULL); remove_proc_entry("scsi/device_info", NULL);
#endif #endif
list_for_each_safe(lh, lh_next, &scsi_dev_info_list) { scsi_dev_info_remove_list(SCSI_DEVINFO_GLOBAL);
}
/**
* scsi_dev_info_add_list - add a new devinfo list
* @key: key of the list to add
* @name: Name of the list to add (for /proc/scsi/device_info)
*
* Adds the requested list, returns zero on success, -EEXIST if the
* key is already registered to a list, or other error on failure.
*/
int scsi_dev_info_add_list(int key, const char *name)
{
struct scsi_dev_info_list_table *devinfo_table =
scsi_devinfo_lookup_by_key(key);
if (!IS_ERR(devinfo_table))
/* list already exists */
return -EEXIST;
devinfo_table = kmalloc(sizeof(*devinfo_table), GFP_KERNEL);
if (!devinfo_table)
return -ENOMEM;
INIT_LIST_HEAD(&devinfo_table->node);
INIT_LIST_HEAD(&devinfo_table->scsi_dev_info_list);
devinfo_table->name = name;
devinfo_table->key = key;
list_add_tail(&devinfo_table->node, &scsi_dev_info_list);
return 0;
}
EXPORT_SYMBOL(scsi_dev_info_add_list);
/**
* scsi_dev_info_remove_list - destroy an added devinfo list
* @key: key of the list to destroy
*
* Iterates over the entire list first, freeing all the values, then
* frees the list itself. Returns 0 on success or -EINVAL if the key
* can't be found.
*/
int scsi_dev_info_remove_list(int key)
{
struct list_head *lh, *lh_next;
struct scsi_dev_info_list_table *devinfo_table =
scsi_devinfo_lookup_by_key(key);
if (IS_ERR(devinfo_table))
/* no such list */
return -EINVAL;
/* remove from the master list */
list_del(&devinfo_table->node);
list_for_each_safe(lh, lh_next, &devinfo_table->scsi_dev_info_list) {
struct scsi_dev_info_list *devinfo;
devinfo = list_entry(lh, struct scsi_dev_info_list, devinfo = list_entry(lh, struct scsi_dev_info_list,
dev_info_list); dev_info_list);
kfree(devinfo); kfree(devinfo);
} }
kfree(devinfo_table);
return 0;
} }
EXPORT_SYMBOL(scsi_dev_info_remove_list);
/** /**
* scsi_init_devinfo - set up the dynamic device list. * scsi_init_devinfo - set up the dynamic device list.
@ -577,10 +776,14 @@ int __init scsi_init_devinfo(void)
#endif #endif
int error, i; int error, i;
error = scsi_dev_info_list_add_str(scsi_dev_flags); error = scsi_dev_info_add_list(SCSI_DEVINFO_GLOBAL, NULL);
if (error) if (error)
return error; return error;
error = scsi_dev_info_list_add_str(scsi_dev_flags);
if (error)
goto out;
for (i = 0; scsi_static_device_list[i].vendor; i++) { for (i = 0; scsi_static_device_list[i].vendor; i++) {
error = scsi_dev_info_list_add(1 /* compatibile */, error = scsi_dev_info_list_add(1 /* compatibile */,
scsi_static_device_list[i].vendor, scsi_static_device_list[i].vendor,

View file

@ -1207,6 +1207,7 @@ int scsi_prep_fn(struct request_queue *q, struct request *req)
ret = scsi_setup_blk_pc_cmnd(sdev, req); ret = scsi_setup_blk_pc_cmnd(sdev, req);
return scsi_prep_return(q, req, ret); return scsi_prep_return(q, req, ret);
} }
EXPORT_SYMBOL(scsi_prep_fn);
/* /*
* scsi_dev_queue_ready: if we can send requests to sdev, return 1 else * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else

View file

@ -39,9 +39,25 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
#endif #endif
/* scsi_devinfo.c */ /* scsi_devinfo.c */
/* list of keys for the lists */
enum {
SCSI_DEVINFO_GLOBAL = 0,
SCSI_DEVINFO_SPI,
};
extern int scsi_get_device_flags(struct scsi_device *sdev, extern int scsi_get_device_flags(struct scsi_device *sdev,
const unsigned char *vendor, const unsigned char *vendor,
const unsigned char *model); const unsigned char *model);
extern int scsi_get_device_flags_keyed(struct scsi_device *sdev,
const unsigned char *vendor,
const unsigned char *model, int key);
extern int scsi_dev_info_list_add_keyed(int compatible, char *vendor,
char *model, char *strflags,
int flags, int key);
extern int scsi_dev_info_add_list(int key, const char *name);
extern int scsi_dev_info_remove_list(int key);
extern int __init scsi_init_devinfo(void); extern int __init scsi_init_devinfo(void);
extern void scsi_exit_devinfo(void); extern void scsi_exit_devinfo(void);
@ -71,7 +87,6 @@ extern int scsi_init_queue(void);
extern void scsi_exit_queue(void); extern void scsi_exit_queue(void);
struct request_queue; struct request_queue;
struct request; struct request;
extern int scsi_prep_fn(struct request_queue *, struct request *);
extern struct kmem_cache *scsi_sdb_cache; extern struct kmem_cache *scsi_sdb_cache;
/* scsi_proc.c */ /* scsi_proc.c */

View file

@ -420,29 +420,12 @@ static int scsi_bus_resume(struct device * dev)
return err; return err;
} }
static int scsi_bus_remove(struct device *dev)
{
struct device_driver *drv = dev->driver;
struct scsi_device *sdev = to_scsi_device(dev);
int err = 0;
/* reset the prep_fn back to the default since the
* driver may have altered it and it's being removed */
blk_queue_prep_rq(sdev->request_queue, scsi_prep_fn);
if (drv && drv->remove)
err = drv->remove(dev);
return 0;
}
struct bus_type scsi_bus_type = { struct bus_type scsi_bus_type = {
.name = "scsi", .name = "scsi",
.match = scsi_bus_match, .match = scsi_bus_match,
.uevent = scsi_bus_uevent, .uevent = scsi_bus_uevent,
.suspend = scsi_bus_suspend, .suspend = scsi_bus_suspend,
.resume = scsi_bus_resume, .resume = scsi_bus_resume,
.remove = scsi_bus_remove,
}; };
EXPORT_SYMBOL_GPL(scsi_bus_type); EXPORT_SYMBOL_GPL(scsi_bus_type);

View file

@ -3397,7 +3397,6 @@ fc_destroy_bsgjob(struct fc_bsg_job *job)
kfree(job); kfree(job);
} }
/** /**
* fc_bsg_jobdone - completion routine for bsg requests that the LLD has * fc_bsg_jobdone - completion routine for bsg requests that the LLD has
* completed * completed
@ -3408,15 +3407,10 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
{ {
struct request *req = job->req; struct request *req = job->req;
struct request *rsp = req->next_rq; struct request *rsp = req->next_rq;
unsigned long flags;
int err; int err;
spin_lock_irqsave(&job->job_lock, flags);
job->state_flags |= FC_RQST_STATE_DONE;
job->ref_cnt--;
spin_unlock_irqrestore(&job->job_lock, flags);
err = job->req->errors = job->reply->result; err = job->req->errors = job->reply->result;
if (err < 0) if (err < 0)
/* we're only returning the result field in the reply */ /* we're only returning the result field in the reply */
job->req->sense_len = sizeof(uint32_t); job->req->sense_len = sizeof(uint32_t);
@ -3433,12 +3427,26 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
rsp->resid_len -= min(job->reply->reply_payload_rcv_len, rsp->resid_len -= min(job->reply->reply_payload_rcv_len,
rsp->resid_len); rsp->resid_len);
} }
blk_complete_request(req);
blk_end_request_all(req, err);
fc_destroy_bsgjob(job);
} }
/**
* fc_bsg_softirq_done - softirq done routine for destroying the bsg requests
* @req: BSG request that holds the job to be destroyed
*/
static void fc_bsg_softirq_done(struct request *rq)
{
struct fc_bsg_job *job = rq->special;
unsigned long flags;
spin_lock_irqsave(&job->job_lock, flags);
job->state_flags |= FC_RQST_STATE_DONE;
job->ref_cnt--;
spin_unlock_irqrestore(&job->job_lock, flags);
blk_end_request_all(rq, rq->errors);
fc_destroy_bsgjob(job);
}
/** /**
* fc_bsg_job_timeout - handler for when a bsg request timesout * fc_bsg_job_timeout - handler for when a bsg request timesout
@ -3471,19 +3479,13 @@ fc_bsg_job_timeout(struct request *req)
"abort failed with status %d\n", err); "abort failed with status %d\n", err);
} }
if (!done) {
spin_lock_irqsave(&job->job_lock, flags);
job->ref_cnt--;
spin_unlock_irqrestore(&job->job_lock, flags);
fc_destroy_bsgjob(job);
}
/* the blk_end_sync_io() doesn't check the error */ /* the blk_end_sync_io() doesn't check the error */
if (done)
return BLK_EH_NOT_HANDLED;
else
return BLK_EH_HANDLED; return BLK_EH_HANDLED;
} }
static int static int
fc_bsg_map_buffer(struct fc_bsg_buffer *buf, struct request *req) fc_bsg_map_buffer(struct fc_bsg_buffer *buf, struct request *req)
{ {
@ -3859,7 +3861,7 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host)
struct fc_internal *i = to_fc_internal(shost->transportt); struct fc_internal *i = to_fc_internal(shost->transportt);
struct request_queue *q; struct request_queue *q;
int err; int err;
char bsg_name[BUS_ID_SIZE]; /*20*/ char bsg_name[20];
fc_host->rqst_q = NULL; fc_host->rqst_q = NULL;
@ -3879,6 +3881,7 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host)
q->queuedata = shost; q->queuedata = shost;
queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q); queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
blk_queue_softirq_done(q, fc_bsg_softirq_done);
blk_queue_rq_timed_out(q, fc_bsg_job_timeout); blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT); blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT);
@ -3924,6 +3927,7 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)
q->queuedata = rport; q->queuedata = rport;
queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q); queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
blk_queue_softirq_done(q, fc_bsg_softirq_done);
blk_queue_rq_timed_out(q, fc_bsg_job_timeout); blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT); blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);

View file

@ -692,6 +692,7 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
"Too many iscsi targets. Max " "Too many iscsi targets. Max "
"number of targets is %d.\n", "number of targets is %d.\n",
ISCSI_MAX_TARGET - 1); ISCSI_MAX_TARGET - 1);
err = -EOVERFLOW;
goto release_host; goto release_host;
} }
} }

View file

@ -173,9 +173,9 @@ static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost,
ret = handler(shost, rphy, req); ret = handler(shost, rphy, req);
req->errors = ret; req->errors = ret;
spin_lock_irq(q->queue_lock); blk_end_request_all(req, ret);
req->end_io(req, ret); spin_lock_irq(q->queue_lock);
} }
} }

View file

@ -46,6 +46,22 @@
#define DV_RETRIES 3 /* should only need at most #define DV_RETRIES 3 /* should only need at most
* two cc/ua clears */ * two cc/ua clears */
/* Our blacklist flags */
enum {
SPI_BLIST_NOIUS = 0x1,
};
/* blacklist table, modelled on scsi_devinfo.c */
static struct {
char *vendor;
char *model;
unsigned flags;
} spi_static_device_list[] __initdata = {
{"HP", "Ultrium 3-SCSI", SPI_BLIST_NOIUS },
{"IBM", "ULTRIUM-TD3", SPI_BLIST_NOIUS },
{NULL, NULL, 0}
};
/* Private data accessors (keep these out of the header file) */ /* Private data accessors (keep these out of the header file) */
#define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress) #define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress)
#define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex) #define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex)
@ -207,6 +223,9 @@ static int spi_device_configure(struct transport_container *tc,
{ {
struct scsi_device *sdev = to_scsi_device(dev); struct scsi_device *sdev = to_scsi_device(dev);
struct scsi_target *starget = sdev->sdev_target; struct scsi_target *starget = sdev->sdev_target;
unsigned bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8],
&sdev->inquiry[16],
SCSI_DEVINFO_SPI);
/* Populate the target capability fields with the values /* Populate the target capability fields with the values
* gleaned from the device inquiry */ * gleaned from the device inquiry */
@ -216,6 +235,10 @@ static int spi_device_configure(struct transport_container *tc,
spi_support_dt(starget) = scsi_device_dt(sdev); spi_support_dt(starget) = scsi_device_dt(sdev);
spi_support_dt_only(starget) = scsi_device_dt_only(sdev); spi_support_dt_only(starget) = scsi_device_dt_only(sdev);
spi_support_ius(starget) = scsi_device_ius(sdev); spi_support_ius(starget) = scsi_device_ius(sdev);
if (bflags & SPI_BLIST_NOIUS) {
dev_info(dev, "Information Units disabled by blacklist\n");
spi_support_ius(starget) = 0;
}
spi_support_qas(starget) = scsi_device_qas(sdev); spi_support_qas(starget) = scsi_device_qas(sdev);
return 0; return 0;
@ -833,7 +856,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
return; return;
} }
if (!scsi_device_wide(sdev)) { if (!spi_support_wide(starget)) {
spi_max_width(starget) = 0; spi_max_width(starget) = 0;
max_width = 0; max_width = 0;
} }
@ -860,7 +883,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
return; return;
/* device can't handle synchronous */ /* device can't handle synchronous */
if (!scsi_device_sync(sdev) && !scsi_device_dt(sdev)) if (!spi_support_sync(starget) && !spi_support_dt(starget))
return; return;
/* len == -1 is the signal that we need to ascertain the /* len == -1 is the signal that we need to ascertain the
@ -876,13 +899,14 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
/* try QAS requests; this should be harmless to set if the /* try QAS requests; this should be harmless to set if the
* target supports it */ * target supports it */
if (scsi_device_qas(sdev) && spi_max_qas(starget)) { if (spi_support_qas(starget) && spi_max_qas(starget)) {
DV_SET(qas, 1); DV_SET(qas, 1);
} else { } else {
DV_SET(qas, 0); DV_SET(qas, 0);
} }
if (scsi_device_ius(sdev) && spi_max_iu(starget) && min_period < 9) { if (spi_support_ius(starget) && spi_max_iu(starget) &&
min_period < 9) {
/* This u320 (or u640). Set IU transfers */ /* This u320 (or u640). Set IU transfers */
DV_SET(iu, 1); DV_SET(iu, 1);
/* Then set the optional parameters */ /* Then set the optional parameters */
@ -902,7 +926,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
i->f->get_signalling(shost); i->f->get_signalling(shost);
if (spi_signalling(shost) == SPI_SIGNAL_SE || if (spi_signalling(shost) == SPI_SIGNAL_SE ||
spi_signalling(shost) == SPI_SIGNAL_HVD || spi_signalling(shost) == SPI_SIGNAL_HVD ||
!scsi_device_dt(sdev)) { !spi_support_dt(starget)) {
DV_SET(dt, 0); DV_SET(dt, 0);
} else { } else {
DV_SET(dt, 1); DV_SET(dt, 1);
@ -1523,7 +1547,21 @@ EXPORT_SYMBOL(spi_release_transport);
static __init int spi_transport_init(void) static __init int spi_transport_init(void)
{ {
int error = transport_class_register(&spi_transport_class); int error = scsi_dev_info_add_list(SCSI_DEVINFO_SPI,
"SCSI Parallel Transport Class");
if (!error) {
int i;
for (i = 0; spi_static_device_list[i].vendor; i++)
scsi_dev_info_list_add_keyed(1, /* compatible */
spi_static_device_list[i].vendor,
spi_static_device_list[i].model,
NULL,
spi_static_device_list[i].flags,
SCSI_DEVINFO_SPI);
}
error = transport_class_register(&spi_transport_class);
if (error) if (error)
return error; return error;
error = anon_transport_class_register(&spi_device_class); error = anon_transport_class_register(&spi_device_class);
@ -1535,6 +1573,7 @@ static void __exit spi_transport_exit(void)
transport_class_unregister(&spi_transport_class); transport_class_unregister(&spi_transport_class);
anon_transport_class_unregister(&spi_device_class); anon_transport_class_unregister(&spi_device_class);
transport_class_unregister(&spi_host_class); transport_class_unregister(&spi_host_class);
scsi_dev_info_remove_list(SCSI_DEVINFO_SPI);
} }
MODULE_AUTHOR("Martin Hicks"); MODULE_AUTHOR("Martin Hicks");

View file

@ -1307,6 +1307,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
int sense_valid = 0; int sense_valid = 0;
int the_result; int the_result;
int retries = 3; int retries = 3;
unsigned int alignment;
unsigned long long lba; unsigned long long lba;
unsigned sector_size; unsigned sector_size;
@ -1358,6 +1359,16 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
return -EOVERFLOW; return -EOVERFLOW;
} }
/* Logical blocks per physical block exponent */
sdkp->hw_sector_size = (1 << (buffer[13] & 0xf)) * sector_size;
/* Lowest aligned logical block */
alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size;
blk_queue_alignment_offset(sdp->request_queue, alignment);
if (alignment && sdkp->first_scan)
sd_printk(KERN_NOTICE, sdkp,
"physical block alignment offset: %u\n", alignment);
sdkp->capacity = lba + 1; sdkp->capacity = lba + 1;
return sector_size; return sector_size;
} }
@ -1409,6 +1420,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
} }
sdkp->capacity = lba + 1; sdkp->capacity = lba + 1;
sdkp->hw_sector_size = sector_size;
return sector_size; return sector_size;
} }
@ -1521,11 +1533,17 @@ got_data:
string_get_size(sz, STRING_UNITS_10, cap_str_10, string_get_size(sz, STRING_UNITS_10, cap_str_10,
sizeof(cap_str_10)); sizeof(cap_str_10));
if (sdkp->first_scan || old_capacity != sdkp->capacity) if (sdkp->first_scan || old_capacity != sdkp->capacity) {
sd_printk(KERN_NOTICE, sdkp, sd_printk(KERN_NOTICE, sdkp,
"%llu %d-byte hardware sectors: (%s/%s)\n", "%llu %d-byte logical blocks: (%s/%s)\n",
(unsigned long long)sdkp->capacity, (unsigned long long)sdkp->capacity,
sector_size, cap_str_10, cap_str_2); sector_size, cap_str_10, cap_str_2);
if (sdkp->hw_sector_size != sector_size)
sd_printk(KERN_NOTICE, sdkp,
"%u-byte physical blocks\n",
sdkp->hw_sector_size);
}
} }
/* Rescale capacity to 512-byte units */ /* Rescale capacity to 512-byte units */
@ -1538,6 +1556,7 @@ got_data:
else if (sector_size == 256) else if (sector_size == 256)
sdkp->capacity >>= 1; sdkp->capacity >>= 1;
blk_queue_physical_block_size(sdp->request_queue, sdkp->hw_sector_size);
sdkp->device->sector_size = sector_size; sdkp->device->sector_size = sector_size;
} }
@ -1775,6 +1794,52 @@ void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer)
return; return;
} }
/**
* sd_read_block_limits - Query disk device for preferred I/O sizes.
* @disk: disk to query
*/
static void sd_read_block_limits(struct scsi_disk *sdkp)
{
unsigned int sector_sz = sdkp->device->sector_size;
char *buffer;
/* Block Limits VPD */
buffer = scsi_get_vpd_page(sdkp->device, 0xb0);
if (buffer == NULL)
return;
blk_queue_io_min(sdkp->disk->queue,
get_unaligned_be16(&buffer[6]) * sector_sz);
blk_queue_io_opt(sdkp->disk->queue,
get_unaligned_be32(&buffer[12]) * sector_sz);
kfree(buffer);
}
/**
* sd_read_block_characteristics - Query block dev. characteristics
* @disk: disk to query
*/
static void sd_read_block_characteristics(struct scsi_disk *sdkp)
{
char *buffer;
u16 rot;
/* Block Device Characteristics VPD */
buffer = scsi_get_vpd_page(sdkp->device, 0xb1);
if (buffer == NULL)
return;
rot = get_unaligned_be16(&buffer[4]);
if (rot == 1)
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue);
kfree(buffer);
}
/** /**
* sd_revalidate_disk - called the first time a new disk is seen, * sd_revalidate_disk - called the first time a new disk is seen,
* performs disk spin up, read_capacity, etc. * performs disk spin up, read_capacity, etc.
@ -1812,6 +1877,8 @@ static int sd_revalidate_disk(struct gendisk *disk)
*/ */
if (sdkp->media_present) { if (sdkp->media_present) {
sd_read_capacity(sdkp, buffer); sd_read_capacity(sdkp, buffer);
sd_read_block_limits(sdkp);
sd_read_block_characteristics(sdkp);
sd_read_write_protect_flag(sdkp, buffer); sd_read_write_protect_flag(sdkp, buffer);
sd_read_cache_type(sdkp, buffer); sd_read_cache_type(sdkp, buffer);
sd_read_app_tag_own(sdkp, buffer); sd_read_app_tag_own(sdkp, buffer);
@ -1934,6 +2001,8 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
add_disk(gd); add_disk(gd);
sd_dif_config_host(sdkp); sd_dif_config_host(sdkp);
sd_revalidate_disk(gd);
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
sdp->removable ? "removable " : ""); sdp->removable ? "removable " : "");
} }
@ -2054,6 +2123,7 @@ static int sd_remove(struct device *dev)
async_synchronize_full(); async_synchronize_full();
sdkp = dev_get_drvdata(dev); sdkp = dev_get_drvdata(dev);
blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn);
device_del(&sdkp->dev); device_del(&sdkp->dev);
del_gendisk(sdkp->disk); del_gendisk(sdkp->disk);
sd_shutdown(dev); sd_shutdown(dev);

View file

@ -45,6 +45,7 @@ struct scsi_disk {
unsigned int openers; /* protected by BKL for now, yuck */ unsigned int openers; /* protected by BKL for now, yuck */
sector_t capacity; /* size in 512-byte sectors */ sector_t capacity; /* size in 512-byte sectors */
u32 index; u32 index;
unsigned short hw_sector_size;
u8 media_present; u8 media_present;
u8 write_prot; u8 write_prot;
u8 protection_type;/* Data Integrity Field */ u8 protection_type;/* Data Integrity Field */

View file

@ -881,6 +881,7 @@ static int sr_remove(struct device *dev)
{ {
struct scsi_cd *cd = dev_get_drvdata(dev); struct scsi_cd *cd = dev_get_drvdata(dev);
blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn);
del_gendisk(cd->disk); del_gendisk(cd->disk);
mutex_lock(&sr_ref_mutex); mutex_lock(&sr_ref_mutex);

View file

@ -2321,6 +2321,7 @@ static void sym_int_par (struct sym_hcb *np, u_short sist)
int phase = cmd & 7; int phase = cmd & 7;
struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa); struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa);
if (printk_ratelimit())
printf("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n", printf("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n",
sym_name(np), hsts, dbc, sbcl); sym_name(np), hsts, dbc, sbcl);

View file

@ -107,7 +107,6 @@ static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp,
break; break;
default: default:
FC_DBG("Invalid op code %x \n", op);
return -EINVAL; return -EINVAL;
} }
*r_ctl = FC_RCTL_DD_UNSOL_CTL; *r_ctl = FC_RCTL_DD_UNSOL_CTL;
@ -298,7 +297,6 @@ static inline int fc_els_fill(struct fc_lport *lport, struct fc_rport *rport,
break; break;
default: default:
FC_DBG("Invalid op code %x \n", op);
return -EINVAL; return -EINVAL;
} }

View file

@ -34,17 +34,72 @@
#include <scsi/fc_frame.h> #include <scsi/fc_frame.h>
#define LIBFC_DEBUG #define FC_LIBFC_LOGGING 0x01 /* General logging, not categorized */
#define FC_LPORT_LOGGING 0x02 /* lport layer logging */
#define FC_DISC_LOGGING 0x04 /* discovery layer logging */
#define FC_RPORT_LOGGING 0x08 /* rport layer logging */
#define FC_FCP_LOGGING 0x10 /* I/O path logging */
#define FC_EM_LOGGING 0x20 /* Exchange Manager logging */
#define FC_EXCH_LOGGING 0x40 /* Exchange/Sequence logging */
#define FC_SCSI_LOGGING 0x80 /* SCSI logging (mostly error handling) */
#ifdef LIBFC_DEBUG extern unsigned int fc_debug_logging;
/* Log messages */
#define FC_DBG(fmt, args...) \ #define FC_CHECK_LOGGING(LEVEL, CMD) \
do { \ do { \
printk(KERN_INFO "%s " fmt, __func__, ##args); \ if (unlikely(fc_debug_logging & LEVEL)) \
} while (0) do { \
#else CMD; \
#define FC_DBG(fmt, args...) } while (0); \
#endif } while (0);
#define FC_LIBFC_DBG(fmt, args...) \
FC_CHECK_LOGGING(FC_LIBFC_LOGGING, \
printk(KERN_INFO "libfc: " fmt, ##args);)
#define FC_LPORT_DBG(lport, fmt, args...) \
FC_CHECK_LOGGING(FC_LPORT_LOGGING, \
printk(KERN_INFO "lport: %6x: " fmt, \
fc_host_port_id(lport->host), ##args);)
#define FC_DISC_DBG(disc, fmt, args...) \
FC_CHECK_LOGGING(FC_DISC_LOGGING, \
printk(KERN_INFO "disc: %6x: " fmt, \
fc_host_port_id(disc->lport->host), \
##args);)
#define FC_RPORT_DBG(rport, fmt, args...) \
do { \
struct fc_rport_libfc_priv *rdata = rport->dd_data; \
struct fc_lport *lport = rdata->local_port; \
FC_CHECK_LOGGING(FC_RPORT_LOGGING, \
printk(KERN_INFO "rport: %6x: %6x: " fmt, \
fc_host_port_id(lport->host), \
rport->port_id, ##args);) \
} while (0);
#define FC_FCP_DBG(pkt, fmt, args...) \
FC_CHECK_LOGGING(FC_FCP_LOGGING, \
printk(KERN_INFO "fcp: %6x: %6x: " fmt, \
fc_host_port_id(pkt->lp->host), \
pkt->rport->port_id, ##args);)
#define FC_EM_DBG(em, fmt, args...) \
FC_CHECK_LOGGING(FC_EM_LOGGING, \
printk(KERN_INFO "em: %6x: " fmt, \
fc_host_port_id(em->lp->host), \
##args);)
#define FC_EXCH_DBG(exch, fmt, args...) \
FC_CHECK_LOGGING(FC_EXCH_LOGGING, \
printk(KERN_INFO "exch: %6x: %4x: " fmt, \
fc_host_port_id(exch->lp->host), \
exch->xid, ##args);)
#define FC_SCSI_DBG(lport, fmt, args...) \
FC_CHECK_LOGGING(FC_SCSI_LOGGING, \
printk(KERN_INFO "scsi: %6x: " fmt, \
fc_host_port_id(lport->host), ##args);)
/* /*
* libfc error codes * libfc error codes

View file

@ -125,6 +125,10 @@ struct iscsi_task {
struct scsi_cmnd *sc; /* associated SCSI cmd*/ struct scsi_cmnd *sc; /* associated SCSI cmd*/
struct iscsi_conn *conn; /* used connection */ struct iscsi_conn *conn; /* used connection */
/* data processing tracking */
unsigned long last_xfer;
unsigned long last_timeout;
bool have_checked_conn;
/* state set/tested under session->lock */ /* state set/tested under session->lock */
int state; int state;
atomic_t refcount; atomic_t refcount;

View file

@ -32,5 +32,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req);
int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req);
int scsi_prep_state_check(struct scsi_device *sdev, struct request *req); int scsi_prep_state_check(struct scsi_device *sdev, struct request *req);
int scsi_prep_return(struct request_queue *q, struct request *req, int ret); int scsi_prep_return(struct request_queue *q, struct request *req, int ret);
int scsi_prep_fn(struct request_queue *, struct request *);
#endif /* _SCSI_SCSI_DRIVER_H */ #endif /* _SCSI_SCSI_DRIVER_H */