Commit 69585dd6 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6: (34 commits)
  [SCSI] qla2xxx: Fix NULL ptr deref bug in fail path during queue create
  [SCSI] st: fix possible memory use after free after MTSETBLK ioctl
  [SCSI] be2iscsi: Moving to pci_pools v3
  [SCSI] libiscsi: iscsi_session_setup to allow for private space
  [SCSI] be2iscsi: add 10Gbps iSCSI - BladeEngine 2 driver
  [SCSI] zfcp: Fix hang when offlining device with offline chpid
  [SCSI] zfcp: Fix lockdep warning when offlining device with offline chpid
  [SCSI] zfcp: Fix oops during shutdown of offline device
  [SCSI] zfcp: Fix initial device and cfdc for delayed adapter allocation
  [SCSI] zfcp: correctly initialize unchained requests
  [SCSI] mpt2sas: Bump version 02.100.03.00
  [SCSI] mpt2sas: Support dev remove when phy status is MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT
  [SCSI] mpt2sas: Timeout occurred within the HANDSHAKE logic while waiting on firmware to ACK.
  [SCSI] mpt2sas: Call init_completion on a per request basis.
  [SCSI] mpt2sas: Target Reset will be issued from Interrupt context.
  [SCSI] mpt2sas: Added SCSIIO, Internal and high priority memory pools to support multiple TM
  [SCSI] mpt2sas: Copyright change to 2009.
  [SCSI] mpt2sas: Added mpi2_history.txt for MPI2 headers.
  [SCSI] mpt2sas: Update driver to MPI2 REV K headers.
  [SCSI] bfa: Brocade BFA FC SCSI driver
  ...
parents bd381934 c7922a91
......@@ -3,6 +3,25 @@ HIGHPOINT ROCKETRAID 3xxx/4xxx ADAPTER DRIVER (hptiop)
Controller Register Map
-------------------------
For RR44xx Intel IOP based adapters, the controller IOP is accessed via PCI BAR0 and BAR2:
BAR0 offset Register
0x11C5C Link Interface IRQ Set
0x11C60 Link Interface IRQ Clear
BAR2 offset Register
0x10 Inbound Message Register 0
0x14 Inbound Message Register 1
0x18 Outbound Message Register 0
0x1C Outbound Message Register 1
0x20 Inbound Doorbell Register
0x24 Inbound Interrupt Status Register
0x28 Inbound Interrupt Mask Register
0x30 Outbound Interrupt Status Register
0x34 Outbound Interrupt Mask Register
0x40 Inbound Queue Port
0x44 Outbound Queue Port
For Intel IOP based adapters, the controller IOP is accessed via PCI BAR0:
BAR0 offset Register
......@@ -93,7 +112,7 @@ The driver exposes following sysfs attributes:
-----------------------------------------------------------------------------
Copyright (C) 2006-2007 HighPoint Technologies, Inc. All Rights Reserved.
Copyright (C) 2006-2009 HighPoint Technologies, Inc. All Rights Reserved.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
......
......@@ -1231,6 +1231,13 @@ L: netdev@vger.kernel.org
S: Supported
F: drivers/net/tg3.*
BROCADE BFA FC SCSI DRIVER
P: Jing Huang
M: huangj@brocade.com
L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/bfa/
BSG (block layer generic sg v4 driver)
M: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
L: linux-scsi@vger.kernel.org
......@@ -4646,6 +4653,14 @@ F: drivers/ata/
F: include/linux/ata.h
F: include/linux/libata.h
SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER
P: Jayamohan Kallickal
M: jayamohank@serverengines.com
L: linux-scsi@vger.kernel.org
W: http://www.serverengines.com
S: Supported
F: drivers/scsi/be2iscsi/
SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER
M: Sathya Perla <sathyap@serverengines.com>
M: Subbu Seetharaman <subbus@serverengines.com>
......
......@@ -426,7 +426,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
* because we preallocate so many resources
*/
cls_session = iscsi_session_setup(&iscsi_iser_transport, shost,
ISCSI_DEF_XMIT_CMDS_MAX,
ISCSI_DEF_XMIT_CMDS_MAX, 0,
sizeof(struct iscsi_iser_task),
initial_cmdsn, 0);
if (!cls_session)
......
......@@ -80,28 +80,35 @@ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter)
static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
{
struct ccw_device *ccwdev;
struct zfcp_adapter *adapter;
struct zfcp_port *port;
struct zfcp_unit *unit;
ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
if (!ccwdev)
return;
if (ccw_device_set_online(ccwdev))
goto out_ccwdev;
mutex_lock(&zfcp_data.config_mutex);
read_lock_irq(&zfcp_data.config_lock);
adapter = zfcp_get_adapter_by_busid(busid);
if (adapter)
adapter = dev_get_drvdata(&ccwdev->dev);
if (!adapter)
goto out_unlock;
zfcp_adapter_get(adapter);
read_unlock_irq(&zfcp_data.config_lock);
if (!adapter)
goto out_adapter;
port = zfcp_port_enqueue(adapter, wwpn, 0, 0);
if (IS_ERR(port))
port = zfcp_get_port_by_wwpn(adapter, wwpn);
if (!port)
goto out_port;
zfcp_port_get(port);
unit = zfcp_unit_enqueue(port, lun);
if (IS_ERR(unit))
goto out_unit;
mutex_unlock(&zfcp_data.config_mutex);
ccw_device_set_online(adapter->ccw_device);
zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL);
zfcp_erp_wait(adapter);
flush_work(&unit->scsi_work);
......@@ -111,8 +118,10 @@ out_unit:
zfcp_port_put(port);
out_port:
zfcp_adapter_put(adapter);
out_adapter:
out_unlock:
mutex_unlock(&zfcp_data.config_mutex);
out_ccwdev:
put_device(&ccwdev->dev);
return;
}
......@@ -593,10 +602,8 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
int retval = 0;
unsigned long flags;
cancel_work_sync(&adapter->scan_work);
cancel_work_sync(&adapter->stat_work);
zfcp_fc_wka_ports_force_offline(adapter->gs);
zfcp_adapter_scsi_unregister(adapter);
sysfs_remove_group(&adapter->ccw_device->dev.kobj,
&zfcp_sysfs_adapter_attrs);
dev_set_drvdata(&adapter->ccw_device->dev, NULL);
......
......@@ -102,6 +102,14 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
adapter = dev_get_drvdata(&ccw_device->dev);
if (!adapter)
goto out;
mutex_unlock(&zfcp_data.config_mutex);
cancel_work_sync(&adapter->scan_work);
mutex_lock(&zfcp_data.config_mutex);
/* this also removes the scsi devices, so call it first */
zfcp_adapter_scsi_unregister(adapter);
write_lock_irq(&zfcp_data.config_lock);
list_for_each_entry_safe(port, p, &adapter->port_list_head, list) {
......@@ -117,11 +125,8 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
write_unlock_irq(&zfcp_data.config_lock);
list_for_each_entry_safe(port, p, &port_remove_lh, list) {
list_for_each_entry_safe(unit, u, &unit_remove_lh, list) {
if (unit->device)
scsi_remove_device(unit->device);
list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
zfcp_unit_dequeue(unit);
}
zfcp_port_dequeue(port);
}
wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
......@@ -192,13 +197,9 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device)
mutex_lock(&zfcp_data.config_mutex);
adapter = dev_get_drvdata(&ccw_device->dev);
if (!adapter)
goto out;
zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL);
zfcp_erp_wait(adapter);
mutex_unlock(&zfcp_data.config_mutex);
out:
return 0;
}
......@@ -253,13 +254,17 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev)
mutex_lock(&zfcp_data.config_mutex);
adapter = dev_get_drvdata(&cdev->dev);
if (!adapter)
goto out;
zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
zfcp_erp_wait(adapter);
zfcp_erp_thread_kill(adapter);
out:
mutex_unlock(&zfcp_data.config_mutex);
}
static struct ccw_driver zfcp_ccw_driver = {
struct ccw_driver zfcp_ccw_driver = {
.owner = THIS_MODULE,
.name = "zfcp",
.ids = zfcp_ccw_device_id,
......@@ -284,20 +289,3 @@ int __init zfcp_ccw_register(void)
{
return ccw_driver_register(&zfcp_ccw_driver);
}
/**
* zfcp_get_adapter_by_busid - find zfcp_adapter struct
* @busid: bus id string of zfcp adapter to find
*/
struct zfcp_adapter *zfcp_get_adapter_by_busid(char *busid)
{
struct ccw_device *ccw_device;
struct zfcp_adapter *adapter = NULL;
ccw_device = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
if (ccw_device) {
adapter = dev_get_drvdata(&ccw_device->dev);
put_device(&ccw_device->dev);
}
return adapter;
}
......@@ -86,8 +86,23 @@ static int zfcp_cfdc_copy_to_user(void __user *user_buffer,
static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
{
char busid[9];
struct ccw_device *ccwdev;
struct zfcp_adapter *adapter = NULL;
snprintf(busid, sizeof(busid), "0.0.%04x", devno);
return zfcp_get_adapter_by_busid(busid);
ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
if (!ccwdev)
goto out;
adapter = dev_get_drvdata(&ccwdev->dev);
if (!adapter)
goto out_put;
zfcp_adapter_get(adapter);
out_put:
put_device(&ccwdev->dev);
out:
return adapter;
}
static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command)
......
......@@ -28,7 +28,7 @@ extern int zfcp_sg_setup_table(struct scatterlist *, int);
/* zfcp_ccw.c */
extern int zfcp_ccw_register(void);
extern int zfcp_ccw_priv_sch(struct zfcp_adapter *);
extern struct zfcp_adapter *zfcp_get_adapter_by_busid(char *);
extern struct ccw_driver zfcp_ccw_driver;
/* zfcp_cfdc.c */
extern struct miscdevice zfcp_cfdc_misc;
......
......@@ -1058,11 +1058,25 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req,
SBAL_FLAGS0_TYPE_WRITE_READ,
sg_resp, max_sbals);
req->qtcb->bottom.support.resp_buf_length = bytes;
if (bytes <= 0)
return -EIO;
return 0;
}
static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
struct scatterlist *sg_req,
struct scatterlist *sg_resp,
int max_sbals)
{
int ret;
ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals);
if (ret)
return ret;
/* common settings for ct/gs and els requests */
req->qtcb->bottom.support.resp_buf_length = bytes;
req->qtcb->bottom.support.service_class = FSF_CLASS_3;
req->qtcb->bottom.support.timeout = 2 * R_A_TOV;
zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10);
......@@ -1094,7 +1108,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool)
}
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
ret = zfcp_fsf_setup_ct_els_sbals(req, ct->req, ct->resp,
ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp,
FSF_MAX_SBALS_PER_REQ);
if (ret)
goto failed_send;
......@@ -1192,7 +1206,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
}
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
ret = zfcp_fsf_setup_ct_els_sbals(req, els->req, els->resp, 2);
ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2);
if (ret)
goto failed_send;
......
......@@ -366,6 +366,7 @@ config ISCSI_TCP
source "drivers/scsi/cxgb3i/Kconfig"
source "drivers/scsi/bnx2i/Kconfig"
source "drivers/scsi/be2iscsi/Kconfig"
config SGIWD93_SCSI
tristate "SGI WD93C93 SCSI Driver"
......@@ -1827,6 +1828,16 @@ config SCSI_SRP
To compile this driver as a module, choose M here: the
module will be called libsrp.
config SCSI_BFA_FC
tristate "Brocade BFA Fibre Channel Support"
depends on PCI && SCSI
select SCSI_FC_ATTRS
help
This bfa driver supports all Brocade PCIe FC/FCOE host adapters.
To compile this driver as a module, choose M here. The module will
be called bfa.
endif # SCSI_LOWLEVEL
source "drivers/scsi/pcmcia/Kconfig"
......
......@@ -86,6 +86,7 @@ obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o
obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/
obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/
obj-$(CONFIG_SCSI_LPFC) += lpfc/
obj-$(CONFIG_SCSI_BFA_FC) += bfa/
obj-$(CONFIG_SCSI_PAS16) += pas16.o
obj-$(CONFIG_SCSI_T128) += t128.o
obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o
......@@ -130,6 +131,7 @@ obj-$(CONFIG_SCSI_MVSAS) += mvsas/
obj-$(CONFIG_PS3_ROM) += ps3rom.o
obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libiscsi.o libiscsi_tcp.o cxgb3i/
obj-$(CONFIG_SCSI_BNX2_ISCSI) += libiscsi.o bnx2i/
obj-$(CONFIG_BE2ISCSI) += libiscsi.o be2iscsi/
obj-$(CONFIG_SCSI_PMCRAID) += pmcraid.o
obj-$(CONFIG_ARM) += arm/
......
config BE2ISCSI
tristate "ServerEngines' 10Gbps iSCSI - BladeEngine 2"
depends on PCI && SCSI
select SCSI_ISCSI_ATTRS
help
This driver implements the iSCSI functionality for ServerEngines'
10Gbps Storage adapter - BladeEngine 2.
#
# Makefile to build the iSCSI driver for ServerEngine's BladeEngine.
#
#
obj-$(CONFIG_BE2ISCSI) += be2iscsi.o
be2iscsi-y := be_iscsi.o be_main.o be_mgmt.o be_cmds.o
/**
* Copyright (C) 2005 - 2009 ServerEngines
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation. The full GNU General
* Public License is included in this distribution in the file called COPYING.
*
* Contact Information:
* linux-drivers@serverengines.com
*
* ServerEngines
* 209 N. Fair Oaks Ave
* Sunnyvale, CA 94085
*/
#ifndef BEISCSI_H
#define BEISCSI_H
#include <linux/pci.h>
#include <linux/if_vlan.h>
#define FW_VER_LEN 32
struct be_dma_mem {
void *va;
dma_addr_t dma;
u32 size;
};
struct be_queue_info {
struct be_dma_mem dma_mem;
u16 len;
u16 entry_size; /* Size of an element in the queue */
u16 id;
u16 tail, head;
bool created;
atomic_t used; /* Number of valid elements in the queue */
};
static inline u32 MODULO(u16 val, u16 limit)
{
WARN_ON(limit & (limit - 1));
return val & (limit - 1);
}
static inline void index_inc(u16 *index, u16 limit)
{
*index = MODULO((*index + 1), limit);
}
static inline void *queue_head_node(struct be_queue_info *q)
{
return q->dma_mem.va + q->head * q->entry_size;
}
static inline void *queue_tail_node(struct be_queue_info *q)
{
return q->dma_mem.va + q->tail * q->entry_size;
}
static inline void queue_head_inc(struct be_queue_info *q)
{
index_inc(&q->head, q->len);
}
static inline void queue_tail_inc(struct be_queue_info *q)
{
index_inc(&q->tail, q->len);
}
/*ISCSI */
struct be_eq_obj {
struct be_queue_info q;
char desc[32];
/* Adaptive interrupt coalescing (AIC) info */
bool enable_aic;
u16 min_eqd; /* in usecs */
u16 max_eqd; /* in usecs */
u16 cur_eqd; /* in usecs */
};
struct be_mcc_obj {
struct be_queue_info *q;
struct be_queue_info *cq;
};
struct be_ctrl_info {
u8 __iomem *csr;
u8 __iomem *db; /* Door Bell */
u8 __iomem *pcicfg; /* PCI config space */
struct pci_dev *pdev;
/* Mbox used for cmd request/response */
spinlock_t mbox_lock; /* For serializing mbox cmds to BE card */
struct be_dma_mem mbox_mem;
/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
* is stored for freeing purpose */
struct be_dma_mem mbox_mem_alloced;
/* MCC Rings */
struct be_mcc_obj mcc_obj;
spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
spinlock_t mcc_cq_lock;
/* MCC Async callback */
void (*async_cb) (void *adapter, bool link_up);
void *adapter_ctxt;
};
#include "be_cmds.h"
#define PAGE_SHIFT_4K 12
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
/* Returns number of pages spanned by the data starting at the given addr */
#define PAGES_4K_SPANNED(_address, size) \
((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \
(size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K))
/* Byte offset into the page corresponding to given address */
#define OFFSET_IN_PAGE(addr) \
((size_t)(addr) & (PAGE_SIZE_4K-1))
/* Returns bit offset within a DWORD of a bitfield */
#define AMAP_BIT_OFFSET(_struct, field) \
(((size_t)&(((_struct *)0)->field))%32)
/* Returns the bit mask of the field that is NOT shifted into location. */
static inline u32 amap_mask(u32 bitsize)
{
return (bitsize == 32 ? 0xFFFFFFFF : (1 << bitsize) - 1);
}
static inline void amap_set(void *ptr, u32 dw_offset, u32 mask,
u32 offset, u32 value)
{
u32 *dw = (u32 *) ptr + dw_offset;
*dw &= ~(mask << offset);
*dw |= (mask & value) << offset;
}
#define AMAP_SET_BITS(_struct, field, ptr, val) \
amap_set(ptr, \
offsetof(_struct, field)/32, \
amap_mask(sizeof(((_struct *)0)->field)), \
AMAP_BIT_OFFSET(_struct, field), \
val)
static inline u32 amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset)
{
u32 *dw = ptr;
return mask & (*(dw + dw_offset) >> offset);
}
#define AMAP_GET_BITS(_struct, field, ptr) \
amap_get(ptr, \
offsetof(_struct, field)/32, \
amap_mask(sizeof(((_struct *)0)->field)), \
AMAP_BIT_OFFSET(_struct, field))
#define be_dws_cpu_to_le(wrb, len) swap_dws(wrb, len)
#define be_dws_le_to_cpu(wrb, len) swap_dws(wrb, len)
static inline void swap_dws(void *wrb, int len)
{
#ifdef __BIG_ENDIAN
u32 *dw = wrb;
WARN_ON(len % 4);
do {
*dw = cpu_to_le32(*dw);
dw++;
len -= 4;
} while (len);
#endif /* __BIG_ENDIAN */
}
extern void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm,
u16 num_popped);
#endif /* BEISCSI_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**
* Copyright (C) 2005 - 2009 ServerEngines
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation. The full GNU General
* Public License is included in this distribution in the file called COPYING.
*
* Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
*
* Contact Information:
* linux-drivers@serverengines.com
*
* ServerEngines
* 209 N. Fair Oaks Ave
* Sunnyvale, CA 94085
*
*/
#ifndef _BE_ISCSI_
#define _BE_ISCSI_
#include "be_main.h"
#include "be_mgmt.h"
#define BE2_IPV4 0x1
#define BE2_IPV6 0x10
void beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
struct beiscsi_offload_params *params);
void beiscsi_offload_iscsi(struct beiscsi_hba *phba, struct iscsi_conn *conn,
struct beiscsi_conn *beiscsi_conn,
unsigned int fw_handle);
struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
uint16_t cmds_max,
uint16_t qdepth,
uint32_t initial_cmdsn);
void beiscsi_session_destroy(struct iscsi_cls_session *cls_session);
struct iscsi_cls_conn *beiscsi_conn_create(struct iscsi_cls_session
*cls_session, uint32_t cid);
int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
struct iscsi_cls_conn *cls_conn,
uint64_t transport_fd, int is_leading);
int beiscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
enum iscsi_param param, char *buf);
int beiscsi_get_host_param(struct Scsi_Host *shost,
enum iscsi_host_param param, char *buf);
int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
enum iscsi_param param, char *buf, int buflen);
int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn);
void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag);
struct iscsi_endpoint *beiscsi_ep_connect(struct Scsi_Host *shost,
struct sockaddr *dst_addr,
int non_blocking);
int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms);
void beiscsi_ep_disconnect(struct iscsi_endpoint *ep);
void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn,
struct iscsi_stats *stats);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**
* Copyright (C) 2005 - 2009 ServerEngines
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation. The full GNU General
* Public License is included in this distribution in the file called COPYING.
*
* Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
*
* Contact Information:
* linux-drivers@serverengines.com
*
* ServerEngines
* 209 N. Fair Oaks Ave
* Sunnyvale, CA 94085
*
*/
#ifndef _BEISCSI_MGMT_
#define _BEISCSI_MGMT_
#include <linux/types.h>
#include <linux/list.h>
#include "be_iscsi.h"
#include "be_main.h"
/**
* Pseudo amap definition in which each bit of the actual structure is defined
* as a byte: used to calculate offset/shift/mask of each field
*/
struct amap_mcc_sge {
u8 pa_lo[32]; /* dword 0 */
u8 pa_hi[32]; /* dword 1 */
u8 length[32]; /* DWORD 2 */
} __packed;
/**
* Pseudo amap definition in which each bit of the actual structure is defined
* as a byte: used to calculate offset/shift/mask of each field
*/
struct amap_mcc_wrb_payload {
union {
struct amap_mcc_sge sgl[19];
u8 embedded[59 * 32]; /* DWORDS 57 to 115 */
} u;
} __packed;
/**
* Pseudo amap definition in which each bit of the actual structure is defined
* as a byte: used to calculate offset/shift/mask of each field
*/
struct amap_mcc_wrb {
u8 embedded; /* DWORD 0 */
u8 rsvd0[2]; /* DWORD 0 */
u8 sge_count[5]; /* DWORD 0 */
u8 rsvd1[16]; /* DWORD 0 */
u8 special[8]; /* DWORD 0 */
u8 payload_length[32];
u8 tag[64]; /* DWORD 2 */
u8 rsvd2[32]; /* DWORD 4 */
struct amap_mcc_wrb_payload payload;
};
struct mcc_sge {
u32 pa_lo; /* dword 0 */
u32 pa_hi; /* dword 1 */
u32 length; /* DWORD 2 */
} __packed;
struct mcc_wrb_payload {
union {
struct mcc_sge sgl[19];
u32 embedded[59]; /* DWORDS 57 to 115 */
} u;
} __packed;
#define MCC_WRB_EMBEDDED_MASK 0x00000001
struct mcc_wrb {
u32 dw[0]; /* DWORD 0 */
u32 payload_length;
u32 tag[2]; /* DWORD 2 */
u32 rsvd2[1]; /* DWORD 4 */
struct mcc_wrb_payload payload;
};
unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute);
int mgmt_open_connection(struct beiscsi_hba *phba, struct sockaddr *dst_addr,
struct beiscsi_endpoint *beiscsi_ep);
unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
unsigned short cid,
unsigned int upload_flag);
unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
unsigned int icd, unsigned int cid);
struct iscsi_invalidate_connection_params_in {
struct be_cmd_req_hdr hdr;
unsigned int session_handle;
unsigned short cid;
unsigned short unused;
unsigned short cleanup_type;
unsigned short save_cfg;
} __packed;
struct iscsi_invalidate_connection_params_out {
unsigned int session_handle;
unsigned short cid;
unsigned short unused;
} __packed;
union iscsi_invalidate_connection_params {
struct iscsi_invalidate_connection_params_in request;
struct iscsi_invalidate_connection_params_out response;
} __packed;
struct invalidate_command_table {
unsigned short icd;
unsigned short cid;
} __packed;
struct invalidate_commands_params_in {
struct be_cmd_req_hdr hdr;
unsigned int ref_handle;
unsigned int icd_count;
struct invalidate_command_table table[128];
unsigned short cleanup_type;
unsigned short unused;
} __packed;
struct invalidate_commands_params_out {
unsigned int ref_handle;
unsigned int icd_count;
unsigned int icd_status[128];
} __packed;
union invalidate_commands_params {
struct invalidate_commands_params_in request;
struct invalidate_commands_params_out response;
} __packed;
struct mgmt_hba_attributes {
u8 flashrom_version_string[32];
u8 manufacturer_name[32];
u32 supported_modes;
u8 seeprom_version_lo;
u8 seeprom_version_hi;
u8 rsvd0[2];
u32 fw_cmd_data_struct_version;
u32 ep_fw_data_struct_version;
u32 future_reserved[12];
u32 default_extended_timeout;
u8 controller_model_number[32];
u8 controller_description[64];
u8 controller_serial_number[32];
u8 ip_version_string[32];
u8 firmware_version_string[32];
u8 bios_version_string[32];
u8 redboot_version_string[32];
u8 driver_version_string[32];
u8 fw_on_flash_version_string[32];
u32 functionalities_supported;
u16 max_cdblength;
u8 asic_revision;
u8 generational_guid[16];
u8 hba_port_count;
u16 default_link_down_timeout;
u8 iscsi_ver_min_max;
u8 multifunction_device;
u8 cache_valid;
u8 hba_status;
u8 max_domains_supported;
u8 phy_port;
u32 firmware_post_status;
u32 hba_mtu[8];
u32 future_u32[4];
} __packed;
struct mgmt_controller_attributes {
struct mgmt_hba_attributes hba_attribs;
u16 pci_vendor_id;
u16 pci_device_id;
u16 pci_sub_vendor_id;
u16 pci_sub_system_id;
u8 pci_bus_number;
u8 pci_device_number;
u8 pci_function_number;
u8 interface_type;
u64 unique_identifier;
u8 netfilters;
u8 rsvd0[3];
u8 future_u32[4];
} __packed;
struct be_mgmt_controller_attributes {
struct be_cmd_req_hdr hdr;
struct mgmt_controller_attributes params;
} __packed;
struct be_mgmt_controller_attributes_resp {
struct be_cmd_resp_hdr hdr;
struct mgmt_controller_attributes params;
} __packed;
/* configuration management */
#define GET_MGMT_CONTROLLER_WS(phba) (phba->pmgmt_ws)
/* MGMT CMD flags */
#define MGMT_CMDH_FREE (1<<0)
/* --- MGMT_ERROR_CODES --- */
/* Error Codes returned in the status field of the CMD response header */
#define MGMT_STATUS_SUCCESS 0 /* The CMD completed without errors */
#define MGMT_STATUS_FAILED 1 /* Error status in the Status field of */
/* the CMD_RESPONSE_HEADER */
#define ISCSI_GET_PDU_TEMPLATE_ADDRESS(pc, pa) {\
pa->lo = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\
bus_address.u.a32.address_lo; \
pa->hi = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\
bus_address.u.a32.address_hi; \
}
struct beiscsi_endpoint {
struct beiscsi_hba *phba;
struct beiscsi_sess *sess;
struct beiscsi_conn *conn;
unsigned short ip_type;
char dst6_addr[ISCSI_ADDRESS_BUF_LEN];
unsigned long dst_addr;
unsigned short ep_cid;
unsigned int fw_handle;
u16 dst_tcpport;
u16 cid_vld;
};
unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba);
unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
struct beiscsi_endpoint *beiscsi_ep,
unsigned short cid,
unsigned short issue_reset,
unsigned short savecfg_flag);
#endif
obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o
bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o
bfa-y += bfa_csdebug.o bfa_sm.o plog.o
bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o
bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o
ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna
/*
* Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
* All rights reserved
* www.brocade.com
*
* Linux driver for Brocade Fibre Channel Host Bus Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#ifndef __BFA_CALLBACK_PRIV_H__
#define __BFA_CALLBACK_PRIV_H__
#include <cs/bfa_q.h>
typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete);
/**
* Generic BFA callback element.
*/
struct bfa_cb_qe_s {
struct list_head qe;
bfa_cb_cbfn_t cbfn;
bfa_boolean_t once;
u32 rsvd;
void *cbarg;
};
#define bfa_cb_queue(__bfa, __hcb_qe, __cbfn, __cbarg) do { \
(__hcb_qe)->cbfn = (__cbfn); \
(__hcb_qe)->cbarg = (__cbarg); \
list_add_tail(&(__hcb_qe)->qe, &(__bfa)->comp_q); \
} while (0)
#define bfa_cb_dequeue(__hcb_qe) list_del(&(__hcb_qe)->qe)
#define bfa_cb_queue_once(__bfa, __hcb_qe, __cbfn, __cbarg) do { \
(__hcb_qe)->cbfn = (__cbfn); \
(__hcb_qe)->cbarg = (__cbarg); \
if (!(__hcb_qe)->once) { \
list_add_tail((__hcb_qe), &(__bfa)->comp_q); \
(__hcb_qe)->once = BFA_TRUE; \
} \
} while (0)
#define bfa_cb_queue_done(__hcb_qe) do { \
(__hcb_qe)->once = BFA_FALSE; \
} while (0)
#endif /* __BFA_CALLBACK_PRIV_H__ */
/*
* Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
* All rights reserved
* www.brocade.com
*
* Linux driver for Brocade Fibre Channel Host Bus Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
/**
* bfa_cb_ioim_macros.h BFA IOIM driver interface macros.
*/
#ifndef __BFA_HCB_IOIM_MACROS_H__
#define __BFA_HCB_IOIM_MACROS_H__
#include <bfa_os_inc.h>
/*
* #include <linux/dma-mapping.h>
*
* #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include
* <scsi/scsi_device.h> #include <scsi/scsi_host.h>
*/
#include "bfad_im_compat.h"
/*
* task attribute values in FCP-2 FCP_CMND IU
*/
#define SIMPLE_Q 0
#define HEAD_OF_Q 1
#define ORDERED_Q 2
#define ACA_Q 4
#define UNTAGGED 5
static inline lun_t
bfad_int_to_lun(u32 luno)
{
union {
u16 scsi_lun[4];
lun_t bfa_lun;
} lun;
lun.bfa_lun = 0;
lun.scsi_lun[0] = bfa_os_htons(luno);
return (lun.bfa_lun);
}
/**
* Get LUN for the I/O request
*/
#define bfa_cb_ioim_get_lun(__dio) \
bfad_int_to_lun(((struct scsi_cmnd *)__dio)->device->lun)
/**
* Get CDB for the I/O request
*/
static inline u8 *
bfa_cb_ioim_get_cdb(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
return ((u8 *) cmnd->cmnd);
}
/**
* Get I/O direction (read/write) for the I/O request
*/
static inline enum fcp_iodir
bfa_cb_ioim_get_iodir(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
enum dma_data_direction dmadir;
dmadir = cmnd->sc_data_direction;
if (dmadir == DMA_TO_DEVICE)
return FCP_IODIR_WRITE;
else if (dmadir == DMA_FROM_DEVICE)
return FCP_IODIR_READ;
else
return FCP_IODIR_NONE;
}
/**
* Get IO size in bytes for the I/O request
*/
static inline u32
bfa_cb_ioim_get_size(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
return (scsi_bufflen(cmnd));
}
/**
* Get timeout for the I/O request
*/
static inline u8
bfa_cb_ioim_get_timeout(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
/*
* TBD: need a timeout for scsi passthru
*/
if (cmnd->device->host == NULL)
return 4;
return 0;
}
/**
* Get SG element for the I/O request given the SG element index
*/
static inline union bfi_addr_u
bfa_cb_ioim_get_sgaddr(struct bfad_ioim_s *dio, int sgeid)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
struct scatterlist *sge;
u64 addr;
sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
addr = (u64) sg_dma_address(sge);
return (*(union bfi_addr_u *) &addr);
}
static inline u32
bfa_cb_ioim_get_sglen(struct bfad_ioim_s *dio, int sgeid)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
struct scatterlist *sge;
u32 len;
sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
len = sg_dma_len(sge);
return len;
}
/**
* Get Command Reference Number for the I/O request. 0 if none.
*/
static inline u8
bfa_cb_ioim_get_crn(struct bfad_ioim_s *dio)
{
return 0;
}
/**
* Get SAM-3 priority for the I/O request. 0 is default.
*/
static inline u8
bfa_cb_ioim_get_priority(struct bfad_ioim_s *dio)
{
return 0;
}
/**
* Get task attributes for the I/O request. Default is FCP_TASK_ATTR_SIMPLE(0).
*/
static inline u8
bfa_cb_ioim_get_taskattr(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
u8 task_attr = UNTAGGED;
if (cmnd->device->tagged_supported) {
switch (cmnd->tag) {
case HEAD_OF_QUEUE_TAG:
task_attr = HEAD_OF_Q;
break;
case ORDERED_QUEUE_TAG:
task_attr = ORDERED_Q;
break;
default:
task_attr = SIMPLE_Q;
break;
}
}
return task_attr;
}
/**
* Get CDB length in bytes for the I/O request. Default is FCP_CMND_CDB_LEN(16).
*/
static inline u8
bfa_cb_ioim_get_cdblen(struct bfad_ioim_s *dio)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
return (cmnd->cmd_len);
}
#endif /* __BFA_HCB_IOIM_MACROS_H__ */
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
* All rights reserved
* www.brocade.com
*
* Linux driver for Brocade Fibre Channel Host Bus Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <cs/bfa_debug.h>
#include <bfa_os_inc.h>
#include <cs/bfa_q.h>
#include <log/bfa_log_hal.h>
/**
* cs_debug_api
*/
void
bfa_panic(int line, char *file, char *panicstr)
{
bfa_log(NULL, BFA_LOG_HAL_ASSERT, file, line, panicstr);
bfa_os_panic();
}
void
bfa_sm_panic(struct bfa_log_mod_s *logm, int line, char *file, int event)
{
bfa_log(logm, BFA_LOG_HAL_SM_ASSERT, file, line, event);
bfa_os_panic();
}
int
bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe)
{
struct list_head *tqe;
tqe = bfa_q_next(q);
while (tqe != q) {
if (tqe == qe)
return (1);
tqe = bfa_q_next(tqe);
if (tqe == NULL)
break;
}
return (0);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
* All rights reserved
* www.brocade.com
*
* Linux driver for Brocade Fibre Channel Host Bus Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
/**
* bfa_fcs_pport.c BFA FCS PPORT ( physical port)
*/
#include <fcs/bfa_fcs.h>
#include <bfa_svc.h>
#include <fcs/bfa_fcs_fabric.h>
#include "fcs_trcmod.h"
#include "fcs.h"
#include "fcs_fabric.h"
#include "fcs_port.h"
BFA_TRC_FILE(FCS, PPORT);
static void
bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event)
{
struct bfa_fcs_s *fcs = cbarg;
bfa_trc(fcs, event);
switch (event) {
case BFA_PPORT_LINKUP:
bfa_fcs_fabric_link_up(&fcs->fabric);
break;
case BFA_PPORT_LINKDOWN:
bfa_fcs_fabric_link_down(&fcs->fabric);
break;
case BFA_PPORT_TRUNK_LINKDOWN:
bfa_assert(0);
break;
default:
bfa_assert(0);
}
}
void
bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs)
{
bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler,
fcs);
}
void
bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs)
{
bfa_fcs_modexit_comp(fcs);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
* All rights reserved
* www.brocade.com
*
* Linux driver for Brocade Fibre Channel Host Bus Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#ifndef __BFA_FWIMG_PRIV_H__
#define __BFA_FWIMG_PRIV_H__
#define BFI_FLASH_CHUNK_SZ 256 /* Flash chunk size */
#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32))
extern u32 *bfi_image_ct_get_chunk(u32 off);
extern u32 bfi_image_ct_size;
extern u32 *bfi_image_cb_get_chunk(u32 off);
extern u32 bfi_image_cb_size;
extern u32 *bfi_image_cb;
extern u32 *bfi_image_ct;
#endif /* __BFA_FWIMG_PRIV_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
* All rights reserved
* www.brocade.com
*
* Linux driver for Brocade Fibre Channel Host Bus Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
/**
* fcs.h FCS module functions
*/
#ifndef __FCS_H__
#define __FCS_H__
#define __fcs_min_cfg(__fcs) (__fcs)->min_cfg
void bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs);
#endif /* __FCS_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment