提交 38567333 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-post-merge-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-post-merge-2.6:
  [SCSI] target: Add LIO target core v4.0.0-rc6
  [SCSI] sd,sr: kill compat SDEV_MEDIA_CHANGE event
  [SCSI] sd: implement sd_check_events()
此差异已折叠。
>>>>>>>>>> The TCM v4 fabric module script generator <<<<<<<<<<
Greetings all,
This document is intended to be a mini-HOWTO for using the tcm_mod_builder.py
script to generate a brand new functional TCM v4 fabric .ko module of your very own,
that once built can be immediately be loaded to start access the new TCM/ConfigFS
fabric skeleton, by simply using:
modprobe $TCM_NEW_MOD
mkdir -p /sys/kernel/config/target/$TCM_NEW_MOD
This script will create a new drivers/target/$TCM_NEW_MOD/, and will do the following
*) Generate new API callers for drivers/target/target_core_fabric_configs.c logic
->make_nodeacl(), ->drop_nodeacl(), ->make_tpg(), ->drop_tpg()
->make_wwn(), ->drop_wwn(). These are created into $TCM_NEW_MOD/$TCM_NEW_MOD_configfs.c
*) Generate basic infrastructure for loading/unloading LKMs and TCM/ConfigFS fabric module
using a skeleton struct target_core_fabric_ops API template.
*) Based on user defined T10 Proto_Ident for the new fabric module being built,
the TransportID / Initiator and Target WWPN related handlers for
SPC-3 persistent reservation are automatically generated in $TCM_NEW_MOD/$TCM_NEW_MOD_fabric.c
using drivers/target/target_core_fabric_lib.c logic.
*) NOP API calls for all other Data I/O path and fabric dependent attribute logic
in $TCM_NEW_MOD/$TCM_NEW_MOD_fabric.c
tcm_mod_builder.py depends upon the mandatory '-p $PROTO_IDENT' and '-m
$FABRIC_MOD_name' parameters, and actually running the script looks like:
target:/mnt/sdb/lio-core-2.6.git/Documentation/target# python tcm_mod_builder.py -p iSCSI -m tcm_nab5000
tcm_dir: /mnt/sdb/lio-core-2.6.git/Documentation/target/../../
Set fabric_mod_name: tcm_nab5000
Set fabric_mod_dir:
/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000
Using proto_ident: iSCSI
Creating fabric_mod_dir:
/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000
Writing file:
/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_base.h
Using tcm_mod_scan_fabric_ops:
/mnt/sdb/lio-core-2.6.git/Documentation/target/../../include/target/target_core_fabric_ops.h
Writing file:
/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_fabric.c
Writing file:
/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_fabric.h
Writing file:
/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_configfs.c
Writing file:
/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/Kbuild
Writing file:
/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/Kconfig
Would you like to add tcm_nab5000to drivers/target/Kbuild..? [yes,no]: yes
Would you like to add tcm_nab5000to drivers/target/Kconfig..? [yes,no]: yes
At the end of tcm_mod_builder.py. the script will ask to add the following
line to drivers/target/Kbuild:
obj-$(CONFIG_TCM_NAB5000) += tcm_nab5000/
and the same for drivers/target/Kconfig:
source "drivers/target/tcm_nab5000/Kconfig"
*) Run 'make menuconfig' and select the new CONFIG_TCM_NAB5000 item:
<M> TCM_NAB5000 fabric module
*) Build using 'make modules', once completed you will have:
target:/mnt/sdb/lio-core-2.6.git# ls -la drivers/target/tcm_nab5000/
total 1348
drwxr-xr-x 2 root root 4096 2010-10-05 03:23 .
drwxr-xr-x 9 root root 4096 2010-10-05 03:22 ..
-rw-r--r-- 1 root root 282 2010-10-05 03:22 Kbuild
-rw-r--r-- 1 root root 171 2010-10-05 03:22 Kconfig
-rw-r--r-- 1 root root 49 2010-10-05 03:23 modules.order
-rw-r--r-- 1 root root 738 2010-10-05 03:22 tcm_nab5000_base.h
-rw-r--r-- 1 root root 9096 2010-10-05 03:22 tcm_nab5000_configfs.c
-rw-r--r-- 1 root root 191200 2010-10-05 03:23 tcm_nab5000_configfs.o
-rw-r--r-- 1 root root 40504 2010-10-05 03:23 .tcm_nab5000_configfs.o.cmd
-rw-r--r-- 1 root root 5414 2010-10-05 03:22 tcm_nab5000_fabric.c
-rw-r--r-- 1 root root 2016 2010-10-05 03:22 tcm_nab5000_fabric.h
-rw-r--r-- 1 root root 190932 2010-10-05 03:23 tcm_nab5000_fabric.o
-rw-r--r-- 1 root root 40713 2010-10-05 03:23 .tcm_nab5000_fabric.o.cmd
-rw-r--r-- 1 root root 401861 2010-10-05 03:23 tcm_nab5000.ko
-rw-r--r-- 1 root root 265 2010-10-05 03:23 .tcm_nab5000.ko.cmd
-rw-r--r-- 1 root root 459 2010-10-05 03:23 tcm_nab5000.mod.c
-rw-r--r-- 1 root root 23896 2010-10-05 03:23 tcm_nab5000.mod.o
-rw-r--r-- 1 root root 22655 2010-10-05 03:23 .tcm_nab5000.mod.o.cmd
-rw-r--r-- 1 root root 379022 2010-10-05 03:23 tcm_nab5000.o
-rw-r--r-- 1 root root 211 2010-10-05 03:23 .tcm_nab5000.o.cmd
*) Load the new module, create a lun_0 configfs group, and add new TCM Core
IBLOCK backstore symlink to port:
target:/mnt/sdb/lio-core-2.6.git# insmod drivers/target/tcm_nab5000.ko
target:/mnt/sdb/lio-core-2.6.git# mkdir -p /sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0
target:/mnt/sdb/lio-core-2.6.git# cd /sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0/
target:/sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0# ln -s /sys/kernel/config/target/core/iblock_0/lvm_test0 nab5000_port
target:/sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0# cd -
target:/mnt/sdb/lio-core-2.6.git# tree /sys/kernel/config/target/nab5000/
/sys/kernel/config/target/nab5000/
|-- discovery_auth
|-- iqn.foo
| `-- tpgt_1
| |-- acls
| |-- attrib
| |-- lun
| | `-- lun_0
| | |-- alua_tg_pt_gp
| | |-- alua_tg_pt_offline
| | |-- alua_tg_pt_status
| | |-- alua_tg_pt_write_md
| | `-- nab5000_port -> ../../../../../../target/core/iblock_0/lvm_test0
| |-- np
| `-- param
`-- version
target:/mnt/sdb/lio-core-2.6.git# lsmod
Module Size Used by
tcm_nab5000 3935 4
iscsi_target_mod 193211 0
target_core_stgt 8090 0
target_core_pscsi 11122 1
target_core_file 9172 2
target_core_iblock 9280 1
target_core_mod 228575 31
tcm_nab5000,iscsi_target_mod,target_core_stgt,target_core_pscsi,target_core_file,target_core_iblock
libfc 73681 0
scsi_debug 56265 0
scsi_tgt 8666 1 target_core_stgt
configfs 20644 2 target_core_mod
----------------------------------------------------------------------
Future TODO items:
*) Add more T10 proto_idents
*) Make tcm_mod_dump_fabric_ops() smarter and generate function pointer
defs directly from include/target/target_core_fabric_ops.h:struct target_core_fabric_ops
structure members.
October 5th, 2010
Nicholas A. Bellinger <nab@linux-iscsi.org>
...@@ -26,6 +26,8 @@ source "drivers/ata/Kconfig" ...@@ -26,6 +26,8 @@ source "drivers/ata/Kconfig"
source "drivers/md/Kconfig" source "drivers/md/Kconfig"
source "drivers/target/Kconfig"
source "drivers/message/fusion/Kconfig" source "drivers/message/fusion/Kconfig"
source "drivers/firewire/Kconfig" source "drivers/firewire/Kconfig"
......
...@@ -46,6 +46,7 @@ obj-y += macintosh/ ...@@ -46,6 +46,7 @@ obj-y += macintosh/
obj-$(CONFIG_IDE) += ide/ obj-$(CONFIG_IDE) += ide/
obj-$(CONFIG_SCSI) += scsi/ obj-$(CONFIG_SCSI) += scsi/
obj-$(CONFIG_ATA) += ata/ obj-$(CONFIG_ATA) += ata/
obj-$(CONFIG_TARGET_CORE) += target/
obj-$(CONFIG_MTD) += mtd/ obj-$(CONFIG_MTD) += mtd/
obj-$(CONFIG_SPI) += spi/ obj-$(CONFIG_SPI) += spi/
obj-y += net/ obj-y += net/
......
...@@ -990,30 +990,51 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -990,30 +990,51 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
static void set_media_not_present(struct scsi_disk *sdkp) static void set_media_not_present(struct scsi_disk *sdkp)
{ {
if (sdkp->media_present)
sdkp->device->changed = 1;
if (sdkp->device->removable) {
sdkp->media_present = 0; sdkp->media_present = 0;
sdkp->capacity = 0; sdkp->capacity = 0;
sdkp->device->changed = 1; }
}
static int media_not_present(struct scsi_disk *sdkp,
struct scsi_sense_hdr *sshdr)
{
if (!scsi_sense_valid(sshdr))
return 0;
/* not invoked for commands that could return deferred errors */
switch (sshdr->sense_key) {
case UNIT_ATTENTION:
case NOT_READY:
/* medium not present */
if (sshdr->asc == 0x3A) {
set_media_not_present(sdkp);
return 1;
}
}
return 0;
} }
/** /**
* sd_media_changed - check if our medium changed * sd_check_events - check media events
* @disk: kernel device descriptor * @disk: kernel device descriptor
* @clearing: disk events currently being cleared
* *
* Returns 0 if not applicable or no change; 1 if change * Returns mask of DISK_EVENT_*.
* *
* Note: this function is invoked from the block subsystem. * Note: this function is invoked from the block subsystem.
**/ **/
static int sd_media_changed(struct gendisk *disk) static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
{ {
struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_disk *sdkp = scsi_disk(disk);
struct scsi_device *sdp = sdkp->device; struct scsi_device *sdp = sdkp->device;
struct scsi_sense_hdr *sshdr = NULL; struct scsi_sense_hdr *sshdr = NULL;
int retval; int retval;
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_media_changed\n")); SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n"));
if (!sdp->removable)
return 0;
/* /*
* If the device is offline, don't send any commands - just pretend as * If the device is offline, don't send any commands - just pretend as
...@@ -1043,40 +1064,32 @@ static int sd_media_changed(struct gendisk *disk) ...@@ -1043,40 +1064,32 @@ static int sd_media_changed(struct gendisk *disk)
sshdr); sshdr);
} }
if (retval) { /* failed to execute TUR, assume media not present */
if (host_byte(retval)) {
set_media_not_present(sdkp); set_media_not_present(sdkp);
goto out; goto out;
} }
if (media_not_present(sdkp, sshdr))
goto out;
/* /*
* For removable scsi disk we have to recognise the presence * For removable scsi disk we have to recognise the presence
* of a disk in the drive. This is kept in the struct scsi_disk * of a disk in the drive.
* struct and tested at open ! Daniel Roche (dan@lectra.fr)
*/ */
if (!sdkp->media_present)
sdp->changed = 1;
sdkp->media_present = 1; sdkp->media_present = 1;
out: out:
/* /*
* Report a media change under the following conditions: * sdp->changed is set under the following conditions:
*
* Medium is present now and wasn't present before.
* Medium wasn't present before and is present now.
* Medium was present at all times, but it changed while
* we weren't looking (sdp->changed is set).
* *
* If there was no medium before and there is no medium now then * Medium present state has changed in either direction.
* don't report a change, even if a medium was inserted and removed * Device has indicated UNIT_ATTENTION.
* while we weren't looking.
*/ */
retval = (sdkp->media_present != sdkp->previous_state ||
(sdkp->media_present && sdp->changed));
if (retval)
sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL);
sdkp->previous_state = sdkp->media_present;
/* sdp->changed indicates medium was changed or is not present */
sdp->changed = !sdkp->media_present;
kfree(sshdr); kfree(sshdr);
retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0;
sdp->changed = 0;
return retval; return retval;
} }
...@@ -1169,7 +1182,7 @@ static const struct block_device_operations sd_fops = { ...@@ -1169,7 +1182,7 @@ static const struct block_device_operations sd_fops = {
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_ioctl = sd_compat_ioctl, .compat_ioctl = sd_compat_ioctl,
#endif #endif
.media_changed = sd_media_changed, .check_events = sd_check_events,
.revalidate_disk = sd_revalidate_disk, .revalidate_disk = sd_revalidate_disk,
.unlock_native_capacity = sd_unlock_native_capacity, .unlock_native_capacity = sd_unlock_native_capacity,
}; };
...@@ -1312,23 +1325,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) ...@@ -1312,23 +1325,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
return good_bytes; return good_bytes;
} }
static int media_not_present(struct scsi_disk *sdkp,
struct scsi_sense_hdr *sshdr)
{
if (!scsi_sense_valid(sshdr))
return 0;
/* not invoked for commands that could return deferred errors */
if (sshdr->sense_key != NOT_READY &&
sshdr->sense_key != UNIT_ATTENTION)
return 0;
if (sshdr->asc != 0x3A) /* medium not present */
return 0;
set_media_not_present(sdkp);
return 1;
}
/* /*
* spinup disk - called only in sd_revalidate_disk() * spinup disk - called only in sd_revalidate_disk()
*/ */
...@@ -1503,7 +1499,7 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, ...@@ -1503,7 +1499,7 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
*/ */
if (sdp->removable && if (sdp->removable &&
sense_valid && sshdr->sense_key == NOT_READY) sense_valid && sshdr->sense_key == NOT_READY)
sdp->changed = 1; set_media_not_present(sdkp);
/* /*
* We used to set media_present to 0 here to indicate no media * We used to set media_present to 0 here to indicate no media
...@@ -2389,8 +2385,10 @@ static void sd_probe_async(void *data, async_cookie_t cookie) ...@@ -2389,8 +2385,10 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
gd->driverfs_dev = &sdp->sdev_gendev; gd->driverfs_dev = &sdp->sdev_gendev;
gd->flags = GENHD_FL_EXT_DEVT; gd->flags = GENHD_FL_EXT_DEVT;
if (sdp->removable) if (sdp->removable) {
gd->flags |= GENHD_FL_REMOVABLE; gd->flags |= GENHD_FL_REMOVABLE;
gd->events |= DISK_EVENT_MEDIA_CHANGE;
}
add_disk(gd); add_disk(gd);
sd_dif_config_host(sdkp); sd_dif_config_host(sdkp);
...@@ -2472,7 +2470,6 @@ static int sd_probe(struct device *dev) ...@@ -2472,7 +2470,6 @@ static int sd_probe(struct device *dev)
sdkp->disk = gd; sdkp->disk = gd;
sdkp->index = index; sdkp->index = index;
atomic_set(&sdkp->openers, 0); atomic_set(&sdkp->openers, 0);
sdkp->previous_state = 1;
if (!sdp->request_queue->rq_timeout) { if (!sdp->request_queue->rq_timeout) {
if (sdp->type != TYPE_MOD) if (sdp->type != TYPE_MOD)
......
...@@ -55,7 +55,6 @@ struct scsi_disk { ...@@ -55,7 +55,6 @@ struct scsi_disk {
u8 media_present; u8 media_present;
u8 write_prot; u8 write_prot;
u8 protection_type;/* Data Integrity Field */ u8 protection_type;/* Data Integrity Field */
unsigned previous_state : 1;
unsigned ATO : 1; /* state of disk ATO bit */ unsigned ATO : 1; /* state of disk ATO bit */
unsigned WCE : 1; /* state of disk WCE bit */ unsigned WCE : 1; /* state of disk WCE bit */
unsigned RCD : 1; /* state of disk RCD bit, unused */ unsigned RCD : 1; /* state of disk RCD bit, unused */
......
...@@ -249,10 +249,6 @@ static unsigned int sr_check_events(struct cdrom_device_info *cdi, ...@@ -249,10 +249,6 @@ static unsigned int sr_check_events(struct cdrom_device_info *cdi,
cd->device->changed = 0; cd->device->changed = 0;
} }
/* for backward compatibility */
if (events & DISK_EVENT_MEDIA_CHANGE)
sdev_evt_send_simple(cd->device, SDEV_EVT_MEDIA_CHANGE,
GFP_KERNEL);
return events; return events;
} }
......
menuconfig TARGET_CORE
tristate "Generic Target Core Mod (TCM) and ConfigFS Infrastructure"
depends on SCSI && BLOCK
select CONFIGFS_FS
default n
help
Say Y or M here to enable the TCM Storage Engine and ConfigFS enabled
control path for target_core_mod. This includes built-in TCM RAMDISK
subsystem logic for virtual LUN 0 access
if TARGET_CORE
config TCM_IBLOCK
tristate "TCM/IBLOCK Subsystem Plugin for Linux/BLOCK"
help
Say Y here to enable the TCM/IBLOCK subsystem plugin for non-buffered
access to Linux/Block devices using BIO
config TCM_FILEIO
tristate "TCM/FILEIO Subsystem Plugin for Linux/VFS"
help
Say Y here to enable the TCM/FILEIO subsystem plugin for buffered
access to Linux/VFS struct file or struct block_device
config TCM_PSCSI
tristate "TCM/pSCSI Subsystem Plugin for Linux/SCSI"
help
Say Y here to enable the TCM/pSCSI subsystem plugin for non-buffered
passthrough access to Linux/SCSI device
endif
EXTRA_CFLAGS += -I$(srctree)/drivers/target/ -I$(srctree)/drivers/scsi/
target_core_mod-y := target_core_configfs.o \
target_core_device.o \
target_core_fabric_configfs.o \
target_core_fabric_lib.o \
target_core_hba.o \
target_core_pr.o \
target_core_alua.o \
target_core_scdb.o \
target_core_tmr.o \
target_core_tpg.o \
target_core_transport.o \
target_core_cdb.o \
target_core_ua.o \
target_core_rd.o \
target_core_mib.o
obj-$(CONFIG_TARGET_CORE) += target_core_mod.o
# Subsystem modules
obj-$(CONFIG_TCM_IBLOCK) += target_core_iblock.o
obj-$(CONFIG_TCM_FILEIO) += target_core_file.o
obj-$(CONFIG_TCM_PSCSI) += target_core_pscsi.o
此差异已折叠。
#ifndef TARGET_CORE_ALUA_H
#define TARGET_CORE_ALUA_H
/*
* INQUIRY response data, TPGS Field
*
* from spc4r17 section 6.4.2 Table 135
*/
#define TPGS_NO_ALUA 0x00
#define TPGS_IMPLICT_ALUA 0x10
#define TPGS_EXPLICT_ALUA 0x20
/*
* ASYMMETRIC ACCESS STATE field
*
* from spc4r17 section 6.27 Table 245
*/
#define ALUA_ACCESS_STATE_ACTIVE_OPTMIZED 0x0
#define ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED 0x1
#define ALUA_ACCESS_STATE_STANDBY 0x2
#define ALUA_ACCESS_STATE_UNAVAILABLE 0x3
#define ALUA_ACCESS_STATE_OFFLINE 0xe
#define ALUA_ACCESS_STATE_TRANSITION 0xf
/*
* REPORT_TARGET_PORT_GROUP STATUS CODE
*
* from spc4r17 section 6.27 Table 246
*/
#define ALUA_STATUS_NONE 0x00
#define ALUA_STATUS_ALTERED_BY_EXPLICT_STPG 0x01
#define ALUA_STATUS_ALTERED_BY_IMPLICT_ALUA 0x02
/*
* From spc4r17, Table D.1: ASC and ASCQ Assignement
*/
#define ASCQ_04H_ALUA_STATE_TRANSITION 0x0a
#define ASCQ_04H_ALUA_TG_PT_STANDBY 0x0b
#define ASCQ_04H_ALUA_TG_PT_UNAVAILABLE 0x0c
#define ASCQ_04H_ALUA_OFFLINE 0x12
/*
* Used as the default for Active/NonOptimized delay (in milliseconds)
* This can also be changed via configfs on a per target port group basis..
*/
#define ALUA_DEFAULT_NONOP_DELAY_MSECS 100
#define ALUA_MAX_NONOP_DELAY_MSECS 10000 /* 10 seconds */
/*
* Used for implict and explict ALUA transitional delay, that is disabled
* by default, and is intended to be used for debugging client side ALUA code.
*/
#define ALUA_DEFAULT_TRANS_DELAY_MSECS 0
#define ALUA_MAX_TRANS_DELAY_MSECS 30000 /* 30 seconds */
/*
* Used by core_alua_update_tpg_primary_metadata() and
* core_alua_update_tpg_secondary_metadata()
*/
#define ALUA_METADATA_PATH_LEN 512
/*
* Used by core_alua_update_tpg_secondary_metadata()
*/
#define ALUA_SECONDARY_METADATA_WWN_LEN 256
extern struct kmem_cache *t10_alua_lu_gp_cache;
extern struct kmem_cache *t10_alua_lu_gp_mem_cache;
extern struct kmem_cache *t10_alua_tg_pt_gp_cache;
extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache;
extern int core_emulate_report_target_port_groups(struct se_cmd *);
extern int core_emulate_set_target_port_groups(struct se_cmd *);
extern int core_alua_check_nonop_delay(struct se_cmd *);
extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *,
struct se_device *, struct se_port *,
struct se_node_acl *, int, int);
extern char *core_alua_dump_status(int);
extern struct t10_alua_lu_gp *core_alua_allocate_lu_gp(const char *, int);
extern int core_alua_set_lu_gp_id(struct t10_alua_lu_gp *, u16);
extern void core_alua_free_lu_gp(struct t10_alua_lu_gp *);
extern void core_alua_free_lu_gp_mem(struct se_device *);
extern struct t10_alua_lu_gp *core_alua_get_lu_gp_by_name(const char *);
extern void core_alua_put_lu_gp_from_name(struct t10_alua_lu_gp *);
extern void __core_alua_attach_lu_gp_mem(struct t10_alua_lu_gp_member *,
struct t10_alua_lu_gp *);
extern void __core_alua_drop_lu_gp_mem(struct t10_alua_lu_gp_member *,
struct t10_alua_lu_gp *);
extern void core_alua_drop_lu_gp_dev(struct se_device *);
extern struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(
struct se_subsystem_dev *, const char *, int);
extern int core_alua_set_tg_pt_gp_id(struct t10_alua_tg_pt_gp *, u16);
extern struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem(
struct se_port *);
extern void core_alua_free_tg_pt_gp(struct t10_alua_tg_pt_gp *);
extern void core_alua_free_tg_pt_gp_mem(struct se_port *);
extern void __core_alua_attach_tg_pt_gp_mem(struct t10_alua_tg_pt_gp_member *,
struct t10_alua_tg_pt_gp *);
extern ssize_t core_alua_show_tg_pt_gp_info(struct se_port *, char *);
extern ssize_t core_alua_store_tg_pt_gp_info(struct se_port *, const char *,
size_t);
extern ssize_t core_alua_show_access_type(struct t10_alua_tg_pt_gp *, char *);
extern ssize_t core_alua_store_access_type(struct t10_alua_tg_pt_gp *,
const char *, size_t);
extern ssize_t core_alua_show_nonop_delay_msecs(struct t10_alua_tg_pt_gp *,
char *);
extern ssize_t core_alua_store_nonop_delay_msecs(struct t10_alua_tg_pt_gp *,
const char *, size_t);
extern ssize_t core_alua_show_trans_delay_msecs(struct t10_alua_tg_pt_gp *,
char *);
extern ssize_t core_alua_store_trans_delay_msecs(struct t10_alua_tg_pt_gp *,
const char *, size_t);
extern ssize_t core_alua_show_preferred_bit(struct t10_alua_tg_pt_gp *,
char *);
extern ssize_t core_alua_store_preferred_bit(struct t10_alua_tg_pt_gp *,
const char *, size_t);
extern ssize_t core_alua_show_offline_bit(struct se_lun *, char *);
extern ssize_t core_alua_store_offline_bit(struct se_lun *, const char *,
size_t);
extern ssize_t core_alua_show_secondary_status(struct se_lun *, char *);
extern ssize_t core_alua_store_secondary_status(struct se_lun *,
const char *, size_t);
extern ssize_t core_alua_show_secondary_write_metadata(struct se_lun *,
char *);
extern ssize_t core_alua_store_secondary_write_metadata(struct se_lun *,
const char *, size_t);
extern int core_setup_alua(struct se_device *, int);
#endif /* TARGET_CORE_ALUA_H */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
#ifndef TARGET_CORE_FILE_H
#define TARGET_CORE_FILE_H
#define FD_VERSION "4.0"
#define FD_MAX_DEV_NAME 256
/* Maximum queuedepth for the FILEIO HBA */
#define FD_HBA_QUEUE_DEPTH 256
#define FD_DEVICE_QUEUE_DEPTH 32
#define FD_MAX_DEVICE_QUEUE_DEPTH 128
#define FD_BLOCKSIZE 512
#define FD_MAX_SECTORS 1024
#define RRF_EMULATE_CDB 0x01
#define RRF_GOT_LBA 0x02
struct fd_request {
struct se_task fd_task;
/* SCSI CDB from iSCSI Command PDU */
unsigned char fd_scsi_cdb[TCM_MAX_COMMAND_SIZE];
/* FILEIO device */
struct fd_dev *fd_dev;
} ____cacheline_aligned;
#define FBDF_HAS_PATH 0x01
#define FBDF_HAS_SIZE 0x02
#define FDBD_USE_BUFFERED_IO 0x04
struct fd_dev {
u32 fbd_flags;
unsigned char fd_dev_name[FD_MAX_DEV_NAME];
/* Unique Ramdisk Device ID in Ramdisk HBA */
u32 fd_dev_id;
/* Number of SG tables in sg_table_array */
u32 fd_table_count;
u32 fd_queue_depth;
u32 fd_block_size;
unsigned long long fd_dev_size;
struct file *fd_file;
/* FILEIO HBA device is connected to */
struct fd_host *fd_host;
} ____cacheline_aligned;
struct fd_host {
u32 fd_host_dev_id_count;
/* Unique FILEIO Host ID */
u32 fd_host_id;
} ____cacheline_aligned;
#endif /* TARGET_CORE_FILE_H */
/*******************************************************************************
* Filename: target_core_hba.c
*
* This file copntains the iSCSI HBA Transport related functions.
*
* Copyright (c) 2003, 2004, 2005 PyX Technologies, Inc.
* Copyright (c) 2005, 2006, 2007 SBE, Inc.
* Copyright (c) 2007-2010 Rising Tide Systems
* Copyright (c) 2008-2010 Linux-iSCSI.org
*
* Nicholas A. Bellinger <nab@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
******************************************************************************/
#include <linux/net.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
#include <linux/in.h>
#include <net/sock.h>
#include <net/tcp.h>
#include <target/target_core_base.h>
#include <target/target_core_device.h>
#include <target/target_core_device.h>
#include <target/target_core_tpg.h>
#include <target/target_core_transport.h>
#include "target_core_hba.h"
static LIST_HEAD(subsystem_list);
static DEFINE_MUTEX(subsystem_mutex);
int transport_subsystem_register(struct se_subsystem_api *sub_api)
{
struct se_subsystem_api *s;
INIT_LIST_HEAD(&sub_api->sub_api_list);
mutex_lock(&subsystem_mutex);
list_for_each_entry(s, &subsystem_list, sub_api_list) {
if (!(strcmp(s->name, sub_api->name))) {
printk(KERN_ERR "%p is already registered with"
" duplicate name %s, unable to process"
" request\n", s, s->name);
mutex_unlock(&subsystem_mutex);
return -EEXIST;
}
}
list_add_tail(&sub_api->sub_api_list, &subsystem_list);
mutex_unlock(&subsystem_mutex);
printk(KERN_INFO "TCM: Registered subsystem plugin: %s struct module:"
" %p\n", sub_api->name, sub_api->owner);
return 0;
}
EXPORT_SYMBOL(transport_subsystem_register);
void transport_subsystem_release(struct se_subsystem_api *sub_api)
{
mutex_lock(&subsystem_mutex);
list_del(&sub_api->sub_api_list);
mutex_unlock(&subsystem_mutex);
}
EXPORT_SYMBOL(transport_subsystem_release);
static struct se_subsystem_api *core_get_backend(const char *sub_name)
{
struct se_subsystem_api *s;
mutex_lock(&subsystem_mutex);
list_for_each_entry(s, &subsystem_list, sub_api_list) {
if (!strcmp(s->name, sub_name))
goto found;
}
mutex_unlock(&subsystem_mutex);
return NULL;
found:
if (s->owner && !try_module_get(s->owner))
s = NULL;
mutex_unlock(&subsystem_mutex);
return s;
}
struct se_hba *
core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags)
{
struct se_hba *hba;
int ret = 0;
hba = kzalloc(sizeof(*hba), GFP_KERNEL);
if (!hba) {
printk(KERN_ERR "Unable to allocate struct se_hba\n");
return ERR_PTR(-ENOMEM);
}
INIT_LIST_HEAD(&hba->hba_dev_list);
spin_lock_init(&hba->device_lock);
spin_lock_init(&hba->hba_queue_lock);
mutex_init(&hba->hba_access_mutex);
hba->hba_index = scsi_get_new_index(SCSI_INST_INDEX);
hba->hba_flags |= hba_flags;
atomic_set(&hba->max_queue_depth, 0);
atomic_set(&hba->left_queue_depth, 0);
hba->transport = core_get_backend(plugin_name);
if (!hba->transport) {
ret = -EINVAL;
goto out_free_hba;
}
ret = hba->transport->attach_hba(hba, plugin_dep_id);
if (ret < 0)
goto out_module_put;
spin_lock(&se_global->hba_lock);
hba->hba_id = se_global->g_hba_id_counter++;
list_add_tail(&hba->hba_list, &se_global->g_hba_list);
spin_unlock(&se_global->hba_lock);
printk(KERN_INFO "CORE_HBA[%d] - Attached HBA to Generic Target"
" Core\n", hba->hba_id);
return hba;
out_module_put:
if (hba->transport->owner)
module_put(hba->transport->owner);
hba->transport = NULL;
out_free_hba:
kfree(hba);
return ERR_PTR(ret);
}
int
core_delete_hba(struct se_hba *hba)
{
struct se_device *dev, *dev_tmp;
spin_lock(&hba->device_lock);
list_for_each_entry_safe(dev, dev_tmp, &hba->hba_dev_list, dev_list) {
se_clear_dev_ports(dev);
spin_unlock(&hba->device_lock);
se_release_device_for_hba(dev);
spin_lock(&hba->device_lock);
}
spin_unlock(&hba->device_lock);
hba->transport->detach_hba(hba);
spin_lock(&se_global->hba_lock);
list_del(&hba->hba_list);
spin_unlock(&se_global->hba_lock);
printk(KERN_INFO "CORE_HBA[%d] - Detached HBA from Generic Target"
" Core\n", hba->hba_id);
if (hba->transport->owner)
module_put(hba->transport->owner);
hba->transport = NULL;
kfree(hba);
return 0;
}
#ifndef TARGET_CORE_HBA_H
#define TARGET_CORE_HBA_H
extern struct se_hba *core_alloc_hba(const char *, u32, u32);
extern int core_delete_hba(struct se_hba *);
#endif /* TARGET_CORE_HBA_H */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
#ifndef TARGET_CORE_SCDB_H
#define TARGET_CORE_SCDB_H
extern void split_cdb_XX_6(unsigned long long, u32 *, unsigned char *);
extern void split_cdb_XX_10(unsigned long long, u32 *, unsigned char *);
extern void split_cdb_XX_12(unsigned long long, u32 *, unsigned char *);
extern void split_cdb_XX_16(unsigned long long, u32 *, unsigned char *);
extern void split_cdb_XX_32(unsigned long long, u32 *, unsigned char *);
#endif /* TARGET_CORE_SCDB_H */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册