diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/backing-dev.h | 12 | ||||
-rw-r--r-- | include/linux/bio.h | 19 | ||||
-rw-r--r-- | include/linux/blkdev.h | 55 | ||||
-rw-r--r-- | include/linux/fs.h | 8 | ||||
-rw-r--r-- | include/linux/leds-bd2802.h | 26 | ||||
-rw-r--r-- | include/linux/leds.h | 4 | ||||
-rw-r--r-- | include/linux/leds_pwm.h | 21 | ||||
-rw-r--r-- | include/scsi/fc/fc_fip.h | 237 | ||||
-rw-r--r-- | include/scsi/fc_transport_fcoe.h | 54 | ||||
-rw-r--r-- | include/scsi/libfc.h | 45 | ||||
-rw-r--r-- | include/scsi/libfcoe.h | 227 |
11 files changed, 506 insertions, 202 deletions
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index bee52abb8a4..0ec2c594868 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -24,8 +24,8 @@ struct dentry; */ enum bdi_state { BDI_pdflush, /* A pdflush thread is working this device */ - BDI_write_congested, /* The write queue is getting full */ - BDI_read_congested, /* The read queue is getting full */ + BDI_async_congested, /* The async (write) queue is getting full */ + BDI_sync_congested, /* The sync queue is getting full */ BDI_unused, /* Available bits start here */ }; @@ -215,18 +215,18 @@ static inline int bdi_congested(struct backing_dev_info *bdi, int bdi_bits) static inline int bdi_read_congested(struct backing_dev_info *bdi) { - return bdi_congested(bdi, 1 << BDI_read_congested); + return bdi_congested(bdi, 1 << BDI_sync_congested); } static inline int bdi_write_congested(struct backing_dev_info *bdi) { - return bdi_congested(bdi, 1 << BDI_write_congested); + return bdi_congested(bdi, 1 << BDI_async_congested); } static inline int bdi_rw_congested(struct backing_dev_info *bdi) { - return bdi_congested(bdi, (1 << BDI_read_congested)| - (1 << BDI_write_congested)); + return bdi_congested(bdi, (1 << BDI_sync_congested) | + (1 << BDI_async_congested)); } void clear_bdi_congested(struct backing_dev_info *bdi, int rw); diff --git a/include/linux/bio.h b/include/linux/bio.h index b05b1d4d17d..b900d2c67d2 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -145,20 +145,21 @@ struct bio { * bit 2 -- barrier * Insert a serialization point in the IO queue, forcing previously * submitted IO to be completed before this one is issued. - * bit 3 -- synchronous I/O hint: the block layer will unplug immediately - * Note that this does NOT indicate that the IO itself is sync, just - * that the block layer will not postpone issue of this IO by plugging. - * bit 4 -- metadata request + * bit 3 -- synchronous I/O hint. + * bit 4 -- Unplug the device immediately after submitting this bio. + * bit 5 -- metadata request * Used for tracing to differentiate metadata and data IO. May also * get some preferential treatment in the IO scheduler - * bit 5 -- discard sectors + * bit 6 -- discard sectors * Informs the lower level device that this range of sectors is no longer * used by the file system and may thus be freed by the device. Used * for flash based storage. - * bit 6 -- fail fast device errors - * bit 7 -- fail fast transport errors - * bit 8 -- fail fast driver errors + * bit 7 -- fail fast device errors + * bit 8 -- fail fast transport errors + * bit 9 -- fail fast driver errors * Don't want driver retries for any fast fail whatever the reason. + * bit 10 -- Tell the IO scheduler not to wait for more requests after this + one has been submitted, even if it is a SYNC request. */ #define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */ #define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */ @@ -170,6 +171,7 @@ struct bio { #define BIO_RW_FAILFAST_DEV 7 #define BIO_RW_FAILFAST_TRANSPORT 8 #define BIO_RW_FAILFAST_DRIVER 9 +#define BIO_RW_NOIDLE 10 #define bio_rw_flagged(bio, flag) ((bio)->bi_rw & (1 << (flag))) @@ -188,6 +190,7 @@ struct bio { #define bio_rw_ahead(bio) bio_rw_flagged(bio, BIO_RW_AHEAD) #define bio_rw_meta(bio) bio_rw_flagged(bio, BIO_RW_META) #define bio_discard(bio) bio_rw_flagged(bio, BIO_RW_DISCARD) +#define bio_noidle(bio) bio_rw_flagged(bio, BIO_RW_NOIDLE) /* * upper 16 bits of bi_rw define the io priority of this bio diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 465d6babc84..e03660964e0 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -38,6 +38,10 @@ struct request; typedef void (rq_end_io_fn)(struct request *, int); struct request_list { + /* + * count[], starved[], and wait[] are indexed by + * BLK_RW_SYNC/BLK_RW_ASYNC + */ int count[2]; int starved[2]; int elvpriv; @@ -66,6 +70,11 @@ enum rq_cmd_type_bits { REQ_TYPE_ATA_PC, }; +enum { + BLK_RW_ASYNC = 0, + BLK_RW_SYNC = 1, +}; + /* * For request of type REQ_TYPE_LINUX_BLOCK, rq->cmd[0] is the opcode being * sent down (similar to how REQ_TYPE_BLOCK_PC means that ->cmd[] holds a @@ -103,12 +112,13 @@ enum rq_flag_bits { __REQ_QUIET, /* don't worry about errors */ __REQ_PREEMPT, /* set for "ide_preempt" requests */ __REQ_ORDERED_COLOR, /* is before or after barrier */ - __REQ_RW_SYNC, /* request is sync (O_DIRECT) */ + __REQ_RW_SYNC, /* request is sync (sync write or read) */ __REQ_ALLOCED, /* request came from our alloc pool */ __REQ_RW_META, /* metadata io request */ __REQ_COPY_USER, /* contains copies of user pages */ __REQ_INTEGRITY, /* integrity metadata has been remapped */ __REQ_UNPLUG, /* unplug queue on submission */ + __REQ_NOIDLE, /* Don't anticipate more IO after this one */ __REQ_NR_BITS, /* stops here */ }; @@ -136,6 +146,7 @@ enum rq_flag_bits { #define REQ_COPY_USER (1 << __REQ_COPY_USER) #define REQ_INTEGRITY (1 << __REQ_INTEGRITY) #define REQ_UNPLUG (1 << __REQ_UNPLUG) +#define REQ_NOIDLE (1 << __REQ_NOIDLE) #define BLK_MAX_CDB 16 @@ -438,8 +449,8 @@ struct request_queue #define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */ #define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */ #define QUEUE_FLAG_STOPPED 2 /* queue is stopped */ -#define QUEUE_FLAG_READFULL 3 /* read queue has been filled */ -#define QUEUE_FLAG_WRITEFULL 4 /* write queue has been filled */ +#define QUEUE_FLAG_SYNCFULL 3 /* read queue has been filled */ +#define QUEUE_FLAG_ASYNCFULL 4 /* write queue has been filled */ #define QUEUE_FLAG_DEAD 5 /* queue being torn down */ #define QUEUE_FLAG_REENTER 6 /* Re-entrancy avoidance */ #define QUEUE_FLAG_PLUGGED 7 /* queue is plugged */ @@ -611,32 +622,42 @@ enum { #define rq_data_dir(rq) ((rq)->cmd_flags & 1) /* - * We regard a request as sync, if it's a READ or a SYNC write. + * We regard a request as sync, if either a read or a sync write */ -#define rq_is_sync(rq) (rq_data_dir((rq)) == READ || (rq)->cmd_flags & REQ_RW_SYNC) +static inline bool rw_is_sync(unsigned int rw_flags) +{ + return !(rw_flags & REQ_RW) || (rw_flags & REQ_RW_SYNC); +} + +static inline bool rq_is_sync(struct request *rq) +{ + return rw_is_sync(rq->cmd_flags); +} + #define rq_is_meta(rq) ((rq)->cmd_flags & REQ_RW_META) +#define rq_noidle(rq) ((rq)->cmd_flags & REQ_NOIDLE) -static inline int blk_queue_full(struct request_queue *q, int rw) +static inline int blk_queue_full(struct request_queue *q, int sync) { - if (rw == READ) - return test_bit(QUEUE_FLAG_READFULL, &q->queue_flags); - return test_bit(QUEUE_FLAG_WRITEFULL, &q->queue_flags); + if (sync) + return test_bit(QUEUE_FLAG_SYNCFULL, &q->queue_flags); + return test_bit(QUEUE_FLAG_ASYNCFULL, &q->queue_flags); } -static inline void blk_set_queue_full(struct request_queue *q, int rw) +static inline void blk_set_queue_full(struct request_queue *q, int sync) { - if (rw == READ) - queue_flag_set(QUEUE_FLAG_READFULL, q); + if (sync) + queue_flag_set(QUEUE_FLAG_SYNCFULL, q); else - queue_flag_set(QUEUE_FLAG_WRITEFULL, q); + queue_flag_set(QUEUE_FLAG_ASYNCFULL, q); } -static inline void blk_clear_queue_full(struct request_queue *q, int rw) +static inline void blk_clear_queue_full(struct request_queue *q, int sync) { - if (rw == READ) - queue_flag_clear(QUEUE_FLAG_READFULL, q); + if (sync) + queue_flag_clear(QUEUE_FLAG_SYNCFULL, q); else - queue_flag_clear(QUEUE_FLAG_WRITEFULL, q); + queue_flag_clear(QUEUE_FLAG_ASYNCFULL, q); } diff --git a/include/linux/fs.h b/include/linux/fs.h index a09e17c8f5f..cae5720f431 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -95,8 +95,12 @@ struct inodes_stat_t { #define SWRITE 3 /* for ll_rw_block() - wait for buffer lock */ #define READ_SYNC (READ | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) #define READ_META (READ | (1 << BIO_RW_META)) -#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) -#define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) +#define WRITE_SYNC_PLUG (WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_NOIDLE)) +#define WRITE_SYNC (WRITE_SYNC_PLUG | (1 << BIO_RW_UNPLUG)) +#define WRITE_ODIRECT (WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) +#define SWRITE_SYNC_PLUG \ + (SWRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_NOIDLE)) +#define SWRITE_SYNC (SWRITE_SYNC_PLUG | (1 << BIO_RW_UNPLUG)) #define WRITE_BARRIER (WRITE | (1 << BIO_RW_BARRIER)) #define DISCARD_NOBARRIER (1 << BIO_RW_DISCARD) #define DISCARD_BARRIER ((1 << BIO_RW_DISCARD) | (1 << BIO_RW_BARRIER)) diff --git a/include/linux/leds-bd2802.h b/include/linux/leds-bd2802.h new file mode 100644 index 00000000000..42f854a1a19 --- /dev/null +++ b/include/linux/leds-bd2802.h @@ -0,0 +1,26 @@ +/* + * leds-bd2802.h - RGB LED Driver + * + * Copyright (C) 2009 Samsung Electronics + * Kim Kyuwon <q1.kim@samsung.com> + * + * 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. + * + * Datasheet: http://www.rohm.com/products/databook/driver/pdf/bd2802gu-e.pdf + * + */ +#ifndef _LEDS_BD2802_H_ +#define _LEDS_BD2802_H_ + +struct bd2802_led_platform_data{ + int reset_gpio; + u8 rgb_time; +}; + +#define RGB_TIME(slopedown, slopeup, waveform) \ + ((slopedown) << 6 | (slopeup) << 4 | (waveform)) + +#endif /* _LEDS_BD2802_H_ */ + diff --git a/include/linux/leds.h b/include/linux/leds.h index 24489da701e..376fe07732e 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -30,6 +30,7 @@ enum led_brightness { struct led_classdev { const char *name; int brightness; + int max_brightness; int flags; /* Lower 16 bits reflect status */ @@ -140,7 +141,8 @@ struct gpio_led { const char *name; const char *default_trigger; unsigned gpio; - u8 active_low; + u8 active_low : 1; + u8 retain_state_suspended : 1; }; struct gpio_led_platform_data { diff --git a/include/linux/leds_pwm.h b/include/linux/leds_pwm.h new file mode 100644 index 00000000000..33a07116748 --- /dev/null +++ b/include/linux/leds_pwm.h @@ -0,0 +1,21 @@ +/* + * PWM LED driver data - see drivers/leds/leds-pwm.c + */ +#ifndef __LINUX_LEDS_PWM_H +#define __LINUX_LEDS_PWM_H + +struct led_pwm { + const char *name; + const char *default_trigger; + unsigned pwm_id; + u8 active_low; + unsigned max_brightness; + unsigned pwm_period_ns; +}; + +struct led_pwm_platform_data { + int num_leds; + struct led_pwm *leds; +}; + +#endif diff --git a/include/scsi/fc/fc_fip.h b/include/scsi/fc/fc_fip.h new file mode 100644 index 00000000000..0627a9ae634 --- /dev/null +++ b/include/scsi/fc/fc_fip.h @@ -0,0 +1,237 @@ +/* + * Copyright 2008 Cisco Systems, Inc. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _FC_FIP_H_ +#define _FC_FIP_H_ + +/* + * This version is based on: + * http://www.t11.org/ftp/t11/pub/fc/bb-5/08-543v1.pdf + */ + +/* + * The FIP ethertype eventually goes in net/if_ether.h. + */ +#ifndef ETH_P_FIP +#define ETH_P_FIP 0x8914 /* FIP Ethertype */ +#endif + +#define FIP_DEF_PRI 128 /* default selection priority */ +#define FIP_DEF_FC_MAP 0x0efc00 /* default FCoE MAP (MAC OUI) value */ +#define FIP_DEF_FKA 8000 /* default FCF keep-alive/advert period (mS) */ +#define FIP_VN_KA_PERIOD 90000 /* required VN_port keep-alive period (mS) */ +#define FIP_FCF_FUZZ 100 /* random time added by FCF (mS) */ + +/* + * Multicast MAC addresses. T11-adopted. + */ +#define FIP_ALL_FCOE_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 0 }) +#define FIP_ALL_ENODE_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 1 }) +#define FIP_ALL_FCF_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 2 }) + +#define FIP_VER 1 /* version for fip_header */ + +struct fip_header { + __u8 fip_ver; /* upper 4 bits are the version */ + __u8 fip_resv1; /* reserved */ + __be16 fip_op; /* operation code */ + __u8 fip_resv2; /* reserved */ + __u8 fip_subcode; /* lower 4 bits are sub-code */ + __be16 fip_dl_len; /* length of descriptors in words */ + __be16 fip_flags; /* header flags */ +} __attribute__((packed)); + +#define FIP_VER_SHIFT 4 +#define FIP_VER_ENCAPS(v) ((v) << FIP_VER_SHIFT) +#define FIP_VER_DECAPS(v) ((v) >> FIP_VER_SHIFT) +#define FIP_BPW 4 /* bytes per word for lengths */ + +/* + * fip_op. + */ +enum fip_opcode { + FIP_OP_DISC = 1, /* discovery, advertisement, etc. */ + FIP_OP_LS = 2, /* Link Service request or reply */ + FIP_OP_CTRL = 3, /* Keep Alive / Link Reset */ + FIP_OP_VLAN = 4, /* VLAN discovery */ + FIP_OP_VENDOR_MIN = 0xfff8, /* min vendor-specific opcode */ + FIP_OP_VENDOR_MAX = 0xfffe, /* max vendor-specific opcode */ +}; + +/* + * Subcodes for FIP_OP_DISC. + */ +enum fip_disc_subcode { + FIP_SC_SOL = 1, /* solicitation */ + FIP_SC_ADV = 2, /* advertisement */ +}; + +/* + * Subcodes for FIP_OP_LS. + */ +enum fip_trans_subcode { + FIP_SC_REQ = 1, /* request */ + FIP_SC_REP = 2, /* reply */ +}; + +/* + * Subcodes for FIP_OP_RESET. + */ +enum fip_reset_subcode { + FIP_SC_KEEP_ALIVE = 1, /* keep-alive from VN_Port */ + FIP_SC_CLR_VLINK = 2, /* clear virtual link from VF_Port */ +}; + +/* + * Subcodes for FIP_OP_VLAN. + */ +enum fip_vlan_subcode { + FIP_SC_VL_REQ = 1, /* request */ + FIP_SC_VL_REP = 2, /* reply */ +}; + +/* + * flags in header fip_flags. + */ +enum fip_flag { + FIP_FL_FPMA = 0x8000, /* supports FPMA fabric-provided MACs */ + FIP_FL_SPMA = 0x4000, /* supports SPMA server-provided MACs */ + FIP_FL_AVAIL = 0x0004, /* available for FLOGI/ELP */ + FIP_FL_SOL = 0x0002, /* this is a solicited message */ + FIP_FL_FPORT = 0x0001, /* sent from an F port */ +}; + +/* + * Common descriptor header format. + */ +struct fip_desc { + __u8 fip_dtype; /* type - see below */ + __u8 fip_dlen; /* length - in 32-bit words */ +}; + +enum fip_desc_type { + FIP_DT_PRI = 1, /* priority for forwarder selection */ + FIP_DT_MAC = 2, /* MAC address */ + FIP_DT_MAP_OUI = 3, /* FC-MAP OUI */ + FIP_DT_NAME = 4, /* switch name or node name */ + FIP_DT_FAB = 5, /* fabric descriptor */ + FIP_DT_FCOE_SIZE = 6, /* max FCoE frame size */ + FIP_DT_FLOGI = 7, /* FLOGI request or response */ + FIP_DT_FDISC = 8, /* FDISC request or response */ + FIP_DT_LOGO = 9, /* LOGO request or response */ + FIP_DT_ELP = 10, /* ELP request or response */ + FIP_DT_VN_ID = 11, /* VN_Node Identifier */ + FIP_DT_FKA = 12, /* advertisement keep-alive period */ + FIP_DT_VENDOR = 13, /* vendor ID */ + FIP_DT_VLAN = 14, /* vlan number */ + FIP_DT_LIMIT, /* max defined desc_type + 1 */ + FIP_DT_VENDOR_BASE = 128, /* first vendor-specific desc_type */ +}; + +/* + * FIP_DT_PRI - priority descriptor. + */ +struct fip_pri_desc { + struct fip_desc fd_desc; + __u8 fd_resvd; + __u8 fd_pri; /* FCF priority: higher is better */ +} __attribute__((packed)); + +/* + * FIP_DT_MAC - MAC address descriptor. + */ +struct fip_mac_desc { + struct fip_desc fd_desc; + __u8 fd_mac[ETH_ALEN]; +} __attribute__((packed)); + +/* + * FIP_DT_MAP - descriptor. + */ +struct fip_map_desc { + struct fip_desc fd_desc; + __u8 fd_resvd[3]; + __u8 fd_map[3]; +} __attribute__((packed)); + +/* + * FIP_DT_NAME descriptor. + */ +struct fip_wwn_desc { + struct fip_desc fd_desc; + __u8 fd_resvd[2]; + __be64 fd_wwn; /* 64-bit WWN, unaligned */ +} __attribute__((packed)); + +/* + * FIP_DT_FAB descriptor. + */ +struct fip_fab_desc { + struct fip_desc fd_desc; + __be16 fd_vfid; /* virtual fabric ID */ + __u8 fd_resvd; + __u8 fd_map[3]; /* FC-MAP value */ + __be64 fd_wwn; /* fabric name, unaligned */ +} __attribute__((packed)); + +/* + * FIP_DT_FCOE_SIZE descriptor. + */ +struct fip_size_desc { + struct fip_desc fd_desc; + __be16 fd_size; +} __attribute__((packed)); + +/* + * Descriptor that encapsulates an ELS or ILS frame. + * The encapsulated frame immediately follows this header, without + * SOF, EOF, or CRC. + */ +struct fip_encaps { + struct fip_desc fd_desc; + __u8 fd_resvd[2]; +} __attribute__((packed)); + +/* + * FIP_DT_VN_ID - VN_Node Identifier descriptor. + */ +struct fip_vn_desc { + struct fip_desc fd_desc; + __u8 fd_mac[ETH_ALEN]; + __u8 fd_resvd; + __u8 fd_fc_id[3]; + __be64 fd_wwpn; /* port name, unaligned */ +} __attribute__((packed)); + +/* + * FIP_DT_FKA - Advertisement keep-alive period. + */ +struct fip_fka_desc { + struct fip_desc fd_desc; + __u8 fd_resvd[2]; + __be32 fd_fka_period; /* adv./keep-alive period in mS */ +} __attribute__((packed)); + +/* + * FIP_DT_VENDOR descriptor. + */ +struct fip_vendor_desc { + struct fip_desc fd_desc; + __u8 fd_resvd[2]; + __u8 fd_vendor_id[8]; +} __attribute__((packed)); + +#endif /* _FC_FIP_H_ */ diff --git a/include/scsi/fc_transport_fcoe.h b/include/scsi/fc_transport_fcoe.h deleted file mode 100644 index 8dca2af14ff..00000000000 --- a/include/scsi/fc_transport_fcoe.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef FC_TRANSPORT_FCOE_H -#define FC_TRANSPORT_FCOE_H - -#include <linux/device.h> -#include <linux/netdevice.h> -#include <scsi/scsi_host.h> -#include <scsi/libfc.h> - -/** - * struct fcoe_transport - FCoE transport struct for generic transport - * for Ethernet devices as well as pure HBAs - * - * @name: name for thsi transport - * @bus: physical bus type (pci_bus_type) - * @driver: physical bus driver for network device - * @create: entry create function - * @destroy: exit destroy function - * @list: list of transports - */ -struct fcoe_transport { - char *name; - unsigned short vendor; - unsigned short device; - struct bus_type *bus; - struct device_driver *driver; - int (*create)(struct net_device *device); - int (*destroy)(struct net_device *device); - bool (*match)(struct net_device *device); - struct list_head list; - struct list_head devlist; - struct mutex devlock; -}; - -/** - * MODULE_ALIAS_FCOE_PCI - * - * some care must be taken with this, vendor and device MUST be a hex value - * preceded with 0x and with letters in lower case (0x12ab, not 0x12AB or 12AB) - */ -#define MODULE_ALIAS_FCOE_PCI(vendor, device) \ - MODULE_ALIAS("fcoe-pci-" __stringify(vendor) "-" __stringify(device)) - -/* exported funcs */ -int fcoe_transport_attach(struct net_device *netdev); -int fcoe_transport_release(struct net_device *netdev); -int fcoe_transport_register(struct fcoe_transport *t); -int fcoe_transport_unregister(struct fcoe_transport *t); -int fcoe_load_transport_driver(struct net_device *netdev); -int __init fcoe_transport_init(void); -int __exit fcoe_transport_exit(void); - -/* fcow_sw is the default transport */ -extern struct fcoe_transport fcoe_sw_transport; -#endif /* FC_TRANSPORT_FCOE_H */ diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index a70eafaad08..0303a6a098c 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -22,6 +22,7 @@ #include <linux/timer.h> #include <linux/if.h> +#include <linux/percpu.h> #include <scsi/scsi_transport.h> #include <scsi/scsi_transport_fc.h> @@ -661,7 +662,8 @@ struct fc_lport { unsigned long boot_time; struct fc_host_statistics host_stats; - struct fcoe_dev_stats *dev_stats[NR_CPUS]; + struct fcoe_dev_stats *dev_stats; + u64 wwpn; u64 wwnn; u8 retry_count; @@ -694,11 +696,6 @@ struct fc_lport { /* * FC_LPORT HELPER FUNCTIONS *****************************/ -static inline void *lport_priv(const struct fc_lport *lp) -{ - return (void *)(lp + 1); -} - static inline int fc_lport_test_ready(struct fc_lport *lp) { return lp->state == LPORT_ST_READY; @@ -722,6 +719,42 @@ static inline void fc_lport_state_enter(struct fc_lport *lp, lp->state = state; } +static inline int fc_lport_init_stats(struct fc_lport *lp) +{ + /* allocate per cpu stats block */ + lp->dev_stats = alloc_percpu(struct fcoe_dev_stats); + if (!lp->dev_stats) + return -ENOMEM; + return 0; +} + +static inline void fc_lport_free_stats(struct fc_lport *lp) +{ + free_percpu(lp->dev_stats); +} + +static inline struct fcoe_dev_stats *fc_lport_get_stats(struct fc_lport *lp) +{ + return per_cpu_ptr(lp->dev_stats, smp_processor_id()); +} + +static inline void *lport_priv(const struct fc_lport *lp) +{ + return (void *)(lp + 1); +} + +/** + * libfc_host_alloc() - Allocate a Scsi_Host with room for the fc_lport + * @sht: ptr to the scsi host templ + * @priv_size: size of private data after fc_lport + * + * Returns: ptr to Scsi_Host + */ +static inline struct Scsi_Host * +libfc_host_alloc(struct scsi_host_template *sht, int priv_size) +{ + return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size); +} /* * LOCAL PORT LAYER diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index c41f7d0c6ef..666cc131732 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -1,5 +1,6 @@ /* - * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. + * Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2007-2008 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -20,134 +21,144 @@ #ifndef _LIBFCOE_H #define _LIBFCOE_H +#include <linux/etherdevice.h> +#include <linux/if_ether.h> #include <linux/netdevice.h> #include <linux/skbuff.h> +#include <linux/workqueue.h> #include <scsi/fc/fc_fcoe.h> #include <scsi/libfc.h> /* - * this percpu struct for fcoe + * FIP tunable parameters. */ -struct fcoe_percpu_s { - int cpu; - struct task_struct *thread; - struct sk_buff_head fcoe_rx_list; - struct page *crc_eof_page; - int crc_eof_offset; +#define FCOE_CTLR_START_DELAY 2000 /* mS after first adv. to choose FCF */ +#define FCOE_CTRL_SOL_TOV 2000 /* min. solicitation interval (mS) */ +#define FCOE_CTLR_FCF_LIMIT 20 /* max. number of FCF entries */ + +/** + * enum fip_state - internal state of FCoE controller. + * @FIP_ST_DISABLED: controller has been disabled or not yet enabled. + * @FIP_ST_LINK_WAIT: the physical link is down or unusable. + * @FIP_ST_AUTO: determining whether to use FIP or non-FIP mode. + * @FIP_ST_NON_FIP: non-FIP mode selected. + * @FIP_ST_ENABLED: FIP mode selected. + */ +enum fip_state { + FIP_ST_DISABLED, + FIP_ST_LINK_WAIT, + FIP_ST_AUTO, + FIP_ST_NON_FIP, + FIP_ST_ENABLED, }; -/* - * the fcoe sw transport private data +/** + * struct fcoe_ctlr - FCoE Controller and FIP state. + * @state: internal FIP state for network link and FIP or non-FIP mode. + * @lp: &fc_lport: libfc local port. + * @sel_fcf: currently selected FCF, or NULL. + * @fcfs: list of discovered FCFs. + * @fcf_count: number of discovered FCF entries. + * @sol_time: time when a multicast solicitation was last sent. + * @sel_time: time after which to select an FCF. + * @port_ka_time: time of next port keep-alive. + * @ctlr_ka_time: time of next controller keep-alive. + * @timer: timer struct used for all delayed events. + * @link_work: &work_struct for doing FCF selection. + * @recv_work: &work_struct for receiving FIP frames. + * @fip_recv_list: list of received FIP frames. + * @user_mfs: configured maximum FC frame size, including FC header. + * @flogi_oxid: exchange ID of most recent fabric login. + * @flogi_count: number of FLOGI attempts in AUTO mode. + * @link: current link status for libfc. + * @last_link: last link state reported to libfc. + * @map_dest: use the FC_MAP mode for destination MAC addresses. + * @dest_addr: MAC address of the selected FC forwarder. + * @ctl_src_addr: the native MAC address of our local port. + * @data_src_addr: the assigned MAC address for the local port after FLOGI. + * @send: LLD-supplied function to handle sending of FIP Ethernet frames. + * @update_mac: LLD-supplied function to handle changes to MAC addresses. + * @lock: lock protecting this structure. + * + * This structure is used by all FCoE drivers. It contains information + * needed by all FCoE low-level drivers (LLDs) as well as internal state + * for FIP, and fields shared with the LLDS. */ -struct fcoe_softc { - struct list_head list; +struct fcoe_ctlr { + enum fip_state state; struct fc_lport *lp; - struct net_device *real_dev; - struct net_device *phys_dev; /* device with ethtool_ops */ - struct packet_type fcoe_packet_type; - struct sk_buff_head fcoe_pending_queue; - u8 fcoe_pending_queue_active; - + struct fcoe_fcf *sel_fcf; + struct list_head fcfs; + u16 fcf_count; + unsigned long sol_time; + unsigned long sel_time; + unsigned long port_ka_time; + unsigned long ctlr_ka_time; + struct timer_list timer; + struct work_struct link_work; + struct work_struct recv_work; + struct sk_buff_head fip_recv_list; + u16 user_mfs; + u16 flogi_oxid; + u8 flogi_count; + u8 link; + u8 last_link; + u8 map_dest; u8 dest_addr[ETH_ALEN]; u8 ctl_src_addr[ETH_ALEN]; u8 data_src_addr[ETH_ALEN]; - /* - * fcoe protocol address learning related stuff - */ - u16 flogi_oxid; - u8 flogi_progress; - u8 address_mode; -}; - -static inline struct net_device *fcoe_netdev( - const struct fc_lport *lp) -{ - return ((struct fcoe_softc *)lport_priv(lp))->real_dev; -} - -static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb) -{ - return (struct fcoe_hdr *)skb_network_header(skb); -} - -static inline int skb_fcoe_offset(const struct sk_buff *skb) -{ - return skb_network_offset(skb); -} - -static inline struct fc_frame_header *skb_fc_header(const struct sk_buff *skb) -{ - return (struct fc_frame_header *)skb_transport_header(skb); -} - -static inline int skb_fc_offset(const struct sk_buff *skb) -{ - return skb_transport_offset(skb); -} -static inline void skb_reset_fc_header(struct sk_buff *skb) -{ - skb_reset_network_header(skb); - skb_set_transport_header(skb, skb_network_offset(skb) + - sizeof(struct fcoe_hdr)); -} - -static inline bool skb_fc_is_data(const struct sk_buff *skb) -{ - return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_SOL_DATA; -} - -static inline bool skb_fc_is_cmd(const struct sk_buff *skb) -{ - return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD; -} + void (*send)(struct fcoe_ctlr *, struct sk_buff *); + void (*update_mac)(struct fcoe_ctlr *, u8 *old, u8 *new); + spinlock_t lock; +}; -static inline bool skb_fc_has_exthdr(const struct sk_buff *skb) -{ - return (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_VFTH) || - (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_IFRH) || - (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_ENCH); -} +/* + * struct fcoe_fcf - Fibre-Channel Forwarder. + * @list: list linkage. + * @time: system time (jiffies) when an advertisement was last received. + * @switch_name: WWN of switch from advertisement. + * @fabric_name: WWN of fabric from advertisement. + * @fc_map: FC_MAP value from advertisement. + * @fcf_mac: Ethernet address of the FCF. + * @vfid: virtual fabric ID. + * @pri: seletion priority, smaller values are better. + * @flags: flags received from advertisement. + * @fka_period: keep-alive period, in jiffies. + * + * A Fibre-Channel Forwarder (FCF) is the entity on the Ethernet that + * passes FCoE frames on to an FC fabric. This structure represents + * one FCF from which advertisements have been received. + * + * When looking up an FCF, @switch_name, @fabric_name, @fc_map, @vfid, and + * @fcf_mac together form the lookup key. + */ +struct fcoe_fcf { + struct list_head list; + unsigned long time; -static inline bool skb_fc_is_roff(const struct sk_buff *skb) -{ - return skb_fc_header(skb)->fh_f_ctl[2] & FC_FC_REL_OFF; -} + u64 switch_name; + u64 fabric_name; + u32 fc_map; + u16 vfid; + u8 fcf_mac[ETH_ALEN]; -static inline u16 skb_fc_oxid(const struct sk_buff *skb) -{ - return be16_to_cpu(skb_fc_header(skb)->fh_ox_id); -} + u8 pri; + u16 flags; + u32 fka_period; +}; -static inline u16 skb_fc_rxid(const struct sk_buff *skb) -{ - return be16_to_cpu(skb_fc_header(skb)->fh_rx_id); -} +/* FIP API functions */ +void fcoe_ctlr_init(struct fcoe_ctlr *); +void fcoe_ctlr_destroy(struct fcoe_ctlr *); +void fcoe_ctlr_link_up(struct fcoe_ctlr *); +int fcoe_ctlr_link_down(struct fcoe_ctlr *); +int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct sk_buff *); +void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *); +int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_frame *fp, u8 *sa); /* libfcoe funcs */ -int fcoe_reset(struct Scsi_Host *shost); -u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], - unsigned int scheme, unsigned int port); - -u32 fcoe_fc_crc(struct fc_frame *fp); -int fcoe_xmit(struct fc_lport *, struct fc_frame *); -int fcoe_rcv(struct sk_buff *, struct net_device *, - struct packet_type *, struct net_device *); - -int fcoe_percpu_receive_thread(void *arg); -void fcoe_clean_pending_queue(struct fc_lport *lp); -void fcoe_percpu_clean(struct fc_lport *lp); -void fcoe_watchdog(ulong vp); -int fcoe_link_ok(struct fc_lport *lp); - -struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); -int fcoe_hostlist_add(const struct fc_lport *); -int fcoe_hostlist_remove(const struct fc_lport *); - -struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int); +u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); -/* fcoe sw hba */ -int __init fcoe_sw_init(void); -int __exit fcoe_sw_exit(void); #endif /* _LIBFCOE_H */ |