You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(19) |
Nov
(18) |
Dec
(34) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(14) |
Feb
(14) |
Mar
(3) |
Apr
(10) |
May
(10) |
Jun
(17) |
Jul
(15) |
Aug
(24) |
Sep
(24) |
Oct
(11) |
Nov
(13) |
Dec
(15) |
2008 |
Jan
(10) |
Feb
(46) |
Mar
(20) |
Apr
(42) |
May
(44) |
Jun
(22) |
Jul
(59) |
Aug
(8) |
Sep
(15) |
Oct
(52) |
Nov
(30) |
Dec
(38) |
2009 |
Jan
(27) |
Feb
(27) |
Mar
(47) |
Apr
(85) |
May
(74) |
Jun
(41) |
Jul
(70) |
Aug
(64) |
Sep
(97) |
Oct
(147) |
Nov
(67) |
Dec
(48) |
2010 |
Jan
(68) |
Feb
(33) |
Mar
(53) |
Apr
(98) |
May
(55) |
Jun
(71) |
Jul
(99) |
Aug
(132) |
Sep
(291) |
Oct
(220) |
Nov
(344) |
Dec
(300) |
2011 |
Jan
(57) |
Feb
(25) |
Mar
(59) |
Apr
(104) |
May
(60) |
Jun
(155) |
Jul
(143) |
Aug
(43) |
Sep
(53) |
Oct
(20) |
Nov
(35) |
Dec
(103) |
2012 |
Jan
(62) |
Feb
(43) |
Mar
(29) |
Apr
(80) |
May
(75) |
Jun
(61) |
Jul
(52) |
Aug
(58) |
Sep
(33) |
Oct
(32) |
Nov
(69) |
Dec
(37) |
2013 |
Jan
(77) |
Feb
(28) |
Mar
(52) |
Apr
(18) |
May
(37) |
Jun
(21) |
Jul
(22) |
Aug
(55) |
Sep
(29) |
Oct
(74) |
Nov
(50) |
Dec
(44) |
2014 |
Jan
(77) |
Feb
(62) |
Mar
(81) |
Apr
(99) |
May
(59) |
Jun
(95) |
Jul
(55) |
Aug
(34) |
Sep
(78) |
Oct
(33) |
Nov
(48) |
Dec
(51) |
2015 |
Jan
(56) |
Feb
(120) |
Mar
(37) |
Apr
(15) |
May
(22) |
Jun
(196) |
Jul
(54) |
Aug
(33) |
Sep
(32) |
Oct
(42) |
Nov
(149) |
Dec
(61) |
2016 |
Jan
(15) |
Feb
(26) |
Mar
(37) |
Apr
(27) |
May
(14) |
Jun
(11) |
Jul
(13) |
Aug
(64) |
Sep
(2) |
Oct
(36) |
Nov
(18) |
Dec
(46) |
2017 |
Jan
(6) |
Feb
(1) |
Mar
(2) |
Apr
(50) |
May
(42) |
Jun
(11) |
Jul
(4) |
Aug
(12) |
Sep
(11) |
Oct
(21) |
Nov
(15) |
Dec
(42) |
2018 |
Jan
(33) |
Feb
(27) |
Mar
(20) |
Apr
(5) |
May
(4) |
Jun
(1) |
Jul
(42) |
Aug
(29) |
Sep
(11) |
Oct
(40) |
Nov
(312) |
Dec
(18) |
2019 |
Jan
(44) |
Feb
(98) |
Mar
(125) |
Apr
(160) |
May
(123) |
Jun
(33) |
Jul
(56) |
Aug
(81) |
Sep
(24) |
Oct
(23) |
Nov
(52) |
Dec
(86) |
2020 |
Jan
(6) |
Feb
(17) |
Mar
(62) |
Apr
(21) |
May
(118) |
Jun
(42) |
Jul
(52) |
Aug
(62) |
Sep
(20) |
Oct
(5) |
Nov
(23) |
Dec
(111) |
2021 |
Jan
(31) |
Feb
(8) |
Mar
(26) |
Apr
(13) |
May
(54) |
Jun
(31) |
Jul
(17) |
Aug
(10) |
Sep
(83) |
Oct
(8) |
Nov
(21) |
Dec
(33) |
2022 |
Jan
(67) |
Feb
(11) |
Mar
(4) |
Apr
(46) |
May
(12) |
Jun
(17) |
Jul
(19) |
Aug
(7) |
Sep
(53) |
Oct
(14) |
Nov
(29) |
Dec
(22) |
2023 |
Jan
(20) |
Feb
(4) |
Mar
(37) |
Apr
(25) |
May
(15) |
Jun
(20) |
Jul
(38) |
Aug
(1) |
Sep
(1) |
Oct
(34) |
Nov
|
Dec
(8) |
2024 |
Jan
(15) |
Feb
(10) |
Mar
|
Apr
(4) |
May
(23) |
Jun
|
Jul
(8) |
Aug
(2) |
Sep
(18) |
Oct
(1) |
Nov
(18) |
Dec
(15) |
2025 |
Jan
(5) |
Feb
(1) |
Mar
(7) |
Apr
(4) |
May
(18) |
Jun
(7) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <vl...@us...> - 2006-11-02 18:39:04
|
Revision: 22 http://svn.sourceforge.net/scst/?rev=22&view=rev Author: vlnb Date: 2006-11-02 02:54:10 -0800 (Thu, 02 Nov 2006) Log Message: ----------- - Fixes wrongly set context in scst_tgt_cmd_done() - Fixes retries for stateful devices Modified Paths: -------------- trunk/scst/include/scsi_tgt.h trunk/scst/src/dev_handlers/scst_changer.c trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_fileio.c trunk/scst/src/dev_handlers/scst_processor.c trunk/scst/src/dev_handlers/scst_raid.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2006-11-02 10:43:29 UTC (rev 21) +++ trunk/scst/include/scsi_tgt.h 2006-11-02 10:54:10 UTC (rev 22) @@ -227,10 +227,9 @@ #define SCST_DEV_TM_NOT_COMPLETED 1 /************************************************************* - ** Default timeout and retries count for cmd's CDB execution - ** by SCSI mid-level (cmd's "timeout" and "retries" fields). + ** Default timeout for cmd's CDB execution + ** by SCSI mid-level (cmd's "timeout" field). *************************************************************/ -#define SCST_DEFAULT_RETRIES 5 #define SCST_DEFAULT_TIMEOUT (30*HZ) /************************************************************* Modified: trunk/scst/src/dev_handlers/scst_changer.c =================================================================== --- trunk/scst/src/dev_handlers/scst_changer.c 2006-11-02 10:43:29 UTC (rev 21) +++ trunk/scst/src/dev_handlers/scst_changer.c 2006-11-02 10:54:10 UTC (rev 22) @@ -141,6 +141,8 @@ * based on info_cdb, therefore change them only if necessary */ + cmd->retries = 1; + if (info_cdb->flags & SCST_LONG_TIMEOUT) { cmd->timeout = CHANGER_LONG_TIMEOUT; } else { Modified: trunk/scst/src/dev_handlers/scst_disk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_disk.c 2006-11-02 10:43:29 UTC (rev 21) +++ trunk/scst/src/dev_handlers/scst_disk.c 2006-11-02 10:54:10 UTC (rev 22) @@ -58,7 +58,7 @@ exec: disk_exec, \ } -#define DISK_RETRIES 2 +#define DISK_RETRIES 5 #define DISK_SMALL_TIMEOUT (3 * HZ) #define DISK_REG_TIMEOUT (60 * HZ) #define DISK_LONG_TIMEOUT (3600 * HZ) @@ -294,6 +294,8 @@ * based on info_cdb, therefore change them only if necessary */ + cmd->retries = DISK_RETRIES; + if (info_cdb->flags & SCST_SMALL_TIMEOUT) { cmd->timeout = DISK_SMALL_TIMEOUT; } else if (info_cdb->flags & SCST_LONG_TIMEOUT) { Modified: trunk/scst/src/dev_handlers/scst_fileio.c =================================================================== --- trunk/scst/src/dev_handlers/scst_fileio.c 2006-11-02 10:43:29 UTC (rev 21) +++ trunk/scst/src/dev_handlers/scst_fileio.c 2006-11-02 10:54:10 UTC (rev 22) @@ -1725,7 +1725,7 @@ nblocks = virt_dev->nblocks; memset(buffer, 0, sizeof(buffer)); - data64 = (uint64_t *)buffer; + data64 = (uint64_t*)buffer; data64[0] = cpu_to_be64(nblocks - 1); buffer[8] = (blocksize >> (BYTE * 3)) & 0xFF; buffer[9] = (blocksize >> (BYTE * 2)) & 0xFF; Modified: trunk/scst/src/dev_handlers/scst_processor.c =================================================================== --- trunk/scst/src/dev_handlers/scst_processor.c 2006-11-02 10:43:29 UTC (rev 21) +++ trunk/scst/src/dev_handlers/scst_processor.c 2006-11-02 10:54:10 UTC (rev 22) @@ -141,6 +141,8 @@ * based on info_cdb, therefore change them only if necessary */ + cmd->retries = 1; + if (info_cdb->flags & SCST_LONG_TIMEOUT) { cmd->timeout = PROCESSOR_LONG_TIMEOUT; } else { Modified: trunk/scst/src/dev_handlers/scst_raid.c =================================================================== --- trunk/scst/src/dev_handlers/scst_raid.c 2006-11-02 10:43:29 UTC (rev 21) +++ trunk/scst/src/dev_handlers/scst_raid.c 2006-11-02 10:54:10 UTC (rev 22) @@ -141,6 +141,8 @@ * based on info_cdb, therefore change them only if necessary */ + cmd->retries = 1; + if (info_cdb->flags & SCST_LONG_TIMEOUT) { cmd->timeout = RAID_LONG_TIMEOUT; } else { Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2006-11-02 10:43:29 UTC (rev 21) +++ trunk/scst/src/dev_handlers/scst_tape.c 2006-11-02 10:54:10 UTC (rev 22) @@ -305,6 +305,8 @@ * based on info_cdb, therefore change them only if necessary */ + cmd->retries = 1; + if (info_cdb->flags & SCST_SMALL_TIMEOUT) { cmd->timeout = TAPE_SMALL_TIMEOUT; } else if (info_cdb->flags & SCST_LONG_TIMEOUT) { Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2006-11-02 10:43:29 UTC (rev 21) +++ trunk/scst/src/scst_lib.c 2006-11-02 10:54:10 UTC (rev 22) @@ -949,7 +949,7 @@ cmd->queue_type = SCST_CMD_QUEUE_UNTAGGED; cmd->timeout = SCST_DEFAULT_TIMEOUT; - cmd->retries = SCST_DEFAULT_RETRIES; + cmd->retries = 1; cmd->data_len = -1; cmd->tgt_resp_flags = SCST_TSC_FLAG_STATUS; cmd->resp_data_len = -1; Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2006-11-02 10:43:29 UTC (rev 21) +++ trunk/scst/src/scst_priv.h 2006-11-02 10:54:10 UTC (rev 22) @@ -102,9 +102,15 @@ #define SCST_CMD_MEM_TIMEOUT (120*HZ) static inline int scst_get_context(void) { - /* Be overinsured */ - return (in_atomic() || in_interrupt()) ? SCST_CONTEXT_DIRECT_ATOMIC : - SCST_CONTEXT_DIRECT; + if (in_irq()) + return SCST_CONTEXT_TASKLET; + if (in_softirq()) + return SCST_CONTEXT_DIRECT_ATOMIC; + if (in_interrupt()) /* Is it possible? */ + return SCST_CONTEXT_THREAD; + if (in_atomic()) + return SCST_CONTEXT_DIRECT_ATOMIC; + return SCST_CONTEXT_DIRECT; } #define SCST_MGMT_CMD_CACHE_STRING "scst_mgmt_cmd" @@ -250,6 +256,8 @@ return; } +void scst_proccess_redirect_cmd(struct scst_cmd *cmd, int context, + int check_retries); void scst_check_retries(struct scst_tgt *tgt, int processible_env); void scst_tgt_retry_timer_fn(unsigned long arg); Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2006-11-02 10:43:29 UTC (rev 21) +++ trunk/scst/src/scst_targ.c 2006-11-02 10:54:10 UTC (rev 22) @@ -744,12 +744,65 @@ goto out; } -void scst_rx_data(struct scst_cmd *cmd, int status, int pref_context) +void scst_proccess_redirect_cmd(struct scst_cmd *cmd, int context, + int check_retries) { unsigned long flags; + int rc; TRACE_ENTRY(); + TRACE_DBG("Context: %d", context); + + switch(context) { + case SCST_CONTEXT_DIRECT: + case SCST_CONTEXT_DIRECT_ATOMIC: + if (check_retries) + scst_check_retries(cmd->tgt, 0); + cmd->non_atomic_only = 0; + rc = __scst_process_active_cmd(cmd, context, 0); + if (rc == SCST_CMD_STATE_RES_NEED_THREAD) + goto out_thread; + break; + + default: + PRINT_ERROR_PR("Context %x is unknown, using the thread one", + context); + /* go through */ + case SCST_CONTEXT_THREAD: + if (check_retries) + scst_check_retries(cmd->tgt, 1); + goto out_thread; + + case SCST_CONTEXT_TASKLET: + if (check_retries) + scst_check_retries(cmd->tgt, 1); + cmd->non_atomic_only = 0; + spin_lock_irqsave(&scst_list_lock, flags); + TRACE_DBG("Moving cmd %p to active cmd list", cmd); + list_move_tail(&cmd->cmd_list_entry, &scst_active_cmd_list); + spin_unlock_irqrestore(&scst_list_lock, flags); + scst_schedule_tasklet(); + break; + } +out: + TRACE_EXIT(); + return; + +out_thread: + cmd->non_atomic_only = 1; + spin_lock_irqsave(&scst_list_lock, flags); + TRACE_DBG("Moving cmd %p to active cmd list", cmd); + list_move_tail(&cmd->cmd_list_entry, &scst_active_cmd_list); + spin_unlock_irqrestore(&scst_list_lock, flags); + wake_up(&scst_list_waitQ); + goto out; +} + +void scst_rx_data(struct scst_cmd *cmd, int status, int pref_context) +{ + TRACE_ENTRY(); + TRACE_DBG("Preferred context: %d", pref_context); TRACE(TRACE_SCSI, "tag=%d status=%#x", scst_cmd_get_tag(cmd), status); cmd->non_atomic_only = 0; @@ -783,41 +836,13 @@ default: PRINT_ERROR_PR("scst_rx_data() received unknown status %x", - status); + status); + cmd->state = SCST_CMD_STATE_DEV_DONE; break; } - switch (pref_context) { - case SCST_CONTEXT_DIRECT: - case SCST_CONTEXT_DIRECT_ATOMIC: - scst_check_retries(cmd->tgt, 0); - __scst_process_active_cmd(cmd, pref_context, 0); - break; + scst_proccess_redirect_cmd(cmd, pref_context, 1); - default: - PRINT_ERROR_PR("Context %x is undefined, using thread one", - pref_context); - /* go through */ - case SCST_CONTEXT_THREAD: - spin_lock_irqsave(&scst_list_lock, flags); - TRACE_DBG("Moving cmd %p to active cmd list", cmd); - list_move_tail(&cmd->cmd_list_entry, &scst_active_cmd_list); - cmd->non_atomic_only = 1; - spin_unlock_irqrestore(&scst_list_lock, flags); - scst_check_retries(cmd->tgt, 1); - wake_up(&scst_list_waitQ); - break; - - case SCST_CONTEXT_TASKLET: - spin_lock_irqsave(&scst_list_lock, flags); - TRACE_DBG("Moving cmd %p to active cmd list", cmd); - list_move_tail(&cmd->cmd_list_entry, &scst_active_cmd_list); - spin_unlock_irqrestore(&scst_list_lock, flags); - scst_schedule_tasklet(); - scst_check_retries(cmd->tgt, 0); - break; - } - TRACE_EXIT(); return; } @@ -1088,7 +1113,7 @@ cmd->state = next_state; cmd->non_atomic_only = 0; - __scst_process_active_cmd(cmd, scst_get_context(), 0); + scst_proccess_redirect_cmd(cmd, scst_get_context(), 0); out: TRACE_EXIT(); @@ -1124,7 +1149,7 @@ cmd->state = next_state; cmd->non_atomic_only = 0; - __scst_process_active_cmd(cmd, scst_get_context(), 0); + scst_proccess_redirect_cmd(cmd, scst_get_context(), 0); out: TRACE_EXIT(); @@ -1153,7 +1178,7 @@ cmd->sg_cnt, sg, (void*)sg[0].page); for(i = 0; i < cmd->sg_cnt; ++i) { TRACE_BUFF_FLAG(TRACE_RECV_TOP, - "Exec'd sg:", page_address(sg[i].page), + "Exec'd sg", page_address(sg[i].page), sg[i].length); } } @@ -1184,7 +1209,7 @@ cmd->state = next_state; cmd->non_atomic_only = 0; - __scst_process_active_cmd(cmd, scst_get_context(), 0); + scst_proccess_redirect_cmd(cmd, scst_get_context(), 0); TRACE_EXIT(); return; @@ -2175,7 +2200,7 @@ cmd->sg_cnt, sg, (void*)sg[0].page); for(i = 0; i < cmd->sg_cnt; ++i) { TRACE_BUFF_FLAG(TRACE_SEND_BOT, - "Xmitting sg:", page_address(sg[i].page), + "Xmitting sg", page_address(sg[i].page), sg[i].length); } } @@ -2277,48 +2302,13 @@ void scst_tgt_cmd_done(struct scst_cmd *cmd) { - int res = 0; - unsigned long flags; - int context; - TRACE_ENTRY(); BUG_ON(cmd->state != SCST_CMD_STATE_XMIT_WAIT); - if (in_irq()) - context = SCST_CONTEXT_TASKLET; - else - context = scst_get_context(); - - TRACE_DBG("Context: %d", context); - cmd->non_atomic_only = 0; cmd->state = SCST_CMD_STATE_FINISHED; + scst_proccess_redirect_cmd(cmd, scst_get_context(), 1); - switch (context) { - case SCST_CONTEXT_DIRECT: - case SCST_CONTEXT_DIRECT_ATOMIC: - flags = 0; - scst_check_retries(cmd->tgt, 0); - res = __scst_process_active_cmd(cmd, context, 0); - BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD); - break; - - case SCST_CONTEXT_TASKLET: - { - spin_lock_irqsave(&scst_list_lock, flags); - TRACE_DBG("Moving cmd %p to active cmd list", cmd); - list_move_tail(&cmd->cmd_list_entry, &scst_active_cmd_list); - spin_unlock_irqrestore(&scst_list_lock, flags); - scst_schedule_tasklet(); - scst_check_retries(cmd->tgt, 0); - break; - } - - default: - BUG(); - break; - } - TRACE_EXIT(); return; } @@ -2577,6 +2567,14 @@ TRACE_ENTRY(); +#ifdef EXTRACHECKS + { + int c = (context & ~SCST_PROCESSIBLE_ENV); + WARN_ON((c != SCST_CONTEXT_DIRECT_ATOMIC) && + (c != SCST_CONTEXT_DIRECT)); + } +#endif + tm_dbg_check_released_cmds(); restart: @@ -2649,7 +2647,7 @@ scst_do_job_init(&scst_init_cmd_list); scst_do_job_active(&scst_active_cmd_list, - SCST_CONTEXT_THREAD|SCST_PROCESSIBLE_ENV); + SCST_CONTEXT_DIRECT|SCST_PROCESSIBLE_ENV); if (unlikely(test_bit(SCST_FLAG_SHUTDOWN, &scst_flags)) && list_empty(&scst_cmd_list) && This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-11-02 18:38:57
|
Revision: 25 http://svn.sourceforge.net/scst/?rev=25&view=rev Author: vlnb Date: 2006-11-02 04:08:28 -0800 (Thu, 02 Nov 2006) Log Message: ----------- Minor cleanup Modified Paths: -------------- trunk/qla2x00t/qla2x00-target/qla2x00t.c Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-11-02 12:03:39 UTC (rev 24) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-11-02 12:08:28 UTC (rev 25) @@ -77,10 +77,6 @@ # endif #endif -#if defined(DEBUG) || defined(TRACING) -unsigned long trace_flag = SCST_DEFAULT_QLA_LOG_FLAGS; -#endif - static int q2t_target_detect(struct scst_tgt_template *templ); static int q2t_target_release(struct scst_tgt *scst_tgt); static int q2t_xmit_response(struct scst_cmd *scst_cmd); @@ -104,6 +100,10 @@ * Global Variables */ +#if defined(DEBUG) || defined(TRACING) +unsigned long trace_flag = SCST_DEFAULT_QLA_LOG_FLAGS; +#endif + struct scst_tgt_template tgt_template = { name:"qla2x00tgt", sg_tablesize:0, @@ -123,8 +123,8 @@ task_mgmt_fn_done:q2t_task_mgmt_fn_done, }; +kmem_cache_t *q2t_cmd_cachep = NULL; static struct qla2x_tgt_target tgt_data; -kmem_cache_t *q2t_cmd_cachep = NULL; /* * Functions This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-11-02 18:38:56
|
Revision: 23 http://svn.sourceforge.net/scst/?rev=23&view=rev Author: vlnb Date: 2006-11-02 03:20:46 -0800 (Thu, 02 Nov 2006) Log Message: ----------- TRACE_MEM() cleanups Modified Paths: -------------- trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/scst/src/dev_handlers/scst_cdrom.c trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_fileio.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/scst.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_proc.c Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-11-02 10:54:10 UTC (rev 22) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-11-02 11:20:46 UTC (rev 23) @@ -53,21 +53,6 @@ #include <scst_debug.h> #include <scst_debug.c> -#ifndef MEMCPY -/* Debugging to see how many memcopys/memsets happen */ -#define MEMCPY(d, s, l) do { \ - TRACE_MEM("memcpy to %p size %zd", d, (size_t)l); \ - memcpy(d, s, l); \ - } while (0) -#endif - -#ifndef MEMSET -#define MEMSET(d, c, l) do { \ - TRACE_MEM("memset of %p size %zd", d, (size_t)l); \ - memset(d, c, l); \ - } while (0) -#endif - #ifndef FC_TARGET_SUPPORT #error "FC_TARGET_SUPPORT is NOT DEFINED" #endif @@ -217,7 +202,7 @@ if (ha->tgt != NULL) ha->tgt->notify_ack_expected++; - MEMSET(ntfy, 0, sizeof(*ntfy)); + memset(ntfy, 0, sizeof(*ntfy)); ntfy->entry_type = NOTIFY_ACK_TYPE; ntfy->entry_count = 1; SET_TARGET_ID(ha, ntfy->target, target_id); @@ -302,7 +287,6 @@ BUG_ON(sess == NULL); tgt = sess->tgt; - TRACE_MEM("kfree for sess %p (tgt %p)", sess, tgt); kfree(sess); if (tgt == NULL) @@ -414,7 +398,6 @@ scst_tgt_set_tgt_priv(scst_tgt, NULL); - TRACE_MEM("kfree for tgt %p", tgt); kfree(tgt); TRACE_EXIT_RES(res); @@ -598,7 +581,7 @@ * that. */ - MEMSET(cont_pkt64, 0, sizeof(*cont_pkt64)); + memset(cont_pkt64, 0, sizeof(*cont_pkt64)); cont_pkt64->entry_count = 1; cont_pkt64->sys_define = 0; @@ -665,10 +648,10 @@ ctio_m1->scsi_status |= __constant_cpu_to_le16(SS_SENSE_LEN_VALID); ctio_m1->sense_length = cpu_to_le16(prm->sense_buffer_len); - MEMCPY(ctio_m1->sense_data, prm->sense_buffer, + memcpy(ctio_m1->sense_data, prm->sense_buffer, prm->sense_buffer_len); } else { - MEMSET(ctio_m1->sense_data, 0, sizeof(ctio_m1->sense_data)); + memset(ctio_m1->sense_data, 0, sizeof(ctio_m1->sense_data)); ctio_m1->sense_length = 0; } @@ -800,7 +783,7 @@ TRACE_DBG("%s", "Building additional status " "packet"); - MEMCPY(ctio_m1, prm.pkt, sizeof(*ctio_m1)); + memcpy(ctio_m1, prm.pkt, sizeof(*ctio_m1)); ctio_m1->entry_count = 1; /* Real finish is ctio_m1's finish */ @@ -965,7 +948,6 @@ static inline void q2t_free_cmd(struct q2t_cmd *cmd) { - TRACE_MEM("kfree for cmd (q2t_cmd) %p", cmd); kmem_cache_free(q2t_cmd_cachep, cmd); } @@ -1367,7 +1349,6 @@ } cmd = kmem_cache_alloc(q2t_cmd_cachep, GFP_ATOMIC); - TRACE_MEM("kmem_cache_alloc(GFP_ATOMIC) for cmd (%zd): %p", sizeof(*cmd), cmd); if (cmd == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of cmd failed"); res = -ENOMEM; @@ -1375,15 +1356,13 @@ } TRACE_BUFFER("ATIO Coming Up", atio, sizeof(*atio)); - MEMSET(cmd, 0, sizeof(*cmd)); - MEMCPY(&cmd->atio, atio, sizeof(*atio)); + memset(cmd, 0, sizeof(*cmd)); + memcpy(&cmd->atio, atio, sizeof(*atio)); cmd->state = Q2T_STATE_NEW; sess = q2t_find_sess_by_lid(tgt, loop_id); if (unlikely(sess == NULL)) { sess = kzalloc(sizeof(*sess), GFP_ATOMIC); - TRACE_MEM("kzalloc(GFP_ATOMIC) for sess (%zd): %p", - sizeof(*sess), sess); if (sess == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of sess failed"); @@ -1431,7 +1410,6 @@ return res; out_free_sess: - TRACE_MEM("kfree for sess %p", sess); kfree(sess); smp_mb__before_atomic_dec(); if (atomic_dec_and_test(&tgt->sess_count)) @@ -1470,8 +1448,6 @@ } mcmd = kzalloc(sizeof(*mcmd), GFP_ATOMIC); - TRACE_MEM("kzalloc(GFP_ATOMIC) for mcmd (%zd): %p", - sizeof(*mcmd), mcmd); if (mcmd == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed"); res = -ENOMEM; @@ -1535,7 +1511,6 @@ return res; out_free: - TRACE_MEM("kfree for mcmd %p", mcmd); kfree(mcmd); goto out; } @@ -1563,7 +1538,6 @@ } mcmd = kzalloc(sizeof(*mcmd), GFP_ATOMIC); - TRACE_MEM("kzalloc(GFP_ATOMIC) for mcmd (%zd): %p", sizeof(*mcmd), mcmd); if (mcmd == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed"); res = -ENOMEM; @@ -1587,7 +1561,6 @@ return res; out_free: - TRACE_MEM("kfree for mcmd %p", mcmd); kfree(mcmd); goto out; } @@ -1617,7 +1590,6 @@ /* scst_mgmt_cmd_set_tgt_priv(scst_mcmd, NULL); */ scst_mcmd->tgt_priv = NULL; - TRACE_MEM("kfree for mcmd %p", mcmd); kfree(mcmd); out: @@ -1982,8 +1954,6 @@ switch (action) { case ENABLE_TARGET_MODE : tgt = kzalloc(sizeof(*tgt), GFP_KERNEL); - TRACE_MEM("kzalloc(GFP_KERNEL) for tgt (%zd): %p", - sizeof(*tgt), tgt); if (tgt == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of tgt failed"); @@ -2021,7 +1991,6 @@ PRINT_ERROR("qla2x00tgt(%ld): scst_register() " "failed for host %ld(%p)", ha->instance, ha->host_no, ha); - TRACE_MEM("kfree for tgt %p", tgt); kfree(tgt); goto out; } Modified: trunk/scst/src/dev_handlers/scst_cdrom.c =================================================================== --- trunk/scst/src/dev_handlers/scst_cdrom.c 2006-11-02 10:54:10 UTC (rev 22) +++ trunk/scst/src/dev_handlers/scst_cdrom.c 2006-11-02 11:20:46 UTC (rev 23) @@ -95,8 +95,6 @@ } cdrom = kzalloc(sizeof(*cdrom), GFP_KERNEL); - TRACE_MEM("kzalloc(GFP_KERNEL) for struct cdrom_params (%zu): %p", - sizeof(*cdrom), cdrom); if (cdrom == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct cdrom_params"); @@ -105,7 +103,6 @@ } buffer = kzalloc(buffer_size, GFP_KERNEL); - TRACE_MEM("kzalloc(GFP_KERNEL) for %d: %p", buffer_size, buffer); if (!buffer) { TRACE(TRACE_OUT_OF_MEM, "%s", "Memory allocation failure"); res = -ENOMEM; @@ -158,16 +155,13 @@ } out_free_buf: - TRACE_MEM("kfree for buffer: %p", buffer); kfree(buffer); out_free_cdrom: if (res == 0) dev->dh_priv = cdrom; - else { - TRACE_MEM("kfree for cdrom: %p", cdrom); + else kfree(cdrom); - } out: TRACE_EXIT(); @@ -189,7 +183,6 @@ TRACE_ENTRY(); - TRACE_MEM("kfree for cdrom: %p", cdrom); kfree(cdrom); dev->dh_priv = NULL; Modified: trunk/scst/src/dev_handlers/scst_disk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_disk.c 2006-11-02 10:54:10 UTC (rev 22) +++ trunk/scst/src/dev_handlers/scst_disk.c 2006-11-02 11:20:46 UTC (rev 23) @@ -171,8 +171,6 @@ } disk = kzalloc(sizeof(*disk), GFP_KERNEL); - TRACE_MEM("kzalloc(GFP_KERNEL) for struct disk_params (%zu): %p", - sizeof(*disk), disk); if (disk == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct disk_params"); @@ -181,7 +179,6 @@ } buffer = kzalloc(buffer_size, GFP_KERNEL); - TRACE_MEM("kzalloc(GFP_KERNEL) for %d: %p", buffer_size, buffer); if (!buffer) { TRACE(TRACE_OUT_OF_MEM, "%s", "Memory allocation failure"); res = -ENOMEM; @@ -231,16 +228,13 @@ } out_free_buf: - TRACE_MEM("kfree for buffer: %p", buffer); kfree(buffer); out_free_disk: if (res == 0) dev->dh_priv = disk; - else { - TRACE_MEM("kfree for disk: %p", disk); + else kfree(disk); - } out: TRACE_EXIT_RES(res); @@ -262,7 +256,6 @@ TRACE_ENTRY(); - TRACE_MEM("kfree for disk: %p", disk); kfree(disk); dev->dh_priv = NULL; Modified: trunk/scst/src/dev_handlers/scst_fileio.c =================================================================== --- trunk/scst/src/dev_handlers/scst_fileio.c 2006-11-02 10:54:10 UTC (rev 22) +++ trunk/scst/src/dev_handlers/scst_fileio.c 2006-11-02 11:20:46 UTC (rev 23) @@ -700,8 +700,6 @@ TRACE_ENTRY(); ftgt_dev = kzalloc(sizeof(*ftgt_dev), GFP_KERNEL); - TRACE_MEM("kzalloc(GFP_KERNEL) for ftgt_dev (%zd): %p", - sizeof(*ftgt_dev), ftgt_dev); if (ftgt_dev == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of per-session " "virtual device failed"); @@ -755,7 +753,6 @@ filp_close(ftgt_dev->fd, NULL); out_free: - TRACE_MEM("kfree ftgt_dev: %p", ftgt_dev); kfree(ftgt_dev); goto out; } @@ -780,12 +777,9 @@ if (ftgt_dev->fd) filp_close(ftgt_dev->fd, NULL); - if (ftgt_dev->iv != NULL) { - TRACE_MEM("kfree ftgt_dev->iv: %p", ftgt_dev->iv); + if (ftgt_dev->iv != NULL) kfree(ftgt_dev->iv); - } - TRACE_MEM("kfree ftgt_dev: %p", ftgt_dev); kfree(ftgt_dev); tgt_dev->dh_priv = NULL; @@ -1892,13 +1886,9 @@ iv_count = scst_get_buf_count(cmd); if (iv_count > ftgt_dev->iv_count) { - if (ftgt_dev->iv != NULL) { - TRACE_MEM("kfree ftgt_dev->iv: %p", ftgt_dev->iv); + if (ftgt_dev->iv != NULL) kfree(ftgt_dev->iv); - } ftgt_dev->iv = kmalloc(sizeof(*ftgt_dev->iv) * iv_count, GFP_KERNEL); - TRACE_MEM("kmalloc(GFP_KERNEL) for iv (%zd): %p", - sizeof(*ftgt_dev->iv) * iv_count, ftgt_dev->iv); if (ftgt_dev->iv == NULL) { PRINT_ERROR_PR("Unable to allocate iv (%d)", iv_count); scst_set_busy(cmd); @@ -2260,7 +2250,6 @@ { struct scst_fileio_dev *dev; dev = kzalloc(sizeof(*dev), GFP_KERNEL); - TRACE_MEM("kzalloc(GFP_KERNEL) for dev (%zd): %p", sizeof(*dev), dev); if (dev == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of virtual " "device failed"); @@ -2551,8 +2540,6 @@ len = strlen(file_name) + 1; virt_dev->file_name = kmalloc(len, GFP_KERNEL); - TRACE_MEM("kmalloc(GFP_KERNEL) for file_name (%d): %p", - len, virt_dev->file_name); if (virt_dev->file_name == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of file_name failed"); @@ -2598,9 +2585,7 @@ list_del(&virt_dev->fileio_dev_list_entry); - TRACE_MEM("kfree for file_name: %p", virt_dev->file_name); kfree(virt_dev->file_name); - TRACE_MEM("kfree for virt_dev: %p", virt_dev); kfree(virt_dev); } res = length; @@ -2615,12 +2600,9 @@ out_free_vpath: list_del(&virt_dev->fileio_dev_list_entry); - - TRACE_MEM("kfree for file_name: %p", virt_dev->file_name); kfree(virt_dev->file_name); out_free_vdev: - TRACE_MEM("kfree for virt_dev: %p", virt_dev); kfree(virt_dev); goto out_up; } @@ -2681,8 +2663,6 @@ if (!virt_dev->cdrom_empty) { len = strlen(file_name) + 1; virt_dev->file_name = kmalloc(len, GFP_KERNEL); - TRACE_MEM("kmalloc(GFP_KERNEL) for file_name (%d): %p", - len, virt_dev->file_name); if (virt_dev->file_name == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of file_name failed"); @@ -2711,12 +2691,9 @@ out_free_vpath: list_del(&virt_dev->fileio_dev_list_entry); - - TRACE_MEM("kfree for file_name: %p", virt_dev->file_name); kfree(virt_dev->file_name); out_free_vdev: - TRACE_MEM("kfree for virt_dev: %p", virt_dev); kfree(virt_dev); goto out; } @@ -2749,11 +2726,8 @@ list_del(&virt_dev->fileio_dev_list_entry); - if (virt_dev->file_name) { - TRACE_MEM("kfree for file_name: %p", virt_dev->file_name); + if (virt_dev->file_name) kfree(virt_dev->file_name); - } - TRACE_MEM("kfree for virt_dev: %p", virt_dev); kfree(virt_dev); out: @@ -2810,8 +2784,6 @@ if (!virt_dev->cdrom_empty) { len = strlen(file_name) + 1; fn = kmalloc(len, GFP_KERNEL); - TRACE_MEM("kmalloc(GFP_KERNEL) for file_name (%d): %p", - len, fn); if (fn == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of file_name failed"); @@ -2908,10 +2880,8 @@ virt_dev->name); } - if (old_fn) { - TRACE_MEM("kfree for old_fn: %p", old_fn); + if (old_fn) kfree(old_fn); - } out_resume: scst_resume_activity(); @@ -2921,19 +2891,16 @@ out_free: virt_dev->file_name = old_fn; - TRACE_MEM("kfree for fn: %p", fn); kfree(fn); goto out; out_free_resume: virt_dev->file_name = old_fn; - TRACE_MEM("kfree for fn: %p", fn); kfree(fn); goto out_resume; out_err_resume: virt_dev->file_name = old_fn; - TRACE_MEM("kfree for fn: %p", fn); kfree(fn); scst_resume_activity(); cdrom_fileio_close(name); @@ -3161,9 +3128,7 @@ PRINT_INFO_PR("Virtual device %s unregistered", virt_dev->name); TRACE_DBG("virt_id %d", virt_dev->virt_id); - TRACE_MEM("kfree for file_name: %p", virt_dev->file_name); kfree(virt_dev->file_name); - TRACE_MEM("kfree for virt_dev: %p", virt_dev); kfree(virt_dev); } up(&scst_fileio_mutex); Modified: trunk/scst/src/dev_handlers/scst_modisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_modisk.c 2006-11-02 10:54:10 UTC (rev 22) +++ trunk/scst/src/dev_handlers/scst_modisk.c 2006-11-02 11:20:46 UTC (rev 23) @@ -171,8 +171,6 @@ } modisk = kzalloc(sizeof(*modisk), GFP_KERNEL); - TRACE_MEM("kzalloc(GFP_KERNEL) for struct modisk_params (%zu): %p", - sizeof(*modisk), modisk); if (modisk == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct modisk_params"); @@ -193,7 +191,6 @@ } buffer = kzalloc(buffer_size, GFP_KERNEL); - TRACE_MEM("kzalloc(GFP_KERNEL) for %d: %p", buffer_size, buffer); if (!buffer) { TRACE(TRACE_OUT_OF_MEM, "%s", "Memory allocation failure"); res = -ENOMEM; @@ -245,16 +242,13 @@ } out_free_buf: - TRACE_MEM("kfree for buffer: %p", buffer); kfree(buffer); out_free_modisk: if (res == 0) dev->dh_priv = modisk; - else { - TRACE_MEM("kfree for modisk: %p", modisk); + else kfree(modisk); - } out: TRACE_EXIT_RES(res); @@ -276,7 +270,6 @@ TRACE_ENTRY(); - TRACE_MEM("kfree for modisk: %p", modisk); kfree(modisk); dev->dh_priv = NULL; Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2006-11-02 10:54:10 UTC (rev 22) +++ trunk/scst/src/dev_handlers/scst_tape.c 2006-11-02 11:20:46 UTC (rev 23) @@ -181,8 +181,6 @@ } tape = kzalloc(sizeof(*tape), GFP_KERNEL); - TRACE_MEM("kzalloc(GFP_KERNEL) for struct tape_params (%zu): %p", - sizeof(*tape), tape); if (tape == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct tape_params"); @@ -192,7 +190,6 @@ spin_lock_init(&tape->tp_lock); buffer = kmalloc(buffer_size, GFP_KERNEL); - TRACE_MEM("kmalloc(GFP_KERNEL) for %d: %p", buffer_size, buffer); if (!buffer) { TRACE(TRACE_OUT_OF_MEM, "%s", "Memory allocation failure"); res = -ENOMEM; @@ -243,16 +240,13 @@ } out_free_buf: - TRACE_MEM("kfree for buffer: %p", buffer); kfree(buffer); out_free_req: if (res == 0) dev->dh_priv = tape; - else { - TRACE_MEM("kfree for tape: %p", tape); + else kfree(tape); - } out: TRACE_EXIT_RES(res); @@ -274,7 +268,6 @@ TRACE_ENTRY(); - TRACE_MEM("kfree for tape: %p", tape); kfree(tape); dev->dh_priv = NULL; Modified: trunk/scst/src/scst.c =================================================================== --- trunk/scst/src/scst.c 2006-11-02 10:54:10 UTC (rev 22) +++ trunk/scst/src/scst.c 2006-11-02 11:20:46 UTC (rev 23) @@ -238,8 +238,6 @@ TRACE_ENTRY(); tgt = kzalloc(sizeof(*tgt), GFP_KERNEL); - TRACE_MEM("kzalloc(GFP_KERNEL) for tgt (%zd): %p", - sizeof(*tgt), tgt); if (tgt == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "kzalloc() failed"); goto out; @@ -272,7 +270,6 @@ return tgt; out_free: - TRACE_MEM("kfree() for tgt %p", tgt); kfree(tgt); goto out; } @@ -314,7 +311,6 @@ del_timer_sync(&tgt->retry_timer); - TRACE_MEM("kfree for tgt: %p", tgt); kfree(tgt); TRACE_EXIT(); Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2006-11-02 10:54:10 UTC (rev 22) +++ trunk/scst/src/scst_lib.c 2006-11-02 11:20:46 UTC (rev 23) @@ -150,7 +150,6 @@ TRACE_ENTRY(); dev = kzalloc(sizeof(*dev), gfp_mask); - TRACE_MEM("kzalloc() for dev (%zd): %p", sizeof(*dev), dev); if (dev == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of scst_device failed"); @@ -185,7 +184,6 @@ } #endif - TRACE_MEM("kfree for dev: %p", dev); kfree(dev); TRACE_EXIT(); @@ -200,7 +198,6 @@ TRACE_ENTRY(); res = kmem_cache_alloc(scst_acgd_cachep, GFP_KERNEL); - TRACE_MEM("kmem_cache_alloc() for acg_dev (%zd): %p", sizeof(*res), res); if (res == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of scst_acg_dev failed"); goto out; @@ -226,7 +223,6 @@ list_del(&acg_dev->acg_dev_list_entry); list_del(&acg_dev->dev_acg_dev_list_entry); - TRACE_MEM("kfree for acg_dev: %p", acg_dev); kmem_cache_free(scst_acgd_cachep, acg_dev); TRACE_EXIT(); @@ -241,7 +237,6 @@ TRACE_ENTRY(); acg = kzalloc(sizeof(*acg), GFP_KERNEL); - TRACE_MEM("kzalloc() for acg (%zd): %p", sizeof(*acg), acg); if (acg == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of acg failed"); goto out; @@ -302,16 +297,12 @@ acn_list_entry) { list_del(&n->acn_list_entry); - TRACE_MEM("kfree() for scst_acn->name: %p", n->name); kfree(n->name); - TRACE_MEM("kfree() for scst_acn: %p", n); kfree(n); } INIT_LIST_HEAD(&acg->acn_list); - TRACE_MEM("kfree for acg: %p", acg); kfree(acg); - out: TRACE_EXIT_RES(res); return res; @@ -331,8 +322,6 @@ TRACE_ENTRY(); tgt_dev = kmem_cache_alloc(scst_tgtd_cachep, GFP_KERNEL); - TRACE_MEM("kmem_cache_alloc(GFP_KERNEL) for tgt_dev (%zd): %p", - sizeof(*tgt_dev), tgt_dev); if (tgt_dev != NULL) memset(tgt_dev, 0, sizeof(*tgt_dev)); else { @@ -394,7 +383,6 @@ return tgt_dev; out_free: - TRACE_MEM("kfree for tgt_dev: %p", tgt_dev); kmem_cache_free(scst_tgtd_cachep, tgt_dev); tgt_dev = NULL; goto out; @@ -463,7 +451,6 @@ TRACE_DBG("%s", "Dev handler's detach_tgt() returned"); } - TRACE_MEM("kfree for tgt_dev: %p", tgt_dev); kmem_cache_free(scst_tgtd_cachep, tgt_dev); TRACE_EXIT(); @@ -649,7 +636,6 @@ } n = kmalloc(sizeof(*n), GFP_KERNEL); - TRACE_MEM("kmalloc(GFP_KERNEL) for scst_acn (%zd): %p", sizeof(*n), n); if (n == NULL) { PRINT_ERROR_PR("%s", "Unable to allocate scst_acn"); res = -ENOMEM; @@ -658,8 +644,6 @@ len = strlen(name); nm = kmalloc(len + 1, GFP_KERNEL); - TRACE_MEM("kmalloc(GFP_KERNEL) for scst_acn->name (%d): %p", - len + 1, nm); if (nm == NULL) { PRINT_ERROR_PR("%s", "Unable to allocate scst_acn->name"); res = -ENOMEM; @@ -676,7 +660,6 @@ return res; out_free: - TRACE_MEM("kfree() for scst_acn: %p", n); kfree(n); goto out; } @@ -693,9 +676,7 @@ { if (strcmp(n->name, name) == 0) { list_del(&n->acn_list_entry); - TRACE_MEM("kfree() for scst_acn->name: %p", n->name); kfree(n->name); - TRACE_MEM("kfree() for scst_acn: %p", n); kfree(n); res = 0; break; @@ -720,11 +701,8 @@ if (scsi_cmd && (req = scsi_cmd->sc_request)) { if (req) { - if (req->sr_bufflen) { - TRACE_MEM("kfree for req->sr_buffer: %p", - req->sr_buffer); + if (req->sr_bufflen) kfree(req->sr_buffer); - } scsi_release_request(req); } } @@ -823,7 +801,6 @@ TRACE_ENTRY(); sess = kmem_cache_alloc(scst_sess_cachep, gfp_mask); - TRACE_MEM("kmem_cache_alloc() for sess (%zd): %p", sizeof(*sess), sess); if (sess != NULL) memset(sess, 0, sizeof(*sess)); else { @@ -842,8 +819,6 @@ len = strlen(initiator_name); nm = kmalloc(len + 1, gfp_mask); - TRACE_MEM("kmalloc(GFP_KERNEL) for sess->initiator_name (%d): %p", - len + 1, nm); if (nm == NULL) { PRINT_ERROR_PR("%s", "Unable to allocate sess->initiator_name"); goto out_free; @@ -857,7 +832,6 @@ return sess; out_free: - TRACE_MEM("kfree() for sess: %p", sess); kmem_cache_free(scst_sess_cachep, sess); sess = NULL; goto out; @@ -881,10 +855,7 @@ up(&scst_mutex); - TRACE_MEM("kfree for sess->initiator_name: %p", sess->initiator_name); kfree(sess->initiator_name); - - TRACE_MEM("kfree for sess: %p", sess); kmem_cache_free(scst_sess_cachep, sess); TRACE_EXIT(); @@ -939,7 +910,6 @@ TRACE_ENTRY(); cmd = kmem_cache_alloc(scst_cmd_cachep, gfp_mask); - TRACE_MEM("kmem_cache_alloc() for cmd (%zd): %p", sizeof(*cmd), cmd); if (cmd != NULL) memset(cmd, 0, sizeof(*cmd)); else { @@ -1112,8 +1082,6 @@ TRACE_ENTRY(); mcmd = mempool_alloc(scst_mgmt_mempool, gfp_mask); - TRACE_MEM("mempool_alloc() for mgmt cmd (%zd): %p", sizeof(*mcmd), - mcmd); if (mcmd == NULL) { PRINT_ERROR("%s", "Allocation of management command " "failed, some commands and their data could leak"); @@ -1143,7 +1111,6 @@ if (mcmd->mcmd_tgt_dev != NULL) scst_dec_cmd_count(); - TRACE_MEM("mempool_free for mgmt cmd: %p", mcmd); mempool_free(mcmd, scst_mgmt_mempool); TRACE_EXIT(); @@ -1755,8 +1722,6 @@ list_del(&UA_entry->UA_list_entry); - - TRACE_MEM("mempool_free for UA_entry: %p", UA_entry); mempool_free(UA_entry, scst_ua_mempool); if (list_empty(&cmd->tgt_dev->UA_list)) { @@ -1784,8 +1749,6 @@ TRACE_ENTRY(); UA_entry = mempool_alloc(scst_ua_mempool, GFP_ATOMIC); - TRACE_MEM("mempool_alloc(GFP_ATOMIC) for UA_entry (%zd): %p", - sizeof(*UA_entry), UA_entry); if (UA_entry == NULL) { PRINT_ERROR_PR("%s", "UNIT ATTENTION memory " "allocation failed. The UNIT ATTENTION " @@ -1876,7 +1839,6 @@ TRACE_MGMT_DBG("Clearing UA for tgt_dev lun %d", tgt_dev->acg_dev->lun); list_del(&UA_entry->UA_list_entry); - TRACE_MEM("kfree for UA_entry: %p", UA_entry); kfree(UA_entry); } INIT_LIST_HEAD(&tgt_dev->UA_list); Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2006-11-02 10:54:10 UTC (rev 22) +++ trunk/scst/src/scst_priv.h 2006-11-02 11:20:46 UTC (rev 23) @@ -251,7 +251,6 @@ void scst_free_cmd(struct scst_cmd *cmd); static inline void scst_destroy_cmd(struct scst_cmd *cmd) { - TRACE_MEM("kfree for cmd: %p", cmd); kmem_cache_free(scst_cmd_cachep, cmd); return; } Modified: trunk/scst/src/scst_proc.c =================================================================== --- trunk/scst/src/scst_proc.c 2006-11-02 10:54:10 UTC (rev 22) +++ trunk/scst/src/scst_proc.c 2006-11-02 11:20:46 UTC (rev 23) @@ -619,7 +619,6 @@ TRACE_ENTRY(); name = kmalloc(len, GFP_KERNEL); - TRACE_MEM("kmalloc() for acg_dev (%d): %p", len, name); if (name == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of name failed"); goto out_nomem; @@ -644,7 +643,6 @@ scst_proc_del_free_acg(acg, 0); out_free: - TRACE_MEM("kfree for name: %p", name); kfree(name); out_nomem: @@ -666,7 +664,6 @@ if (res == 0) { if (remove_proc) scst_proc_del_acg_tree(acg_proc_root, name); - TRACE_MEM("kfree for name: %p", name); kfree(name); } } @@ -2231,9 +2228,7 @@ list_for_each_entry_safe(n, nn, &acg->acn_list, acn_list_entry) { list_del(&n->acn_list_entry); - TRACE_MEM("kfree() for scst_acn->name: %p", n->name); kfree(n->name); - TRACE_MEM("kfree() for scst_acn: %p", n); kfree(n); } break; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-11-02 18:38:52
|
Revision: 21 http://svn.sourceforge.net/scst/?rev=21&view=rev Author: vlnb Date: 2006-11-02 02:43:29 -0800 (Thu, 02 Nov 2006) Log Message: ----------- Updates Modified Paths: -------------- trunk/qla2x00t/qla2x00-target/ChangeLog Modified: trunk/qla2x00t/qla2x00-target/ChangeLog =================================================================== --- trunk/qla2x00t/qla2x00-target/ChangeLog 2006-11-02 10:43:12 UTC (rev 20) +++ trunk/qla2x00t/qla2x00-target/ChangeLog 2006-11-02 10:43:29 UTC (rev 21) @@ -1,3 +1,13 @@ +Summary of changes between versions 0.9.3.8 and 0.9.5 +----------------------------------------------------- + + - Ported to 2.6.17.x and 2.6.18. + + - Updated for the latest SCST interfaces changes. + + - Cleanups and minor bug fixes. + + Summary of changes between versions 0.9.3.8 and 0.9.3.9 ------------------------------------------------------- Patch vs: qla2xxx v8.01.03-k (in kernels 2.6.15.x+, including 2.6.16-prex) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-27 10:44:07
|
Revision: 19 http://svn.sourceforge.net/scst/?rev=19&view=rev Author: vlnb Date: 2006-10-27 03:43:58 -0700 (Fri, 27 Oct 2006) Log Message: ----------- Small ORDERED commands handling optimization Modified Paths: -------------- trunk/scst/src/dev_handlers/scst_fileio.c Modified: trunk/scst/src/dev_handlers/scst_fileio.c =================================================================== --- trunk/scst/src/dev_handlers/scst_fileio.c 2006-10-27 09:45:12 UTC (rev 18) +++ trunk/scst/src/dev_handlers/scst_fileio.c 2006-10-27 10:43:58 UTC (rev 19) @@ -105,6 +105,7 @@ struct scst_fileio_tgt_dev { spinlock_t fdev_lock; + enum scst_cmd_queue_type last_write_cmd_queue_type; int shutdown; struct file *fd; struct iovec *iv; @@ -380,6 +381,26 @@ return; } +static inline int fileio_sync_queue_type(enum scst_cmd_queue_type qt) +{ + switch(qt) { + case SCST_CMD_QUEUE_ORDERED: + case SCST_CMD_QUEUE_HEAD_OF_QUEUE: + return 1; + default: + return 0; + } +} + +static inline int fileio_need_pre_sync(enum scst_cmd_queue_type cwqt, + enum scst_cmd_queue_type lwqt) +{ + if (fileio_sync_queue_type(cwqt)) + if (!fileio_sync_queue_type(lwqt)) + return 1; + return 0; +} + static void fileio_do_job(struct scst_cmd *cmd) { uint64_t lba_start; @@ -482,11 +503,15 @@ struct scst_fileio_tgt_dev *ftgt_dev = (struct scst_fileio_tgt_dev*) cmd->tgt_dev->dh_priv; - if ((cmd->queue_type == SCST_CMD_QUEUE_ORDERED) && + enum scst_cmd_queue_type last_queue_type = + ftgt_dev->last_write_cmd_queue_type; + ftgt_dev->last_write_cmd_queue_type = cmd->queue_type; + if (fileio_need_pre_sync(cmd->queue_type, last_queue_type) && !virt_dev->wt_flag) { - TRACE(TRACE_SCSI/*|TRACE_SPECIAL*/, "ORDERED WRITE: " - "loff=%Ld, data_len=%Ld", (uint64_t)loff, - (uint64_t)data_len); + TRACE(TRACE_SCSI/*|TRACE_SPECIAL*/, "ORDERED " + "WRITE(%d): loff=%Ld, data_len=%Ld", + cmd->queue_type, (uint64_t)loff, + (uint64_t)data_len); do_fsync = 1; if (fileio_fsync(ftgt_dev, 0, 0, cmd) != 0) goto done; @@ -509,11 +534,15 @@ struct scst_fileio_tgt_dev *ftgt_dev = (struct scst_fileio_tgt_dev*) cmd->tgt_dev->dh_priv; - if ((cmd->queue_type == SCST_CMD_QUEUE_ORDERED) && + enum scst_cmd_queue_type last_queue_type = + ftgt_dev->last_write_cmd_queue_type; + ftgt_dev->last_write_cmd_queue_type = cmd->queue_type; + if (fileio_need_pre_sync(cmd->queue_type, last_queue_type) && !virt_dev->wt_flag) { TRACE(TRACE_SCSI/*|TRACE_SPECIAL*/, "ORDERED " - "WRITE_VERIFY: loff=%Ld, data_len=%Ld", - (uint64_t)loff, (uint64_t)data_len); + "WRITE_VERIFY(%d): loff=%Ld, data_len=%Ld", + cmd->queue_type, (uint64_t)loff, + (uint64_t)data_len); do_fsync = 1; if (fileio_fsync(ftgt_dev, 0, 0, cmd) != 0) goto done; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-27 09:45:34
|
Revision: 18 http://svn.sourceforge.net/scst/?rev=18&view=rev Author: vlnb Date: 2006-10-27 02:45:12 -0700 (Fri, 27 Oct 2006) Log Message: ----------- Renamed tgt_dev_specific to dh_priv as well as all *_specific to *_priv Modified Paths: -------------- trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/scst/include/scsi_tgt.h trunk/scst/src/dev_handlers/scst_cdrom.c trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_fileio.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/scst.c trunk/scst/src/scst_targ.c Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-10-26 16:58:44 UTC (rev 17) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-10-27 09:45:12 UTC (rev 18) @@ -297,7 +297,7 @@ TRACE_ENTRY(); BUG_ON(scst_sess == NULL); - sess = (struct q2t_sess *)scst_sess_get_tgt_specific(scst_sess); + sess = (struct q2t_sess *)scst_sess_get_tgt_priv(scst_sess); BUG_ON(sess == NULL); tgt = sess->tgt; @@ -387,8 +387,7 @@ static int q2t_target_release(struct scst_tgt *scst_tgt) { int res = 0; - struct q2t_tgt *tgt = - (struct q2t_tgt *)scst_tgt_get_tgt_specific(scst_tgt); + struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt); scsi_qla_host_t *ha = tgt->ha; unsigned long flags = 0; @@ -412,7 +411,7 @@ "sess_count=%d", tgt, list_empty(&tgt->sess_list), atomic_read(&tgt->sess_count)); - scst_tgt_set_tgt_specific(scst_tgt, NULL); + scst_tgt_set_tgt_priv(scst_tgt, NULL); TRACE_MEM("kfree for tgt %p", tgt); kfree(tgt); @@ -698,9 +697,9 @@ TRACE_ENTRY(); TRACE(TRACE_SCSI, "tag=%d", scst_cmd_get_tag(scst_cmd)); - prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_specific(scst_cmd); + prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd); sess = (struct q2t_sess *) - scst_sess_get_tgt_specific(scst_cmd_get_session(scst_cmd)); + scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd)); if (unlikely(scst_cmd_aborted(scst_cmd))) { scsi_qla_host_t *ha = sess->tgt->ha; @@ -844,9 +843,9 @@ TRACE_ENTRY(); TRACE(TRACE_SCSI, "tag=%d", scst_cmd_get_tag(scst_cmd)); - prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_specific(scst_cmd); + prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd); sess = (struct q2t_sess *) - scst_sess_get_tgt_specific(scst_cmd_get_session(scst_cmd)); + scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd)); prm.sg = scst_cmd_get_sg(scst_cmd); prm.bufflen = scst_cmd_get_bufflen(scst_cmd); @@ -967,13 +966,12 @@ void q2t_on_free_cmd(struct scst_cmd *scst_cmd) { - struct q2t_cmd *cmd = - (struct q2t_cmd *)scst_cmd_get_tgt_specific(scst_cmd); + struct q2t_cmd *cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd); TRACE_ENTRY(); TRACE(TRACE_SCSI, "END Command tag %d", scst_cmd_get_tag(scst_cmd)); - scst_cmd_set_tgt_specific(scst_cmd, NULL); + scst_cmd_set_tgt_priv(scst_cmd, NULL); q2t_free_cmd(cmd); @@ -1082,7 +1080,7 @@ } else goto out; - cmd = (struct q2t_cmd *)scst_cmd_get_tgt_specific(scst_cmd); + cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd); if (cmd->state == Q2T_STATE_PROCESSED) { TRACE_DBG("Command %p finished", cmd); @@ -1205,7 +1203,7 @@ } scst_cmd_set_tag(cmd->scst_cmd, le16_to_cpu(cmd->atio.exchange_id)); - scst_cmd_set_tgt_specific(cmd->scst_cmd, cmd); + scst_cmd_set_tgt_priv(cmd->scst_cmd, cmd); if (cmd->atio.execution_codes & ATIO_EXEC_READ) dir = SCST_DATA_READ; @@ -1402,7 +1400,7 @@ res = -EFAULT; goto out_free_sess; } - scst_sess_set_tgt_specific(sess->scst_sess, sess); + scst_sess_set_tgt_priv(sess->scst_sess, sess); /* add session data to host data structure */ list_add(&sess->list, &tgt->sess_list); @@ -1591,7 +1589,7 @@ TRACE(TRACE_MGMT, "scst_mcmd (%p) status %#x state %#x", scst_mcmd, scst_mcmd->status, scst_mcmd->state); - mcmd = scst_mgmt_cmd_get_tgt_specific(scst_mcmd); + mcmd = scst_mgmt_cmd_get_tgt_priv(scst_mcmd); if (unlikely(mcmd == NULL)) { PRINT_ERROR("scst_mcmd %p tgt_spec is NULL", mcmd); goto out; @@ -1603,8 +1601,8 @@ ? 0 : FC_TM_FAILED, 1); spin_unlock_irqrestore(&mcmd->sess->tgt->ha->hardware_lock, flags); - /* scst_mgmt_cmd_set_tgt_specific(scst_mcmd, NULL); */ - scst_mcmd->tgt_specific = NULL; + /* scst_mgmt_cmd_set_tgt_priv(scst_mcmd, NULL); */ + scst_mcmd->tgt_priv = NULL; TRACE_MEM("kfree for mcmd %p", mcmd); kfree(mcmd); @@ -2008,7 +2006,7 @@ goto out; } - scst_tgt_set_tgt_specific(tgt->scst_tgt, tgt); + scst_tgt_set_tgt_priv(tgt->scst_tgt, tgt); spin_lock_irqsave(&ha->hardware_lock, flags); ha->tgt = tgt; Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2006-10-26 16:58:44 UTC (rev 17) +++ trunk/scst/include/scsi_tgt.h 2006-10-27 09:45:12 UTC (rev 18) @@ -832,8 +832,8 @@ /* Maximum SG table size */ int sg_tablesize; - /* Used for storage of target specific stuff */ - void *tgt_specific; + /* Used for storage of target driver private stuff */ + void *tgt_priv; }; struct scst_session @@ -870,8 +870,8 @@ /* List entry for the sessions list inside ACG */ struct list_head acg_sess_list_entry; - /* Used for storage of target specific stuff */ - void *tgt_specific; + /* Used for storage of target driver private stuff */ + void *tgt_priv; /* * List of cmds in this session. Used to find a cmd in the @@ -1114,11 +1114,11 @@ struct list_head fileio_cmd_list_entry; int fileio_in_list; - /* Used for storage of target specific stuff */ - void *tgt_specific; + /* Used for storage of target driver private stuff */ + void *tgt_priv; - /* Used for storage of dev handler specific stuff */ - void *tgt_dev_specific; + /* Used for storage of dev handler private stuff */ + void *dh_priv; /* * Used to store previous tgt_dev if dev handler returns @@ -1162,8 +1162,8 @@ /* completition status, one of the SCST_MGMT_STATUS_* constants */ int status; - /* Used for storage of target specific stuff */ - void *tgt_specific; + /* Used for storage of target driver private stuff */ + void *tgt_priv; }; struct scst_device @@ -1211,8 +1211,8 @@ /* Corresponding real SCSI device, could be NULL for virtual devices */ struct scsi_device *scsi_dev; - /* Used for storage of dev handler specific stuff */ - void *tgt_dev_specific; + /* Used for storage of dev handler private stuff */ + void *dh_priv; /* Used to wait for requested amount of "on_dev" commands */ wait_queue_head_t on_dev_waitQ; @@ -1262,8 +1262,8 @@ unsigned long tgt_dev_flags; /* tgt_dev's flags */ - /* Used for storage of dev handler specific stuff */ - void *tgt_dev_specific; + /* Used for storage of dev handler private stuff */ + void *dh_priv; /* * Used to execute cmd's in order of arrival. @@ -1553,7 +1553,7 @@ * same sess. Returns 0 for success, error code otherwise. */ int scst_rx_mgmt_fn_tag(struct scst_session *sess, int fn, uint32_t tag, - int atomic, void *tgt_specific); + int atomic, void *tgt_priv); /* * Creates new management command using LUN and sends it for execution. @@ -1563,7 +1563,7 @@ */ int scst_rx_mgmt_fn_lun(struct scst_session *sess, int fn, const uint8_t *lun, int lun_len, - int atomic, void *tgt_specific); + int atomic, void *tgt_priv); /* * Provides various CDB info @@ -1649,30 +1649,30 @@ void scst_unregister_virtual_device(int id); /* - * Get/Set functions for tgt's target specific data + * Get/Set functions for tgt's target private data */ -static inline void *scst_tgt_get_tgt_specific(struct scst_tgt *tgt) +static inline void *scst_tgt_get_tgt_priv(struct scst_tgt *tgt) { - return tgt->tgt_specific; + return tgt->tgt_priv; } -static inline void scst_tgt_set_tgt_specific(struct scst_tgt *tgt, void *val) +static inline void scst_tgt_set_tgt_priv(struct scst_tgt *tgt, void *val) { - tgt->tgt_specific = val; + tgt->tgt_priv = val; } /* - * Get/Set functions for session's target specific data + * Get/Set functions for session's target private data */ -static inline void *scst_sess_get_tgt_specific(struct scst_session *sess) +static inline void *scst_sess_get_tgt_priv(struct scst_session *sess) { - return sess->tgt_specific; + return sess->tgt_priv; } -static inline void scst_sess_set_tgt_specific(struct scst_session *sess, +static inline void scst_sess_set_tgt_priv(struct scst_session *sess, void *val) { - sess->tgt_specific = val; + sess->tgt_priv = val; } /* Returns TRUE if cmd is being executed in atomic context */ @@ -1811,23 +1811,23 @@ } /* - * Get/Set functions for cmd's target specific data. + * Get/Set functions for cmd's target private data. * Variant with *_lock must be used if target driver uses * scst_find_cmd() to avoid race with it, except inside scst_find_cmd()'s * callback, where lock is already taken. */ -static inline void *scst_cmd_get_tgt_specific(struct scst_cmd *cmd) +static inline void *scst_cmd_get_tgt_priv(struct scst_cmd *cmd) { - return cmd->tgt_specific; + return cmd->tgt_priv; } -static inline void scst_cmd_set_tgt_specific(struct scst_cmd *cmd, void *val) +static inline void scst_cmd_set_tgt_priv(struct scst_cmd *cmd, void *val) { - cmd->tgt_specific = val; + cmd->tgt_priv = val; } -void *scst_cmd_get_tgt_specific_lock(struct scst_cmd *cmd); -void scst_cmd_set_tgt_specific_lock(struct scst_cmd *cmd, void *val); +void *scst_cmd_get_tgt_priv_lock(struct scst_cmd *cmd); +void scst_cmd_set_tgt_priv_lock(struct scst_cmd *cmd, void *val); /* * Get/Set functions for data_buf_tgt_alloc flag @@ -1897,17 +1897,17 @@ } /* - * Get/Set function for mgmt cmd's target specific data + * Get/Set function for mgmt cmd's target private data */ -static inline void *scst_mgmt_cmd_get_tgt_specific(struct scst_mgmt_cmd *mcmd) +static inline void *scst_mgmt_cmd_get_tgt_priv(struct scst_mgmt_cmd *mcmd) { - return mcmd->tgt_specific; + return mcmd->tgt_priv; } -static inline void scst_mgmt_cmd_set_tgt_specific(struct scst_mgmt_cmd *mcmd, +static inline void scst_mgmt_cmd_set_tgt_priv(struct scst_mgmt_cmd *mcmd, void *val) { - mcmd->tgt_specific = val; + mcmd->tgt_priv = val; } /* Modified: trunk/scst/src/dev_handlers/scst_cdrom.c =================================================================== --- trunk/scst/src/dev_handlers/scst_cdrom.c 2006-10-26 16:58:44 UTC (rev 17) +++ trunk/scst/src/dev_handlers/scst_cdrom.c 2006-10-27 09:45:12 UTC (rev 18) @@ -163,7 +163,7 @@ out_free_cdrom: if (res == 0) - dev->tgt_dev_specific = cdrom; + dev->dh_priv = cdrom; else { TRACE_MEM("kfree for cdrom: %p", cdrom); kfree(cdrom); @@ -185,14 +185,13 @@ ************************************************************/ void cdrom_detach(struct scst_device *dev) { - struct cdrom_params *cdrom = - (struct cdrom_params *)dev->tgt_dev_specific; + struct cdrom_params *cdrom = (struct cdrom_params *)dev->dh_priv; TRACE_ENTRY(); TRACE_MEM("kfree for cdrom: %p", cdrom); kfree(cdrom); - dev->tgt_dev_specific = NULL; + dev->dh_priv = NULL; TRACE_EXIT(); return; @@ -277,7 +276,7 @@ * No need for locks here, since *_detach() can not be * called, when there are existing commands. */ - cdrom = (struct cdrom_params *)cmd->dev->tgt_dev_specific; + cdrom = (struct cdrom_params *)cmd->dev->dh_priv; cmd->bufflen = info_cdb->transfer_len * cdrom->sector_size; } @@ -341,8 +340,7 @@ * No need for locks here, since *_detach() can not be * called, when there are existing commands. */ - cdrom = - (struct cdrom_params *)cmd->dev->tgt_dev_specific; + cdrom = (struct cdrom_params *)cmd->dev->dh_priv; sector_size = ((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | (buffer[7] << 0)); Modified: trunk/scst/src/dev_handlers/scst_disk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_disk.c 2006-10-26 16:58:44 UTC (rev 17) +++ trunk/scst/src/dev_handlers/scst_disk.c 2006-10-27 09:45:12 UTC (rev 18) @@ -236,7 +236,7 @@ out_free_disk: if (res == 0) - dev->tgt_dev_specific = disk; + dev->dh_priv = disk; else { TRACE_MEM("kfree for disk: %p", disk); kfree(disk); @@ -258,13 +258,13 @@ ************************************************************/ void disk_detach(struct scst_device *dev) { - struct disk_params *disk = (struct disk_params *)dev->tgt_dev_specific; + struct disk_params *disk = (struct disk_params *)dev->dh_priv; TRACE_ENTRY(); TRACE_MEM("kfree for disk: %p", disk); kfree(disk); - dev->tgt_dev_specific = NULL; + dev->dh_priv = NULL; TRACE_EXIT(); return; @@ -337,7 +337,7 @@ * No need for locks here, since *_detach() can not be * called, when there are existing commands. */ - disk = (struct disk_params *)cmd->dev->tgt_dev_specific; + disk = (struct disk_params *)cmd->dev->dh_priv; cmd->bufflen = info_cdb->transfer_len * disk->sector_size; } @@ -401,7 +401,7 @@ * No need for locks here, since *_detach() can not be * called, when there are existing commands. */ - disk = (struct disk_params *)cmd->dev->tgt_dev_specific; + disk = (struct disk_params *)cmd->dev->dh_priv; sector_size = ((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | (buffer[7] << 0)); Modified: trunk/scst/src/dev_handlers/scst_fileio.c =================================================================== --- trunk/scst/src/dev_handlers/scst_fileio.c 2006-10-26 16:58:44 UTC (rev 17) +++ trunk/scst/src/dev_handlers/scst_fileio.c 2006-10-27 09:45:12 UTC (rev 18) @@ -341,7 +341,7 @@ virt_dev->name); } - dev->tgt_dev_specific = virt_dev; + dev->dh_priv = virt_dev; out: TRACE_EXIT(); @@ -364,7 +364,7 @@ static void fileio_detach(struct scst_device *dev) { struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)dev->tgt_dev_specific; + (struct scst_fileio_dev *)dev->dh_priv; TRACE_ENTRY(); @@ -374,7 +374,7 @@ virt_dev->name, virt_dev->file_name); /* virt_dev will be freed by the caller */ - dev->tgt_dev_specific = NULL; + dev->dh_priv = NULL; TRACE_EXIT(); return; @@ -388,7 +388,7 @@ loff_t loff; struct scst_device *dev = cmd->dev; struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)dev->tgt_dev_specific; + (struct scst_fileio_dev *)dev->dh_priv; int fua = 0; TRACE_ENTRY(); @@ -481,7 +481,7 @@ int do_fsync = 0; struct scst_fileio_tgt_dev *ftgt_dev = (struct scst_fileio_tgt_dev*) - cmd->tgt_dev->tgt_dev_specific; + cmd->tgt_dev->dh_priv; if ((cmd->queue_type == SCST_CMD_QUEUE_ORDERED) && !virt_dev->wt_flag) { TRACE(TRACE_SCSI/*|TRACE_SPECIAL*/, "ORDERED WRITE: " @@ -508,7 +508,7 @@ int do_fsync = 0; struct scst_fileio_tgt_dev *ftgt_dev = (struct scst_fileio_tgt_dev*) - cmd->tgt_dev->tgt_dev_specific; + cmd->tgt_dev->dh_priv; if ((cmd->queue_type == SCST_CMD_QUEUE_ORDERED) && !virt_dev->wt_flag) { TRACE(TRACE_SCSI/*|TRACE_SPECIAL*/, "ORDERED " @@ -535,7 +535,7 @@ int immed = cmd->cdb[1] & 0x2; struct scst_fileio_tgt_dev *ftgt_dev = (struct scst_fileio_tgt_dev*) - cmd->tgt_dev->tgt_dev_specific; + cmd->tgt_dev->dh_priv; TRACE(TRACE_SCSI, "SYNCHRONIZE_CACHE: " "loff=%Ld, data_len=%Ld, immed=%d", (uint64_t)loff, (uint64_t)data_len, immed); @@ -664,7 +664,7 @@ static int fileio_attach_tgt(struct scst_tgt_dev *tgt_dev) { struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)tgt_dev->acg_dev->dev->tgt_dev_specific; + (struct scst_fileio_dev *)tgt_dev->acg_dev->dev->dh_priv; struct scst_fileio_tgt_dev *ftgt_dev; int res = 0; @@ -710,7 +710,7 @@ res = 0; atomic_inc(&ftgt_dev->threads_count); - tgt_dev->tgt_dev_specific = ftgt_dev; + tgt_dev->dh_priv = ftgt_dev; down(&virt_dev->ftgt_list_mutex); list_add_tail(&ftgt_dev->ftgt_list_entry, @@ -734,9 +734,9 @@ static void fileio_detach_tgt(struct scst_tgt_dev *tgt_dev) { struct scst_fileio_tgt_dev *ftgt_dev = - (struct scst_fileio_tgt_dev *)tgt_dev->tgt_dev_specific; + (struct scst_fileio_tgt_dev *)tgt_dev->dh_priv; struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)tgt_dev->acg_dev->dev->tgt_dev_specific; + (struct scst_fileio_dev *)tgt_dev->acg_dev->dev->dh_priv; TRACE_ENTRY(); @@ -759,7 +759,7 @@ TRACE_MEM("kfree ftgt_dev: %p", ftgt_dev); kfree(ftgt_dev); - tgt_dev->tgt_dev_specific = NULL; + tgt_dev->dh_priv = NULL; TRACE_EXIT(); } @@ -781,7 +781,7 @@ int res = SCST_CMD_STATE_DEFAULT; int fixed; struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + (struct scst_fileio_dev *)cmd->dev->dh_priv; TRACE_ENTRY(); @@ -842,7 +842,7 @@ static inline void fileio_queue_cmd(struct scst_cmd *cmd) { struct scst_fileio_tgt_dev *ftgt_dev = - (struct scst_fileio_tgt_dev *)cmd->tgt_dev->tgt_dev_specific; + (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv; spin_lock_bh(&ftgt_dev->fdev_lock); TRACE_DBG("Pushing cmd %p to IO thread", cmd); list_add_tail(&cmd->fileio_cmd_list_entry, @@ -963,7 +963,7 @@ int res = SCST_CMD_STATE_DEFAULT; int fixed; struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + (struct scst_fileio_dev *)cmd->dev->dh_priv; TRACE_ENTRY(); @@ -1029,7 +1029,7 @@ int delayed = 0; int opcode = cmd->cdb[0]; struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + (struct scst_fileio_dev *)cmd->dev->dh_priv; TRACE_ENTRY(); @@ -1129,7 +1129,7 @@ uint8_t *address; uint8_t *buf; struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + (struct scst_fileio_dev *)cmd->dev->dh_priv; /* ToDo: Performance Boost: * 1. remove kzalloc, buf @@ -1378,7 +1378,7 @@ goto out; } - virt_dev = (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv; blocksize = virt_dev->block_size; nblocks = virt_dev->nblocks; @@ -1560,7 +1560,7 @@ TRACE_ENTRY(); - virt_dev = (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv; mselect_6 = (MODE_SELECT == cmd->cdb[0]); length = scst_get_buf_first(cmd, &address); @@ -1640,7 +1640,7 @@ TRACE_ENTRY(); - virt_dev = (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv; blocksize = virt_dev->block_size; nblocks = virt_dev->nblocks; @@ -1691,7 +1691,7 @@ TRACE_ENTRY(); - virt_dev = (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv; blocksize = virt_dev->block_size; nblocks = virt_dev->nblocks; @@ -1763,7 +1763,7 @@ goto out; } - virt_dev = (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv; /* FIXME when you have > 8TB ROM device. */ nblocks = (uint32_t)virt_dev->nblocks; @@ -1806,7 +1806,7 @@ static void fileio_exec_prevent_allow_medium_removal(struct scst_cmd *cmd) { struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + (struct scst_fileio_dev *)cmd->dev->dh_priv; TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]); @@ -1889,9 +1889,9 @@ ssize_t length, full_len; uint8_t *address; struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + (struct scst_fileio_dev *)cmd->dev->dh_priv; struct scst_fileio_tgt_dev *ftgt_dev = - (struct scst_fileio_tgt_dev *)cmd->tgt_dev->tgt_dev_specific; + (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv; struct file *fd = ftgt_dev->fd; struct iovec *iv; int iv_count, i; @@ -1974,9 +1974,9 @@ ssize_t length, full_len; uint8_t *address; struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; + (struct scst_fileio_dev *)cmd->dev->dh_priv; struct scst_fileio_tgt_dev *ftgt_dev = - (struct scst_fileio_tgt_dev *)cmd->tgt_dev->tgt_dev_specific; + (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv; struct file *fd = ftgt_dev->fd; struct iovec *iv, *eiv; int iv_count, eiv_count; @@ -2092,7 +2092,7 @@ uint8_t *address_sav, *address; int compare; struct scst_fileio_tgt_dev *ftgt_dev = - (struct scst_fileio_tgt_dev *)cmd->tgt_dev->tgt_dev_specific; + (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv; struct file *fd = ftgt_dev->fd; uint8_t *mem_verify = NULL; @@ -2205,8 +2205,7 @@ unsigned long flags; struct scst_cmd *cmd_to_abort = mcmd->cmd_to_abort; struct scst_fileio_tgt_dev *ftgt_dev = - (struct scst_fileio_tgt_dev *)cmd_to_abort->tgt_dev-> - tgt_dev_specific; + (struct scst_fileio_tgt_dev *)cmd_to_abort->tgt_dev->dh_priv; /* * Actually, _bh lock is enough here. But, since we * could be called with IRQ off, the in-kernel debug check Modified: trunk/scst/src/dev_handlers/scst_modisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_modisk.c 2006-10-26 16:58:44 UTC (rev 17) +++ trunk/scst/src/dev_handlers/scst_modisk.c 2006-10-27 09:45:12 UTC (rev 18) @@ -250,7 +250,7 @@ out_free_modisk: if (res == 0) - dev->tgt_dev_specific = modisk; + dev->dh_priv = modisk; else { TRACE_MEM("kfree for modisk: %p", modisk); kfree(modisk); @@ -272,14 +272,13 @@ ************************************************************/ void modisk_detach(struct scst_device *dev) { - struct modisk_params *modisk = - (struct modisk_params *)dev->tgt_dev_specific; + struct modisk_params *modisk = (struct modisk_params *)dev->dh_priv; TRACE_ENTRY(); TRACE_MEM("kfree for modisk: %p", modisk); kfree(modisk); - dev->tgt_dev_specific = NULL; + dev->dh_priv = NULL; TRACE_EXIT(); return; @@ -364,7 +363,7 @@ * No need for locks here, since *_detach() can not be * called, when there are existing commands. */ - modisk = (struct modisk_params *)cmd->dev->tgt_dev_specific; + modisk = (struct modisk_params *)cmd->dev->dh_priv; cmd->bufflen = info_cdb->transfer_len * modisk->sector_size; } @@ -428,8 +427,7 @@ * No need for locks here, since *_detach() can not be * called, when there are existing commands. */ - modisk = - (struct modisk_params *)cmd->dev->tgt_dev_specific; + modisk = (struct modisk_params *)cmd->dev->dh_priv; sector_size = ((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | (buffer[7] << 0)); Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2006-10-26 16:58:44 UTC (rev 17) +++ trunk/scst/src/dev_handlers/scst_tape.c 2006-10-27 09:45:12 UTC (rev 18) @@ -248,7 +248,7 @@ out_free_req: if (res == 0) - dev->tgt_dev_specific = tape; + dev->dh_priv = tape; else { TRACE_MEM("kfree for tape: %p", tape); kfree(tape); @@ -270,13 +270,13 @@ ************************************************************/ void tape_detach(struct scst_device *dev) { - struct tape_params *tape = (struct tape_params *)dev->tgt_dev_specific; + struct tape_params *tape = (struct tape_params *)dev->dh_priv; TRACE_ENTRY(); TRACE_MEM("kfree for tape: %p", tape); kfree(tape); - dev->tgt_dev_specific = NULL; + dev->dh_priv = NULL; TRACE_EXIT(); return; @@ -337,7 +337,7 @@ * No need for locks here, since *_detach() can not be called, * when there are existing commands. */ - tape = (struct tape_params *)cmd->dev->tgt_dev_specific; + tape = (struct tape_params *)cmd->dev->dh_priv; cmd->bufflen = info_cdb->transfer_len * tape->block_size; } @@ -400,7 +400,7 @@ * can not be called, when there are * existing commands. */ - tape = (struct tape_params *)cmd->dev->tgt_dev_specific; + tape = (struct tape_params *)cmd->dev->dh_priv; spin_lock_bh(&tape->tp_lock); if (buffer[3] == 8) { tape->block_size = (buffer[9] << 16) | @@ -419,7 +419,7 @@ * No need for locks here, since *_detach() can not be * called, when there are existing commands. */ - tape = (struct tape_params *)cmd->dev->tgt_dev_specific; + tape = (struct tape_params *)cmd->dev->dh_priv; spin_lock_bh(&tape->tp_lock); if (buffer[3] == 8) { tape->block_size = @@ -477,7 +477,7 @@ * *_detach() can not be called, when * there are existing commands. */ - tape = (struct tape_params *)cmd->dev->tgt_dev_specific; + tape = (struct tape_params *)cmd->dev->dh_priv; resp_data_len *= tape->block_size; } scst_set_resp_data_len(cmd, resp_data_len); Modified: trunk/scst/src/scst.c =================================================================== --- trunk/scst/src/scst.c 2006-10-26 16:58:44 UTC (rev 17) +++ trunk/scst/src/scst.c 2006-10-27 09:45:12 UTC (rev 18) @@ -1280,8 +1280,8 @@ * Other Commands */ EXPORT_SYMBOL(scst_get_cdb_info); -EXPORT_SYMBOL(scst_cmd_get_tgt_specific_lock); -EXPORT_SYMBOL(scst_cmd_set_tgt_specific_lock); +EXPORT_SYMBOL(scst_cmd_get_tgt_priv_lock); +EXPORT_SYMBOL(scst_cmd_set_tgt_priv_lock); #ifdef DEBUG EXPORT_SYMBOL(scst_random); Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2006-10-26 16:58:44 UTC (rev 17) +++ trunk/scst/src/scst_targ.c 2006-10-27 09:45:12 UTC (rev 18) @@ -3400,7 +3400,7 @@ break; } - mcmd->tgt_specific = NULL; + mcmd->tgt_priv = NULL; TRACE_EXIT(); return; @@ -3535,7 +3535,7 @@ } static struct scst_mgmt_cmd *scst_pre_rx_mgmt_cmd(struct scst_session - *sess, int fn, int atomic, void *tgt_specific) + *sess, int fn, int atomic, void *tgt_priv) { struct scst_mgmt_cmd *mcmd = NULL; @@ -3554,7 +3554,7 @@ mcmd->sess = sess; mcmd->fn = fn; mcmd->state = SCST_MGMT_CMD_STATE_INIT; - mcmd->tgt_specific = tgt_specific; + mcmd->tgt_priv = tgt_priv; out: TRACE_EXIT(); @@ -3623,7 +3623,7 @@ */ int scst_rx_mgmt_fn_lun(struct scst_session *sess, int fn, const uint8_t *lun, int lun_len, int atomic, - void *tgt_specific) + void *tgt_priv) { int res = -EFAULT; struct scst_mgmt_cmd *mcmd = NULL; @@ -3636,7 +3636,7 @@ goto out; } - mcmd = scst_pre_rx_mgmt_cmd(sess, fn, atomic, tgt_specific); + mcmd = scst_pre_rx_mgmt_cmd(sess, fn, atomic, tgt_priv); if (mcmd == NULL) goto out; @@ -3666,7 +3666,7 @@ * same sess */ int scst_rx_mgmt_fn_tag(struct scst_session *sess, int fn, uint32_t tag, - int atomic, void *tgt_specific) + int atomic, void *tgt_priv) { int res = -EFAULT; struct scst_mgmt_cmd *mcmd = NULL; @@ -3679,7 +3679,7 @@ goto out; } - mcmd = scst_pre_rx_mgmt_cmd(sess, fn, atomic, tgt_specific); + mcmd = scst_pre_rx_mgmt_cmd(sess, fn, atomic, tgt_priv); if (mcmd == NULL) goto out; @@ -4024,20 +4024,20 @@ return cmd; } -void *scst_cmd_get_tgt_specific_lock(struct scst_cmd *cmd) +void *scst_cmd_get_tgt_priv_lock(struct scst_cmd *cmd) { void *res; unsigned long flags; spin_lock_irqsave(&scst_list_lock, flags); - res = cmd->tgt_specific; + res = cmd->tgt_priv; spin_unlock_irqrestore(&scst_list_lock, flags); return res; } -void scst_cmd_set_tgt_specific_lock(struct scst_cmd *cmd, void *val) +void scst_cmd_set_tgt_priv_lock(struct scst_cmd *cmd, void *val) { unsigned long flags; spin_lock_irqsave(&scst_list_lock, flags); - cmd->tgt_specific = val; + cmd->tgt_priv = val; spin_unlock_irqrestore(&scst_list_lock, flags); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-26 16:59:08
|
Revision: 17 http://svn.sourceforge.net/scst/?rev=17&view=rev Author: vlnb Date: 2006-10-26 09:58:44 -0700 (Thu, 26 Oct 2006) Log Message: ----------- Property svn:ignore set Property Changed: ---------------- / branches/ tags/ trunk/ trunk/doc/ trunk/qla2x00t/ trunk/qla2x00t/qla2x00-target/ trunk/scst/ trunk/scst/include/ trunk/scst/kernel/ trunk/scst/kernel/in-tree/ trunk/scst/src/ trunk/scst/src/dev_handlers/ trunk/www/ Property changes on: ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: branches ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: tags ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: trunk ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: trunk/doc ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: trunk/qla2x00t ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: trunk/qla2x00t/qla2x00-target ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: trunk/scst ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: trunk/scst/include ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: trunk/scst/kernel ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: trunk/scst/kernel/in-tree ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: trunk/scst/src ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: trunk/scst/src/dev_handlers ___________________________________________________________________ Name: svn:ignore - *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Property changes on: trunk/www ___________________________________________________________________ Name: svn:ignore + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-26 16:51:54
|
Revision: 16 http://svn.sourceforge.net/scst/?rev=16&view=rev Author: vlnb Date: 2006-10-26 09:51:41 -0700 (Thu, 26 Oct 2006) Log Message: ----------- Removing of Module.symvers added Modified Paths: -------------- trunk/qla2x00t/Makefile trunk/qla2x00t/qla2x00-target/Makefile trunk/scst/src/Makefile trunk/scst/src/dev_handlers/Makefile Modified: trunk/qla2x00t/Makefile =================================================================== --- trunk/qla2x00t/Makefile 2006-10-26 16:09:56 UTC (rev 15) +++ trunk/qla2x00t/Makefile 2006-10-26 16:51:41 UTC (rev 16) @@ -40,7 +40,7 @@ endif clean: - rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers Module.symvers rm -rf .tmp_versions extraclean: clean Modified: trunk/qla2x00t/qla2x00-target/Makefile =================================================================== --- trunk/qla2x00t/qla2x00-target/Makefile 2006-10-26 16:09:56 UTC (rev 15) +++ trunk/qla2x00t/qla2x00-target/Makefile 2006-10-26 16:51:41 UTC (rev 16) @@ -91,7 +91,7 @@ endif clean: - rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers Module.symvers rm -rf .tmp_versions extraclean: clean Modified: trunk/scst/src/Makefile =================================================================== --- trunk/scst/src/Makefile 2006-10-26 16:09:56 UTC (rev 15) +++ trunk/scst/src/Makefile 2006-10-26 16:51:41 UTC (rev 16) @@ -99,7 +99,7 @@ #EXTRA_CFLAGS += -DSCST_HIGHMEM clean: - rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers Module.symvers rm -rf .tmp_versions cd $(DEV_HANDLERS_DIR) && $(MAKE) $@ Modified: trunk/scst/src/dev_handlers/Makefile =================================================================== --- trunk/scst/src/dev_handlers/Makefile 2006-10-26 16:09:56 UTC (rev 15) +++ trunk/scst/src/dev_handlers/Makefile 2006-10-26 16:51:41 UTC (rev 16) @@ -56,7 +56,7 @@ EXTRA_CFLAGS += -DDEBUG clean: - rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers Module.symvers rm -rf .tmp_versions extraclean: clean This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-26 16:10:11
|
Revision: 15 http://svn.sourceforge.net/scst/?rev=15&view=rev Author: vlnb Date: 2006-10-26 09:09:56 -0700 (Thu, 26 Oct 2006) Log Message: ----------- Added support of non-original kernels (i.e. not 2.6.17) Modified Paths: -------------- trunk/qla2x00t/Kconfig trunk/qla2x00t/ql2400.c trunk/qla2x00t/qla2x00-target/Makefile trunk/qla2x00t/qla2x00-target/README trunk/qla2x00t/qla_os.c Modified: trunk/qla2x00t/Kconfig =================================================================== --- trunk/qla2x00t/Kconfig 2006-10-26 16:08:29 UTC (rev 14) +++ trunk/qla2x00t/Kconfig 2006-10-26 16:09:56 UTC (rev 15) @@ -41,7 +41,7 @@ You will also need the SCST middle level drivers from http://scst.sf.net/. config SCSI_QLA2XXX_EMBEDDED_FIRMWARE - bool " Use firmware-loader modules (DEPRECATED)" + bool "Use firmware-loader modules (DEPRECATED)" depends on SCSI_QLA_FC help This option offers you the deprecated firmware-loader @@ -49,33 +49,33 @@ Firmware Loader interface in the qla2xxx driver. config SCSI_QLA21XX - tristate " Build QLogic ISP2100 firmware-module" + tristate "Build QLogic ISP2100 firmware-module" depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE ---help--- This driver supports the QLogic 21xx (ISP2100) host adapter family. config SCSI_QLA22XX - tristate " Build QLogic ISP2200 firmware-module" + tristate "Build QLogic ISP2200 firmware-module" depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE ---help--- This driver supports the QLogic 22xx (ISP2200) host adapter family. config SCSI_QLA2300 - tristate " Build QLogic ISP2300/ISP6312 firmware-module" + tristate "Build QLogic ISP2300/ISP6312 firmware-module" depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE ---help--- This driver supports the QLogic 2300 (ISP2300, ISP2312 and ISP6312) host adapter family. config SCSI_QLA2322 - tristate " Build QLogic ISP2322/ISP6322 firmware-module" + tristate "Build QLogic ISP2322/ISP6322 firmware-module" depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE ---help--- This driver supports the QLogic 2322 (ISP2322 and ISP6322) host adapter family. config SCSI_QLA24XX - tristate " Build QLogic ISP24xx firmware-module" + tristate "Build QLogic ISP24xx firmware-module" depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE ---help--- This driver supports the QLogic 24xx (ISP2422 and ISP2432) host Modified: trunk/qla2x00t/ql2400.c =================================================================== --- trunk/qla2x00t/ql2400.c 2006-10-26 16:08:29 UTC (rev 14) +++ trunk/qla2x00t/ql2400.c 2006-10-26 16:09:56 UTC (rev 15) @@ -78,6 +78,7 @@ .subdevice = PCI_ANY_ID, .driver_data = (unsigned long)&qla_board_tbl[1], }, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) { .vendor = PCI_VENDOR_ID_QLOGIC, .device = PCI_DEVICE_ID_QLOGIC_ISP5422, @@ -92,7 +93,7 @@ .subdevice = PCI_ANY_ID, .driver_data = (unsigned long)&qla_board_tbl[3], }, - +#endif {0, 0}, }; MODULE_DEVICE_TABLE(pci, qla24xx_pci_tbl); Modified: trunk/qla2x00t/qla2x00-target/Makefile =================================================================== --- trunk/qla2x00t/qla2x00-target/Makefile 2006-10-26 16:08:29 UTC (rev 14) +++ trunk/qla2x00t/qla2x00-target/Makefile 2006-10-26 16:09:56 UTC (rev 15) @@ -56,10 +56,10 @@ else -all: Modules.symvers +all: Modules.symvers Module.symvers $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) BUILD_INI=m -tgt: Modules.symvers +tgt: Modules.symvers Module.symvers $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) BUILD_INI=n install: all @@ -67,9 +67,24 @@ modules_install -depmod -a +SCST_MOD_VERS := $(shell ls $(SCST_DIR)/Modules.symvers 2>/dev/null) +ifneq ($(SCST_MOD_VERS),) Modules.symvers: $(SCST_DIR)/Modules.symvers - -cp $(SCST_DIR)/Modules.symvers . + echo $(SCST_MOD_VERS) + cp $(SCST_DIR)/Modules.symvers . +else +.PHONY: Modules.symvers +endif +# It's renamed in 2.6.18 +SCST_MOD_VERS := $(shell ls $(SCST_DIR)/Module.symvers 2>/dev/null) +ifneq ($(SCST_MOD_VERS),) +Module.symvers: $(SCST_DIR)/Module.symvers + cp $(SCST_DIR)/Module.symvers . +else +.PHONY: Module.symvers +endif + uninstall: rm -f $(INSTALL_DIR)/qla2[23x]00tgt.ko -/sbin/depmod -a Modified: trunk/qla2x00t/qla2x00-target/README =================================================================== --- trunk/qla2x00t/qla2x00-target/README 2006-10-26 16:08:29 UTC (rev 14) +++ trunk/qla2x00t/qla2x00-target/README 2006-10-26 16:09:56 UTC (rev 15) @@ -20,7 +20,9 @@ This version is compatible with SCST version 0.9.5 and higher. -Tested on stable kernels from http://www.kernel.org +Tested on stable kernels from http://www.kernel.org. The original +initiator driver was taken from kernel version 2.6.17.8, but it should +also work on other versions, including 2.6.18.x and 2.6.16.x. NOTE: WWN-based authentification on 2200 cards doesn't always work from ---- the first "connect", but works on all subsequent attempts. Modified: trunk/qla2x00t/qla_os.c =================================================================== --- trunk/qla2x00t/qla_os.c 2006-10-26 16:08:29 UTC (rev 14) +++ trunk/qla2x00t/qla_os.c 2006-10-26 16:09:56 UTC (rev 15) @@ -10,6 +10,7 @@ #include <linux/vmalloc.h> #include <linux/delay.h> #include <linux/kthread.h> +#include <linux/version.h> #include <scsi/scsi_tcq.h> #include <scsi/scsicam.h> @@ -1197,12 +1198,14 @@ ha->device_type |= DT_ISP2432; ha->device_type |= DT_ZIO_SUPPORTED; break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) case PCI_DEVICE_ID_QLOGIC_ISP5422: ha->device_type |= DT_ISP5422; break; case PCI_DEVICE_ID_QLOGIC_ISP5432: ha->device_type |= DT_ISP5432; break; +#endif } } @@ -2168,7 +2171,12 @@ int rval; rval = QLA_SUCCESS; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep); +#else + ha->srb_mempool = mempool_create(SRB_MIN_REQ, mempool_alloc_slab, + mempool_free_slab, srb_cachep); +#endif if (ha->srb_mempool == NULL) { qla_printk(KERN_INFO, ha, "Unable to allocate SRB mempool.\n"); rval = QLA_FUNCTION_FAILED; @@ -2701,10 +2709,12 @@ PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432, PCI_ANY_ID, PCI_ANY_ID, }, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432, PCI_ANY_ID, PCI_ANY_ID, }, +#endif { 0 }, }; MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-26 16:08:53
|
Revision: 14 http://svn.sourceforge.net/scst/?rev=14&view=rev Author: vlnb Date: 2006-10-26 09:08:29 -0700 (Thu, 26 Oct 2006) Log Message: ----------- 1. Added support of 2.6.18 kernels 2. FILEIO_ONLY added Modified Paths: -------------- trunk/scst/ChangeLog trunk/scst/README trunk/scst/include/scsi_tgt.h trunk/scst/src/Makefile trunk/scst/src/scst.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Added Paths: ----------- trunk/scst/kernel/26_scst-2.6.18.patch Modified: trunk/scst/ChangeLog =================================================================== --- trunk/scst/ChangeLog 2006-10-26 13:58:39 UTC (rev 13) +++ trunk/scst/ChangeLog 2006-10-26 16:08:29 UTC (rev 14) @@ -4,6 +4,12 @@ - Fixed many found task management related problems, especially in the RESETs area. DEBUG_TM compilation option added (see README). + - Updated to work on kernels version 2.6.18+. + + - FILEIO_ONLY added. If it's defined, there is no need to patch the + kernel, but pass-through modules (scst_disk, scst_tape, etc.) are not + supported). + - Timer-based retries for targets after SCST_TGT_RES_QUEUE_FULL status implemented. Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2006-10-26 13:58:39 UTC (rev 13) +++ trunk/scst/README 2006-10-26 16:08:29 UTC (rev 14) @@ -134,6 +134,11 @@ There are the following compilation options, that could be commented in/out in Makefile: + - FILEIO_ONLY - if defined, the pass-through device handlers + (scst_disk, scst_tape) will not work, but SCST will not require the + kernel patching. Defined by default to ease new people try SCST on + their kernels. + - DEBUG - turns on some debugging code, including some logging. Makes the driver considerably bigger and slower, producing large amount of log data. @@ -424,12 +429,18 @@ IMPORTANT: If you use on initiator some versions of Windows (at least W2K) ========= you can't get good write performance for FILEIO devices with - default 512 bytes block sizes. You could get about 10% of - the expected one. This is because of "unusual" write access + default 512 bytes block sizes. You could get about 10% of the + expected one. This is because of "unusual" write access pattern, with which Windows'es write data and which is - (simplifying) incompatible with how Linux page cache works. + (simplifying) incompatible with how Linux page cache works, + so for each write the corresponding block must be read first. With 4096 bytes block sizes for FILEIO devices the write - performance will be as expected. + performance will be as expected. Actually, any system on + initiator, not only Windows, will benefit from block size + max(PAGE_SIZE, BLOCK_SIZE_ON_UNDERLYING_FS), where PAGE_SIZE + is the page size, BLOCK_SIZE_ON_UNDERLYING_FS is block size on + the underlying FS, on which the device file located, or 0, if + a device node is used. Both values are on the target. Just for reference: we had with 0.9.2 and "old" Qlogic driver on 2.4.2x kernel, where we did carefull performance study, aggregate throuhput Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2006-10-26 13:58:39 UTC (rev 13) +++ trunk/scst/include/scsi_tgt.h 2006-10-26 16:08:29 UTC (rev 14) @@ -1026,7 +1026,9 @@ struct scst_tgt_dev *tgt_dev; /* corresponding device for this cmd */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) struct scsi_request *scsi_req; /* SCSI request */ +#endif /* List entry for tgt_dev's SN related lists */ struct list_head sn_cmd_list_entry; Added: trunk/scst/kernel/26_scst-2.6.18.patch =================================================================== --- trunk/scst/kernel/26_scst-2.6.18.patch (rev 0) +++ trunk/scst/kernel/26_scst-2.6.18.patch 2006-10-26 16:08:29 UTC (rev 14) @@ -0,0 +1,106 @@ +--- linux-2.6.18.1-scst-dbg/drivers/scsi/scsi_lib.c_scst 2006-09-20 07:42:06.000000000 +0400 ++++ linux-2.6.18.1-scst-dbg/drivers/scsi/scsi_lib.c 2006-10-25 20:52:58.000000000 +0400 +@@ -367,7 +367,7 @@ + } + + /** +- * scsi_execute_async - insert request ++ * __scsi_execute_async - insert request + * @sdev: scsi device + * @cmd: scsi command + * @cmd_len: length of scsi cdb +@@ -378,11 +378,14 @@ + * @timeout: request timeout in seconds + * @retries: number of times to retry request + * @flags: or into request flags ++ * @at_head: insert request at head or tail of queue + **/ +-int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++static inline int __scsi_execute_async(struct scsi_device *sdev, ++ const unsigned char *cmd, + int cmd_len, int data_direction, void *buffer, unsigned bufflen, + int use_sg, int timeout, int retries, void *privdata, +- void (*done)(void *, char *, int, int), gfp_t gfp) ++ void (*done)(void *, char *, int, int), gfp_t gfp, ++ int at_head) + { + struct request *req; + struct scsi_io_context *sioc; +@@ -418,7 +421,7 @@ + sioc->data = privdata; + sioc->done = done; + +- blk_execute_rq_nowait(req->q, NULL, req, 1, scsi_end_async); ++ blk_execute_rq_nowait(req->q, NULL, req, at_head, scsi_end_async); + return 0; + + free_req: +@@ -427,8 +430,53 @@ + kfree(sioc); + return DRIVER_ERROR << 24; + } ++ ++/** ++ * scsi_execute_async - insert request ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, unsigned bufflen, ++ int use_sg, int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 1); ++} + EXPORT_SYMBOL_GPL(scsi_execute_async); + ++/** ++ * scsi_execute_async_fifi - insert request at tail, in FIFO order ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async_fifo(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, unsigned bufflen, ++ int use_sg, int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 0); ++} ++EXPORT_SYMBOL_GPL(scsi_execute_async_fifo); ++ + /* + * Function: scsi_init_cmd_errh() + * +--- linux-2.6.18.1-scst-dbg/include/scsi/scsi_device.h_scst 2006-09-20 07:42:06.000000000 +0400 ++++ linux-2.6.18.1-scst-dbg/include/scsi/scsi_device.h 2006-10-25 20:09:23.000000000 +0400 +@@ -297,6 +297,12 @@ + int timeout, int retries, void *privdata, + void (*done)(void *, char *, int, int), + gfp_t gfp); ++extern int scsi_execute_async_fifo(struct scsi_device *sdev, ++ const unsigned char *cmd, int cmd_len, int data_direction, ++ void *buffer, unsigned bufflen, int use_sg, ++ int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), ++ gfp_t gfp); + + static inline void scsi_device_reprobe(struct scsi_device *sdev) + { Modified: trunk/scst/src/Makefile =================================================================== --- trunk/scst/src/Makefile 2006-10-26 13:58:39 UTC (rev 13) +++ trunk/scst/src/Makefile 2006-10-26 16:08:29 UTC (rev 14) @@ -75,7 +75,8 @@ #EXTRA_CFLAGS += -DSTRICT_SERIALIZING -EXTRA_CFLAGS += -DEXTRACHECKS +EXTRA_CFLAGS += -DEXTRACHECKS +#EXTRA_CFLAGS += -DFILEIO_ONLY #EXTRA_CFLAGS += -fno-inline Modified: trunk/scst/src/scst.c =================================================================== --- trunk/scst/src/scst.c 2006-10-26 13:58:39 UTC (rev 13) +++ trunk/scst/src/scst.c 2006-10-26 16:08:29 UTC (rev 14) @@ -631,6 +631,16 @@ goto out; } +#ifdef FILEIO_ONLY + if (dev_type->exec == NULL) { + PRINT_ERROR_PR("Pass-through dev handlers (handler %s) not " + "supported. Recompile SCST with undefined FILEIO_ONLY", + dev_type->name); + res = -EINVAL; + goto out; + } +#endif + if (down_interruptible(&scst_mutex) != 0) { res = -EINTR; goto out; @@ -950,11 +960,22 @@ { int res = 0, i; struct scst_cmd *cmd; - struct scsi_request *req; TRACE_ENTRY(); - BUILD_BUG_ON(sizeof(cmd->sense_buffer) != sizeof(req->sr_sense_buffer)); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + { + struct scsi_request *req; + BUILD_BUG_ON(sizeof(cmd->sense_buffer) != + sizeof(req->sr_sense_buffer)); + } +#else + { + struct scsi_sense_hdr *shdr; + BUILD_BUG_ON((sizeof(cmd->sense_buffer) < sizeof(*shdr)) && + (sizeof(cmd->sense_buffer) >= SCSI_SENSE_BUFFERSIZE)); + } +#endif scst_num_cpus = get_cpus_count(); @@ -1130,6 +1151,9 @@ static void __exit exit_scst(void) { +#ifdef CONFIG_LOCKDEP + static /* To hide the lockdep's warning about non-static key */ +#endif DECLARE_MUTEX_LOCKED(shm); TRACE_ENTRY(); Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2006-10-26 13:58:39 UTC (rev 13) +++ trunk/scst/src/scst_lib.c 2006-10-26 16:08:29 UTC (rev 14) @@ -711,6 +711,7 @@ return res; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) static void scst_req_done(struct scsi_cmnd *scsi_cmd) { struct scsi_request *req; @@ -776,7 +777,42 @@ TRACE_EXIT(); return; } +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */ +static void scst_send_release(struct scst_tgt_dev *tgt_dev) +{ + struct scsi_device *scsi_dev; + unsigned char cdb[6]; + unsigned char sense[SCSI_SENSE_BUFFERSIZE]; + int rc; + TRACE_ENTRY(); + + if (tgt_dev->acg_dev->dev->scsi_dev == NULL) + goto out; + + scsi_dev = tgt_dev->acg_dev->dev->scsi_dev; + + memset(cdb, 0, sizeof(cdb)); + cdb[0] = RELEASE; + cdb[1] = (scsi_dev->scsi_level <= SCSI_2) ? + ((scsi_dev->lun << 5) & 0xe0) : 0; + + TRACE(TRACE_DEBUG | TRACE_SCSI, "%s", "Sending RELEASE req to SCSI " + "mid-level"); + rc = scsi_execute(scsi_dev, cdb, SCST_DATA_NONE, NULL, 0, + sense, SCST_DEFAULT_TIMEOUT, + 3, GFP_KERNEL); + if (rc) { + PRINT_INFO_PR("scsi_execute() failed: %d", rc); + goto out; + } + +out: + TRACE_EXIT(); + return; +} +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */ + struct scst_session *scst_alloc_session(struct scst_tgt *tgt, int gfp_mask, const char *initiator_name) { @@ -944,7 +980,7 @@ BUG_ON(cmd->blocking); -#ifdef EXTRACHECKS +#if defined(EXTRACHECKS) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) if (cmd->scsi_req) { PRINT_ERROR_PR("%s: %s", __FUNCTION__, "Cmd with unfreed " "scsi_req!"); @@ -1114,6 +1150,7 @@ return; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) int scst_alloc_request(struct scst_cmd *cmd) { int res = 0; @@ -1154,6 +1191,7 @@ scsi_release_request(cmd->scsi_req); cmd->scsi_req = NULL; } +#endif int scst_alloc_space(struct scst_cmd *cmd) { Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2006-10-26 13:58:39 UTC (rev 13) +++ trunk/scst/src/scst_priv.h 2006-10-26 16:08:29 UTC (rev 14) @@ -24,9 +24,12 @@ #include <scsi/scsi_cmnd.h> #include <scsi/scsi_driver.h> #include <scsi/scsi_device.h> -#include <scsi/scsi_request.h> #include <scsi/scsi_host.h> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +#include <scsi/scsi_request.h> +#endif + #define SCST_MAJOR 177 #define TRACE_RETRY 0x80000000 @@ -250,6 +253,7 @@ void scst_check_retries(struct scst_tgt *tgt, int processible_env); void scst_tgt_retry_timer_fn(unsigned long arg); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) int scst_alloc_request(struct scst_cmd *cmd); void scst_release_request(struct scst_cmd *cmd); @@ -257,12 +261,33 @@ const void *cmnd, void *buffer, unsigned bufflen, void (*done)(struct scsi_cmnd *), int timeout, int retries) { -#ifdef STRICT_SERIALIZING + #ifdef STRICT_SERIALIZING scsi_do_req(sreq, cmnd, buffer, bufflen, done, timeout, retries); + #elif defined(FILEIO_ONLY) + BUG(); + #else + scsi_do_req_fifo(sreq, cmnd, buffer, bufflen, done, timeout, retries); + #endif +} #else - scsi_do_req_fifo(sreq, cmnd, buffer, bufflen, done, timeout, retries); +static inline int scst_exec_req(struct scsi_device *sdev, + const unsigned char *cmd, int cmd_len, int data_direction, + void *buffer, unsigned bufflen, int use_sg, int timeout, int retries, + void *privdata, void (*done)(void *, char *, int, int), gfp_t gfp) +{ + #ifdef STRICT_SERIALIZING + return scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, + bufflen, use_sg, timeout, retries, privdata, done, gfp); + #elif defined(FILEIO_ONLY) + BUG(); + return -1; + #else + return scsi_execute_async_fifo(sdev, cmd, cmd_len, data_direction, + buffer, bufflen, use_sg, timeout, retries, privdata, done, gfp); + #endif +} #endif -} + int scst_alloc_space(struct scst_cmd *cmd); void scst_release_space(struct scst_cmd *cmd); void scst_scsi_op_list_init(void); Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2006-10-26 13:58:39 UTC (rev 13) +++ trunk/scst/src/scst_targ.c 2006-10-26 16:08:29 UTC (rev 14) @@ -823,8 +823,8 @@ } /* No locks supposed to be held */ -static void scst_check_sense(struct scst_cmd *cmd, struct scsi_request *req, - int *next_state) +static void scst_check_sense(struct scst_cmd *cmd, const uint8_t *rq_sense, + int rq_sense_len, int *next_state) { int sense_valid; struct scst_device *dev = cmd->dev; @@ -848,11 +848,15 @@ smp_mb(); } - if (req != NULL) { - sense_valid = SCST_SENSE_VALID(req->sr_sense_buffer); + if (rq_sense != NULL) { + sense_valid = SCST_SENSE_VALID(rq_sense); if (sense_valid) { - memcpy(cmd->sense_buffer, req->sr_sense_buffer, - sizeof(cmd->sense_buffer)); + memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); + /* + * We checked that rq_sense_len < sizeof(cmd->sense_buffer) + * in init_scst() + */ + memcpy(cmd->sense_buffer, rq_sense, rq_sense_len); } } else sense_valid = SCST_SENSE_VALID(cmd->sense_buffer); @@ -971,38 +975,60 @@ return res; } -static void scst_do_cmd_done(struct scst_cmd *cmd, - struct scsi_request *req, int *next_state) +static void scst_do_cmd_done(struct scst_cmd *cmd, int result, + const uint8_t *rq_sense, int rq_sense_len, int *next_state) { + unsigned char type; + TRACE_ENTRY(); - cmd->status = req->sr_result & 0xff; - cmd->masked_status = status_byte(req->sr_result); - cmd->msg_status = msg_byte(req->sr_result); - cmd->host_status = host_byte(req->sr_result); - cmd->driver_status = driver_byte(req->sr_result); - TRACE(TRACE_SCSI, "req->sr_result=%x, cmd->status=%x, " + cmd->status = result & 0xff; + cmd->masked_status = status_byte(result); + cmd->msg_status = msg_byte(result); + cmd->host_status = host_byte(result); + cmd->driver_status = driver_byte(result); + TRACE(TRACE_SCSI, "result=%x, cmd->status=%x, " "cmd->masked_status=%x, cmd->msg_status=%x, cmd->host_status=%x, " - "cmd->driver_status=%x", req->sr_result, cmd->status, + "cmd->driver_status=%x", result, cmd->status, cmd->masked_status, cmd->msg_status, cmd->host_status, cmd->driver_status); - scst_check_sense(cmd, req, next_state); + cmd->completed = 1; - cmd->bufflen = req->sr_bufflen; //?? + scst_dec_on_dev_cmd(cmd); - /* Clear out request structure */ - req->sr_use_sg = 0; - req->sr_sglist_len = 0; - req->sr_bufflen = 0; - req->sr_buffer = NULL; - req->sr_underflow = 0; - req->sr_request->rq_disk = NULL; /* disown request blk */ ; + type = cmd->dev->handler->type; + if ((cmd->cdb[0] == MODE_SENSE || cmd->cdb[0] == MODE_SENSE_10) && + cmd->tgt_dev->acg_dev->rd_only_flag && + (type == TYPE_DISK || type == TYPE_WORM || type == TYPE_MOD || + type == TYPE_TAPE)) { + int32_t length; + uint8_t *address; + length = scst_get_buf_first(cmd, &address); + TRACE_DBG("length %d", length); + if (unlikely(length <= 0)) { + PRINT_ERROR_PR("%s: scst_get_buf_first() failed", + __func__); + goto next; + } + if (length > 2 && cmd->cdb[0] == MODE_SENSE) { + address[2] |= 0x80; /* Write Protect*/ + } + else if (length > 3 && cmd->cdb[0] == MODE_SENSE_10) { + address[3] |= 0x80; /* Write Protect*/ + } + scst_put_buf(cmd, address); + } + +next: + scst_check_sense(cmd, rq_sense, rq_sense_len, next_state); + TRACE_EXIT(); return; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) static inline struct scst_cmd *scst_get_cmd(struct scsi_cmnd *scsi_cmd, struct scsi_request **req) { @@ -1025,7 +1051,6 @@ struct scsi_request *req = NULL; struct scst_cmd *cmd; int next_state; - unsigned char type; TRACE_ENTRY(); @@ -1044,38 +1069,58 @@ if (cmd == NULL) goto out; - cmd->completed = 1; + next_state = SCST_CMD_STATE_DEV_DONE; + scst_do_cmd_done(cmd, req->sr_result, req->sr_sense_buffer, + sizeof(req->sr_sense_buffer), &next_state); - scst_dec_on_dev_cmd(cmd); + /* Clear out request structure */ + req->sr_use_sg = 0; + req->sr_sglist_len = 0; + req->sr_bufflen = 0; + req->sr_buffer = NULL; + req->sr_underflow = 0; + req->sr_request->rq_disk = NULL; /* disown request blk */ - type = cmd->dev->handler->type; - if ((cmd->cdb[0] == MODE_SENSE || cmd->cdb[0] == MODE_SENSE_10) && - cmd->tgt_dev->acg_dev->rd_only_flag && - (type == TYPE_DISK || type == TYPE_WORM || type == TYPE_MOD || - type == TYPE_TAPE)) { - int32_t length; - uint8_t *address; + cmd->bufflen = req->sr_bufflen; //?? - length = scst_get_buf_first(cmd, &address); - TRACE_DBG("length %d", length); - if (unlikely(length <= 0)) { - goto out; - } - if (length > 2 && cmd->cdb[0] == MODE_SENSE) { - address[2] |= 0x80; /* Write Protect*/ - } - else if (length > 3 && cmd->cdb[0] == MODE_SENSE_10) { - address[3] |= 0x80; /* Write Protect*/ - } - scst_put_buf(cmd, address); - } + scst_release_request(cmd); - next_state = SCST_CMD_STATE_DEV_DONE; + cmd->state = next_state; + cmd->non_atomic_only = 0; - scst_do_cmd_done(cmd, req, &next_state); + __scst_process_active_cmd(cmd, scst_get_context(), 0); - scst_release_request(cmd); +out: + TRACE_EXIT(); + return; +} +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */ +static void scst_cmd_done(void *data, char *sense, int result, int resid) +{ + struct scst_cmd *cmd; + int next_state; + TRACE_ENTRY(); + + WARN_ON(in_irq()); + + /* + * We don't use resid, because: + * 1. Many low level initiator drivers don't use (set) this field + * 2. We determine the command's buffer size directly from CDB, + * so resid is not relevant for us, and target drivers + * should know the residual, if necessary, by comparing expected + * and actual transfer sizes. + */ + + cmd = (struct scst_cmd *)data; + if (cmd == NULL) + goto out; + + next_state = SCST_CMD_STATE_DEV_DONE; + scst_do_cmd_done(cmd, result, sense, SCSI_SENSE_BUFFERSIZE, + &next_state); + cmd->state = next_state; cmd->non_atomic_only = 0; @@ -1085,6 +1130,7 @@ TRACE_EXIT(); return; } +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */ static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state) { @@ -1133,7 +1179,7 @@ } #endif - scst_check_sense(cmd, NULL, &next_state); + scst_check_sense(cmd, NULL, 0, &next_state); cmd->state = next_state; cmd->non_atomic_only = 0; @@ -1557,7 +1603,8 @@ (uint64_t)cmd->lun); goto out_error; } - + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) if (scst_alloc_request(cmd) != 0) { PRINT_INFO_PR("%s", "Unable to allocate request, " "sending BUSY status"); @@ -1568,6 +1615,16 @@ (void *)cmd->scsi_req->sr_buffer, cmd->scsi_req->sr_bufflen, scst_cmd_done, cmd->timeout, cmd->retries); +#else + rc = scst_exec_req(cmd->dev->scsi_dev, cmd->cdb, cmd->cdb_len, + cmd->data_direction, cmd->sg, cmd->bufflen, cmd->sg_cnt, + cmd->timeout, cmd->retries, cmd, scst_cmd_done, + GFP_KERNEL); + if (rc) { + PRINT_INFO_PR("scst_exec_req() failed: %d", rc); + goto out_error; + } +#endif rc = SCST_EXEC_COMPLETED; @@ -1593,7 +1650,8 @@ rc = SCST_EXEC_COMPLETED; scst_cmd_done_local(cmd, SCST_CMD_STATE_DEFAULT); goto out; - + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) out_busy: scst_set_busy(cmd); cmd->completed = 1; @@ -1601,6 +1659,7 @@ rc = SCST_EXEC_COMPLETED; scst_cmd_done_local(cmd, SCST_CMD_STATE_DEFAULT); goto out; +#endif out_aborted: rc = SCST_EXEC_COMPLETED; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-26 13:58:46
|
Revision: 13 http://svn.sourceforge.net/scst/?rev=13&view=rev Author: vlnb Date: 2006-10-26 06:58:39 -0700 (Thu, 26 Oct 2006) Log Message: ----------- Oops, previous commit erased ERASE16. Fixed. Modified Paths: -------------- trunk/scst/src/scst_cdbprobe.h Modified: trunk/scst/src/scst_cdbprobe.h =================================================================== --- trunk/scst/src/scst_cdbprobe.h 2006-10-26 13:56:42 UTC (rev 12) +++ trunk/scst/src/scst_cdbprobe.h 2006-10-26 13:58:39 UTC (rev 13) @@ -383,6 +383,8 @@ SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0}, {0x93, "O O ", "WRITE SAME(16)", SCST_DATA_WRITE, 4, SCST_UNKNOWN_LENGTH, 1, 0}, /*N2! */ + {0x93, " M ", "ERASE(16)", + SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0}, {0x9E, "M ", "SERVICE ACTION IN", SCST_DATA_READ, 4, 0, 0, 0}, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-26 13:57:20
|
Revision: 12 http://svn.sourceforge.net/scst/?rev=12&view=rev Author: vlnb Date: 2006-10-26 06:56:42 -0700 (Thu, 26 Oct 2006) Log Message: ----------- Added SERVICE ACTION IN in scst_scsi_op_table Modified Paths: -------------- trunk/scst/src/scst_cdbprobe.h Modified: trunk/scst/src/scst_cdbprobe.h =================================================================== --- trunk/scst/src/scst_cdbprobe.h 2006-10-20 18:29:55 UTC (rev 11) +++ trunk/scst/src/scst_cdbprobe.h 2006-10-26 13:56:42 UTC (rev 12) @@ -383,8 +383,8 @@ SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0}, {0x93, "O O ", "WRITE SAME(16)", SCST_DATA_WRITE, 4, SCST_UNKNOWN_LENGTH, 1, 0}, /*N2! */ - {0x93, " M ", "ERASE(16)", - SCST_DATA_NONE, 0, SCST_LONG_TIMEOUT, 0, 0}, + {0x9E, "M ", "SERVICE ACTION IN", + SCST_DATA_READ, 4, 0, 0, 0}, /* 12-bytes length CDB */ {0xA0, "VVVVVVVVVV M ", "REPORT LUN", This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-20 18:30:02
|
Revision: 11 http://svn.sourceforge.net/scst/?rev=11&view=rev Author: vlnb Date: 2006-10-20 11:29:55 -0700 (Fri, 20 Oct 2006) Log Message: ----------- Debugging cleanups Modified Paths: -------------- trunk/qla2x00t/qla2x00-target/qla2x00t.c Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-10-20 18:18:46 UTC (rev 10) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-10-20 18:29:55 UTC (rev 11) @@ -772,10 +772,10 @@ prm.residual = le32_to_cpu(prm.cmd->atio.data_length) - prm.bufflen; if (prm.residual > 0) { - TRACE_MGMT_DBG("Residual underflow: %d", prm.residual); + TRACE_DBG("Residual underflow: %d", prm.residual); prm.rq_result |= SS_RESIDUAL_UNDER; } else if (prm.residual < 0) { - TRACE_MGMT_DBG("Residual overflow: %d", prm.residual); + TRACE_DBG("Residual overflow: %d", prm.residual); prm.rq_result |= SS_RESIDUAL_OVER; prm.residual = -prm.residual; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-20 18:19:19
|
Revision: 10 http://svn.sourceforge.net/scst/?rev=10&view=rev Author: vlnb Date: 2006-10-20 11:18:46 -0700 (Fri, 20 Oct 2006) Log Message: ----------- In FILEIO: - Improved errors reporting - Improved SYNCHRONIZE_CACHE support, fsync() reimplemented - Improved ORDERED commands support - Added FUA support - Added NV_CACHE - Improved CDROM FILEIO Modified Paths: -------------- trunk/scst/ChangeLog trunk/scst/README trunk/scst/include/scsi_tgt.h trunk/scst/src/dev_handlers/scst_dev_handler.h trunk/scst/src/dev_handlers/scst_fileio.c trunk/scst/src/scst.c Modified: trunk/scst/ChangeLog =================================================================== --- trunk/scst/ChangeLog 2006-10-17 09:22:31 UTC (rev 9) +++ trunk/scst/ChangeLog 2006-10-20 18:18:46 UTC (rev 10) @@ -12,6 +12,9 @@ - Fixed broken CDROM FILEIO. Before that it always reported "No medium found" + - Data synchronization fixes and improvements in FILEIO. Added FUA + support. + - Fixed READ(6)/WRITE(6) CDB decoding for block devices. This bug prevented FreeBSD initiators from working. Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2006-10-17 09:22:31 UTC (rev 9) +++ trunk/scst/README 2006-10-20 18:18:46 UTC (rev 10) @@ -13,13 +13,12 @@ SCST looks to be quite stable (for beta) and useful. It supports disks (SCSI type 0), tapes (type 1), processor (type 3), CDROM's (type 5), MO disks (type 7), medium changers (type 8) and RAID controller (type 0xC). -There are also FILEIO and "performance" device handlers. In addition, -starting from version 0.9.3 advanced per-initiator access and devices -visibility management is added, so different initiators could see -different set of devices with different access permissions. See below -for details. +There are also FILEIO and "performance" device handlers. In addition, it +supports advanced per-initiator access and devices visibility +management, so different initiators could see different set of devices +with different access permissions. See below for details. -This is more or less stable (but still beta) version. +This is quite stable (but still beta) version. Tested mostly on "vanilla" 2.6.17.8 kernel from kernel.org. @@ -53,9 +52,6 @@ exec() method skip (pretend to execute) all READ and WRITE operations and thus provide a way for direct link performance measurements without overhead of actual data transferring from/to underlying SCSI device. -Starting from 0.9.3 these handlers are incorporated inside of -corresponding device handler for real device and could be assigned on -run-time via "assign" command in "/proc/scsi_tgt/scsi_tgt" (see below). NOTE: Since "perf" device handlers on READ operations don't touch the ==== commands' data buffer, it is returned to remote initiators as it @@ -105,7 +101,7 @@ are seen remotely. There must be LUN 0 in each security group, i.e. LUs numeration must not start from, e.g., 1. -IMPORTANT: without loading appropriate device handler, corresponding devices +IMPORTANT: Without loading appropriate device handler, corresponding devices ========= will be invisible for remote initiators, which could lead to holes in the LUN addressing, so automatic device scanning by remote SCSI mid-level could not notice the devices. Therefore you will have @@ -113,15 +109,15 @@ 'echo "scsi add-single-device A 0 0 B" >/proc/scsi/scsi', where A - is the host number, B - LUN. -IMPORTANT 1: In the current version simultaneous access to local SCSI -=========== devices via standard high-level SCSI drivers (sd, st, sg, - etc.) and SCST's target drivers is unsupported. Especially - it is important for execution via sg and st commands that - change the state of devices and their parameters, because - that could lead to data corruption. If any such command - is done, at least related device handler driver(s) must be - restarted. For block devices READ/WRITE commands using direct - disk handler look to be safe. +IMPORTANT: In the current version simultaneous access to local SCSI devices +========= via standard high-level SCSI drivers (sd, st, sg, etc.) and + SCST's target drivers is unsupported. Especially it is + important for execution via sg and st commands that change + the state of devices and their parameters, because that could + lead to data corruption. If any such command is done, at + least related device handler driver(s) must be restarted. For + block devices READ/WRITE commands using direct disk handler + look to be safe. To uninstall, type 'make uninstall'. It is not implemented for 2.6 kernels. @@ -302,8 +298,10 @@ information of currently open device files. On write it supports the following command: - * "open NAME PATH [FLAGS]" - opens file "PATH" as device "NAME" with - flags "FLAGS. Possible flags: + * "open NAME PATH [BLOCK_SIZE] [FLAGS]" - opens file "PATH" as + device "NAME" with block size "BLOCK_SIZE" bytes with flags + "FLAGS". The block size must be power of 2 and >= 512 bytes + Default is 512. Possible flags: - WRITE_THROUGH - write back caching disabled @@ -315,21 +313,61 @@ - NULLIO - in this mode no real IO will be done, but success will be returned. Intended to be used for performance measurements at the same way as "*_perf" handlers. + + - NV_CACHE - enables "non-volatile cache" mode. In this mode it is + assumed that the target has GOOD uninterruptable power supply + and software/hardware bug free, i.e. all data from the target's + cache are guaranteed sooner or later to go to the media, hence + all data synchronization with media operations, like + SYNCHRONIZE_CACHE, are ignored (BTW, so violating SCSI standard) + in order to bring a bit more performance. Use with extreme + caution, since in this mode after a crash of the target + journaled file systems don't guarantee the consistency after + journal recovery, therefore manual fsck MUST be ran. The main + intent for it is to determine the performance impact caused by + the cache synchronization. Note, that since usually the journal + barrier protection (see "IMPORTANT" below) turned off, enabling + NV_CACHE could change nothing, since no data synchronization + with media operations will go from the initiator. * "close NAME" - closes device "NAME". For example, "echo "open disk1 /vdisks/disk1" >/proc/scsi_tgt/disk_fileio/disk_fileio" will open file /vdisks/disk1 as virtual FILEIO disk with name "disk1". -IMPORTANT: by default for performance reasons FILEIO devices use write back -========= caching policy, so if you care about the consistence of file systems, - laying over them, and your data you must supply your target - server with some king of UPS or disable write back caching - via WRITE_THROUGH flag. The FS joutnaling over write back - caching enabled devices doesn't protect from power failures - on the target side, therefore even after successful journal - rollback you very much risk to loose your data. +IMPORTANT: By default for performance reasons FILEIO devices use write back +========= caching policy. This is generally safe from the consistence of + journaled file systems, laying over them, point of view, but + your unsaved cached data will be lost in case of + power/hardware/software faulure, so you must supply your + target server with some kind of UPS or disable write back + caching using WRITE_THROUGH flag. You also should note, that + the file systems journaling over write back caching enabled + devices works reliably *ONLY* if it uses some kind of data + protection barriers (i.e. after writing journaling data some + kind of synchronization with media operations will be used), + otherwise, because of possible reordering in the cache, even + after successful journal rollback you very much risk to loose + your data on the FS. On Linux initiators for EXT3 and + ReiserFS file systems the barrier protection could be turned + on using "barrier=1" and "barrier=flush" mount options + correspondingly. Note, that usually it turned off by default + and the status of barriers usage isn't reported anywhere in + the system logs as well as there is no way to know it on the + mounted file system (at least we don't know how). Also note + that on some real-life workloads write through caching might + perform better, than write back one with barrier protection + turned on. +IMPORTANT: Many disk and partition table mananagement utilities don't support +========= block sizes >512 bytes, therefore make sure that your favorite one + supports it. Also, if you export disk file or device with + another block size, than one, with which it was already + divided on partitions, you could get various weird things + like utilities hang up or other unexpected behaviour. Thus, to + be sure, zero the exported file or device before the first + access to it from the remote initiator with another block size. + Performance ----------- @@ -384,6 +422,15 @@ that in some cases it could lead to 5-10 times less performance, than expected. +IMPORTANT: If you use on initiator some versions of Windows (at least W2K) +========= you can't get good write performance for FILEIO devices with + default 512 bytes block sizes. You could get about 10% of + the expected one. This is because of "unusual" write access + pattern, with which Windows'es write data and which is + (simplifying) incompatible with how Linux page cache works. + With 4096 bytes block sizes for FILEIO devices the write + performance will be as expected. + Just for reference: we had with 0.9.2 and "old" Qlogic driver on 2.4.2x kernel, where we did carefull performance study, aggregate throuhput about 390 Mb/sec from 2 qla2300 cards sitting on different 64-bit PCI @@ -394,10 +441,7 @@ The target computer configuration was not very modern for the moment: something like 2x1GHz Intel P3 Xeon CPUs. You can estimate the memory/PCI speed from that. CPU load was ~5%, there were ~30K IRQ/sec -and no additional SCST related context switches. Version 0.9.3 at the -same setup will usually have 1 CS/cmd for buffer allocation, so the will -be about 5-10K CS/sec. This will be fixed in the next version, when -sgv_pool is integrated. +and no additional SCST related context switches. Credits ------- Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2006-10-17 09:22:31 UTC (rev 9) +++ trunk/scst/include/scsi_tgt.h 2006-10-20 18:18:46 UTC (rev 10) @@ -1388,6 +1388,9 @@ #define scst_sense_miscompare_error MISCOMPARE, 0x1D, 0 #define scst_sense_block_out_range_error ILLEGAL_REQUEST, 0x21, 0 #define scst_sense_medium_changed_UA UNIT_ATTENTION, 0x28, 0 +#define scst_sense_read_error MEDIUM_ERROR, 0x11, 0 +#define scst_sense_write_error MEDIUM_ERROR, 0x03, 0 +#define scst_sense_not_ready NOT_READY, 0x04, 0x10 #ifndef smp_mb__after_set_bit /* There is no smp_mb__after_set_bit() in the kernel */ @@ -2055,5 +2058,11 @@ */ int scst_check_mem(struct scst_cmd *cmd); +/* + * Get/put global ref counter that prevents from entering into suspended + * activities stage, so protects from any global management operations. + */ +void scst_get(void); +void scst_put(void); #endif /* __SCST_H */ Modified: trunk/scst/src/dev_handlers/scst_dev_handler.h =================================================================== --- trunk/scst/src/dev_handlers/scst_dev_handler.h 2006-10-17 09:22:31 UTC (rev 9) +++ trunk/scst/src/dev_handlers/scst_dev_handler.h 2006-10-20 18:18:46 UTC (rev 10) @@ -11,7 +11,8 @@ #ifdef DEBUG #define SCST_DEFAULT_DEV_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_PID | \ - TRACE_FUNCTION | TRACE_MGMT | TRACE_MINOR | TRACE_MGMT_DEBUG) + TRACE_FUNCTION | TRACE_MGMT | TRACE_MINOR | TRACE_MGMT_DEBUG | \ + TRACE_SPECIAL) #else #define SCST_DEFAULT_DEV_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR) #endif Modified: trunk/scst/src/dev_handlers/scst_fileio.c =================================================================== --- trunk/scst/src/dev_handlers/scst_fileio.c 2006-10-17 09:22:31 UTC (rev 9) +++ trunk/scst/src/dev_handlers/scst_fileio.c 2006-10-20 18:18:46 UTC (rev 10) @@ -31,6 +31,7 @@ #include <linux/proc_fs.h> #include <linux/list.h> #include <linux/ctype.h> +#include <linux/writeback.h> #include <asm/atomic.h> #define LOG_PREFIX "dev_fileio" @@ -57,6 +58,7 @@ #define MSENSE_BUF_SZ 256 #define DBD 0x08 /* disable block descriptor */ #define WP 0x80 /* write protect */ +#define DPOFUA 0x10 /* DPOFUA bit */ #define WCE 0x04 /* write cache enable */ #define PF 0x10 /* page format */ @@ -86,10 +88,12 @@ loff_t file_size; /* in bytes */ unsigned int rd_only_flag:1; unsigned int wt_flag:1; + unsigned int nv_cache:1; unsigned int o_direct_flag:1; unsigned int media_changed:1; unsigned int prevent_allow_medium_removal:1; unsigned int nullio:1; + unsigned int cdrom_empty:1; int virt_id; char name[16+1]; /* Name of virtual device, must be <= SCSI Model + 1 */ @@ -107,6 +111,7 @@ int iv_count; struct list_head fdev_cmd_list; wait_queue_head_t fdev_waitQ; + struct scst_fileio_dev *virt_dev; atomic_t threads_count; struct semaphore shutdown_mutex; struct list_head ftgt_list_entry; @@ -132,7 +137,8 @@ static void fileio_exec_mode_select(struct scst_cmd *cmd); static void fileio_exec_read_toc(struct scst_cmd *cmd); static void fileio_exec_prevent_allow_medium_removal(struct scst_cmd *cmd); -static int fileio_fsync(struct scst_cmd *cmd, uint64_t lba_start, uint32_t number_of_blocks); +static int fileio_fsync(struct scst_fileio_tgt_dev *ftgt_dev, + loff_t loff, loff_t len, struct scst_cmd *cmd); static int disk_fileio_proc(char *buffer, char **start, off_t offset, int length, int *eof, struct scst_dev_type *dev_type, int inout); static int cdrom_fileio_proc(char *buffer, char **start, off_t offset, @@ -180,9 +186,9 @@ static struct scst_dev_type cdrom_devtype_fileio = CDROM_TYPE_FILEIO; static char *disk_fileio_proc_help_string = - "echo \"open|close NAME [FILE_NAME [WRITE_THROUGH READ_ONLY " - "O_DIRECT NULLIO]]\" >/proc/scsi_tgt/" DISK_FILEIO_NAME "/" - DISK_FILEIO_NAME "\n"; + "echo \"open|close NAME [FILE_NAME [BLOCK_SIZE] [WRITE_THROUGH " + "READ_ONLY O_DIRECT NULLIO NV_CACHE]]\" >/proc/scsi_tgt/" + DISK_FILEIO_NAME "/" DISK_FILEIO_NAME "\n"; static char *cdrom_fileio_proc_help_string = "echo \"open|change|close NAME [FILE_NAME]\" " @@ -274,59 +280,66 @@ if (dev->handler->type == TYPE_ROM) virt_dev->rd_only_flag = 1; - fd = fileio_open(virt_dev); - if (IS_ERR(fd)) { - res = PTR_ERR(fd); - PRINT_ERROR_PR("filp_open(%s) returned an error %d", - virt_dev->file_name, res); - goto out; - } + if (!virt_dev->cdrom_empty) { + fd = fileio_open(virt_dev); + if (IS_ERR(fd)) { + res = PTR_ERR(fd); + PRINT_ERROR_PR("filp_open(%s) returned an error %d", + virt_dev->file_name, res); + goto out; + } - if ((fd->f_op == NULL) || (fd->f_op->readv == NULL) || - (fd->f_op->writev == NULL)) - { - PRINT_ERROR_PR("%s", "Wrong f_op or FS doesn't have required " - "capabilities"); - res = -EINVAL; - goto out_close_file; - } + if ((fd->f_op == NULL) || (fd->f_op->readv == NULL) || + (fd->f_op->writev == NULL)) + { + PRINT_ERROR_PR("%s", "Wrong f_op or FS doesn't have " + "required capabilities"); + res = -EINVAL; + goto out_close_file; + } - /* seek to end */ - old_fs = get_fs(); - set_fs(get_ds()); - if (fd->f_op->llseek) { - err = fd->f_op->llseek(fd, 0, 2/*SEEK_END*/); - } else { - err = default_llseek(fd, 0, 2/*SEEK_END*/); - } - set_fs(old_fs); - if (err < 0) { - res = err; - PRINT_ERROR_PR("llseek %s returned an error %d", - virt_dev->file_name, res); - goto out_close_file; - } - virt_dev->file_size = err; - TRACE_DBG("size of file: %Ld", (uint64_t)err); + /* seek to end */ + old_fs = get_fs(); + set_fs(get_ds()); + if (fd->f_op->llseek) { + err = fd->f_op->llseek(fd, 0, 2/*SEEK_END*/); + } else { + err = default_llseek(fd, 0, 2/*SEEK_END*/); + } + set_fs(old_fs); + if (err < 0) { + res = err; + PRINT_ERROR_PR("llseek %s returned an error %d", + virt_dev->file_name, res); + goto out_close_file; + } + virt_dev->file_size = err; + TRACE_DBG("size of file: %Ld", (uint64_t)err); - filp_close(fd, NULL); - + filp_close(fd, NULL); + } else + virt_dev->file_size = 0; + if (dev->handler->type == TYPE_DISK) { - virt_dev->block_size = DEF_DISK_BLOCKSIZE; - virt_dev->block_shift = DEF_DISK_BLOCKSIZE_SHIFT; - virt_dev->nblocks = virt_dev->file_size >> DEF_DISK_BLOCKSIZE_SHIFT; + virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift; } else { virt_dev->block_size = DEF_CDROM_BLOCKSIZE; virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT; virt_dev->nblocks = virt_dev->file_size >> DEF_CDROM_BLOCKSIZE_SHIFT; } - PRINT_INFO_PR("Attached SCSI target virtual %s %s " + + if (!virt_dev->cdrom_empty) { + PRINT_INFO_PR("Attached SCSI target virtual %s %s " "(file=\"%s\", fs=%LdMB, bs=%d, nblocks=%Ld, cyln=%Ld%s)", (dev->handler->type == TYPE_DISK) ? "disk" : "cdrom", virt_dev->name, virt_dev->file_name, virt_dev->file_size >> 20, virt_dev->block_size, virt_dev->nblocks, virt_dev->nblocks/64/32, virt_dev->nblocks < 64*32 ? " !WARNING! cyln less than 1" : ""); + } else { + PRINT_INFO_PR("Attached empty SCSI target virtual cdrom %s", + virt_dev->name); + } dev->tgt_dev_specific = virt_dev; @@ -369,13 +382,14 @@ static void fileio_do_job(struct scst_cmd *cmd) { - uint64_t lba_start = 0; - uint32_t number_of_blocks; + uint64_t lba_start; + loff_t data_len; int opcode = cmd->cdb[0]; loff_t loff; struct scst_device *dev = cmd->dev; struct scst_fileio_dev *virt_dev = (struct scst_fileio_dev *)dev->tgt_dev_specific; + int fua = 0; TRACE_ENTRY(); @@ -393,6 +407,7 @@ lba_start = (((cmd->cdb[1] & 0x1f) << (BYTE * 2)) + (cmd->cdb[2] << (BYTE * 1)) + (cmd->cdb[3] << (BYTE * 0))); + data_len = cmd->bufflen; break; case READ_10: case READ_12: @@ -402,31 +417,56 @@ case WRITE_VERIFY: case WRITE_VERIFY_12: case VERIFY_12: + lba_start = be32_to_cpu(*(u32 *)&cmd->cdb[2]); + data_len = cmd->bufflen; + break; case SYNCHRONIZE_CACHE: lba_start = be32_to_cpu(*(u32 *)&cmd->cdb[2]); + data_len = ((cmd->cdb[7] << (BYTE * 1)) + + (cmd->cdb[8] << (BYTE * 0))) << virt_dev->block_shift; + if (data_len == 0) + data_len = virt_dev->file_size - + ((loff_t)lba_start << virt_dev->block_shift); break; case READ_16: case WRITE_16: case WRITE_VERIFY_16: case VERIFY_16: - lba_start = be64_to_cpu(*(u64 *)&cmd->cdb[2]); + lba_start = be64_to_cpu(*(u64*)&cmd->cdb[2]); + data_len = cmd->bufflen; break; + default: + lba_start = 0; + data_len = 0; } loff = (loff_t)lba_start << virt_dev->block_shift; - TRACE_DBG("cmd %p, lba_start %Ld, loff %Ld", cmd, lba_start, - (uint64_t)loff); - if (unlikely(loff < 0) || - unlikely((loff + cmd->bufflen) > virt_dev->file_size)) { + TRACE_DBG("cmd %p, lba_start %Ld, loff %Ld, data_len %Ld", cmd, + lba_start, (uint64_t)loff, (uint64_t)data_len); + if (unlikely(loff < 0) || unlikely(data_len < 0) || + unlikely((loff + data_len) > virt_dev->file_size)) { PRINT_INFO_PR("Access beyond the end of the device " - "(%lld of %lld, len %zd)", (uint64_t)loff, - (uint64_t)virt_dev->file_size, cmd->bufflen); + "(%lld of %lld, len %Ld)", (uint64_t)loff, + (uint64_t)virt_dev->file_size, (uint64_t)data_len); scst_set_cmd_error(cmd, SCST_LOAD_SENSE( scst_sense_block_out_range_error)); goto done; } - + switch (opcode) { + case WRITE_10: + case WRITE_12: + case WRITE_16: + fua = (cmd->cdb[1] & 0x8) && !virt_dev->wt_flag; + if (cmd->cdb[1] & 0x8) { + TRACE(TRACE_SCSI, "FUA(%d): loff=%Ld, " + "data_len=%Ld", fua, (uint64_t)loff, + (uint64_t)data_len); + } + break; + } + + switch (opcode) { case READ_6: case READ_10: case READ_12: @@ -438,16 +478,24 @@ case WRITE_12: case WRITE_16: if (likely(!virt_dev->rd_only_flag)) { + int do_fsync = 0; + struct scst_fileio_tgt_dev *ftgt_dev = + (struct scst_fileio_tgt_dev*) + cmd->tgt_dev->tgt_dev_specific; + if ((cmd->queue_type == SCST_CMD_QUEUE_ORDERED) && + !virt_dev->wt_flag) { + TRACE(TRACE_SCSI/*|TRACE_SPECIAL*/, "ORDERED WRITE: " + "loff=%Ld, data_len=%Ld", (uint64_t)loff, + (uint64_t)data_len); + do_fsync = 1; + if (fileio_fsync(ftgt_dev, 0, 0, cmd) != 0) + goto done; + } fileio_exec_write(cmd, loff); -#if 0 /* instead, O_SYNC flag is used */ - if ((cmd->status == 0) && virt_dev->wt_flag) { - number_of_blocks = cmd->bufflen >> - virt_dev->block_shift; - fileio_fsync(cmd, lba_start, number_of_blocks); - } -#endif - } - else { + /* O_SYNC flag is used for wt_flag devices */ + if (do_fsync || fua) + fileio_fsync(ftgt_dev, loff, data_len, cmd); + } else { TRACE_DBG("%s", "Attempt to write to read-only device"); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_data_protect)); @@ -457,29 +505,54 @@ case WRITE_VERIFY_12: case WRITE_VERIFY_16: if (likely(!virt_dev->rd_only_flag)) { + int do_fsync = 0; + struct scst_fileio_tgt_dev *ftgt_dev = + (struct scst_fileio_tgt_dev*) + cmd->tgt_dev->tgt_dev_specific; + if ((cmd->queue_type == SCST_CMD_QUEUE_ORDERED) && + !virt_dev->wt_flag) { + TRACE(TRACE_SCSI/*|TRACE_SPECIAL*/, "ORDERED " + "WRITE_VERIFY: loff=%Ld, data_len=%Ld", + (uint64_t)loff, (uint64_t)data_len); + do_fsync = 1; + if (fileio_fsync(ftgt_dev, 0, 0, cmd) != 0) + goto done; + } fileio_exec_write(cmd, loff); -#if 0 /* instead, O_SYNC flag is used */ - if ((cmd->status == 0) && virt_dev->wt_flag) { - number_of_blocks = cmd->bufflen >> - virt_dev->block_shift; - fileio_fsync(cmd, lba_start, number_of_blocks); - } -#endif + /* O_SYNC flag is used for wt_flag devices */ if (cmd->status == 0) fileio_exec_verify(cmd, loff); - } - else { + else if (do_fsync) + fileio_fsync(ftgt_dev, loff, data_len, cmd); + } else { TRACE_DBG("%s", "Attempt to write to read-only device"); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_data_protect)); } break; case SYNCHRONIZE_CACHE: - /* ToDo: IMMED bit */ - number_of_blocks = ((cmd->cdb[7] << (BYTE * 1)) + - (cmd->cdb[8] << (BYTE * 0))); - fileio_fsync(cmd, lba_start, number_of_blocks); - break; + { + int immed = cmd->cdb[1] & 0x2; + struct scst_fileio_tgt_dev *ftgt_dev = + (struct scst_fileio_tgt_dev*) + cmd->tgt_dev->tgt_dev_specific; + TRACE(TRACE_SCSI, "SYNCHRONIZE_CACHE: " + "loff=%Ld, data_len=%Ld, immed=%d", (uint64_t)loff, + (uint64_t)data_len, immed); + if (immed) { + scst_get(); + cmd->completed = 1; + cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT); + /* cmd is dead here */ + fileio_fsync(ftgt_dev, loff, data_len, NULL); + /* ToDo: fileio_fsync() error processing */ + scst_put(); + goto out; + } else { + fileio_fsync(ftgt_dev, loff, data_len, cmd); + break; + } + } case VERIFY_6: case VERIFY: case VERIFY_12: @@ -518,6 +591,7 @@ done_uncompl: cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT); +out: TRACE_EXIT(); return; } @@ -611,14 +685,18 @@ init_waitqueue_head(&ftgt_dev->fdev_waitQ); atomic_set(&ftgt_dev->threads_count, 0); init_MUTEX_LOCKED(&ftgt_dev->shutdown_mutex); + ftgt_dev->virt_dev = virt_dev; - ftgt_dev->fd = fileio_open(virt_dev); - if (IS_ERR(ftgt_dev->fd)) { - res = PTR_ERR(ftgt_dev->fd); - PRINT_ERROR_PR("filp_open(%s) returned an error %d", - virt_dev->file_name, res); - goto out_free; - } + if (!virt_dev->cdrom_empty) { + ftgt_dev->fd = fileio_open(virt_dev); + if (IS_ERR(ftgt_dev->fd)) { + res = PTR_ERR(ftgt_dev->fd); + PRINT_ERROR_PR("filp_open(%s) returned an error %d", + virt_dev->file_name, res); + goto out_free; + } + } else + ftgt_dev->fd = NULL; /* * Only ONE thread must be run here, otherwise the commands could @@ -644,7 +722,8 @@ return res; out_free_close: - filp_close(ftgt_dev->fd, NULL); + if (ftgt_dev->fd) + filp_close(ftgt_dev->fd, NULL); out_free: TRACE_MEM("kfree ftgt_dev: %p", ftgt_dev); @@ -669,7 +748,8 @@ wake_up_all(&ftgt_dev->fdev_waitQ); down(&ftgt_dev->shutdown_mutex); - filp_close(ftgt_dev->fd, NULL); + if (ftgt_dev->fd) + filp_close(ftgt_dev->fd, NULL); if (ftgt_dev->iv != NULL) { TRACE_MEM("kfree ftgt_dev->iv: %p", ftgt_dev->iv); @@ -852,7 +932,7 @@ case REPORT_LUNS: def: default: - TRACE_DBG("Wrong opcode 0x%02x", opcode); + TRACE_DBG("Invalid opcode 0x%02x", opcode); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_opcode)); } @@ -959,6 +1039,13 @@ cmd->host_status = DID_OK; cmd->driver_status = 0; + if (virt_dev->cdrom_empty && (opcode != INQUIRY)) { + TRACE_DBG("%s", "CDROM empty"); + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_not_ready)); + goto out; + } + /* * No protection is necessary, because media_changed set only * in suspended state and exec() is serialized @@ -966,8 +1053,9 @@ if (virt_dev->media_changed && (cmd->cdb[0] != INQUIRY) && (cmd->cdb[0] != REQUEST_SENSE) && (cmd->cdb[0] != REPORT_LUNS)) { virt_dev->media_changed = 0; + TRACE_DBG("%s", "Reporting media changed"); scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_medium_changed_UA)); + SCST_LOAD_SENSE(scst_sense_medium_changed_UA)); goto out; } @@ -1020,9 +1108,9 @@ break; case REPORT_LUNS: default: - TRACE_DBG("Wrong opcode 0x%02x", opcode); + TRACE_DBG("Invalid opcode 0x%02x", opcode); scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_opcode)); + SCST_LOAD_SENSE(scst_sense_invalid_opcode)); } out: @@ -1062,6 +1150,7 @@ length = scst_get_buf_first(cmd, &address); TRACE_DBG("length %d", length); if (unlikely(length <= 0)) { + PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); goto out_free; @@ -1073,6 +1162,7 @@ */ if (cmd->cdb[1] & CMDDT) { + TRACE_DBG("%s", "INQUIRY: CMDDT is unsupported"); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb)); goto out_put; @@ -1135,13 +1225,15 @@ buf[3] = num + 12 - 4; } else { - /* Illegal request, invalid field in cdb */ + TRACE_DBG("INQUIRY: Unsupported EVPD page %x", + cmd->cdb[2]); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb)); goto out_put; } } else { if (cmd->cdb[2] != 0) { + TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb)); goto out_put; @@ -1187,8 +1279,8 @@ static int fileio_err_recov_pg(unsigned char *p, int pcontrol, struct scst_fileio_dev *virt_dev) { /* Read-Write Error Recovery page for mode_sense */ - unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0, - 5, 0, 0xff, 0xff}; + const unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0, + 5, 0, 0xff, 0xff}; memcpy(p, err_recov_pg, sizeof(err_recov_pg)); if (1 == pcontrol) @@ -1199,8 +1291,8 @@ static int fileio_disconnect_pg(unsigned char *p, int pcontrol, struct scst_fileio_dev *virt_dev) { /* Disconnect-Reconnect page for mode_sense */ - unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; + const unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; memcpy(p, disconnect_pg, sizeof(disconnect_pg)); if (1 == pcontrol) @@ -1211,9 +1303,9 @@ static int fileio_format_pg(unsigned char *p, int pcontrol, struct scst_fileio_dev *virt_dev) { /* Format device page for mode_sense */ - unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x40, 0, 0, 0}; + const unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x40, 0, 0, 0}; memcpy(p, format_pg, sizeof(format_pg)); p[10] = (DEF_SECTORS_PER >> 8) & 0xff; @@ -1228,11 +1320,11 @@ static int fileio_caching_pg(unsigned char *p, int pcontrol, struct scst_fileio_dev *virt_dev) { /* Caching page for mode_sense */ - unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0, - 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0}; + const unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0, + 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0}; - caching_pg[2] |= !(virt_dev->wt_flag) ? WCE : 0; memcpy(p, caching_pg, sizeof(caching_pg)); + p[2] |= !(virt_dev->wt_flag) ? WCE : 0; if (1 == pcontrol) memset(p + 2, 0, sizeof(caching_pg) - 2); return sizeof(caching_pg); @@ -1241,10 +1333,12 @@ static int fileio_ctrl_m_pg(unsigned char *p, int pcontrol, struct scst_fileio_dev *virt_dev) { /* Control mode page for mode_sense */ - unsigned char ctrl_m_pg[] = {0xa, 0xa, 0x22, 0, 0, 0x40, 0, 0, - 0, 0, 0x2, 0x4b}; + const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0x22, 0, 0, 0x40, 0, 0, + 0, 0, 0x2, 0x4b}; memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); + if (!virt_dev->wt_flag) + p[3] |= 0x10; /* Enable unrestricted reordering */ if (1 == pcontrol) memset(p + 2, 0, sizeof(ctrl_m_pg) - 2); return sizeof(ctrl_m_pg); @@ -1253,8 +1347,8 @@ static int fileio_iec_m_pg(unsigned char *p, int pcontrol, struct scst_fileio_dev *virt_dev) { /* Informational Exceptions control mode page for mode_sense */ - unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, - 0, 0, 0x0, 0x0}; + const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, + 0, 0, 0x0, 0x0}; memcpy(p, iec_m_pg, sizeof(iec_m_pg)); if (1 == pcontrol) memset(p + 2, 0, sizeof(iec_m_pg) - 2); @@ -1294,10 +1388,11 @@ pcode = cmd->cdb[2] & 0x3f; subpcode = cmd->cdb[3]; msense_6 = (MODE_SENSE == cmd->cdb[0]); - dev_spec = virt_dev->rd_only_flag ? WP : 0; + dev_spec = (virt_dev->rd_only_flag ? WP : 0) | DPOFUA; length = scst_get_buf_first(cmd, &address); if (unlikely(length <= 0)) { + PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); goto out_free; @@ -1305,7 +1400,8 @@ memset(buf, 0, sizeof(buf)); - if (0x3 == pcontrol) { /* Saving values not supported */ + if (0x3 == pcontrol) { + TRACE_DBG("%s", "MODE SENSE: Saving values not supported"); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_saving_params_unsup)); goto out_put; @@ -1322,6 +1418,7 @@ } if (0 != subpcode) { /* TODO: Control Extension page */ + TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported"); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb)); goto out_put; @@ -1386,6 +1483,7 @@ offset += len; break; default: + TRACE_DBG("MODE SENSE: Unsupported page %x", pcode); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb)); goto out_put; @@ -1439,7 +1537,8 @@ res = 0; /* ?? ToDo */ goto out_resume; } - filp_close(ftgt_dev->fd, NULL); + if (ftgt_dev->fd) + filp_close(ftgt_dev->fd, NULL); ftgt_dev->fd = fd; } up(&virt_dev->ftgt_list_mutex); @@ -1466,12 +1565,15 @@ length = scst_get_buf_first(cmd, &address); if (unlikely(length <= 0)) { + PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); goto out; } if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) { + PRINT_ERROR_PR("MODE SELECT: PF and/or SP are wrongly set " + "(cdb[1]=%x)", cmd->cdb[1]); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb)); goto out_put; @@ -1486,6 +1588,8 @@ if (address[offset - 1] == 8) { offset += 8; } else if (address[offset - 1] != 0) { + PRINT_ERROR_PR("%s", "MODE SELECT: Wrong parameters list " + "lenght"); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list)); goto out_put; @@ -1493,15 +1597,16 @@ while (length > offset + 2) { if (address[offset] & PS) { - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE( + PRINT_ERROR_PR("%s", "MODE SELECT: Illegal PS bit"); + scst_set_cmd_error(cmd, SCST_LOAD_SENSE( scst_sense_invalid_field_in_parm_list)); goto out_put; } if ((address[offset] & 0x3f) == 0x8) { /* Caching page */ if (address[offset + 1] != 18) { - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE( + PRINT_ERROR_PR("%s", "MODE SELECT: Invalid " + "caching page request"); + scst_set_cmd_error(cmd, SCST_LOAD_SENSE( scst_sense_invalid_field_in_parm_list)); goto out_put; } @@ -1559,6 +1664,7 @@ length = scst_get_buf_first(cmd, &address); if (unlikely(length <= 0)) { + PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); goto out; @@ -1599,6 +1705,7 @@ length = scst_get_buf_first(cmd, &address); if (unlikely(length <= 0)) { + PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); goto out; @@ -1626,22 +1733,31 @@ TRACE_ENTRY(); if (cmd->dev->handler->type != TYPE_ROM) { + PRINT_ERROR_PR("%s", "READ TOC for non-CDROM device"); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_opcode)); goto out; } - if ((cmd->cdb[1] & 0x02/*TIME*/) || - (cmd->cdb[2] & 0x0e/*Format*/) || - (cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) || + if (cmd->cdb[2] & 0x0e/*Format*/) { + PRINT_ERROR_PR("%s", "READ TOC: invalid requested data format"); + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb)); + goto out; + } + + if ((cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) || (cmd->cdb[6] > 1 && cmd->cdb[6] != 0xAA)) { + PRINT_ERROR_PR("READ TOC: invalid requested track number %x", + cmd->cdb[6]); scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb)); - goto out_put; + SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb)); + goto out; } length = scst_get_buf_first(cmd, &address); if (unlikely(length <= 0)) { + PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); goto out; @@ -1654,7 +1770,7 @@ /* Header */ memset(buffer, 0, sizeof(buffer)); buffer[2] = 0x01; /* First Track/Session */ - buffer[3] = 0x01; /* Last Track/Session */ + buffer[3] = 0x01; /* Last Track/Session */ off = 4; if (cmd->cdb[6] <= 1) { @@ -1666,7 +1782,7 @@ } if (!(cmd->cdb[2] & 0x01)) { - /* Lead-out area TOC Track Descriptor */ + /* Lead-out area TOC Track Descriptor */ buffer[off+1] = 0x14; buffer[off+2] = 0xAA; /* Track Number */ buffer[off+4] = (nblocks >> (BYTE * 3)) & 0xFF; /* Track Start Address */ @@ -1678,9 +1794,8 @@ buffer[1] = off - 2; /* Data Length */ - memcpy(address, buffer, length < off ? length : off); + memcpy(address, buffer, (length < off) ? length : off); -out_put: scst_put_buf(cmd, address); out: @@ -1702,62 +1817,43 @@ if (cmd->dev->handler->type == TYPE_ROM) virt_dev->prevent_allow_medium_removal = cmd->cdb[4] & 0x01 ? 1 : 0; - else + else { + PRINT_ERROR_PR("%s", "Prevent allow medium removal for " + "non-CDROM device"); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_opcode)); + } return; } -static int fileio_fsync(struct scst_cmd *cmd, uint64_t lba_start, uint32_t number_of_blocks) +static int fileio_fsync(struct scst_fileio_tgt_dev *ftgt_dev, + loff_t loff, loff_t len, struct scst_cmd *cmd) { - /* Mostly borrowed from sys_fsync() */ - struct address_space *mapping; - int ret = 0, err; - struct scst_fileio_tgt_dev *ftgt_dev = - (struct scst_fileio_tgt_dev *)cmd->tgt_dev->tgt_dev_specific; + int res = 0; struct file *file = ftgt_dev->fd; + struct inode *inode = file->f_dentry->d_inode; + struct address_space *mapping = file->f_mapping; TRACE_ENTRY(); - mapping = file->f_mapping; + if (ftgt_dev->virt_dev->nv_cache) + goto out; - ret = -EINVAL; - if (!file->f_op || !file->f_op->fsync) { - /* Why? We can still call filemap_fdatawrite */ - goto out; + res = sync_page_range(inode, mapping, loff, len); + if (unlikely(res != 0)) { + PRINT_ERROR_PR("sync_page_range() failed (%d)", res); + if (cmd != NULL) { + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_write_error)); + } } - /* We need to protect against concurrent writers.. */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) - mutex_lock(&mapping->host->i_mutex); -#else - down(&mapping->host->i_sem); -#endif - current->flags |= PF_SYNCWRITE; - ret = filemap_fdatawrite(mapping); - err = file->f_op->fsync(file, file->f_dentry, 0); - if (!ret) - ret = err; - err = filemap_fdatawait(mapping); - if (!ret) - ret = err; - current->flags &= ~PF_SYNCWRITE; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) - mutex_unlock(&mapping->host->i_mutex); -#else - up(&mapping->host->i_sem); -#endif + /* ToDo: flush the device cache, if needed */ out: - if (ret != 0) - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_hardw_error)); - - /* ToDo: flush the device cache */ - - TRACE_EXIT_RES(ret); - return ret; + TRACE_EXIT_RES(res); + return res; } static struct iovec *fileio_alloc_iv(struct scst_cmd *cmd, @@ -1854,7 +1950,7 @@ scst_set_busy(cmd); else { scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_hardw_error)); + SCST_LOAD_SENSE(scst_sense_read_error)); } goto out_set_fs; } @@ -1942,7 +2038,7 @@ scst_set_busy(cmd); else { scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_hardw_error)); + SCST_LOAD_SENSE(scst_sense_write_error)); } goto out_set_fs; } else if (err < full_len) { @@ -1990,9 +2086,6 @@ static void fileio_exec_verify(struct scst_cmd *cmd, loff_t loff) { - uint32_t number_of_blocks; - struct scst_fileio_dev *virt_dev = - (struct scst_fileio_dev *)cmd->dev->tgt_dev_specific; mm_segment_t old_fs; loff_t err; ssize_t length, len_mem = 0; @@ -2005,10 +2098,8 @@ TRACE_ENTRY(); - if (!virt_dev->wt_flag) { - number_of_blocks = cmd->bufflen >> virt_dev->block_shift; - fileio_fsync(cmd, loff, number_of_blocks); - } + if (fileio_fsync(ftgt_dev, loff, cmd->bufflen, cmd) != 0) + goto out; /* * Until the cache is cleared prior the verifying, there is not @@ -2063,7 +2154,7 @@ scst_set_busy(cmd); else { scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_hardw_error)); + SCST_LOAD_SENSE(scst_sense_read_error)); } scst_put_buf(cmd, address_sav); goto out_set_fs; @@ -2097,6 +2188,7 @@ if (mem_verify) vfree(mem_verify); +out: TRACE_EXIT(); return; } @@ -2192,7 +2284,7 @@ } if (inout == 0) { /* read */ - size = scnprintf(buffer, length, "%-17s %-9s %-8s %s\n", + size = scnprintf(buffer, length, "%-17s %-12s %-15s %s\n", "Name", "Size(MB)", "Options", "File name"); if (fileio_proc_update_size(size, &len, &begin, &pos, &offset)) { res = len; @@ -2204,7 +2296,7 @@ { int c; size = scnprintf(buffer + len, length - len, - "%-17s %-10d", virt_dev->name, + "%-17s %-13d", virt_dev->name, (uint32_t)(virt_dev->file_size >> 20)); if (fileio_proc_update_size(size, &len, &begin, &pos, &offset)) { @@ -2221,6 +2313,16 @@ goto out_up; } } + if (virt_dev->nv_cache) { + size = scnprintf(buffer + len, length - len, + c ? ",NV" : "NV"); + c += size; + if (fileio_proc_update_size(size, &len, &begin, + &pos, &offset)) { + res = len; + goto out_up; + } + } if (virt_dev->rd_only_flag) { size = scnprintf(buffer + len, length - len, c ? ",RO" : "RO"); @@ -2251,7 +2353,7 @@ goto out_up; } } - while (c < 9) { + while (c < 16) { size = scnprintf(buffer + len, length - len, " "); if (fileio_proc_update_size(size, &len, &begin, &pos, &offset)) { @@ -2276,12 +2378,8 @@ *eof = 1; } else { /* write */ - /* - * Usage: - * echo "open|close NAME FILE_NAME [WRITE_THROUGH \ - * READ_ONLY O_DIRECT NULLIO]" > - * /proc/scsi_tgt/DISK_FILEIO_NAME/DISK_FILEIO_NAME - */ + uint32_t block_size = DEF_DISK_BLOCKSIZE; + int block_shift = DEF_DISK_BLOCKSIZE_SHIFT; p = buffer; if (p[strlen(p) - 1] == '\n') { p[strlen(p) - 1] = '\0'; @@ -2359,12 +2457,47 @@ while (isspace(*p) && *p != '\0') p++; + + if (isdigit(*p)) { + char *pp; + uint32_t t; + block_size = simple_strtoul(p, &pp, 0); + p = pp; + if ((*p != '\0') && !isspace(*p)) { + PRINT_ERROR_PR("Parse error: \"%s\"", p); + res = -EINVAL; + goto out_free_vdev; + } + while (isspace(*p) && *p != '\0') + p++; + + t = block_size; + block_shift = 0; + while(1) { + if ((t & 1) != 0) + break; + t >>= 1; + block_shift++; + } + if (block_shift < 9) { + PRINT_ERROR_PR("Wrong block size %d", + block_size); + res = -EINVAL; + goto out_free_vdev; + } + } + virt_dev->block_size = block_size; + virt_dev->block_shift = block_shift; while (*p != '\0') { if (!strncmp("WRITE_THROUGH", p, 13)) { p += 13; virt_dev->wt_flag = 1; TRACE_DBG("%s", "WRITE_THROUGH"); + } else if (!strncmp("NV_CACHE", p, 8)) { + p += 8; + virt_dev->nv_cache = 1; + TRACE_DBG("%s", "NON-VOLATILE CACHE"); } else if (!strncmp("READ_ONLY", p, 9)) { p += 9; virt_dev->rd_only_flag = 1; @@ -2410,9 +2543,11 @@ res = virt_dev->virt_id; goto out_free_vpath; } - TRACE_DBG("Added virt_dev (name %s file name %s id %d) " - "to disk_fileio_dev_list", virt_dev->name, - virt_dev->file_name, virt_dev->virt_id); + TRACE_DBG("Added virt_dev (name %s, file name %s, " + "id %d, block size %d) to " + "disk_fileio_dev_list", virt_dev->name, + virt_dev->file_name, virt_dev->virt_id, + virt_dev->block_size); } else { /* close */ virt_dev = NULL; list_for_each_entry(vv, &disk_fileio_dev_list, @@ -2469,6 +2604,7 @@ char *file_name; int len; int res = 0; + int cdrom_empty; virt_dev = NULL; list_for_each_entry(vv, &cdrom_fileio_dev_list, @@ -2493,15 +2629,15 @@ p++; *p++ = '\0'; if (*file_name == '\0') { - PRINT_ERROR_PR("%s", "File name required"); - res = -EINVAL; - goto out; + cdrom_empty = 1; + TRACE_DBG("%s", "No media"); } else if (*file_name != '/') { PRINT_ERROR_PR("File path \"%s\" is not " "absolute", file_name); res = -EINVAL; goto out; - } + } else + cdrom_empty = 0; virt_dev = fileio_alloc_dev(); if (virt_dev == NULL) { @@ -2510,20 +2646,23 @@ res = -ENOMEM; goto out; } + virt_dev->cdrom_empty = cdrom_empty; strcpy(virt_dev->name, name); - len = strlen(file_name) + 1; - virt_dev->file_name = kmalloc(len, GFP_KERNEL); - TRACE_MEM("kmalloc(GFP_KERNEL) for file_name (%d): %p", - len, virt_dev->file_name); - if (virt_dev->file_name == NULL) { - TRACE(TRACE_OUT_OF_MEM, "%s", - "Allocation of file_name failed"); - res = -ENOMEM; - goto out_free_vdev; + if (!virt_dev->cdrom_empty) { + len = strlen(file_name) + 1; + virt_dev->file_name = kmalloc(len, GFP_KERNEL); + TRACE_MEM("kmalloc(GFP_KERNEL) for file_name (%d): %p", + len, virt_dev->file_name); + if (virt_dev->file_name == NULL) { + TRACE(TRACE_OUT_OF_MEM, "%s", + "Allocation of file_name failed"); + res = -ENOMEM; + goto out_free_vdev; + } + strncpy(virt_dev->file_name, file_name, len); } - strncpy(virt_dev->file_name, file_name, len); list_add_tail(&virt_dev->fileio_dev_list_entry, &cdrom_fileio_dev_list); @@ -2582,8 +2721,10 @@ list_del(&virt_dev->fileio_dev_list_entry); - TRACE_MEM("kfree for file_name: %p", virt_dev->file_name); - kfree(virt_dev->file_name); + if (virt_dev->file_name) { + TRACE_MEM("kfree for file_name: %p", virt_dev->file_name); + kfree(virt_dev->file_name); + } TRACE_MEM("kfree for virt_dev: %p", virt_dev); kfree(virt_dev); @@ -2626,63 +2767,70 @@ p++; *p++ = '\0'; if (*file_name == '\0') { - PRINT_ERROR_PR("%s", "File name required"); - res = -EINVAL; - goto out; + virt_dev->cdrom_empty = 1; + TRACE_DBG("%s", "No media"); } else if (*file_name != '/') { PRINT_ERROR_PR("File path \"%s\" is not " "absolute", file_name); res = -EINVAL; goto out; - } + } else + virt_dev->cdrom_empty = 0; - len = strlen(file_name) + 1; - fn = kmalloc(len, GFP_KERNEL); - TRACE_MEM("kmalloc(GFP_KERNEL) for file_name (%d): %p", - len, fn); - if (fn == NULL) { - TRACE(TRACE_OUT_OF_MEM, "%s", - "Allocation of file_name failed"); - res = -ENOMEM; - goto out; - } - old_fn = virt_dev->file_name; - virt_dev->file_name = fn; - strncpy(virt_dev->file_name, file_name, len); - fd = fileio_open(virt_dev); - if (IS_ERR(fd)) { - res = PTR_ERR(fd); - PRINT_ERROR_PR("filp_open(%s) returned an error %d", - virt_dev->file_name, res); - goto out_free; - } - if ((fd->f_op == NULL) || (fd->f_op->readv == NULL)) - { - PRINT_ERROR_PR("%s", "Wrong f_op or FS doesn't" - " have required capabilities"); - res = -EINVAL; + if (!virt_dev->cdrom_empty) { + len = strlen(file_name) + 1; + fn = kmalloc(len, GFP_KERNEL); + TRACE_MEM("kmalloc(GFP_KERNEL) for file_name (%d): %p", + len, fn); + if (fn == NULL) { + TRACE(TRACE_OUT_OF_MEM, "%s", + "Allocation of file_name failed"); + res = -ENOMEM; + goto out; + } + + strncpy(fn, file_name, len); + virt_dev->file_name = fn; + + fd = fileio_open(virt_dev); + if (IS_ERR(fd)) { + res = PTR_ERR(fd); + PRINT_ERROR_PR("filp_open(%s) returned an error %d", + virt_dev->file_name, res); + goto out_free; + } + if ((fd->f_op == NULL) || (fd->f_op->readv == NULL)) { + PRINT_ERROR_PR("%s", "Wrong f_op or FS doesn't " + "have required capabilities"); + res = -EINVAL; + filp_close(fd, NULL); + goto out_free; + } + + /* seek to end */ + old_fs = get_fs(); + set_fs(get_ds()); + if (fd->f_op->llseek) { + err = fd->f_op->llseek(fd, 0, 2/*SEEK_END*/); + } else { + err = default_llseek(fd, 0, 2/*SEEK_END*/); + } + set_fs(old_fs); filp_close(fd, NULL); - goto out_free; - } - - /* seek to end */ - old_fs = get_fs(); - set_fs(get_ds()); - if (fd->f_op->llseek) { - err = fd->f_op->llseek(fd, 0, 2/*SEEK_END*/); + if (err < 0) { + res = err; + PRINT_ERROR_PR("llseek %s returned an error %d", + virt_dev->file_name, res); + goto out_free; + } } else { - err = default_llseek(fd, 0, 2/*SEEK_END*/); + len = 0; + err = 0; + fn = NULL; + virt_dev->file_name = fn; } - set_fs(old_fs); - filp_close(fd, NULL); - if (err < 0) { - res = err; - PRINT_ERROR_PR("llseek %s returned an error %d", - virt_dev->file_name, res); - goto out_free; - } scst_suspend_activity(); @@ -2695,34 +2843,48 @@ virt_dev->file_size = err; virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift; - virt_dev->media_changed = 1; - PRINT_INFO_PR("Changed SCSI target virtual cdrom %s " - "(file=\"%s\", fs=%LdMB, bs=%d, nblocks=%Ld, cyln=%Ld%s)", - virt_dev->name, virt_dev->file_name, - virt_dev->file_size >> 20, virt_dev->block_size, - virt_dev->nblocks, virt_dev->nblocks/64/32, - virt_dev->nblocks < 64*32 ? " !WARNING! cyln less than 1" : ""); + if (!virt_dev->cdrom_empty) + virt_dev->media_changed = 1; down(&virt_dev->ftgt_list_mutex); list_for_each_entry(ftgt_dev, &virt_dev->ftgt_list, ftgt_list_entry) { - fd = fileio_open(virt_dev); - if (IS_ERR(fd)) { - res = PTR_ERR(fd); - PRINT_ERROR_PR("filp_open(%s) returned an error %d, " - "closing the device", virt_dev->file_name, res); - up(&virt_dev->ftgt_list_mutex); - goto out_err_resume; - } - filp_close(ftgt_dev->fd, NULL); + if (!virt_dev->cdrom_empty) { + fd = fileio_open(virt_dev); + if (IS_ERR(fd)) { + res = PTR_ERR(fd); + PRINT_ERROR_PR("filp_open(%s) returned an error %d, " + "closing the device", virt_dev->file_name, res); + up(&virt_dev->ftgt_list_mutex); + goto out_err_resume; + } + } else + fd = NULL; + if (ftgt_dev->fd) + filp_close(ftgt_dev->fd, NULL); ftgt_dev->fd = fd; } up(&virt_dev->ftgt_list_mutex); - TRACE_MEM("kfree for old_fn: %p", old_fn); - kfree(old_fn); + if (!virt_dev->cdrom_empty) { + PRINT_INFO_PR("Changed SCSI target virtual cdrom %s " + "(file=\"%s\", fs=%LdMB, bs=%d, nblocks=%Ld, cyln=%Ld%s)", + virt_dev->name, virt_dev->file_name, + virt_dev->file_size >> 20, virt_dev->block_size, + virt_dev->nblocks, virt_dev->nblocks/64/32, + virt_dev->nblocks < 64*32 ? " !WARNING! cyln less " + "than 1" : ""); + } else { + PRINT_INFO_PR("Removed media from SCSI target virtual cdrom %s", + virt_dev->name); + } + if (old_fn) { + TRACE_MEM("kfree for old_fn: %p", old_fn); + kfree(old_fn); + } + out_resume: scst_resume_activity(); @@ -2799,11 +2961,6 @@ res = len; } else { /* write */ - /* - * Usage: - * echo "open|change|close NAME [FILE_NAME SIZE_IN_MB]" > - * /proc/scsi_tgt/CDROM_FILEIO_NAME/CDROM_FILEIO_NAME - */ p = buffer; if (p[strlen(p) - 1] == '\n') { p[strlen(p) - 1] = '\0'; Modified: trunk/scst/src/scst.c =================================================================== --- trunk/scst/src/scst.c 2006-10-17 09:22:31 UTC (rev 9) +++ trunk/scst/src/scst.c 2006-10-20 18:18:46 UTC (rev 10) @@ -881,6 +881,16 @@ return; } +void scst_get(void) +{ + scst_inc_cmd_count(); +} + +void scst_put(void) +{ + scst_dec_cmd_count(); +} + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) static int scst_add(struct class_device *cdev) #else @@ -1239,6 +1249,8 @@ EXPORT_SYMBOL(__scst_get_buf); EXPORT_SYMBOL(scst_check_mem); +EXPORT_SYMBOL(scst_get); +EXPORT_SYMBOL(scst_put); /* * Other Commands This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-17 09:23:03
|
Revision: 9 http://svn.sourceforge.net/scst/?rev=9&view=rev Author: vlnb Date: 2006-10-17 02:22:31 -0700 (Tue, 17 Oct 2006) Log Message: ----------- More intelligent IO flow control implemented Modified Paths: -------------- trunk/scst/ChangeLog trunk/scst/README trunk/scst/ToDo trunk/scst/include/scsi_tgt.h trunk/scst/src/scst.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_mem.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/scst/ChangeLog =================================================================== --- trunk/scst/ChangeLog 2006-10-12 16:43:38 UTC (rev 8) +++ trunk/scst/ChangeLog 2006-10-17 09:22:31 UTC (rev 9) @@ -7,11 +7,13 @@ - Timer-based retries for targets after SCST_TGT_RES_QUEUE_FULL status implemented. + - More intelligent IO flow control implemented. + - Fixed broken CDROM FILEIO. Before that it always reported "No medium found" - Fixed READ(6)/WRITE(6) CDB decoding for block devices. - This bug prevented FreeBSD initiator from working. + This bug prevented FreeBSD initiators from working. - Implemented sgv_pool. It is mempool-like interface, which caches built SG-vectors in order not to rebuild them again for every @@ -33,7 +35,7 @@ - Exported symbols are now not GPL'ed - - Various cleanups and bug fixes. + - Various cleanups and a lot of bug fixes. Summary of changes between versions 0.9.3 and 0.9.4 --------------------------------------------------- Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2006-10-12 16:43:38 UTC (rev 8) +++ trunk/scst/README 2006-10-17 09:22:31 UTC (rev 9) @@ -105,9 +105,6 @@ are seen remotely. There must be LUN 0 in each security group, i.e. LUs numeration must not start from, e.g., 1. -Module "scst_target" supports parameter "scst_threads", which allows to -set count of SCST's threads (CPU count by default). - IMPORTANT: without loading appropriate device handler, corresponding devices ========= will be invisible for remote initiators, which could lead to holes in the LUN addressing, so automatic device scanning by remote SCSI @@ -182,6 +179,18 @@ and eases CPU load, but could create a security hole (information leakage), so enable it, if you have strict security requirements. +Module parameters +----------------- + +Module scsi_tgt supports the following parameters: + + - scst_threads - allows to set count of SCST's threads. By default it + is CPU count. + + - scst_max_cmd_mem - sets maximum amount of memory in Mb allowed to be + consumed by the SCST commands for data buffers at any given time. By + default it is approximately TotalMem/4. + SCST "/proc" commands --------------------- Modified: trunk/scst/ToDo =================================================================== --- trunk/scst/ToDo 2006-10-12 16:43:38 UTC (rev 8) +++ trunk/scst/ToDo 2006-10-17 09:22:31 UTC (rev 9) @@ -32,8 +32,6 @@ To enable it, set SCST_HIGHMEM in 1 in scst_priv.h. HIGHMEM is not supported on 2.4 and is not going to be. - - More intelligent IO-throttling. - - Small ToDo's spread all over the code. - Investigate possible missed emulated UA cases. Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2006-10-12 16:43:38 UTC (rev 8) +++ trunk/scst/include/scsi_tgt.h 2006-10-17 09:22:31 UTC (rev 9) @@ -341,12 +341,6 @@ /* Set if the cmd is dead and can be destroyed at any time */ #define SCST_CMD_CAN_BE_DESTROYED 6 -/* - * Set if the cmd is throtteled, ie put on hold since there - * are too many pending commands. - */ -#define SCST_CMD_THROTTELED 7 - /************************************************************* ** Tgt_dev's flags *************************************************************/ @@ -1014,6 +1008,12 @@ */ unsigned int sg_buff_modified:1; + /* + * Set if the cmd's memory requirements are checked and found + * acceptable + */ + unsigned int mem_checked:1; + /**************************************************************/ unsigned long cmd_flags; /* cmd's async flags */ @@ -1022,9 +1022,9 @@ struct scst_tgt *tgt; /* to save extra dereferences */ struct scst_device *dev; /* to save extra dereferences */ - lun_t lun; /* LUN for this cmd */ + lun_t lun; /* LUN for this cmd */ - struct scst_tgt_dev *tgt_dev; /* corresponding device for this cmd */ + struct scst_tgt_dev *tgt_dev; /* corresponding device for this cmd */ struct scsi_request *scsi_req; /* SCSI request */ @@ -1253,9 +1253,6 @@ */ int cmd_count; - /* Throttled commands, protected by scst_list_lock */ - struct list_head thr_cmd_list; - spinlock_t tgt_dev_lock; /* per-session device lock */ /* List of UA's for this device, protected by tgt_dev_lock */ @@ -2048,4 +2045,15 @@ */ void scst_set_resp_data_len(struct scst_cmd *cmd, int resp_data_len); +/* + * Checks if total memory allocated by commands is less, than defined + * limit (scst_cur_max_cmd_mem) and returns 0, if it is so. Otherwise, + * returnes 1 and sets on cmd QUEUE FULL or BUSY status as well as + * SCST_CMD_STATE_XMIT_RESP state. Target drivers and dev handlers are + * required to call this function if they allocate data buffers on their + * own. + */ +int scst_check_mem(struct scst_cmd *cmd); + + #endif /* __SCST_H */ Modified: trunk/scst/src/scst.c =================================================================== --- trunk/scst/src/scst.c 2006-10-12 16:43:38 UTC (rev 8) +++ trunk/scst/src/scst.c 2006-10-17 09:22:31 UTC (rev 9) @@ -72,10 +72,18 @@ LIST_HEAD(scst_init_cmd_list); LIST_HEAD(scst_cmd_list); DECLARE_WAIT_QUEUE_HEAD(scst_list_waitQ); + +spinlock_t scst_cmd_mem_lock = SPIN_LOCK_UNLOCKED; +unsigned long scst_cur_cmd_mem, scst_cur_max_cmd_mem; + struct tasklet_struct scst_tasklets[NR_CPUS]; struct scst_sgv_pools scst_sgv; +DECLARE_WORK(scst_cmd_mem_work, scst_cmd_mem_work_fn, 0); + +unsigned long scst_max_cmd_mem; + LIST_HEAD(scst_mgmt_cmd_list); LIST_HEAD(scst_active_mgmt_cmd_list); LIST_HEAD(scst_delayed_mgmt_cmd_list); @@ -105,6 +113,10 @@ module_param_named(scst_threads, scst_threads, int, 0); MODULE_PARM_DESC(scst_threads, "SCSI target threads count"); +module_param_named(scst_max_cmd_mem, scst_max_cmd_mem, long, 0); +MODULE_PARM_DESC(scst_max_cmd_mem, "Maximum memory allowed to be consumed by " + "the SCST commands at any given time in Mb"); + int scst_register_target_template(struct scst_tgt_template *vtt) { int res = 0; @@ -1032,9 +1044,23 @@ } atomic_inc(&scst_threads_count); - PRINT_INFO_PR("SCST version %s loaded successfully", - SCST_VERSION_STRING); + if (scst_max_cmd_mem == 0) { + struct sysinfo si; + si_meminfo(&si); +#if BITS_PER_LONG == 32 + scst_max_cmd_mem = min(((uint64_t)si.totalram << PAGE_SHIFT) >> 2, + (uint64_t)1 << 30); +#else + scst_max_cmd_mem = (si.totalram << PAGE_SHIFT) >> 2; +#endif + } else + scst_max_cmd_mem <<= 20; + scst_cur_max_cmd_mem = scst_max_cmd_mem; + + PRINT_INFO_PR("SCST version %s loaded successfully (max mem for " + "commands %ld Mb)", SCST_VERSION_STRING, scst_max_cmd_mem >> 20); + out: TRACE_EXIT_RES(res); return res; @@ -1125,6 +1151,11 @@ } } + if (test_bit(SCST_FLAG_CMD_MEM_WORK_SCHEDULED, &scst_flags)) { + cancel_delayed_work(&scst_cmd_mem_work); + flush_scheduled_work(); + } + scst_proc_cleanup_module(); scsi_unregister_interface(&scst_interface); scst_destroy_acg(scst_default_acg); @@ -1207,6 +1238,7 @@ #endif EXPORT_SYMBOL(__scst_get_buf); +EXPORT_SYMBOL(scst_check_mem); /* * Other Commands Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2006-10-12 16:43:38 UTC (rev 8) +++ trunk/scst/src/scst_lib.c 2006-10-17 09:22:31 UTC (rev 9) @@ -92,15 +92,13 @@ { scst_set_cmd_error_status(cmd, SAM_STAT_BUSY); TRACE_MGMT_DBG("Sending BUSY status to initiator %s " - "(cmds count %d, queue_type %x, sess->init_phase %d), " - "probably the system is overloaded", + "(cmds count %d, queue_type %x, sess->init_phase %d)", cmd->sess->initiator_name, cmd->sess->sess_cmd_count, cmd->queue_type, cmd->sess->init_phase); } else { scst_set_cmd_error_status(cmd, SAM_STAT_TASK_SET_FULL); TRACE_MGMT_DBG("Sending QUEUE_FULL status to initiator %s " - "(cmds count %d, queue_type %x, sess->init_phase %d), " - "probably the system is overloaded", + "(cmds count %d, queue_type %x, sess->init_phase %d)", cmd->sess->initiator_name, cmd->sess->sess_cmd_count, cmd->queue_type, cmd->sess->init_phase); } @@ -358,7 +356,6 @@ (uint64_t)tgt_dev->acg_dev->lun); } - INIT_LIST_HEAD(&tgt_dev->thr_cmd_list); spin_lock_init(&tgt_dev->tgt_dev_lock); INIT_LIST_HEAD(&tgt_dev->UA_list); spin_lock_init(&tgt_dev->sn_lock); @@ -2036,28 +2033,6 @@ return; } -/* Called under scst_list_lock and IRQs disabled */ -void scst_throttle_cmd(struct scst_cmd *cmd) -{ - struct scst_tgt_dev *tgt_dev = cmd->tgt_dev; - - TRACE(TRACE_RETRY, "Too many pending commands in session, initiator " - "\"%s\". Moving cmd %p to thr cmd list", - (cmd->sess->initiator_name[0] == '\0') ? "Anonymous" : - cmd->sess->initiator_name, cmd); - list_move_tail(&cmd->cmd_list_entry, &tgt_dev->thr_cmd_list); - set_bit(SCST_CMD_THROTTELED, &cmd->cmd_flags); -} - -/* Called under scst_list_lock and IRQs disabled */ -void scst_unthrottle_cmd(struct scst_cmd *cmd) -{ - TRACE(TRACE_RETRY|TRACE_DEBUG, "Moving cmd %p from " - "thr cmd list to active cmd list", cmd); - list_move_tail(&cmd->cmd_list_entry, &scst_active_cmd_list); - clear_bit(SCST_CMD_THROTTELED, &cmd->cmd_flags); -} - static struct scst_cmd *scst_inc_expected_sn( struct scst_tgt_dev *tgt_dev, struct scst_cmd *out_of_sn_cmd) { Modified: trunk/scst/src/scst_mem.c =================================================================== --- trunk/scst/src/scst_mem.c 2006-10-12 16:43:38 UTC (rev 8) +++ trunk/scst/src/scst_mem.c 2006-10-17 09:22:31 UTC (rev 9) @@ -171,7 +171,7 @@ obj->sg_count = 0; for (pg = 0; pg < pages; pg++) { #ifdef DEBUG_OOM - if (((scst_random() % 100) == 55)) + if ((scst_random() % 10000) == 55) obj->entries[obj->sg_count].page = NULL; else #endif Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2006-10-12 16:43:38 UTC (rev 8) +++ trunk/scst/src/scst_priv.h 2006-10-17 09:22:31 UTC (rev 9) @@ -73,6 +73,9 @@ /* Set if a TM command is being performed */ #define SCST_FLAG_TM_ACTIVE 2 +/* Set if scst_cmd_mem_work is scheduled */ +#define SCST_FLAG_CMD_MEM_WORK_SCHEDULED 3 + /** ** Return codes for cmd state process functions **/ @@ -93,6 +96,7 @@ #define SCST_THREAD_FLAGS CLONE_KERNEL #define SCST_TGT_RETRY_TIMEOUT (3/2*HZ) +#define SCST_CMD_MEM_TIMEOUT (120*HZ) static inline int scst_get_context(void) { /* Be overinsured */ @@ -141,6 +145,11 @@ extern struct list_head scst_init_cmd_list; extern struct list_head scst_cmd_list; +extern spinlock_t scst_cmd_mem_lock; +extern unsigned long scst_max_cmd_mem, scst_cur_max_cmd_mem, scst_cur_cmd_mem; +extern struct work_struct scst_cmd_mem_work; + +/* The following lists protected by scst_list_lock as well */ extern struct list_head scst_mgmt_cmd_list; extern struct list_head scst_active_mgmt_cmd_list; extern struct list_head scst_delayed_mgmt_cmd_list; @@ -202,6 +211,7 @@ void scst_cmd_tasklet(long p); int scst_mgmt_cmd_thread(void *arg); int scst_mgmt_thread(void *arg); +void scst_cmd_mem_work_fn(void *p); struct scst_device *scst_alloc_device(int gfp_mask); void scst_free_device(struct scst_device *tgt_dev); Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2006-10-12 16:43:38 UTC (rev 8) +++ trunk/scst/src/scst_targ.c 2006-10-17 09:22:31 UTC (rev 9) @@ -468,6 +468,96 @@ goto out; } +void scst_cmd_mem_work_fn(void *p) +{ + TRACE_ENTRY(); + + spin_lock_bh(&scst_cmd_mem_lock); + + scst_cur_max_cmd_mem += (scst_cur_max_cmd_mem >> 3); + if (scst_cur_max_cmd_mem < scst_max_cmd_mem) { + TRACE_MGMT_DBG("%s", "Schedule cmd_mem_work"); + schedule_delayed_work(&scst_cmd_mem_work, SCST_CMD_MEM_TIMEOUT); + } else { + scst_cur_max_cmd_mem = scst_max_cmd_mem; + clear_bit(SCST_FLAG_CMD_MEM_WORK_SCHEDULED, &scst_flags); + } + TRACE_MGMT_DBG("New max cmd mem %ld Mb", scst_cur_max_cmd_mem >> 20); + + spin_unlock_bh(&scst_cmd_mem_lock); + + TRACE_EXIT(); + return; +} + +int scst_check_mem(struct scst_cmd *cmd) +{ + int res = 0; + + TRACE_ENTRY(); + + if (cmd->mem_checked) + goto out; + + spin_lock_bh(&scst_cmd_mem_lock); + + scst_cur_cmd_mem += cmd->bufflen; + cmd->mem_checked = 1; + if (likely(scst_cur_cmd_mem <= scst_cur_max_cmd_mem)) + goto out_unlock; + + TRACE(TRACE_OUT_OF_MEM, "Total memory allocated by commands (%ld Kb) " + "is too big, returning QUEUE FULL to initiator \"%s\" (maximum " + "allowed %ld Kb)", scst_cur_cmd_mem >> 10, + (cmd->sess->initiator_name[0] == '\0') ? + "Anonymous" : cmd->sess->initiator_name, + scst_cur_max_cmd_mem >> 10); + + scst_cur_cmd_mem -= cmd->bufflen; + cmd->mem_checked = 0; + scst_set_busy(cmd); + cmd->state = SCST_CMD_STATE_XMIT_RESP; + res = 1; + +out_unlock: + spin_unlock_bh(&scst_cmd_mem_lock); + +out: + TRACE_EXIT_RES(res); + return res; +} + +static void scst_low_cur_max_cmd_mem(void) +{ + TRACE_ENTRY(); + + if (test_bit(SCST_FLAG_CMD_MEM_WORK_SCHEDULED, &scst_flags)) { + cancel_delayed_work(&scst_cmd_mem_work); + flush_scheduled_work(); + clear_bit(SCST_FLAG_CMD_MEM_WORK_SCHEDULED, &scst_flags); + } + + spin_lock_bh(&scst_cmd_mem_lock); + + scst_cur_max_cmd_mem = (scst_cur_cmd_mem >> 1) + + (scst_cur_cmd_mem >> 2); + if (scst_cur_max_cmd_mem < 16*1024*1024) + scst_cur_max_cmd_mem = 16*1024*1024; + + if (!test_bit(SCST_FLAG_CMD_MEM_WORK_SCHEDULED, &scst_flags)) { + TRACE_MGMT_DBG("%s", "Schedule cmd_mem_work"); + schedule_delayed_work(&scst_cmd_mem_work, SCST_CMD_MEM_TIMEOUT); + set_bit(SCST_FLAG_CMD_MEM_WORK_SCHEDULED, &scst_flags); + } + + spin_unlock_bh(&scst_cmd_mem_lock); + + TRACE_MGMT_DBG("New max cmd mem %ld Mb", scst_cur_max_cmd_mem >> 20); + + TRACE_EXIT(); + return; +} + static int scst_prepare_space(struct scst_cmd *cmd) { int r, res = SCST_CMD_STATE_RES_CONT_SAME; @@ -479,6 +569,10 @@ goto out; } + r = scst_check_mem(cmd); + if (unlikely(r != 0)) + goto out; + if (cmd->data_buf_tgt_alloc) { TRACE_MEM("%s", "Custom tgt data buf allocation requested"); r = cmd->tgtt->alloc_data_buf(cmd); @@ -512,7 +606,8 @@ out_no_space: TRACE(TRACE_OUT_OF_MEM, "Unable to allocate or build requested buffer " - "(size %zd), sending BUSY status", cmd->bufflen); + "(size %zd), sending BUSY or QUEUE FULL status", cmd->bufflen); + scst_low_cur_max_cmd_mem(); scst_set_busy(cmd); cmd->state = SCST_CMD_STATE_DEV_DONE; res = SCST_CMD_STATE_RES_CONT_SAME; @@ -2090,6 +2185,12 @@ TRACE_ENTRY(); + if (cmd->mem_checked) { + spin_lock_bh(&scst_cmd_mem_lock); + scst_cur_cmd_mem -= cmd->bufflen; + spin_unlock_bh(&scst_cmd_mem_lock); + } + spin_lock_irq(&scst_list_lock); TRACE_DBG("Deleting cmd %p from cmd list", cmd); @@ -2098,18 +2199,8 @@ if (cmd->mgmt_cmnd) scst_complete_cmd_mgmt(cmd, cmd->mgmt_cmnd); - if (likely(cmd->tgt_dev != NULL)) { - struct scst_tgt_dev *tgt_dev = cmd->tgt_dev; - tgt_dev->cmd_count--; - if (!list_empty(&tgt_dev->thr_cmd_list)) { - struct scst_cmd *t = - list_entry(tgt_dev->thr_cmd_list.next, - typeof(*t), cmd_list_entry); - scst_unthrottle_cmd(t); - if (!cmd->processible_env) - wake_up(&scst_list_waitQ); - } - } + if (likely(cmd->tgt_dev != NULL)) + cmd->tgt_dev->cmd_count--; cmd->sess->sess_cmd_count--; @@ -2261,18 +2352,7 @@ res = scst_translate_lun(cmd); if (likely(res == 0)) { cmd->state = SCST_CMD_STATE_DEV_PARSE; - if (cmd->tgt_dev->cmd_count > SCST_MAX_DEVICE_COMMANDS) -#if 0 /* don't know how it's better */ - { - scst_throttle_cmd(cmd); - } else { - BUG_ON(!list_empty(&cmd->tgt_dev->thr_cmd_list)); - TRACE_DBG("Moving cmd %p to active cmd list", cmd); - list_move_tail(&cmd->cmd_list_entry, - &scst_active_cmd_list); - } -#else - { + if (cmd->tgt_dev->cmd_count > SCST_MAX_DEVICE_COMMANDS) { TRACE(TRACE_RETRY, "Too many pending commands in " "session, returning BUSY to initiator \"%s\"", (cmd->sess->initiator_name[0] == '\0') ? @@ -2282,7 +2362,6 @@ } TRACE_DBG("Moving cmd %p to active cmd list", cmd); list_move_tail(&cmd->cmd_list_entry, &scst_active_cmd_list); -#endif } else if (res < 0) { TRACE_DBG("Finishing cmd %p", cmd); scst_set_cmd_error(cmd, @@ -2688,9 +2767,6 @@ set_bit(SCST_CMD_ABORTED, &cmd->cmd_flags); smp_mb__after_set_bit(); - if (test_bit(SCST_CMD_THROTTELED, &cmd->cmd_flags)) - scst_unthrottle_cmd(cmd); - if (call_dev_task_mgmt_fn && cmd->tgt_dev) scst_call_dev_task_mgmt_fn(mcmd, cmd->tgt_dev, 0); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-12 16:43:50
|
Revision: 8 http://svn.sourceforge.net/scst/?rev=8&view=rev Author: vlnb Date: 2006-10-12 09:43:38 -0700 (Thu, 12 Oct 2006) Log Message: ----------- Minor fixes and cleanups Modified Paths: -------------- trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/qla2x00t/qla2x00-target/qla2x00t.h trunk/qla2x00t/qla2x_tgt_def.h Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-10-12 15:27:12 UTC (rev 7) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-10-12 16:43:38 UTC (rev 8) @@ -198,7 +198,7 @@ static void __q2t_send_notify_ack(scsi_qla_host_t *ha, uint16_t target_id, uint16_t status, uint16_t task_flags, uint16_t seq_id, uint32_t add_flags, uint16_t resp_code, - int resp_code_valid) + int resp_code_valid, uint16_t ox_id) { nack_entry_t *ntfy; @@ -226,7 +226,7 @@ /* Do not increment here, the chip isn't decrementing */ /* ntfy->flags = __constant_cpu_to_le16(NOTIFY_ACK_RES_COUNT); */ ntfy->flags |= cpu_to_le16(add_flags); - /* ntfy->ox_id = iocb->ox_id; ToDo */ + ntfy->ox_id = ox_id; if (resp_code_valid) { ntfy->resp_code = cpu_to_le16(resp_code); @@ -246,14 +246,12 @@ } /* ha->hardware_lock supposed to be held on entry */ static inline void q2t_send_notify_ack(scsi_qla_host_t *ha, - notify_entry_t *iocb, - uint32_t add_flags, - uint16_t resp_code, - int resp_code_valid) + notify_entry_t *iocb, uint32_t add_flags, uint16_t resp_code, + int resp_code_valid) { __q2t_send_notify_ack(ha, GET_TARGET_ID(ha, iocb), iocb->status, - iocb->task_flags, iocb->seq_id, - add_flags, resp_code, resp_code_valid); + iocb->task_flags, iocb->seq_id, add_flags, resp_code, + resp_code_valid, iocb->ox_id); } /* @@ -938,7 +936,7 @@ } SET_TARGET_ID(ha, ctio->target, GET_TARGET_ID(ha, atio)); -//ToDo!! ctio->rx_id = atio->rx_id; + ctio->exchange_id = atio->exchange_id; ctio->flags = __constant_cpu_to_le16(OF_FAST_POST | OF_TERM_EXCH | OF_NO_DATA | OF_SS_MODE_1); Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.h =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.h 2006-10-12 15:27:12 UTC (rev 7) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.h 2006-10-12 16:43:38 UTC (rev 8) @@ -79,17 +79,6 @@ #define ATIO_ACA_QUEUE 4 #define ATIO_UNTAGGED 5 -/* CTIO additional flag ToDo: move to the appropriate place */ -#define OF_TERM_EXCH BIT_14 /* Terminate exchange */ - -/* ToDo: move to the appropriate place */ -#define CTIO_INVALID_RX_ID 0x08 -#define CTIO_TIMEOUT 0x0B -#define CTIO_LIP_RESET 0x0E -#define CTIO_TARGET_RESET 0x17 -#define CTIO_PORT_UNAVAILABLE 0x28 -#define CTIO_PORT_LOGGED_OUT 0x29 - /* TM failed response code, see FCP */ #define FC_TM_FAILED 0x5 Modified: trunk/qla2x00t/qla2x_tgt_def.h =================================================================== --- trunk/qla2x00t/qla2x_tgt_def.h 2006-10-12 15:27:12 UTC (rev 7) +++ trunk/qla2x00t/qla2x_tgt_def.h 2006-10-12 16:43:38 UTC (rev 8) @@ -74,6 +74,7 @@ #define OF_NO_DATA (BIT_7 | BIT_6) #define OF_INC_RC BIT_8 /* Increment command resource count */ #define OF_FAST_POST BIT_9 /* Enable mailbox fast posting. */ +#define OF_TERM_EXCH BIT_14 /* Terminate exchange */ #define OF_SSTS BIT_15 /* Send SCSI status */ #endif @@ -181,7 +182,8 @@ uint16_t seq_id; uint16_t reserved_5[11]; uint16_t scsi_status; - uint8_t sense_data[18]; + uint8_t sense_data[16]; + uint16_t ox_id; }notify_entry_t; #endif @@ -205,7 +207,8 @@ uint16_t status; uint16_t task_flags; uint16_t seq_id; - uint16_t reserved_3[21]; + uint16_t reserved_3[20]; + uint16_t ox_id; }nack_entry_t; #define NOTIFY_ACK_SUCCESS 0x01 #endif @@ -285,10 +288,14 @@ uint32_t dseg_2_address; /* Data segment 2 address. */ uint32_t dseg_2_length; /* Data segment 2 length. */ }ctio_entry_t; -#define CTIO_SUCCESS 0x01 -#define CTIO_ABORTED 0x02 -#define CTIO_ERROR_INVALID_RX_ID 0x08 -#define CTIO_ERROR_PORT_LOGGED_OUT 0x29 +#define CTIO_SUCCESS 0x01 +#define CTIO_ABORTED 0x02 +#define CTIO_INVALID_RX_ID 0x08 +#define CTIO_TIMEOUT 0x0B +#define CTIO_LIP_RESET 0x0E +#define CTIO_TARGET_RESET 0x17 +#define CTIO_PORT_UNAVAILABLE 0x28 +#define CTIO_PORT_LOGGED_OUT 0x29 #endif #ifndef CTIO_RET_TYPE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-12 15:27:16
|
Revision: 7 http://svn.sourceforge.net/scst/?rev=7&view=rev Author: vlnb Date: 2006-10-12 08:27:12 -0700 (Thu, 12 Oct 2006) Log Message: ----------- Tiny typo fixed Modified Paths: -------------- trunk/qla2x00t/qla2x00-target/README Modified: trunk/qla2x00t/qla2x00-target/README =================================================================== --- trunk/qla2x00t/qla2x00-target/README 2006-10-12 15:25:28 UTC (rev 6) +++ trunk/qla2x00t/qla2x00-target/README 2006-10-12 15:27:12 UTC (rev 7) @@ -16,7 +16,7 @@ If you have a driver's version (e.g. development) without the patch, but with the full patched initiator source code, you should replace by it qla2xxx subdirectory in kernel_source/drivers/scsi/ and then rebuild the -kernels or only its modules. +kernel or only its modules. This version is compatible with SCST version 0.9.5 and higher. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-12 15:25:42
|
Revision: 6 http://svn.sourceforge.net/scst/?rev=6&view=rev Author: vlnb Date: 2006-10-12 08:25:28 -0700 (Thu, 12 Oct 2006) Log Message: ----------- - Versions changed from "pre1" on "pre2" - Note added in qla2x00-target/README how to deal with full patched initiator driver Modified Paths: -------------- trunk/qla2x00t/qla2x00-target/README trunk/qla2x00t/qla2x00-target/qla2x00t.h trunk/scst/include/scsi_tgt.h Modified: trunk/qla2x00t/qla2x00-target/README =================================================================== --- trunk/qla2x00t/qla2x00-target/README 2006-10-12 15:15:46 UTC (rev 5) +++ trunk/qla2x00t/qla2x00-target/README 2006-10-12 15:25:28 UTC (rev 6) @@ -1,7 +1,7 @@ Target driver for Qlogic 2200/2300 Fibre Channel cards ====================================================== -Version 0.9.5-pre1, XX XXX 2006 +Version 0.9.5-pre2, XX XXX 2006 ------------------------------- This driver has all required features and looks to be quite stable (for @@ -13,6 +13,11 @@ a host acts as the initiator and the target simultaneously, is supported as well. +If you have a driver's version (e.g. development) without the patch, but +with the full patched initiator source code, you should replace by it +qla2xxx subdirectory in kernel_source/drivers/scsi/ and then rebuild the +kernels or only its modules. + This version is compatible with SCST version 0.9.5 and higher. Tested on stable kernels from http://www.kernel.org Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.h =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.h 2006-10-12 15:15:46 UTC (rev 5) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.h 2006-10-12 15:25:28 UTC (rev 6) @@ -31,7 +31,7 @@ /* Version numbers, the same as for the kernel */ #define Q2T_VERSION(a,b,c,d) (((a) << 030) + ((b) << 020) + (c) << 010 + (d)) #define Q2T_VERSION_CODE Q2T_VERSION(0,9,5,0) -#define Q2T_VERSION_STRING "0.9.5-pre1" +#define Q2T_VERSION_STRING "0.9.5-pre2" #define Q2T_MAX_CDB_LEN 16 #define Q2T_TIMEOUT 10 /* in seconds */ Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2006-10-12 15:15:46 UTC (rev 5) +++ trunk/scst/include/scsi_tgt.h 2006-10-12 15:25:28 UTC (rev 6) @@ -32,7 +32,7 @@ /* Version numbers, the same as for the kernel */ #define SCST_VERSION_CODE 0x000905 #define SCST_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -#define SCST_VERSION_STRING "0.9.5-pre1" +#define SCST_VERSION_STRING "0.9.5-pre2" /************************************************************* ** States of command processing state machine This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-12 15:15:55
|
Revision: 5 http://svn.sourceforge.net/scst/?rev=5&view=rev Author: vlnb Date: 2006-10-12 08:15:46 -0700 (Thu, 12 Oct 2006) Log Message: ----------- Initial commit on SCST WWW page Added Paths: ----------- trunk/www/ trunk/www/scst_page.html Added: trunk/www/scst_page.html =================================================================== --- trunk/www/scst_page.html (rev 0) +++ trunk/www/scst_page.html 2006-10-12 15:15:46 UTC (rev 5) @@ -0,0 +1,246 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> +<head> + <meta http-equiv="content-type" + content="text/html; charset=ISO-8859-1"> + <title>SCST: Generic SCSI Target Middle Level for Linux</title> + <meta name="Keywords" + content="SCST, Linux, SCSI target, Qlogic, QLA2200, QLA2300, iSCSI, SCSI"> +</head> +<body> +<a href="http://sourceforge.net"> <img + src="http://sourceforge.net/sflogo.php?group_id=110471&type=5" + alt="SourceForge.net Logo" border="0" height="62" width="210"></a> +<h1><small>Generic SCSI Target Middle Level for Linux</small><br> +</h1> +<p style="text-align: justify;">The SCSI target mid-level subsystem for +Linux (SCST) is a new subsystem of the Linux kernel that provides a +standard framework for SCSI target drivers development. It is designed +to +provide unified, consistent interface between SCSI target drivers and +Linux kernel and simplify target drivers development as much as +possible. A system with a SCSI target device is able to share its local +or virtual devices with other systems on a network with SCSI protocol +support, e.g. SCSI bus, Fibre Channel, TCP/IP with iSCSI. This is +commonly used for data storage virtualization.<br> +</p> +<p style="text-align: justify;">SCST has the following features:</p> +<div style="text-align: justify;"> +</div> +<p style="text-align: justify;"> +</p> +<div style="text-align: justify;"> +</div> +<ul style="text-align: justify;"> + <li>Simple, easy to use interface with target drivers. Particularly, +SCST performs all required pre- and post- processing of incoming +requests and all necessary error recovery.</li> + <li>Undertakes most problems, related to execution contexts, thus +practically eliminating one of the most complicated problem in the +kernel drivers development. For example, a target driver for Qlogic +2200/2300 cards, which has all necessary features, is only ~2000 lines +of code long.</li> + <li> Very low overhead, fine-grained locks and simplest commands +processing path, which allow to reach maximum possible performance and +scalability. Particularly, incoming +requests can be processed in the caller's context or in +one of the internal SCST's tasklets, therefore no extra context +switches +required.</li> + <li>Provides advanced per-initiator device visibility management, +which allows different initiators could see different set of devices +with different access permissions. For instance, initiator A could see +exported from +target T devices Da and Db read-writable, and initiator B from the same +target T could see devices Db read-only and Dc read-writable.<br> + </li> + <li> Complete SMP support.<br> + </li> + <li> Emulates necessary functionality of SCSI host adapter, because +from a remote initiator's point of view SCST acts as a SCSI host with +its +own devices. Some of the emulated functions are the following: + <ul> + <li> Generation of necessary UNIT ATTENTIONs, their storage and +delivery to all connected remote initiators (sessions). </li> + <li> RESERVE/RELEASE functionality. </li> + <li> CA/ACA conditions. </li> + <li> All types of RESETs and other task management functions. </li> + <li> REPORT LUNS command as well as SCSI address space management +in order to have consistent address space on all remote initiators, +since local SCSI devices could not know about each other to report +via REPORT LUNS command. Additionally, SCST responds with error on +all commands to non-existing devices and provides access control +(not implemented yet), so different remote initiators could see +different set of devices. </li> + <li> Other necessary functionality (task attributes, etc.) as +specified in SAM-2, SPC-2, SAM-3, SPC-3 and other SCSI standards. </li> + </ul> + </li> + <li> Device handlers (i.e. plugins) architecture provides extra +flexibility by allowing to make any additional +requests processing, which is completely independent from target +drivers and SCST core, like, for instance, device dependent exceptional +conditions treatment, data caching or passing commands in the user +space for device emulation. Example of such plugin is FILEIO device +handler (see below) .<br> + </li> + <li>Well documented.<br> + </li> +</ul> +<div style="text-align: justify;"> +</div> +<p style="text-align: justify;">Interoperability between SCST and local +SCSI initiators (like sd, st) is +the additional issue that SCST is going to address (it is not +implemented yet). It is necessary, because local SCSI initiators can +change the state of the device, for example RESERVE the device, or some +of its parameters and that would be done behind SCST, which could lead +to various problems. Thus, RESERVE/RELEASE commands, locally generated +UNIT ATTENTIONs, etc. should be intercepted and processed as if local +SCSI initiators act as remote SCSI initiators connected to SCST. This +feature requires some the kernel modification. Since in the current +version it is not implemented, SCST and target drivers are +able to work with any 2.4 or 2.6 kernel version.<br> +</p> +<p style="text-align: justify;">Interface between SCST and target +drivers is based on work, done by <a href="http://www.iol.unh.edu/">University +of New Hampshire Interoperability Labs (UNH IOL)</a> for the <a + href="http://www.iol.unh.edu/consortiums/iscsi/index.html">UNH-iSCSI +project</a>, which is currently developed on <a + href="http://unh-iscsi.sourceforge.net/">SourceForge.net</a>.<br> +</p> +<p style="text-align: justify;">The latest stable version is 0.9.4. It +supports SCSI disks (type 0), tapes (type 1), processors (type +3), CDROMs (type 5), MO disks (type 7), medium changers (type 8) and +RAID controllers (type 0xC). Also it supports FILEIO and "performance" +device handlers. FILEIO device handler allows to use files on file +systems or block devices as virtual remotely available SCSI disks or +CDROM's. "Performance" device handlers provide a way for direct +performance measurements without overhead of actual data transferring +from/to underlying SCSI device. Requires Linux kernel 2.6.14 or higher. +Tested on i386 and x86_64 only, +but should also +work on any other +supported by Linux platform. More detail information you could find in +the project README file.<br> +</p> +<p style="text-align: justify;">Starting from version 0.9.4 2.4 Linux +kernels are not supported anymore, although there could be new SCST +releases those kernels with very important bug fixes. The latest stable +version of SCST with 2.4 kernels support is 0.9.3.1-24.</p> +<p style="text-align: justify;">If you have any questions you can ask +them on the SCST SF.net page either using forum, or scst-devel mailing +list.<br> +</p> +<a href="http://sourceforge.net/project/showfiles.php?group_id=110471">Download</a><br> +<a href="http://www.sourceforge.net/projects/scst">SCST SF.net project +page</a><br> +<a href="ChangeLog.scst">Change Log</a><br> +Documentation: <a href="doc/scst_pg.html">HTML</a>, <a + href="doc/scst_pg.pdf">PDF</a><br> +<p>The latest development versions of SCST and its drivers are +available directly from the +project's SVN. You can access it using either <a + href="http://svn.sourceforge.net/scst">web-based SVN +repository viewer</a> or using anonymous access: </p> +<p> <tt> svn co https://svn.sourceforge.net/svnroot/scst<br> +</tt></p> +<p>More information about accessing SVN repository may be found <a + href="http://sourceforge.net/docs/E09">here</a>.<br> +</p> +<p>History of the pre-SVN SCST development is available in SCST CVS +repository, which is accessible using <a + href="http://cvs.sourceforge.net/viewcvs.py/scst">web-based CVS +repository viewer</a> or anonymous CVS access.<br> +</p> +<hr + style="width: 100%; height: 2px; margin-left: 0px; margin-right: 0px;"> +<h1><small>Target driver for Qlogic 2200/2300 cards for 2.6 kernels<br> +</small></h1> +<div style="text-align: justify;"> +<p>This is ported version of the +previous target driver for 2.4 kernels (see below) to the in-tree 2.6 +Qlogic 2x00 initiator +driver. The port was done by Nathaniel Clark. This is stable and +functional driver with +the larger feature set, than the parent driver has.</p> +<p style="text-align: justify;">The latest version is 0.9.3.8. Requires +Linux kernel version 2.6.15.X and SCST version 0.9.4 or higher. +For usage with other kernel versions you will need to port the +initiator patch to that version of the kernel.<br> +</p> +<p style="text-align: justify;">You can find the latest development +version of this driver in the SCST CVS. See above how to setup access +to it.<br> +</p> +<p style="text-align: justify;"><a + href="http://sourceforge.net/project/showfiles.php?group_id=110471">Download</a><br> +<a href="ChangeLog.qla26">Change Log</a><br> +</p> +</div> +<hr style="width: 100%; height: 2px;"> +<h1><small>Target driver for Qlogic 2200/2300 cards<br> +</small></h1> +<div style="text-align: justify;">Target driver for Qlogic 2200/2300 +cards has all required features and +looks to be quite stable. It is designed to work in conjunction with +the initiator +driver, which is intended to perform all the initialization and +shutdown tasks. In the current release as a base for the initiator +driver was taken Red Hat's driver from the stock 2.4.20 kernel. Then it +was patched, basically, to enable the target mode and provide all +necessary callbacks, and it's still able to work as initiator only. +Mode, when a host acts as the initiator and the target simultaneously, +is also supported. This driver is going to be obsolete soon in favor of +2.6-based driver (see above).<br> +<br> +The latest version is 0.9.3.4. Requires Linux kernel versions 2.4.20 or +higher and SCST version 0.9.3-pre4 or higher. If you are lucky, it +works also on 2.6 kernels, see README file +for details. Tested on i386 only, but +should work on any other supported by Linux platform.<br> +<br> +</div> +<a href="http://sourceforge.net/project/showfiles.php?group_id=110471">Download</a><br> +<a href="ChangeLog.qla">Change Log</a> +<p style="text-align: justify;"></p> +<hr style="width: 100%; height: 2px;"> +<span style="font-weight: bold;"></span> +<h1><small>Target drivers for Adaptec 7xxx, LSI/MPT and Qlogic QLA12xx +cards</small></h1> +Target drivers for Adaptec 7xxx, LSI/MPT and Qlogic QLA12xx cards have +being developed by Hu Gang and they available for download from <a + href="http://bj.soulinfo.com/%7Ehugang/scst/tgt/">http://bj.soulinfo.com/~hugang/scst/tgt/</a>. +These drivers are not completed, but looks to be a good starting point +if you are going to use one of these cards. +SCST team don't have the appropriate hardware, therefore have not +tested and don't support these drivers. Send all questions to Hu Gang +<hugang +% soulinfo.com>. If some of these drivers don't compile for you, try +again with SCST version 0.9.3-pre2.<br> +<br> +<a href="http://bj.soulinfo.com/%7Ehugang/scst/tgt/">Download</a><br> +<br> +<hr style="width: 100%; height: 2px;"> +<h1><small>Patches for UNH-iSCSI Target 1.5.03 and 1.6.00 to work over +SCST</small></h1> +SCST is much more advanced, than the internal mid-level of <a + href="http://sourceforge.net/projects/unh-iscsi">UNH-iSCSI target +driver</a>. +With SCST the iSCSI target benefits from all its features and gets +ability to use all its advantages, like high performance and +scalability, SMP support, required SCSI functionality emulation, etc.<br> +<br> +Since the interface between SCST and the target drivers is based on +work, done by UNH IOL, it was relatively simple to update UNH-iSCSI +target to work over SCST. Mostly it was "search and replace" job. The +built-in scsi_target remains available as a compile-time option.<br> +<br> +Requires Linux kernel versions 2.4.20 or +higher or 2.6.7 or higher and SCST version 0.9.2 or higher.<br> +<br> +<a href="http://sourceforge.net/project/showfiles.php?group_id=110471">Download</a><br> +<br> +</body> +</html> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-12 14:25:16
|
Revision: 4 http://svn.sourceforge.net/scst/?rev=4&view=rev Author: vlnb Date: 2006-10-12 07:25:08 -0700 (Thu, 12 Oct 2006) Log Message: ----------- - Fixed dev->on_dev_count underleak - Minor fixes and cosmetics Modified Paths: -------------- trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2006-10-12 14:18:50 UTC (rev 3) +++ trunk/scst/src/scst_priv.h 2006-10-12 14:25:08 UTC (rev 4) @@ -346,7 +346,8 @@ __scst_block_dev(dev); spin_unlock_bh(&dev->dev_lock); - TRACE_MGMT_DBG("%s", "Waiting during blocking"); + TRACE_MGMT_DBG("Waiting during blocking outstanding %d (on_dev_count " + "%d)", outstanding, atomic_read(&dev->on_dev_count)); wait_event(dev->on_dev_waitQ, atomic_read(&dev->on_dev_count) <= outstanding); TRACE_MGMT_DBG("%s", "wait_event() returned"); Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2006-10-12 14:18:50 UTC (rev 3) +++ trunk/scst/src/scst_targ.c 2006-10-12 14:25:08 UTC (rev 4) @@ -1580,7 +1580,7 @@ } count = 0; - do { + while(1) { rc = scst_do_send_to_midlev(cmd); if (rc == SCST_EXEC_NEED_THREAD) { TRACE_DBG("%s", "scst_do_send_to_midlev() requested " @@ -1597,8 +1597,11 @@ count++; expected_sn = __scst_inc_expected_sn(tgt_dev); cmd = scst_check_deferred_commands(tgt_dev, expected_sn); + if (cmd == NULL) + break; + if (unlikely(scst_inc_on_dev_cmd(cmd) != 0)) + break; } - while(cmd != NULL); out_unplug: if (dev->scsi_dev != NULL) @@ -1742,9 +1745,6 @@ TRACE_ENTRY(); - if (unlikely(cmd->sg == NULL)) - goto out; - if (cmd->cdb[0] == REQUEST_SENSE) { if (cmd->internal) cmd = scst_complete_request_sense(cmd); @@ -1775,15 +1775,12 @@ uint8_t *address; length = scst_get_buf_first(cmd, &address); - if (unlikely(length <= 0)) { + if (length <= 0) goto out; - } - if (length > 2 && cmd->cdb[0] == MODE_SENSE) { + if (length > 2 && cmd->cdb[0] == MODE_SENSE) address[2] |= 0x80; /* Write Protect*/ - } - else if (length > 3 && cmd->cdb[0] == MODE_SENSE_10) { + else if (length > 3 && cmd->cdb[0] == MODE_SENSE_10) address[3] |= 0x80; /* Write Protect*/ - } scst_put_buf(cmd, address); } @@ -1800,7 +1797,7 @@ /* ToDo: all pages ?? */ buflen = scst_get_buf_first(cmd, &buffer); - if (likely(buflen > 0)) { + if (buflen > 0) { if (buflen > SCST_INQ_BYTE3) { #ifdef EXTRACHECKS if (buffer[SCST_INQ_BYTE3] & SCST_INQ_NORMACA_BIT) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-12 14:19:13
|
Revision: 3 http://svn.sourceforge.net/scst/?rev=3&view=rev Author: vlnb Date: 2006-10-12 07:18:50 -0700 (Thu, 12 Oct 2006) Log Message: ----------- Property svn:ignore set Property Changed: ---------------- / branches/ tags/ trunk/ trunk/doc/ trunk/qla2x00t/ trunk/qla2x00t/qla2x00-target/ trunk/scst/ trunk/scst/include/ trunk/scst/kernel/ trunk/scst/kernel/in-tree/ trunk/scst/src/ trunk/scst/src/dev_handlers/ Property changes on: ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: branches ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: tags ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: trunk ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: trunk/doc ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: trunk/qla2x00t ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: trunk/qla2x00t/qla2x00-target ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: trunk/scst ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: trunk/scst/include ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: trunk/scst/kernel ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: trunk/scst/kernel/in-tree ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: trunk/scst/src ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Property changes on: trunk/scst/src/dev_handlers ___________________________________________________________________ Name: svn:ignore + *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2006-10-12 14:03:25
|
Revision: 2 http://svn.sourceforge.net/scst/?rev=2&view=rev Author: vlnb Date: 2006-10-12 07:02:57 -0700 (Thu, 12 Oct 2006) Log Message: ----------- Initial doc's commit Added Paths: ----------- trunk/doc/ trunk/doc/Makefile trunk/doc/fig1.png trunk/doc/fig2.png trunk/doc/fig3.png trunk/doc/fig4.png trunk/doc/scst_pg.sgml Added: trunk/doc/Makefile =================================================================== --- trunk/doc/Makefile (rev 0) +++ trunk/doc/Makefile 2006-10-12 14:02:57 UTC (rev 2) @@ -0,0 +1,61 @@ +COMMAND=linuxdoc --backend= + +SOURCE_NAME=scst_pg + +SOURCE=$(SOURCE_NAME).sgml + +default: html txt pdf + +all: html txt pdf tex dvi ps info lyx rtf + +txt: $(SOURCE_NAME).txt + +html: $(SOURCE_NAME).html + +tex: $(SOURCE_NAME).tex + +dvi: $(SOURCE_NAME).dvi + +ps: $(SOURCE_NAME).ps + +pdf: $(SOURCE_NAME).pdf + +info: $(SOURCE_NAME).info + +lyx: $(SOURCE_NAME).lyx + +rtf: $(SOURCE_NAME).rtf + +$(SOURCE_NAME).txt: $(SOURCE) + $(COMMAND)txt $(SOURCE) + +$(SOURCE_NAME).html: $(SOURCE) + $(COMMAND)html --split=0 $(SOURCE) + +$(SOURCE_NAME).tex: $(SOURCE) + $(COMMAND)latex -o tex $(SOURCE) + +$(SOURCE_NAME).dvi: $(SOURCE) + $(COMMAND)latex -o dvi $(SOURCE) + +$(SOURCE_NAME).ps: $(SOURCE) + $(COMMAND)latex -o ps $(SOURCE) + +$(SOURCE_NAME).pdf: $(SOURCE) + $(COMMAND)latex -o pdf $(SOURCE) + +$(SOURCE_NAME).info: $(SOURCE) + $(COMMAND)info $(SOURCE) + +$(SOURCE_NAME).lyx: $(SOURCE) + $(COMMAND)lyx $(SOURCE) + +$(SOURCE_NAME).rtf: $(SOURCE) + $(COMMAND)rtf $(SOURCE) + +clean: + rm -f *.txt *.html *.tex *.dvi *.ps *.pdf *.info *.lyx *.rtf + +extraclean: clean + +.PHONY: all default html txt pdf tex dvi ps info lyx rtf clean extraclean Added: trunk/doc/fig1.png =================================================================== (Binary files differ) Property changes on: trunk/doc/fig1.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/doc/fig2.png =================================================================== (Binary files differ) Property changes on: trunk/doc/fig2.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/doc/fig3.png =================================================================== (Binary files differ) Property changes on: trunk/doc/fig3.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/doc/fig4.png =================================================================== (Binary files differ) Property changes on: trunk/doc/fig4.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/doc/scst_pg.sgml =================================================================== --- trunk/doc/scst_pg.sgml (rev 0) +++ trunk/doc/scst_pg.sgml 2006-10-12 14:02:57 UTC (rev 2) @@ -0,0 +1,2278 @@ +<!doctype linuxdoc system> + +<article> + +<title>Generic SCSI Target Middle Level for Linux</title> + +<author> + <name>Vladislav Bolkhovitin <<tt/vst @at@ vlnb .dot. net/></name> +</author> + +<date>Version 0.9.3-pre4 2006/02/07, actual for SCST 0.9.3-pre4 and later</date> + +<abstract> +This document describes SCSI target mid-level for Linux (SCST), its +architecture and drivers from the driver writer's point of view. +</abstract> + +<toc> + +<sect>Introduction + +<p> +SCST is a SCSI target mid-level subsystem for Linux. It is designed to +provide unified, consistent interface between SCSI target drivers and +Linux kernel and simplify target drivers development as much as +possible. It has the following features: + +<itemize> + +<item> Very low overhead, fine-grained locks and simplest commands +processing path, which allow to reach maximum possible performance and +scalability that close to theoretical limit. + +<item> Incoming requests can be processed in the caller's context or in +one of the internal SCST's tasklets, therefore no extra context switches +required. + +<item> Complete SMP support. + +<item> Undertakes most problems, related to execution contexts, thus +practically eliminating one of the most complicated problem in the +kernel drivers development. For example, a target driver for Qlogic +2200/2300 cards, which has all necessary features, is about 2000 +lines of code long, that is at least in several times less, than the +initiator one. + +<item> Performs all required pre- and post- processing of incoming +requests and all necessary error recovery functionality. + +<item> Emulates necessary functionality of SCSI host adapter, because +from a remote initiator's point of view SCST acts as a SCSI host with +its own devices. Some of the emulated functions are the following: + + <itemize> + + <item> Generation of necessary UNIT ATTENTIONs, their storage and + delivery to all connected remote initiators (sessions). + + <item> RESERVE/RELEASE functionality. + + <item> CA/ACA conditions. + + <item> All types of RESETs and other task management functions. + + <item> REPORT LUNS command as well as SCSI address space management + in order to have consistent address space on all remote initiators, + since local SCSI devices could not know about each other to report + via REPORT LUNS command. Additionally, SCST responds with error on + all commands to non-existing devices and provides access control + (not implemented yet), so different remote initiators could see + different set of devices. + + <item> Other necessary functionality (task attributes, etc.) as + specified in SAM-2, SPC-2, SAM-3, SPC-3 and other SCSI standards. + + </itemize> + +<item> Device handlers architecture provides extra reliability and +security via verifying all incoming requests and allows to make any +additional requests processing, which is completely independent from +target drivers, for example, data caching or device dependent +exceptional conditions treatment. + +</itemize> + +Interoperability between SCST and local SCSI initiators (like sd, st) is +the additional issue that SCST is going to address (it is not +implemented yet). It is necessary, because local SCSI initiators can +change the state of the device, for example RESERVE the device, or some +of its parameters and that would be done behind SCST, which could lead +to various problems. Thus, RESERVE/RELEASE commands, locally generated +UNIT ATTENTIONs, etc. should be intercepted and processed as if local +SCSI initiators act as remote SCSI initiators connected to SCST. This +feature requires some the kernel modification. Since in the current +version it is not implemented, SCST and the target drivers are able to +work with any unpatched 2.4 kernel version. + +Interface between SCST and the target drivers is based on work, done by +University of New Hampshire Interoperability Labs (UNH IOL). + +All described below data structures and function could be found in +<bf/scsi_tgt.h/. The SCST's Internet page is +<url url="http://scst.sourceforge.net">. + +<sect>Terms and Definitions + +<p><bf/SCSI initiator device/ + +A SCSI device that originates service and task management requests to be +processed by a SCSI target device and receives device service and task +management responses from SCSI target devices. + +<bf/SCSI target device/ + +A SCSI device that receives device service and task management requests +for processing and sends device service and task management responses +to SCSI initiator devices or drivers. + +<bf/SCST session/ + +SCST session is the object that describes relationship between a remote +initiator and SCST via a target driver. All the commands from the remote +initiator is passed to SCST in the session. For example, for connection +oriented protocols, like iSCSI, SCST session could be mapped to the TCP +connection. SCST session is the close equivalent of I_T nexus object. + +<bf/Local SCSI initiator/ + +A SCSI initiator that is located on the same host as SCST subsystem. +Examples are sg and st drivers. + +<bf/Remote SCSI initiator/ + +A SCSI initiator that is located on the remote host for SCST subsystem +and makes client connections to SCST via SCSI target drivers. + +<bf/SCSI target driver/ + +A Linux hardware or logical driver that acts as a SCSI target for remote +SCSI initiators, i.e. accepts remote connections, passes incoming SCSI +requests to SCST and sends SCSI responses from SCST back to their +originators. + +<bf/Device handler driver/ + +Also known as "device type specific driver" or "dev handler", is plugin +for SCST, which helps SCST to analyze incoming requests and determine +parameters, specific to various types of devices as well as perform some +processing. See appropriate section for details. + +<sect>SCST Architecture + +<p> +SCST accepts commands and passes them to SCSI mid-level at the same +way as SCSI high-level drivers (sg, sd, st) do. Figure 1 shows +interaction between SCST, its drivers and Linux SCSI subsystem. + +<figure> +<eps file="fig1.png"> +<img src="fig1.png"> +<caption> + <newline> Interaction between SCST, its drivers and Linux SCSI subsystem. +</caption> +</figure> + +<sect>Target driver registration + +<p> +To work with SCST a target driver must register its template in SCST by +calling scst_register_target_template(). The template lets SCST know the +target driver's entry points. It is defined as the following: + +<sect1>Structure scst_tgt_template + +<p> +<verb> +struct scst_tgt_template +{ + int sg_tablesize; + const char name[15]; + + unsigned unchecked_isa_dma:1; + unsigned use_clustering:1; + + unsigned xmit_response_atomic:1; + unsigned rdy_to_xfer_atomic:1; + unsigned report_aen_atomic:1; + + int (* detect) (struct scst_tgt_template *tgt_template); + int (* release)(struct scst_tgt *tgt); + + int (* xmit_response)(struct scst_cmd *cmd); + int (* rdy_to_xfer)(struct scst_cmd *cmd); + + void (*on_free_cmd) (struct scst_cmd *cmd); + + void (* task_mgmt_fn_done)(struct scst_mgmt_cmd *mgmt_cmd); + void (* report_aen)(int mgmt_fn, const uint8_t *lun, int lun_len); + + int (*proc_info) (char *buffer, char **start, off_t offset, + int length, int *eof, struct scst_tgt *tgt, int inout); +} +</verb> + +Where: + +<itemize> + +<item><bf/sg_tablesize/ - allows checking whether scatter/gather can be +used or not and, if yes, sets the maximum supported count of +scatter/gather entries + +<item><bf/name/ - the name of the template. Must be unique to identify +the template. Must be defined. + +<item><bf/unchecked_isa_dma/ - true, if this target adapter uses +unchecked DMA onto an ISA bus. + +<item><bf/use_clustering/ - true, if this target adapter wants to use +clustering (i.e. smaller number of segments). + +<item><bf/xmit_response_atomic/, <bf/rdy_to_xfer_atomic/ - true, if the +corresponding function supports execution in the atomic (non-sleeping) +context. + +<item><bf/int (* detect) (struct scst_tgt_template *tgt_template)/ - this +function is intended to detect the target adapters that are present in +the system. Each found adapter should be registered by calling +<bf/scst_register()/. The function should return a value >= 0 to signify +the number of detected target adapters. A negative value should be +returned whenever there is an error. Must be defined. + +<item><bf/int (* release)(struct scst_tgt *tgt)/ - this function is +intended to free up the resources allocated to the device. The function +should return 0 to indicate successful release or a negative value if +there are some issues with the release. In the current version of SCST +the return value is ignored. Must be defined. + +<item><bf/int (* xmit_response)(struct scst_cmd *cmd)/ - this +function is equivalent to the SCSI queuecommand(). The target should +transmit the response data and the status in the struct scst_cmd. See +below for details. Must be defined. + +<item><bf/int (* rdy_to_xfer)(struct scst_cmd *cmd)/ - this function +informs the driver that data buffer corresponding to the said command +have now been allocated and it is OK to receive data for this command. +This function is necessary because a SCSI target does not have any +control over the commands it receives. Most lower-level protocols have a +corresponding function which informs the initiator that buffers have +been allocated e.g., XFER_RDY in Fibre Channel. After the data is +actually received the low-level driver should call <bf/scst_rx_data()/ +in order to continue processing this command. Returns one of the +<bf/SCST_TGT_RES_*/ constants, described below. Pay attention to +"atomic" attribute of the command, which can be get via +<bf/scst_cmd_atomic()/: it is true if the function called in the atomic +(non-sleeping) context. Must be defined. + +<item><bf/void (*on_free_cmd)(struct scst_cmd *cmd)/ - this function +called to notify the driver that the command is about to be freed. +Necessary, because for aborted commands <bf/xmit_response()/ could not be +called. Could be used on IRQ context. Must be defined. + +<item><bf/void (* task_mgmt_fn_done)(struct scst_mgmt_cmd *mgmt_cmd)/ - +this function informs the driver that a received task management +function has been completed. Completion status could be get via +<bf/scst_mgmt_cmd_get_status()/. No return value expected. Must be +defined, if the target supports task management functionality. + +<item><bf/int (* report_aen)(int mgmt_fn, const uint8_t *lun, int +lun_len)/ - this function is used for Asynchronous Event Notification. +It is the responsibility of the driver to notify any/all initiators +about the Asynchronous Event reported. Returns one of the +<bf/SCST_TGT_RES_*/ constants, described below. Must be defined, if +low-level protocol supports AEN. This feature is not implemented yet. + +<item><bf/int (*proc_info) (char *buffer, char **start, off_t offset, +int length, int *eof, struct scst_tgt *tgt, int inout)/ - this function +can be used to export the driver's statistics and other information to +the world outside the kernel. Parameters: + + <enum> + + <item> <bf/buffer, start, offset, length, eof/ - have the same + meaning as for <bf/read_proc_t/ function of the kernel + + <item> <bf/tgt/ - pointer to the target, for which the function + is called + + <item> <bf/inout/ - read/write direction flag, 0 - for reads, other + value - for writes + + </enum> + +If the driver needs to create additional files in its /proc +subdirectory, it can use <bf/scst_proc_get_tgt_root()/ function to get +the root proc_dir_entry. + +</itemize> + +Functions <bf/xmit_response()/, <bf/rdy_to_xfer()/ are expected to be +non-blocking, i.e. return immediately and don't wait for actual data +transfer to finish. Blocking in such command could negatively impact on +overall system performance. If blocking is necessary, it is worth to +consider creating dedicated thread(s) in target driver, to which the +commands would be passed and which would perform blocking operations +instead of SCST. If the function allowed to sleep or not is defined by +"atomic" attribute of the cmd that can be get via +<bf/scst_cmd_atomic()/, which is true, if sleeping is not allowed. In +this case, if the function requires sleeping, it can return +<bf/SCST_TGT_RES_NEED_THREAD_CTX/ in order to be recalled in the thread +context, where sleeping is allowed. + +Functions <bf/task_mgmt_fn_done()/ and <bf/report_aen()/ are recommended +to be non-blocking as well. Blocking there will stop all management +processing for all target drivers in the system (there is only one +management thread in the system). + +Functions <bf/xmit_response()/, <bf/rdy_to_xfer()/ and <bf/report_aen()/ +can return the following error codes: + +<itemize> + +<item><bf/SCST_TGT_RES_SUCCESS/ - success. + +<item><bf/SCST_TGT_RES_QUEUE_FULL/ - internal device queue is full, retry +again later. + +<item><bf/SCST_TGT_RES_NEED_THREAD_CTX/ - it is impossible to complete +requested task in atomic context. The command should be restarted in the +thread context as described above. + +<item><bf/SCST_TGT_RES_FATAL_ERROR/ - fatal error, i.e. it is unable to +perform requested operation. If returned by <bf/xmit_response()/ the +command will be destroyed, if by <bf/rdy_to_xfer()/, +<bf/xmit_response()/ will be called with <bf/HARDWARE ERROR/ sense data. + +</itemize> + +<sect2>More about <bf/xmit_response()/ + +<p> +As already written above, function <bf/xmit_response()/ should transmit +the response data and the status from the cmd parameter. Either it +should transmit the data or the status is defined by bits of the value, +returned by <bf/scst_cmd_get_tgt_resp_flags()/. They are: + +<itemize> + +<item><bf/SCST_TSC_FLAG_DATA/ - set if there are data to be sent + +<item><bf/SCST_TSC_FLAG_STATUS/ - set if the command is finished and +there is status/sense to be sent + +</itemize> + +If <bf/SCST_TSC_FLAG_DATA/ is set, the data contained in the buffer, +returned by <bf/scst_cmd_get_buffer()/ (pay attention to +<bf/scst_cmd_get_use_sg()/ for scatter/gather) with length, returned by +<bf/scst_cmd_get_resp_data_len()/. It is recommended to use +<bf/scst_get_buf_*()/scst_put_buf()/ family of function instead of +direct access to the data buffers, because they hide all HIGHMEM and +SG/plain buffer issues. + +If <bf/SCST_TSC_FLAG_STATUS/ is set the status could be received by the +appropriate <bf/scst_cmd_get_*_status()/ functions (see below). + +The sense, if any, is contained in the buffer, returned by +<bf/scst_cmd_get_sense_buffer()/, with length, returned by +<bf/scst_cmd_get_sense_buffer_len()/. SCST always works in +<bf/autosense/ mode. If a low-level SCSI driver/device doesn't support +autosense mode, SCST will issue REQUEST SENSE command, if necessary. +Thus, if CHECK CONDITION established, target driver will always see +sense in the sense buffer and isn't required to request the sense +manually. + +It is possible, that <bf/SCST_TSC_FLAG_DATA/ is set, but +<bf/SCST_TSC_FLAG_STATUS/ is not set. In this case the driver should +only transmit the data, but not finish the command and transmit the +status. Function <bf/xmit_response()/ will be called again either to +transmit the status or data once more. + +After the response is completely sent, the target should call +<bf/scst_tgt_cmd_done()/ function in order to allow SCST to free the +command. + +Function <bf/xmit_response()/ returns one of the <bf/SCST_TGT_RES_*/ +constants, described above. Pay attention to "atomic" attribute of the +cmd, which can be get via <bf/scst_cmd_atomic()/: it is true if the +function called in the atomic (non-sleeping) context. + +<sect1>Target driver registration functions + +<sect2>scst_register_target_template() + +<p> +Function <bf/scst_register_target_template()/ is defined as the following: + +<verb> +int scst_register_target_template( + struct scst_tgt_template *vtt) +</verb> + +Where: + +<itemize> +<item><bf/vtt/ - pointer to the target driver template +</itemize> + +Returns 0 on success or appropriate error code otherwise. + +<sect2>scst_register() + +<p> +Function <bf/scst_register()/ is defined as the following: + +<verb> +struct scst_tgt *scst_register( + struct scst_tgt_template *vtt) +</verb> + +Where: + +<itemize> +<item><bf/vtt/ - pointer to the target driver template +</itemize> + +Returns target structure based on template vtt or NULL in case of error. + +<sect>Target driver unregistration + +<p> +In order to unregister itself target driver should at first call +<bf/scst_unregister()/ for all its adapters and then call +<bf/scst_unregister_target_template()/ for its template. + +<sect1>scst_unregister() + +<p> +Function <bf/scst_unregister()/ is defined as the following: + +<verb> +void scst_unregister( + struct scst_tgt *tgt) +</verb> + +Where: + +<itemize> +<item><bf/tgt/ - pointer to the target driver structure +</itemize> + +<sect1>scst_unregister_target_template() + +<p> +Function <bf/scst_unregister_target_template()/ is defined as the following: + +<verb> +void scst_unregister_target_template( + struct scst_tgt_template *vtt) +</verb> + +Where: + +<itemize> +<item><bf/vtt/ - pointer to the target driver template +</itemize> + +<sect>SCST session registration + +<p> +When target driver determines that it needs to create new SCST session +(for example, by receiving new TCP connection), it should call +<bf/scst_register_session()/, that is defined as the following: + +<verb> +struct scst_session *scst_register_session( + struct scst_tgt *tgt, + int atomic, + const char *initiator_name, + void *data, + void (*result_fn) ( + struct scst_session *sess, + void *data, + int result)); +</verb> + +Where: + +<itemize> + +<item><bf/tgt/ - target + +<item><bf/atomic/ - true, if the function called in the atomic context + +<item><bf/initiator_name/ - remote initiator's name, any NULL-terminated +string, e.g. iSCSI name, which used as the key to found appropriate +access control group. Could be NULL, then "default" group is used. The +groups are set up via /proc interface. + +<item><bf/data/ - data that will be used as the second +parameter for <bf/bf/result_fn/()/ function + +<item><bf/result_fn/ - pointer to the function that will be +asynchronously called when session initialization finishes. Can be NULL. +Parameters: + + <itemize> + + <item><bf/sess/ - session + + <item><bf/data/ - target driver supplied to + <bf/scst_register_session()/ data + + <item><bf/result/ - session initialization result, 0 on success or + appropriate error code otherwise + + </itemize> + +</itemize> + +A session creation and initialization is a complex task, which requires +sleeping state, so it can't be fully done in interrupt context. +Therefore the "bottom half" of it, if <bf/scst_register_session()/ is +called from atomic context, will be done in SCST thread context. In this +case <bf/scst_register_session()/ will return not completely initialized +session, but the target driver can supply commands to this session via +<bf/scst_rx_cmd()/. Those commands processing will be delayed inside +SCST until the session initialization is finished, then their processing +will be restarted. The target driver will be notified about finish of +the session initialization by function <bf/result_fn()/. On success the +target driver could do nothing, but if the initialization fails, the +target driver must ensure that no more new commands being sent or will +be sent to SCST after <bf/result_fn()/ returns. All already sent to SCST +commands for failed session will be returned in <bf/xmit_response()/ +with BUSY status. In case of failure the driver shall call +<bf/scst_unregister_session()/ inside <bf/result_fn()/, it will NOT be +called automatically. Thus, <bf/scst_register_session()/ can be called +even on IRQ context. + +Session registration is illustrated on Figure 2 and Figure 3. + +<figure> +<eps file="fig2.png"> +<img src="fig2.png"> +<caption> + <newline> Session registration when <bf/atomic/ parameter is false +</caption> +</figure> + +<figure> +<eps file="fig3.png"> +<img src="fig3.png"> +<caption> + <newline> Session registration when <bf/atomic/ parameter is true +</caption> +</figure> + +<sect>SCST session unregistration + +<p> +SCST session unregistration basically is the same, except that instead of +atomic parameter there is <bf/wait/ one. + +<verb> +void scst_unregister_session( + struct scst_session *sess, + int wait, + void (* unreg_done_fn)( + struct scst_session *sess)) +</verb> + +Where: + +<itemize> + +<item><bf/sess/ - session to be unregistered + +<item><bf/wait/ - if true, instructs to wait until all commands, which +currently executing and belonged to the session, finished. Otherwise, +target driver should be prepared to receive <bf/xmit_response()/ for +the session after <bf/scst_unregister_session()/ returns. + +<item><bf/unreg_done_fn/ - pointer to the function that will be +asynchronously called when the last session's command finishes and the +session is about to be completely freed. Can be NULL. Parameter: + + <itemize> + + <item><bf/sess/ - session + + </itemize> + +</itemize> + +All outstanding commands will be finished regularly. After +<bf/scst_unregister_session()/ returned no new commands must be sent to +SCST via <bf/scst_rx_cmd()/. Also, the caller must ensure that no +<bf/scst_rx_cmd()/ or <bf/scst_rx_mgmt_fn_*()/ is called in paralell +with <bf/scst_unregister_session()/. + +Function <bf/scst_unregister_session()/ can be called before +<bf/result_fn()/ of <bf/scst_register_session()/ called, i.e. during the +session registration/initialization. + +<sect>The commands processing and interaction between SCST and its drivers + +<p> +The commands processing by SCST started when target driver calls +<bf/scst_rx_cmd()/. This function returns SCST's command. Then the target +driver finishes the command's initialization, if necessary, for +example, storing necessary target driver specific data there, and calls +<bf/scst_cmd_init_done()/ telling SCST that it can start the processing. +Then SCST translates the command's LUN to local device, determines the +command's data direction and required data buffer size by calling +appropriate device handler's <bf/parse()/ function. Then: + +<itemize> + +<item>If the command required no data transfer, it will be passed to +SCSI mid-level directly or via device handler's <bf/exec()/ call. + +<item>If the command is <bf/READ/ command (data to the target), +necessary space will be allocated and then the command will be passed +to SCSI mid-level directly or via device handler's <bf/exec()/ call. + +<item>If the command is <bf/WRITE/ command (data from the target), +necessary space will be allocated, then the target's <bf/rdy_to_xfer()/ +function will be called, telling the target that the space is ready and +it can start data transferring. When all the data are read from the +target, it will call <bf/scst_rx_data()/, and the command will be passed +to SCSI mid-level directly or via device handler's <bf/exec()/ call. + +</itemize> + +When the command is finished by SCSI mid-level, device handler's +<bf/dev_done()/ is called to notify it about the command's +completion. Then in order to send the response the target's +<bf/xmit_response()/ is called. When the response, including data, if +any, is transmitted, the target will call <bf/scst_tgt_cmd_done()/ +telling SCST that it can free the command and its data buffer. + +Then during the command's deallocation device handler's and the target's +<bf/on_free_cmd()/ will be called in this order, if set. + +This sequence is illustrated on Figure 4. To simplify the picture, sign +"..." means SCST's waiting state for the corresponding command to +complete. During this state SCST and its drivers continue processing of +other commands, if there are any. One way arrow, for example to +<bf/xmit_response()/, means that after this function returns, nothing +valuable for the current command will be done and SCST goes sleeping or +to the next command processing until corresponding event happens. + +<figure> +<eps file="fig4.png"> +<img src="fig4.png"> +<caption> + <newline> The commands processing flow +</caption> +</figure> + +Additionally, before calling <bf/scst_cmd_init_done()/ the target driver can +set the following the command's flags or parameters: + +<itemize> + +<item> <bf/DATA_BUF_ALLOCED/ - set if the data buffer is already +allocated. The flag is set via <bf/scst_cmd_set_data_buff_alloced()/ and +get via <bf/scst_cmd_get_data_buff_alloced()/. Useful, for instance, for +iSCSI unsolicited data. + +<item> Expected transfer length and direction via +<bf/scst_cmd_set_expected()/ as supplied by remote initiator, if any. +This values will be used only if the command's opcode is unknown for +SCST, for example for vendor-specific commands. If these values not set +and opcode isn't known, the command will be completed by SCST in +preprocessing phase with <bf/INVALID OPCODE/ sense. + +</itemize> + +<sect1>The commands processing functions + +<sect2>scst_rx_cmd() + +<p> +Function <bf/scst_rx_cmd()/ creates and sends new command to SCST. Returns +the command on success or NULL otherwise. It is defined as the +following: + +<verb> +struct scst_cmd *scst_rx_cmd( + struct scst_session *sess, + const uint8_t *lun, + int lun_len, + const uint8_t *cdb, + int cdb_len, + int atomic) +</verb> + +Where: + +<itemize> + +<item><bf/sess/ - SCST's session + +<item><bf/lun/ - pointer to device's LUN as specified in SCSI +Architecture Model 2/3 without any byte order translation. Extended +addressing method is not supported. + +<item><bf/lun_len/ - LUN's length + +<item><bf/cdb/ - SCSI CDB + +<item><bf/cdb_len/ - CDB's length + +<item><bf/atomic/ - if true, the command will be allocated with +GFP_ATOMIC flag, otherwise GFP_KERNEL will be used + +</itemize> + +<sect2>scst_cmd_init_done() + +<p> +Function <bf/scst_cmd_init_done()/ notifies SCST that the driver finished +its part of the command initialization, and the command is ready for +execution. It is defined as the following: + +<verb> +void scst_cmd_init_done( + struct scst_cmd *cmd, + int pref_context) +</verb> + +Where: + +<itemize> + +<item><bf/cmd/ - the command + +<item><bf/pref_context/ - preferred command execution context. See +<bf/SCST_CONTEXT_*/ constants below for details. + +</itemize> + +<sect2>scst_rx_data() + +<p> +Function <bf/scst_rx_data()/ notifies SCST that the driver received all +the necessary data and the command is ready for further processing. It +is defined as the following: + +<verb> +void scst_rx_data( + struct scst_cmd *cmd, + int status, + int pref_context) +</verb> + +Where: + +<itemize> + +<item><bf/cmd/ - the command + +<item><bf/status/ - completion status, see below. + +<item><bf/pref_context/ - preferred command execution context. See +<bf/SCST_CONTEXT_*/ constants below for details. + +</itemize> + +Parameter <bf/status/ can have one of the following values: + +<itemize> + +<item><bf/SCST_RX_STATUS_SUCCESS/ - success + +<item><bf/SCST_RX_STATUS_ERROR/ - data receiving finished with error, so +SCST should set the sense and finish the command by calling +<bf/xmit_response()/ + +<item><bf/SCST_RX_STATUS_ERROR_SENSE_SET/ - data receiving finished with +error and the sense is set, so SCST should finish the command by calling +<bf/xmit_response()/ + +<item><bf/SCST_RX_STATUS_ERROR_FATAL/ - data receiving finished with +fatal error, so SCST should finish the command, but don't call +<bf/xmit_response()/. In this case the driver must free all associated +with the command data before calling <bf/scst_rx_data()/. + +</itemize> + +<sect2>scst_tgt_cmd_done() + +<p> +Function <bf/scst_tgt_cmd_done()/ notifies SCST that the driver sent the +data and/or response. It must not been called if there are an error and +<bf/xmit_response()/ returned something other, than +<bf/SCST_TGT_RES_SUCCESS/. It is defined as the following: + +<verb> +void scst_tgt_cmd_done( + struct scst_cmd *cmd) +</verb> + +Where: +<itemize> +<item><bf/cmd/ - the command +</itemize> + +<sect1>The commands processing context + +<p> +Execution context often is a major problem in the kernel drivers +development, because many contexts, like IRQ one, greatly limit +available functionality, therefore require additional complex code in +order to pass processing to more simple context. SCST does its best to +undertake most of the context handling. + +On the initialization time SCST creates for internal command processing +as many threads as there are processors in the system or specified by +user via <bf/scst_threads/ module parameter. Similarly, as many tasklets +created as there are processors in the system. + +Each command can be processed in one of four contexts: + +<enum> +<item>Directly, i.e. in the caller's context, without limitations +<item>Directly atomically, i.e. with sleeping forbidden +<item>In the SCST's internal per processor or per session thread +<item>In the SCST's per processor tasklet +</enum> + +The target driver sets this context as pref_context parameter for +<bf/scst_cmd_init_done()/ and <bf/scst_rx_data()/. Additionally, target's +template's <bf/xmit_response_atomic/ and <bf/rdy_to_xfer_atomic/ flags +have direct influence on the context. If one of them is false, the +corresponding function will never be called in the atomic context and, +if necessary, the command will be rescheduled to one of the SCST's +threads. + +SCST in some circumstances can change preferred context to less +restrictive one, for example, for large data buffer allocation, if +there is not enough GFP_ATOMIC memory. + +<sect2>Preferred context constants + +<p> +There are the following preferred context constants: + +<itemize> + +<item><bf/SCST_CONTEXT_DIRECT/ - sets direct command processing (i.e. +regular function calls in the current context) sleeping is allowed, no +context restrictions. Supposed to be used when calling from thread +context where no locks are held and the driver's architecture allows +sleeping without performance degradation or anything like that. + +<item><bf/SCST_CONTEXT_DIRECT_ATOMIC/ - sets direct command processing +(i.e. regular function calls in the current context), sleeping is not +allowed. Supposed to be used when calling on thread context where there +are locks held, when calling on softirq context or the driver's +architecture does not allow sleeping without performance degradation or +anything like that. + +<item><bf/SCST_CONTEXT_TASKLET/ - tasklet or thread context required for +the command processing. Supposed to be used when calling from IRQ +context. + +<item><bf/SCST_CONTEXT_THREAD/ - thread context required for the +command processing. Supposed to be used if the driver's architecture +does not allow using any of above. + +</itemize> + +<sect>Task management functions + +<p> +There are the following task management functions supported: + +<itemize> + +<item> <bf/SCST_ABORT_TASK/ - <bf/ABORT_TASK/ task management function, +aborts the specified task (command). Returns completion status via +<bf/task_mgmt_fn_done()/ when the command (task) is actually aborted. + +<item> <bf/SCST_ABORT_TASK_SET/ - <bf/ABORT_TASK_SET/ task management +function, aborts all tasks (commands) on the specified device. Returns +the success via <bf/task_mgmt_fn_done()/ immediately, not waiting for +the commands being actually aborted. + +<item> <bf/SCST_CLEAR_ACA/ - <bf/CLEAR_ACA/ task management function, +currently does nothing. + +<item> <bf/SCST_CLEAR_TASK_SET/ - <bf/CLEAR_TASK_SET/ task management +function, the same as <bf/SCST_ABORT_TASK_SET/. + +<item> <bf/SCST_LUN_RESET/ - <bf/LUN_RESET/ task management function, +implemented via <bf/scsi_reset_provider()/ call for the specified device +with <bf/SCSI_TRY_RESET_DEVICE/ parameter. + +<item> <bf/SCST_TARGET_RESET/ - <bf/TARGET_RESET/ task management +function, implemented via <bf/scsi_reset_provider()/ call for all the +hosts in the system (one device per each host) with +<bf/SCSI_TRY_RESET_BUS/ parameter at first and then, if failed, with +<bf/SCSI_TRY_RESET_HOST/. + +</itemize> + +<sect1>scst_rx_mgmt_fn_tag() + +<p> +Function <bf/scst_rx_mgmt_fn_tag()/ tells SCST to perform the specified +task management function, based on the command's tag. Can be used only +for <bf/SCST_ABORT_TASK/. + +It is defined as the following: + +<verb> +int scst_rx_mgmt_fn_tag( + struct scst_session *sess, + int fn, + uint32_t tag, + int atomic, + void *tgt_specific) +</verb> + +Where: + +<itemize> + +<item> <bf/sess/ - the session, on which the command should be performed. + +<item> <bf/fn/ - task management function, one of the constants above. + +<item> <bf/tag/ - the command's tag. + +<item> <bf/atomic/ - true, if the function called in the atomic context. + +<item> <bf/tgt_specific/ - pointer to the target driver specific data, +can be retrieved in <bf/task_mgmt_fn_done()/ via +<bf/scst_mgmt_cmd_get_status()/ function. + +</itemize> + +Returns 0 if the command was successfully created and scheduled for +execution, error code otherwise. On success, the completion status of +the command will be reported asynchronously via <bf/task_mgmt_fn_done()/ +driver's callback. + +<sect1>scst_rx_mgmt_fn_lun() + +<p> +Function <bf/scst_rx_mgmt_fn_lun()/ tells SCST to perform the specified +task management function, based on the LUN. Currently it can be used for +any function, except <bf/SCST_ABORT_TASK/. + +It is defined as the following: + +<verb> +int scst_rx_mgmt_fn_lun( + struct scst_session *sess, + int fn, + const uint8_t *lun, + int lun_len, + int atomic, + void *tgt_specific); +</verb> + +Where: + +<itemize> + +<item> <bf/sess/ - the session, on which the command should be performed. + +<item> <bf/fn/ - task management function, one of the constants above. + +<item> <bf/lun/ - LUN, the format is the same as for <bf/scst_rx_cmd()/. + +<item> <bf/lun_len/ - LUN's length. + +<item> <bf/atomic/ - true, if the function called in the atomic context. + +<item> <bf/tgt_specific/ - pointer to the target driver specific data, +can be retrieved in <bf/task_mgmt_fn_done()/ via +<bf/scst_mgmt_cmd_get_status()/ function. + +</itemize> + +Returns 0 if the command was successfully created and scheduled for +execution, error code otherwise. On success, the completion status of +the command will be reported asynchronously via <bf/task_mgmt_fn_done()/ +driver's callback. + +<sect>Device specific drivers (device handlers) + +<p> +Device specific drivers are plugins for SCST, which help SCST to analyze +incoming requests and determine parameters, specific to various types +of devices. Device handlers are intended for the following: + +<itemize> + +<item>To get data transfer length and direction directly from CDB and +current device's configuration exactly as an end-target SCSI device +does. This serves two purposes: + + <itemize> + + <item> Improves security and reliability by not trusting the data + supplied by remote initiator via SCSI low-level protocol. + + <item> Some low-level SCSI protocols don't provide data transfer + length and direction, so that information can be get only + directly from CDB and current device's configuration. For + example, for tape devices to get data transfer size it might be + necessary to know block size setting. + + </itemize> + +<item>To process some exceptional conditions, like ILI on tape devices. + +<item>To initialize incoming commands with some device-specific +parameters, like timeout value. + +<item>To allow some additional device-specific commands pre-, post- +processing or alternative execution, like copying data from system +cache, and do that completely independently from target drivers. + +</itemize> + +Device handlers performs very lightweight processing and therefore +should not considerably affect performance or CPU load. They are +considered to be part of SCST, so they could directly access any fields +in SCST's structures as well as use the corresponding functions. + +Without appropriate device handler SCST hides devices of this type from +remote initiators and returns <bf/HARDWARE ERROR/ sense data to any +requests to them. + +<sect1>Device specific driver registration + +<sect2>scst_register_dev_driver() + +<p> +To work with SCST a device specific driver must register itself in SCST by +calling <bf/scst_register_dev_driver()/. It is defined as the following: + +<verb> +int scst_register_dev_driver( + struct scst_dev_type *dev_type) +</verb> + +Where: + +<itemize> +<item><bf/dev_type/ - device specific driver's description structure +</itemize> + +The function returns 0 on success or appropriate error code otherwise. + +<sect2>Structure <bf/scst_dev_type/ + +<p> +Structure <bf/scst_dev_type/ is defined as the following: + +<verb> +struct scst_dev_type +{ + char name[15]; + int type; + + unsigned parse_atomic:1; + unsigned exec_atomic:1; + unsigned dev_done_atomic:1; + + int (*init) (struct scst_dev_type *dev_type); + void (*release) (struct scst_dev_type *dev_type); + + int (*attach) (struct scst_device *dev); + void (*detach) (struct scst_device *dev); + + int (*attach_tgt) (struct scst_tgt_device *tgt_dev); + void (*detach_tgt) (struct scst_tgt_device *tgt_dev); + + int (*parse) (struct scst_cmd *cmd); + int (*exec) (struct scst_cmd *cmd, + void (*scst_cmd_done)(struct scsi_cmnd *cmd, int next_state)); + int (*dev_done) (struct scst_cmd *cmd); + int (*task_mgmt_fn) (struct scst_mgmt_cmd *mgmt_cmd, + struct scst_tgt_dev *tgt_dev, struct scst_cmd *cmd_to_abort); + int (*on_free_cmd) (struct scst_cmd *cmd); + + int (*proc_info) (char *buffer, char **start, off_t offset, + int length, int *eof, struct scst_dev_type *dev_type, + int inout) + + struct module *module; +} +</verb> + +Where: + +<itemize> + +<item><bf/name/ - the name of the device handler. Must be defined and +unique + +<item><bf/type/ - SCSI type of the supported device. Must be defined. + +<item><bf/parse_atomic/, <bf/exec_atomic/, <bf/dev_done_atomic/ - true, +if corresponding function supports execution in the atomic +(non-sleeping) context + +<item><bf/int (*init) (struct scst_dev_type *dev_type)/ - called on the +device handler load, before the first attach(). Returns 0 on success, +error code otherwise. + +<item><bf/void (*release) (struct scst_dev_type *dev_type)/ - called on +the device handler unload, after final detach() + +<item><bf/int (*attach) (struct scst_device *dev)/ - called when new +device is attaching to the device handler + +<item><bf/void (*detach) (struct scst_device *dev)/ - called when new +device is detaching from the device handler + +<item><bf/int (*attach_tgt) (struct scst_tgt_device *tgt_dev)/ - called +when new tgt_device (session) is attaching to the device handler + +<item><bf/void (*detach_tgt) (struct scst_tgt_device *tgt_dev)/ - called +when tgt_device (session) is detaching from the device handler + +<item><bf/int (*parse) (struct scst_cmd *cmd, const struct scst_info_cdb +*cdb_info)/ - called to parse CDB from the command. It should initialize +<bf/cmd->bufflen/ and <bf/cmd->data_direction/ (see below +<bf/SCST_DATA_*/ constants) if necessary, otherwise defaults based on +<bf/cdb_info/ will be used. Parameter <bf/cdb_info/ provides some info +about the CDB (see below). Pay attention to "atomic" attribute of the +cmd, which can be via by <bf/scst_cmd_atomic()/: it is true if the +function called in the atomic (non-sleeping) context. Returns the +command's next state or <bf/SCST_CMD_STATE_DEFAULT/, if the next default +state should be used, or <bf/SCST_CMD_STATE_NEED_THREAD_CTX/ if the +function called in atomic context, but requires sleeping. In the last +case, the function will be recalled in the thread context, where +sleeping is allowed. Additionally, <bf/SCST_CMD_DATA_BUF_ALLOCED/ flag +can be set by <bf/parse()/ (see above). Must be defined. + +<item><bf/int (*exec) (struct scst_cmd *cmd, void (*scst_cmd_done)( struct +scst_cmd *cmd, int next_state))/ - called to execute CDB. The result of +the CDB execution is reported via <bf/scst_cmd_done()/ callback. Pay +attention to "atomic" attribute of the command, which can be get via +<bf/scst_cmd_atomic()/: it is true if the function called in the +atomic (non-sleeping) context. For <bf/scst_cmd_done()/ parameter +<bf/next_state/ is the command's next state or +<bf/SCST_CMD_STATE_DEFAULT/, if the next default state should be used. +Using this function modules <bf/devdisk_perf/ and <bf/devtape_perf/ were +implemented. These modules in their <bf/exec()/ method skip (pretend to +execute) all READ and WRITE operations and thus allow direct link +performance measurements without overhead of actual data transferring +from/to underlying SCSI device. See also <bf/scst_is_cmd_local()/ below. +Returns: + + <itemize> + + <item><bf/SCST_EXEC_COMPLETED/ - the command is done, go to + other ones + + <item><bf/SCST_EXEC_NEED_THREAD/ - thread context is required to + execute the command. <bf/Exec()/ will be called again in the + thread context. + + <item><bf/SCST_EXEC_NOT_COMPLETED/ - the command should be sent + to SCSI mid-level. + + </itemize> + +<item><bf/int (*dev_done) (struct scst_cmd *cmd)/ - called to notify +device handler about the result of the command's execution and perform +some post processing. If <bf/parse()/ function is called, +<bf/dev_done()/ is guaranteed to be called as well. The command's fields +<bf/tgt_resp_flags/ and <bf/resp_data_len/ should be set by this +function, but SCST offers good defaults. Pay attention to "atomic" +attribute of the command, which can be get via +<bf/scst_cmd_atomic()/: it is true if the function called in the +atomic (non-sleeping) context. Returns the command's next state or +<bf/SCST_CMD_STATE_DEFAULT/, if the next default state should be used, +or <bf/SCST_CMD_STATE_NEED_THREAD_CTX/ if the function called in atomic +context, but requires sleeping. In the last case, the function will be +recalled in the thread context, where sleeping is allowed. + +<item><bf/int (*task_mgmt_fn) (struct scst_mgmt_cmd *mgmt_cmd, struct +scst_tgt_dev *tgt_dev, struct scst_cmd *cmd_to_abort)/ - called to +execute a task management command. Returns: + + <itemize> + + <item><bf/SCST_DEV_TM_COMPLETED_SUCCESS/ - the command is done + with success, no firther actions required + + <item><bf/SCST_DEV_TM_COMPLETED_FAILED/ - the command is failed, + no firther actions required + + <item><bf/SCST_DEV_TM_NOT_COMPLETED/ - regular standard actions + for the command should be done + + </itemize> + +<bf/NOTE/: for <bf/SCST_ABORT_TASK/ called under spinlock + +<item><bf/void (*on_free_cmd) (struct scst_cmd *cmd)/ - called to notify +device handler that the command is about to be freed. Could be called on +IRQ context. + +<item><bf/int (*proc_info) (char *buffer, char **start, off_t offset, +int length, int *eof, struct scst_dev_type *dev_type, int inout)/ - this +function can be used to export the handler's statistics and other +information to the world outside the kernel. Parameters: + + <enum> + + <item> <bf/buffer, start, offset, length, eof/ - have the same + meaning as for <bf/read_proc_t/ function of the kernel + + <item> <bf/dev_type/ - pointer to the device handler, for which + the function is called + + <item> <bf/inout/ - read/write direction flag, 0 - for reads, other + value - for writes + + </enum> + +If the driver needs to create additional files in its /proc +subdirectory, it can use <bf/scst_proc_get_dev_type_root()/ function to get +the root proc_dir_entry. + +<item><bf/struct module *module/ - pointer to device handler's module + +</itemize> + +Structure <bf/scst_info_cdb/ is defined as the following: + +<verb> +struct scst_info_cdb +{ + enum scst_cdb_flags flags; + scst_data_direction direction; + unsigned int transfer_len; + unsigned short cdb_len; + const char *op_name; +} +</verb> + +Where: + +<itemize> + +<item><bf/flags/ - CDB's flags can be (OR'ed): + + <itemize> + + <item><bf/SCST_TRANSFER_LEN_TYPE_FIXED/ - set if data length in + CDB set in blocks + + <item><bf/SCST_SMALL_TIMEOUT/ - set if CDB requires small timeout + + <item><bf/SCST_LONG_TIMEOUT/ - set if CDB requires long timeout + + </itemize> + +<item><bf/direction/ - one of the <bf/SCST_DATA_*/ constants (see below) + +<item><bf/transfer_len/ - CDB's data length as set in CDB + +<item><bf/cdb_len/ - CDB's length + +<item><bf/op_name/ - the name of the command + +</itemize> + +Field <bf/cmd->data_direction/, set by <bf/parse()/, can have one of the +following values: + +<itemize> + +<item><bf/SCST_DATA_UNKNOWN/ - data flow direction is unknown + +<item><bf/SCST_DATA_WRITE/ - data flow direction is <bf/WRITE/ (from +target to initiator) + +<item><bf/SCST_DATA_READ/ - data flow direction is <bf/READ/ (from +initiator to target) + +<item><bf/SCST_DATA_NONE/ - there is no data transfer + +</itemize> + +<sect1>Device specific driver unregistration + +<p> +Device specific driver is unregistered by calling +<bf/scst_unregister_dev_driver()/. It is defined as the following: + +<verb> +void scst_unregister_dev_driver( + struct scst_dev_type *dev_type) +</verb> + +Where: + +<itemize> +<item><bf/dev_type/ - device specific driver's description structure +</itemize> + +<sect>SCST commands' states + +<p> +There are the following states, which a SCST command passes through +during execution and which could be returned by device handler's +<bf/parse()/ and <bf/dev_done()/ (but not all states are allowed to be +returned): + +<itemize> + +<item><bf/SCST_CMD_STATE_INIT_WAIT/ - the command is created, but +<bf/scst_cmd_init_done()/ not called + +<item><bf/SCST_CMD_STATE_INIT/ - LUN translation (i.e. <bf/cmd->tgt_dev/ +assignment) state + +<item><bf/SCST_CMD_STATE_REINIT/ - again LUN translation, used if device +handler wants to restart the command on another LUN + +<item><bf/SCST_CMD_STATE_DEV_PARSE/ - device handler's <bf/parse()/ is going +to be called + +<item><bf/SCST_CMD_STATE_PREPARE_SPACE/ - allocation of the command's +data buffer + +<item><bf/SCST_CMD_STATE_RDY_TO_XFER/ - target driver's +<bf/rdy_to_xfer()/ is going to be called + +<item><bf/SCST_CMD_STATE_DATA_WAIT/ - waiting for data from the initiator +(until <bf/scst_rx_data()/ called) + +<item><bf/SCST_CMD_STATE_SEND_TO_MIDLEV/ - the command is going to be +sent to SCSI mid-level for execution + +<item><bf/SCST_CMD_STATE_EXECUTING/ - waiting for the command's execution +finish + +<item><bf/SCST_CMD_STATE_DEV_DONE/ - device handler's <bf/dev_done()/ is +going to be called + +<item><bf/SCST_CMD_STATE_XMIT_RESP/ - target driver's +<bf/xmit_response()/ is going to be called + +<item><bf/SCST_CMD_STATE_XMIT_WAIT/ - waiting for data/response's +transmission finish (until <bf/scst_tgt_cmd_done()/ called) + +<item><bf/SCST_CMD_STATE_FINISHED/ - the command finished and going to be +freed + +</itemize> + +<sect>SCST's structures manipulation functions + +<p> +Target drivers must not directly access any fields in SCST's structures, +they must use only described below functions. + +<sect1>SCST target driver manipulation functions + +<sect2>scst_tgt_get_tgt_specific() and scst_tgt_set_tgt_specific() + +<p> +Function <bf/scst_tgt_get_tgt_specific()/ returns pointer to the target +driver specific data, set by <bf/scst_tgt_set_tgt_specific()/. It is +defined as the following: + +<verb> +void *scst_tgt_get_tgt_specific( + struct scst_tgt *tgt) +</verb> + +Function <bf/scst_tgt_set_tgt_specific()/ stores the target driver +specific data that could be retrieved later by +by<bf/scst_tgt_get_tgt_specific()/. It is defined as the following: + +<verb> +void scst_tgt_set_tgt_specific( + struct scst_tgt *tgt, + void *val) +</verb> + +Where: + +<itemize> +<item><bf/tgt/ - pointer to the SCST target structure +<item><bf/val/ - pointer to the target driver specific data +</itemize> + +<sect1>SCST session manipulation functions + +<sect2>scst_sess_get_tgt_specific() and scst_sess_set_tgt_specific() + +<p> +Function <bf/scst_sess_get_tgt_specific()/ returns pointer to the target +driver specific data, set by <bf/scst_sess_set_tgt_specific()/. It is +defined as the following: + +<verb> +void *scst_sess_get_tgt_specific( + struct scst_session *sess) +</verb> + +Function <bf/scst_sess_set_tgt_specific()/ stores the target driver +specific data that could be retrieved later by +by<bf/scst_sess_get_tgt_specific()/. It is defined as the following: + +<verb> +void scst_sess_set_tgt_specific( + struct scst_session *sess, + void *val) +</verb> + +Where: + +<itemize> +<item><bf/sess/ - pointer to the SCST session structure +<item><bf/val/ - pointer to the target driver specific data +</itemize> + +<sect1>SCST command manipulation functions + +<sect2>scst_cmd_atomic() + +<p> +Function <bf/scst_cmd_atomic()/ returns true if the command is +being executed in the atomic context or false otherwise. It is defined +as the following: + +<verb> +int scst_cmd_atomic( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command to check +</itemize> + +<sect2>scst_cmd_get_session() + +<p> +Function <bf/scst_cmd_get_session()/ returns the command's session. It +is defined as the following: + +<verb> +struct scst_session *scst_cmd_get_session( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_get_resp_data_len() + +<p> +Function <bf/scst_cmd_get_resp_data_len()/ returns the command's +response data length. It is defined as the following: + +<verb> +unsigned int scst_cmd_get_resp_data_len( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_get_tgt_resp_flags() + +<p> +Function <bf/scst_cmd_get_tgt_resp_flags()/ returns the command's +response data response flags (SCST_TSC_FLAG_* constants). It is defined +as the following: + +<verb> +int scst_cmd_get_tgt_resp_flags( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_get_buffer() + +<p> +Function <bf/scst_cmd_get_buffer()/ returns the command's data buffer. +It is defined as the following: + +<verb> +void *scst_cmd_get_buffer( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +It is recommended to use <bf/scst_get_buf_*()/scst_put_buf()/ family of +function instead of direct access to the data buffers, because they hide +all HIGHMEM and SG/plain buffer issues. + +<sect2>scst_cmd_get_bufflen() + +<p> +Function <bf/scst_cmd_get_bufflen()/ returns the command's data buffer +length. It is defined as the following: + +<verb> +unsigned int scst_cmd_get_bufflen( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +It is recommended to use <bf/scst_get_buf_*()/scst_put_buf()/ family of +function instead of direct access to the data buffers, because they hide +all HIGHMEM and SG/plain buffer issues. + +<sect2>scst_cmd_get_use_sg() + +<p> +Function <bf/scst_cmd_get_use_sg()/ returns the command's <bf/use_sg/ +value. Its meaning is the same as for <bf/scsi_cmnd/. The function is +defined as the following: + +<verb> +unsigned short scst_cmd_get_use_sg( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +It is recommended to use <bf/scst_get_buf_*()/scst_put_buf()/ family of +function instead of direct access to the data buffers, because they hide +all HIGHMEM and SG/plain buffer issues. + +<sect2>scst_cmd_get_data_direction() + +<p> +Function <bf/scst_cmd_get_data_direction()/ returns the command's data +direction (SCST_DATA_* constants). It is defined as the following: + +<verb> +scst_data_direction scst_cmd_get_data_direction( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_get_status() + +<p> +Functions <bf/scst_cmd_get_status()/ returns the status byte from +host device. It is defined as the following: + +<verb> +uint8_t scst_cmd_get_status( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_get_masked_status() + +<p> +Functions <bf/scst_cmd_get_masked_status()/ returns the status byte set +from host device by status_byte(). It is defined as the following: + +<verb> +uint8_t scst_cmd_get_masked_status( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_get_msg_status() + +<p> +Functions <bf/scst_cmd_get_msg_status()/ returns the status from host +adapter itself. It is defined as the following: + +<verb> +uint8_t scst_cmd_get_msg_status( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_get_host_status() + +<p> +Functions <bf/scst_cmd_get_host_status()/ returns the status set by +low-level driver to indicate its status. It is defined as the following: + +<verb> +uint16_t scst_cmd_get_host_status( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_get_driver_status() + +<p> +Functions <bf/scst_cmd_get_driver_status()/ returns the status set by +SCSI mid-level. It is defined as the following: + +<verb> +uint16_t scst_cmd_get_driver_status( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_get_sense_buffer() + +<p> +Functions <bf/scst_cmd_get_sense_buffer()/ returns pointer to the sense +buffer. It is defined as the following: + +<verb> +uint8_t *scst_cmd_get_sense_buffer( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_get_sense_buffer_len() + +<p> +Functions <bf/scst_cmd_get_sense_buffer_len()/ returns the sense buffer +length. It is defined as the following: + +<verb> +int scst_cmd_get_sense_buffer_len( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_get_tag() and scst_cmd_set_tag() + +<p> Function <bf/scst_cmd_get_tag()/ returns the command's tag, set by +<bf/scst_cmd_set_tag()/. It is defined as the following: + +<verb> +uint32_t scst_cmd_get_tag( + struct scst_cmd *cmd) +</verb> + +Function <bf/scst_cmd_set_tag()/ sets command's tag that could be +retrieved later by <bf/scst_cmd_get_tag()/. It is defined as the +following: + +<verb> +void scst_cmd_set_tag( + struct scst_cmd *cmd, + uint32_t tag) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +<item><bf/tag/ - the tag +</itemize> + +<sect2>scst_cmd_get_tgt_specific() and scst_cmd_get_tgt_specific_lock() + +<p> +Functions <bf/scst_cmd_get_tgt_specific()/ and +<bf/scst_cmd_get_tgt_specific_lock()/ return pointer to the target +driver specific data, set by <bf/scst_cmd_set_tgt_specific()/ or +<bf/scst_cmd_set_tgt_specific_lock()/. Both function are basically the +same, but the later one additionally takes lock, which helps to prevent +some races. See <bf/scst_find_cmd()/ below for details. + +They are defined as the following: + +<verb> +void *scst_cmd_get_tgt_specific( + struct scst_cmd *cmd) +</verb> + +<verb> +void *scst_cmd_get_tgt_specific_lock( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_set_tgt_specific() and scst_cmd_set_tgt_specific_lock() + +<p> +Functions <bf/scst_cmd_set_tgt_specific()/ and +<bf/scst_cmd_set_tgt_specific_lock()/ store the target driver specific +data, that could be retrieved later by <bf/scst_cmd_get_tgt_specific()/ +or <bf/scst_cmd_get_tgt_specific_lock()/. Both function are basically +the same, but the later one additionally takes lock, which helps to +prevent some races. See <bf/scst_find_cmd()/ below for details. + +They are defined as the following: + +<verb> +void *scst_cmd_set_tgt_specific( + struct scst_cmd *cmd, + void *val) +</verb> + +<verb> +void *scst_cmd_set_tgt_specific_lock( + struct scst_cmd *cmd, + void *val) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +<item><bf/val/ - pointer to the target driver specific data +</itemize> + +<sect2>scst_cmd_get_data_buff_alloced() and scst_cmd_set_data_buff_alloced() + +<p> +Function <bf/scst_cmd_get_data_buff_alloced()/ returns the state of the +<bf/SCST_CMD_DATA_BUF_ALLOCED/ flag. It is defined as the following: + +<verb> +int scst_cmd_get_data_buff_alloced( + struct scst_cmd *cmd) +</verb> + +Function <bf/scst_cmd_set_data_buff_alloced()/ tells SCST that the data +buffer is alloced by target driver or device handler by setting the +<bf/SCST_CMD_DATA_BUF_ALLOCED/ flag on. Could be useful, for instance, +for iSCSI unsolicited data. It is defined as the following: + +<verb> +void scst_cmd_set_data_buff_alloced( + struct scst_cmd *cmd) +</verb> + +Where: + +<itemize> +<item><bf/cmd/ - pointer to the command +</itemize> + +<sect2>scst_cmd_set_expected(), scst_cmd_is_expected_set(), +scst_cmd_get_expected_data_direction() and +scst_cmd_get_expected_transfer_len() + +<p> +Function <bf/scst_cmd_set_expected()/ tells SCST expected data transfer +direction and its length, as supplied by remote initiator. It is defined +as the following: + +<verb> +void scst_cmd_set_expected( + struct scst_cmd *cmd, + scst_data_direction expected_data_direction, + unsigned int expected_transfer_len) +</verb> + +Function <bf/scst_cmd_is_expected_set()/ returns true, if the expected +values were set by target driver and false ot... [truncated message content] |
From: <vl...@us...> - 2006-10-12 13:49:00
|
Revision: 1 http://svn.sourceforge.net/scst/?rev=1&view=rev Author: vlnb Date: 2006-10-12 06:47:28 -0700 (Thu, 12 Oct 2006) Log Message: ----------- Initial commit Added Paths: ----------- branches/ tags/ trunk/ trunk/Makefile trunk/qla2x00t/ trunk/qla2x00t/Kconfig trunk/qla2x00t/Makefile trunk/qla2x00t/ql2100.c trunk/qla2x00t/ql2100_fw.c trunk/qla2x00t/ql2200.c trunk/qla2x00t/ql2200_fw.c trunk/qla2x00t/ql2300.c trunk/qla2x00t/ql2300_fw.c trunk/qla2x00t/ql2322.c trunk/qla2x00t/ql2322_fw.c trunk/qla2x00t/ql2400.c trunk/qla2x00t/ql2400_fw.c trunk/qla2x00t/qla2x00-target/ trunk/qla2x00t/qla2x00-target/ChangeLog trunk/qla2x00t/qla2x00-target/Makefile trunk/qla2x00t/qla2x00-target/README trunk/qla2x00t/qla2x00-target/ToDo trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/qla2x00t/qla2x00-target/qla2x00t.h trunk/qla2x00t/qla2x_tgt.h trunk/qla2x00t/qla2x_tgt_def.h trunk/qla2x00t/qla_attr.c trunk/qla2x00t/qla_dbg.c trunk/qla2x00t/qla_dbg.h trunk/qla2x00t/qla_def.h trunk/qla2x00t/qla_devtbl.h trunk/qla2x00t/qla_fw.h trunk/qla2x00t/qla_gbl.h trunk/qla2x00t/qla_gs.c trunk/qla2x00t/qla_init.c trunk/qla2x00t/qla_inline.h trunk/qla2x00t/qla_iocb.c trunk/qla2x00t/qla_isr.c trunk/qla2x00t/qla_mbx.c trunk/qla2x00t/qla_os.c trunk/qla2x00t/qla_rscn.c trunk/qla2x00t/qla_settings.h trunk/qla2x00t/qla_sup.c trunk/qla2x00t/qla_version.h trunk/scst/ trunk/scst/COPYING trunk/scst/ChangeLog trunk/scst/Makefile trunk/scst/README trunk/scst/ToDo trunk/scst/include/ trunk/scst/include/scsi_tgt.h trunk/scst/include/scst_debug.c trunk/scst/include/scst_debug.h trunk/scst/kernel/ trunk/scst/kernel/26_scst-2.6.14-.patch trunk/scst/kernel/26_scst-2.6.15+.patch trunk/scst/kernel/26_scst-2.6.16.patch trunk/scst/kernel/in-tree/ trunk/scst/kernel/in-tree/Kconfig.scsi.Linux-2.6.7.patch trunk/scst/kernel/in-tree/Kconfig.scsi_tgt trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.7.patch trunk/scst/kernel/in-tree/Makefile.scsi_tgt trunk/scst/src/ trunk/scst/src/Makefile trunk/scst/src/dev_handlers/ trunk/scst/src/dev_handlers/Makefile trunk/scst/src/dev_handlers/scst_cdrom.c trunk/scst/src/dev_handlers/scst_changer.c trunk/scst/src/dev_handlers/scst_dev_handler.h trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_fileio.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_processor.c trunk/scst/src/dev_handlers/scst_raid.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/scst.c trunk/scst/src/scst_cdbprobe.h trunk/scst/src/scst_lib.c trunk/scst/src/scst_mem.c trunk/scst/src/scst_mem.h trunk/scst/src/scst_module.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_proc.c trunk/scst/src/scst_targ.c Added: trunk/Makefile =================================================================== --- trunk/Makefile (rev 0) +++ trunk/Makefile 2006-10-12 13:47:28 UTC (rev 1) @@ -0,0 +1,102 @@ +# +# Common makefile for SCSI target mid-level and its drivers +# +# Copyright (C) 2006 Vladislav Bolkhovitin <vs...@vl...> +# +# 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, version 2 +# of the License. +# +# 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. +# +# + +# Decide to use which kernel src. If not specified, is current running kernel. +#export KDIR=/usr/src/linux-2.6 + +SCST_DIR=scst +QLA_INI_DIR=qla2x00t +QLA_DIR=qla2x00t/qla2x00-target + +all: + cd $(SCST_DIR) && $(MAKE) $@ + @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi + +install: + cd $(SCST_DIR) && $(MAKE) $@ + @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi + +uninstall: + cd $(SCST_DIR) && $(MAKE) $@ + @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi + +clean: + cd $(SCST_DIR) && $(MAKE) $@ + @if [ -d $(QLA_INI_DIR) ]; then cd $(QLA_INI_DIR) && $(MAKE) $@; fi + @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi + +extraclean: + cd $(SCST_DIR) && $(MAKE) $@ + @if [ -d $(QLA_INI_DIR) ]; then cd $(QLA_INI_DIR) && $(MAKE) $@; fi + @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi + +scst: + cd $(SCST_DIR) && $(MAKE) + +scst_install: + cd $(SCST_DIR) && $(MAKE) install + +scst_uninstall: + cd $(SCST_DIR) && $(MAKE) uninstall + +scst_clean: + cd $(SCST_DIR) && $(MAKE) clean + +scst_extraclean: + cd $(SCST_DIR) && $(MAKE) extraclean + +qla: + cd $(QLA_DIR) && $(MAKE) + +qla_install: + cd $(QLA_DIR) && $(MAKE) install + +qla_uninstall: + cd $(QLA_DIR) && $(MAKE) uninstall + +qla_clean: + cd $(QLA_INI_DIR) && $(MAKE) clean + cd $(QLA_DIR) && $(MAKE) clean + +qla_extraclean: + cd $(QLA_INI_DIR)/.. && $(MAKE) extraclean + cd $(QLA_DIR) && $(MAKE) extraclean + +help: + @echo " all (the default) : make all" + @echo " clean : clean files" + @echo " extraclean : clean + clean dependencies" + @echo " install : install" + @echo " uninstall : uninstall" + @echo "" + @echo " scst : make scst only" + @echo " scst_clean : scst: clean " + @echo " scst_extraclean : scst: clean + clean dependencies" + @echo " scst_install : scst: install" + @echo " scst_uninstall : scst: uninstall" + @echo "" + @echo " qla : make new qla target using 2.6.x kernel qla2xxx" + @echo " qla_clean : 2.6 qla target: clean " + @echo " qla_extraclean : 2.6 qla target: clean + clean dependencies" + @echo " qla_install : 2.6 qla target: install" + @echo " qla_uninstall : 2.6 qla target: uninstall" + @echo " Notes :" + @echo " - install and uninstall must be made as root" + +.PHONY: all install uninstall clean extraclean help \ + qla qla_install qla_uninstall qla_clean qla_extraclean \ + scst scst_install scst_uninstall scst_clean scst_extraclean Added: trunk/qla2x00t/Kconfig =================================================================== --- trunk/qla2x00t/Kconfig (rev 0) +++ trunk/qla2x00t/Kconfig 2006-10-12 13:47:28 UTC (rev 1) @@ -0,0 +1,82 @@ +config SCSI_QLA_FC + tristate "QLogic QLA2XXX Fibre Channel Support" + depends on PCI && SCSI + select SCSI_FC_ATTRS + select FW_LOADER + ---help--- + This qla2xxx driver supports all QLogic Fibre Channel + PCI and PCIe host adapters. + + By default, firmware for the ISP parts will be loaded + via the Firmware Loader interface. + + ISP Firmware Filename + ---------- ----------------- + 21xx ql2100_fw.bin + 22xx ql2200_fw.bin + 2300, 2312, 6312 ql2300_fw.bin + 2322, 6322 ql2322_fw.bin + 24xx ql2400_fw.bin + + Upon request, the driver caches the firmware image until + the driver is unloaded. + + Firmware images can be retrieved from: + + ftp://ftp.qlogic.com/outgoing/linux/firmware/ + + NOTE: The original method of building firmware-loader + modules has been deprecated as the firmware-images will + be removed from the kernel sources. + +config SCSI_QLA2XXX_TARGET + bool "QLogic 2xxx target mode support" + depends on SCSI_QLA_FC + default y + ---help--- + This option enables target mode hooks used by the SCST QLA2x00tgt driver. + Once the qla2x00tgt module is loaded, target mode can be enable via a + sysfs interface under scsi_host, thus enabling target mode for specific + cards. + You will also need the SCST middle level drivers from http://scst.sf.net/. + +config SCSI_QLA2XXX_EMBEDDED_FIRMWARE + bool " Use firmware-loader modules (DEPRECATED)" + depends on SCSI_QLA_FC + help + This option offers you the deprecated firmware-loader + modules that have been obsoleted by the usage of the + Firmware Loader interface in the qla2xxx driver. + +config SCSI_QLA21XX + tristate " Build QLogic ISP2100 firmware-module" + depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE + ---help--- + This driver supports the QLogic 21xx (ISP2100) host adapter family. + +config SCSI_QLA22XX + tristate " Build QLogic ISP2200 firmware-module" + depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE + ---help--- + This driver supports the QLogic 22xx (ISP2200) host adapter family. + +config SCSI_QLA2300 + tristate " Build QLogic ISP2300/ISP6312 firmware-module" + depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE + ---help--- + This driver supports the QLogic 2300 (ISP2300, ISP2312 and + ISP6312) host adapter family. + +config SCSI_QLA2322 + tristate " Build QLogic ISP2322/ISP6322 firmware-module" + depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE + ---help--- + This driver supports the QLogic 2322 (ISP2322 and ISP6322) host + adapter family. + +config SCSI_QLA24XX + tristate " Build QLogic ISP24xx firmware-module" + depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE + ---help--- + This driver supports the QLogic 24xx (ISP2422 and ISP2432) host + adapter family. Added: trunk/qla2x00t/Makefile =================================================================== --- trunk/qla2x00t/Makefile (rev 0) +++ trunk/qla2x00t/Makefile 2006-10-12 13:47:28 UTC (rev 1) @@ -0,0 +1,48 @@ +ifneq ($(KERNELRELEASE),) +EXTRA_CFLAGS += -DUNIQUE_FW_NAME + +qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ + qla_dbg.o qla_sup.o qla_rscn.o qla_attr.o + +obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o + +qla2100-y := ql2100.o ql2100_fw.o +qla2200-y := ql2200.o ql2200_fw.o +qla2300-y := ql2300.o ql2300_fw.o +qla2322-y := ql2322.o ql2322_fw.o +qla2400-y := ql2400.o ql2400_fw.o + +obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o +obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o +obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o +obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o +obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o qla2400.o + +else +ifeq ($(KVER),) + ifeq ($(KDIR),) + KDIR := /lib/modules/$(shell uname -r)/build + endif +else + KDIR := /lib/modules/$(KVER)/build +endif + +all: + $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) + +install: all + $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) BUILD_INI=m \ + modules_install + +uninstall: + rm -f $(INSTALL_DIR)/qla2[2-3]00.ko $(INSTALL_DIR)/qla2xxx.ko + -/sbin/depmod -a +endif + +clean: + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers + rm -rf .tmp_versions + +extraclean: clean + +.PHONY: all install uninstall clean extraclean Added: trunk/qla2x00t/ql2100.c =================================================================== --- trunk/qla2x00t/ql2100.c (rev 0) +++ trunk/qla2x00t/ql2100.c 2006-10-12 13:47:28 UTC (rev 1) @@ -0,0 +1,91 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (C) 2003 Christoph Hellwig. + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/pci.h> + +#include "qla_def.h" + +static char qla_driver_name[] = "qla2100"; + +extern unsigned char fw2100tp_version[]; +extern unsigned char fw2100tp_version_str[]; +extern unsigned short fw2100tp_addr01; +extern unsigned short fw2100tp_code01[]; +extern unsigned short fw2100tp_length01; + +static struct qla_fw_info qla_fw_tbl[] = { + { + .addressing = FW_INFO_ADDR_NORMAL, + .fwcode = &fw2100tp_code01[0], + .fwlen = &fw2100tp_length01, + .fwstart = &fw2100tp_addr01, + }, + + { FW_INFO_ADDR_NOMORE, }, +}; + +static struct qla_board_info qla_board_tbl = { + .drv_name = qla_driver_name, + + .isp_name = "ISP2100", + .fw_info = qla_fw_tbl, +}; + +static struct pci_device_id qla2100_pci_tbl[] = { + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP2100, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl, + }, + + {0, 0}, +}; +MODULE_DEVICE_TABLE(pci, qla2100_pci_tbl); + +static int __devinit +qla2100_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) +{ + return qla2x00_probe_one(pdev, + (struct qla_board_info *)id->driver_data); +} + +static void __devexit +qla2100_remove_one(struct pci_dev *pdev) +{ + qla2x00_remove_one(pdev); +} + +static struct pci_driver qla2100_pci_driver = { + .name = "qla2100", + .id_table = qla2100_pci_tbl, + .probe = qla2100_probe_one, + .remove = __devexit_p(qla2100_remove_one), +}; + +static int __init +qla2100_init(void) +{ + return pci_module_init(&qla2100_pci_driver); +} + +static void __exit +qla2100_exit(void) +{ + pci_unregister_driver(&qla2100_pci_driver); +} + +module_init(qla2100_init); +module_exit(qla2100_exit); + +MODULE_AUTHOR("QLogic Corporation"); +MODULE_DESCRIPTION("QLogic ISP21xx FC-SCSI Host Bus Adapter driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(QLA2XXX_VERSION); Added: trunk/qla2x00t/ql2100_fw.c =================================================================== --- trunk/qla2x00t/ql2100_fw.c (rev 0) +++ trunk/qla2x00t/ql2100_fw.c 2006-10-12 13:47:28 UTC (rev 1) @@ -0,0 +1,4848 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ + +/* + * Firmware Version 1.19.25 (13:12 Dec 10, 2003) + */ + +#ifdef UNIQUE_FW_NAME +unsigned short fw2100tp_version = 1*1024+19; +#else +unsigned short risc_code_version = 1*1024+19; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned char fw2100tp_version_str[] = {1,19,25}; +#else +unsigned char firmware_version[] = {1,19,25}; +#endif + +#ifdef UNIQUE_FW_NAME +#define fw2100tp_VERSION_STRING "1.19.25" +#else +#define FW_VERSION_STRING "1.19.25" +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2100tp_addr01 = 0x1000 ; +#else +unsigned short risc_code_addr01 = 0x1000 ; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2100tp_code01[] = { +#else +unsigned short risc_code01[] = { +#endif + 0x0078, 0x102d, 0x0000, 0x9601, 0x0000, 0x0001, 0x0013, 0x0019, + 0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030, + 0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, + 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3231, 0x3030, 0x2046, 0x6972, + 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, + 0x312e, 0x3139, 0x2020, 0x2020, 0x2400, 0x2091, 0x2000, 0x20c1, + 0x0021, 0x2039, 0xffff, 0x2019, 0xaaaa, 0x2760, 0x2069, 0x7fff, + 0x20c1, 0x0020, 0x2c2c, 0x2d34, 0x2762, 0x236a, 0x2c24, 0x2d04, + 0x266a, 0x2562, 0xa406, 0x00c0, 0x1052, 0x20c1, 0x0021, 0x2c2c, + 0x2362, 0x2c04, 0x2562, 0xa306, 0x0040, 0x1052, 0x20c1, 0x0020, + 0x2039, 0x8fff, 0x20a1, 0xae00, 0x2708, 0x810d, 0x810d, 0x810d, + 0x810d, 0xa18c, 0x000f, 0x2001, 0x000a, 0xa112, 0xa00e, 0x21a8, + 0x41a4, 0x3400, 0x8211, 0x00c0, 0x105f, 0x2708, 0x3400, 0xa102, + 0x0040, 0x106f, 0x0048, 0x106f, 0x20a8, 0xa00e, 0x41a4, 0x20a1, + 0xa601, 0x2009, 0x0000, 0x20a9, 0x07ff, 0x41a4, 0x3400, 0x20c9, + 0xabff, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x25c7, + 0x2051, 0xa700, 0x2a70, 0x7762, 0xa786, 0x8fff, 0x0040, 0x1092, + 0x705f, 0xce00, 0x705b, 0xcdf1, 0x7067, 0x0200, 0x706b, 0x0200, + 0x0078, 0x109a, 0x705b, 0xbe01, 0x7067, 0x0100, 0x706b, 0x0100, + 0x705f, 0xbe00, 0x1078, 0x12df, 0x1078, 0x13ca, 0x1078, 0x1577, + 0x1078, 0x1ce9, 0x1078, 0x42ec, 0x1078, 0x76bf, 0x1078, 0x1355, + 0x1078, 0x2ac0, 0x1078, 0x4e93, 0x1078, 0x49a3, 0x1078, 0x594a, + 0x1078, 0x2263, 0x1078, 0x5c43, 0x1078, 0x5485, 0x1078, 0x2162, + 0x1078, 0x2240, 0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x10cf, + 0x7820, 0xa086, 0x0002, 0x00c0, 0x10cf, 0x7823, 0x4000, 0x0068, + 0x10c7, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, + 0x7003, 0x0000, 0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000, + 0xa08e, 0x0003, 0x00c0, 0x10ef, 0x1078, 0x365e, 0x1078, 0x2ae8, + 0x1078, 0x4ee3, 0x1078, 0x4b66, 0x2009, 0x0100, 0x2104, 0xa082, + 0x0002, 0x0048, 0x10f3, 0x1078, 0x5966, 0x0078, 0x10d6, 0x1079, + 0x10f7, 0x0078, 0x10dc, 0x1078, 0x7197, 0x0078, 0x10eb, 0x1101, + 0x1102, 0x11be, 0x10ff, 0x1246, 0x12dc, 0x12dd, 0x12de, 0x1078, + 0x1332, 0x007c, 0x127e, 0x0f7e, 0x2091, 0x8000, 0x7000, 0xa086, + 0x0001, 0x00c0, 0x1198, 0x1078, 0x3aec, 0x2079, 0x0100, 0x7844, + 0xa005, 0x00c0, 0x1198, 0x2011, 0x41dc, 0x1078, 0x5a45, 0x1078, + 0x1adf, 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, + 0x8010, 0x73c4, 0x1078, 0x361b, 0x2001, 0xffff, 0x1078, 0x5ae6, + 0x723c, 0xc284, 0x723e, 0x2001, 0xa70c, 0x2014, 0xc2ac, 0x2202, + 0x1078, 0x6f9f, 0x2011, 0x0004, 0x1078, 0x8d2b, 0x1078, 0x489e, + 0x1078, 0x42d4, 0x0040, 0x1144, 0x7087, 0x0001, 0x70bf, 0x0000, + 0x1078, 0x3c9e, 0x0078, 0x1198, 0x1078, 0x4967, 0x0040, 0x114d, + 0x7a0c, 0xc2b4, 0x7a0e, 0x0078, 0x1159, 0x1078, 0x90b6, 0x70cc, + 0xd09c, 0x00c0, 0x1159, 0x7098, 0xa005, 0x0040, 0x1159, 0x1078, + 0x42b8, 0x70d7, 0x0000, 0x70d3, 0x0000, 0x72cc, 0x2079, 0xa752, + 0x7804, 0xd0ac, 0x0040, 0x1165, 0xc295, 0x72ce, 0xa296, 0x0004, + 0x0040, 0x1186, 0x2011, 0x0001, 0x1078, 0x8d2b, 0x7093, 0x0000, + 0x7097, 0xffff, 0x7003, 0x0002, 0x0f7f, 0x1078, 0x2677, 0x2011, + 0x0005, 0x1078, 0x70e0, 0x1078, 0x62d1, 0x0c7e, 0x2061, 0x0100, + 0x60e3, 0x0008, 0x0c7f, 0x127f, 0x0078, 0x119a, 0x7093, 0x0000, + 0x7097, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005, 0x1078, 0x70e0, + 0x1078, 0x62d1, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, + 0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082, 0x2009, 0x007e, + 0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019, 0x0029, 0x1078, + 0x73d0, 0x027f, 0x1078, 0xa501, 0x037f, 0x027f, 0x017f, 0x1078, + 0x298e, 0x8108, 0x00f0, 0x11a0, 0x0c7f, 0x706f, 0x0000, 0x7070, + 0xa084, 0x00ff, 0x7072, 0x709b, 0x0000, 0x007c, 0x127e, 0x2091, + 0x8000, 0x7000, 0xa086, 0x0002, 0x00c0, 0x1244, 0x7094, 0xa086, + 0xffff, 0x0040, 0x11d1, 0x1078, 0x2677, 0x1078, 0x62d1, 0x0078, + 0x1244, 0x70cc, 0xd09c, 0x0040, 0x11fd, 0xd084, 0x0040, 0x11fd, + 0x0f7e, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c, + 0x0040, 0x11fd, 0x70d0, 0xa086, 0xffff, 0x0040, 0x11f9, 0x1078, + 0x27f7, 0x1078, 0x62d1, 0x70cc, 0xd094, 0x00c0, 0x1244, 0x2011, + 0x0001, 0x2019, 0x0000, 0x1078, 0x282f, 0x1078, 0x62d1, 0x0078, + 0x1244, 0x70d4, 0xa005, 0x00c0, 0x1244, 0x7090, 0xa005, 0x00c0, + 0x1244, 0x1078, 0x4967, 0x00c0, 0x1244, 0x2001, 0xa753, 0x2004, + 0xd0ac, 0x0040, 0x1227, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009, + 0x0000, 0x017e, 0x1078, 0x45c4, 0x00c0, 0x121a, 0x6000, 0xd0ec, + 0x00c0, 0x1222, 0x017f, 0x8108, 0x00f0, 0x1211, 0x0c7f, 0x157f, + 0x0078, 0x1227, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x1244, 0x7003, + 0x0003, 0x7097, 0xffff, 0x2001, 0x0000, 0x1078, 0x24e8, 0x1078, + 0x3699, 0x2001, 0xa9b2, 0x2004, 0xa086, 0x0005, 0x00c0, 0x123c, + 0x2011, 0x0000, 0x1078, 0x70e0, 0x2011, 0x0000, 0x1078, 0x70ea, + 0x1078, 0x62d1, 0x1078, 0x639b, 0x127f, 0x007c, 0x017e, 0x0f7e, + 0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0x00f7, 0x1078, + 0x42a1, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0040, + 0x125b, 0x7827, 0x0040, 0xd19c, 0x0040, 0x1260, 0x7827, 0x0008, + 0x007e, 0x037e, 0x157e, 0xa006, 0x1078, 0x5ae6, 0x7900, 0xa18a, + 0x0003, 0x0050, 0x1289, 0x7954, 0xd1ac, 0x00c0, 0x1289, 0x2009, + 0x00f8, 0x1078, 0x42a1, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, + 0x09c4, 0x7820, 0xd09c, 0x00c0, 0x1281, 0x7824, 0xd0ac, 0x00c0, + 0x12ca, 0x00f0, 0x1279, 0x2001, 0x0001, 0x1078, 0x24e8, 0x0078, + 0x12d5, 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0050, 0x00e0, + 0x128f, 0x2091, 0x6000, 0x00f0, 0x128f, 0x7853, 0x0400, 0x782f, + 0x0000, 0x2009, 0x00f8, 0x1078, 0x42a1, 0x20a9, 0x000e, 0x0005, + 0x00f0, 0x129f, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, 0x0010, + 0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, 0x12b4, + 0x7824, 0xd0ac, 0x00c0, 0x12ca, 0x8319, 0x00c0, 0x12aa, 0x2009, + 0xa732, 0x2104, 0x8000, 0x200a, 0xa084, 0xfff0, 0x0040, 0x12c4, + 0x200b, 0x0000, 0x1078, 0x2588, 0x2001, 0x0001, 0x1078, 0x24e8, + 0x0078, 0x12d3, 0x2001, 0xa732, 0x2003, 0x0000, 0x7828, 0xc09d, + 0x782a, 0x7827, 0x0048, 0x7853, 0x0400, 0x157f, 0x037f, 0x007f, + 0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, 0x007c, 0x2a70, + 0x2061, 0xa9ad, 0x2063, 0x0001, 0x6007, 0x0013, 0x600b, 0x0019, + 0x600f, 0x0017, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, + 0x12f5, 0x7053, 0xffff, 0x0078, 0x12f7, 0x7053, 0x0000, 0x7057, + 0xffff, 0x706f, 0x0000, 0x7073, 0x0000, 0x1078, 0x90b6, 0x2061, + 0xa98d, 0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, + 0x0200, 0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, + 0x07d0, 0x2061, 0xa995, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, + 0x0000, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, + 0x0001, 0x601f, 0x0000, 0x2061, 0xa9a5, 0x6003, 0x514c, 0x6007, + 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0xa726, 0x2003, + 0x0000, 0x007c, 0x2091, 0x8000, 0x0068, 0x1334, 0x007e, 0x017e, + 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x133a, 0x017f, 0x792e, + 0x007f, 0x782a, 0x007f, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, + 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0xa700, + 0x7803, 0x0005, 0x0078, 0x1352, 0x007c, 0x2071, 0xa700, 0x715c, + 0x712e, 0x2021, 0x0001, 0xa190, 0x002d, 0xa298, 0x002d, 0x0048, + 0x136b, 0x7060, 0xa302, 0x00c8, 0x136b, 0x220a, 0x2208, 0x2310, + 0x8420, 0x0078, 0x135d, 0x200b, 0x0000, 0x74aa, 0x74ae, 0x007c, + 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa700, 0x70ac, 0xa0ea, + 0x0010, 0x00c8, 0x137e, 0xa06e, 0x0078, 0x1388, 0x8001, 0x70ae, + 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, + 0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa700, 0x127e, 0x2091, + 0x8000, 0x70ac, 0x8001, 0x00c8, 0x1398, 0xa06e, 0x0078, 0x13a1, + 0x70ae, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, + 0x0000, 0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, + 0x2071, 0xa700, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000, + 0x70ae, 0x127f, 0x0e7f, 0x007c, 0x8dff, 0x0040, 0x13c0, 0x6804, + 0x6807, 0x0000, 0x007e, 0x1078, 0x13a4, 0x0d7f, 0x0078, 0x13b4, + 0x007c, 0x0e7e, 0x2071, 0xa700, 0x70ac, 0xa08a, 0x0010, 0xa00d, + 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa9d6, 0x7007, 0x0000, 0x701b, + 0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004, + 0x7012, 0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x0e7e, 0x2270, + 0x700b, 0x0000, 0x2071, 0xa9d6, 0x7018, 0xa088, 0xa9df, 0x220a, + 0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x00c0, 0x13f6, + 0x0f7e, 0x2079, 0x0010, 0x1078, 0x1408, 0x0f7f, 0x0e7f, 0x127f, + 0x007c, 0x0e7e, 0x2071, 0xa9d6, 0x7004, 0xa005, 0x00c0, 0x1406, + 0x0f7e, 0x2079, 0x0010, 0x1078, 0x1408, 0x0f7f, 0x0e7f, 0x007c, + 0x7000, 0x0079, 0x140b, 0x140f, 0x1479, 0x1496, 0x1496, 0x7018, + 0x711c, 0xa106, 0x00c0, 0x1417, 0x7007, 0x0000, 0x007c, 0x0d7e, + 0xa180, 0xa9df, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007, + 0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c, + 0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804, + 0x0d7f, 0xd084, 0x0040, 0x1439, 0x7007, 0x0001, 0x1078, 0x143e, + 0x007c, 0x7007, 0x0002, 0x1078, 0x1454, 0x007c, 0x017e, 0x027e, + 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x1449, 0x2110, + 0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803, + 0x0041, 0x027f, 0x017f, 0x007c, 0x017e, 0x027e, 0x137e, 0x147e, + 0x157e, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803, 0x0026, 0x710c, + 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x1468, 0x2110, 0xa006, + 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, 0x3300, + 0x7016, 0x7803, 0x0001, 0x157f, 0x147f, 0x137f, 0x027f, 0x017f, + 0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0xa7fa, 0x20a1, 0x0018, + 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000, + 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x700b, + 0xa7f5, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x137e, 0x147e, + 0x157e, 0x2001, 0xa829, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026, + 0x2001, 0xa82a, 0x20ac, 0x53a6, 0x2099, 0xa82b, 0x20a1, 0x0018, + 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000, + 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, 0x700b, + 0xa826, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x017e, 0x0e7e, + 0x2071, 0xa9d6, 0x0f7e, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002, + 0xd1fc, 0x0040, 0x14d0, 0xa18c, 0x0700, 0x7004, 0x1079, 0x14d4, + 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x1408, 0x14dc, 0x1509, 0x1531, + 0x1564, 0x14da, 0x0078, 0x14da, 0xa18c, 0x0700, 0x00c0, 0x1502, + 0x137e, 0x147e, 0x157e, 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, + 0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400, 0x7016, 0x157f, 0x147f, + 0x137f, 0x700c, 0xa005, 0x0040, 0x151e, 0x1078, 0x143e, 0x007c, + 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000, 0x1078, + 0x1408, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, 0x0078, + 0x14fd, 0xa18c, 0x0700, 0x00c0, 0x1514, 0x700c, 0xa005, 0x0040, + 0x151e, 0x1078, 0x1454, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, + 0x0200, 0x7007, 0x0000, 0x1078, 0x1408, 0x007c, 0x0d7e, 0x7008, + 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, 0x783c, + 0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000, 0x1078, 0x1408, + 0x007c, 0xa18c, 0x0700, 0x00c0, 0x155e, 0x137e, 0x147e, 0x157e, + 0x2001, 0xa7f8, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, 0x0014, + 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xa7fa, 0x2004, + 0xd0bc, 0x0040, 0x1554, 0x2001, 0xa803, 0x2004, 0xa080, 0x000d, + 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x157f, 0x147f, 0x137f, 0x7007, + 0x0000, 0x1078, 0x4f8c, 0x1078, 0x1408, 0x007c, 0x2011, 0x8003, + 0x1078, 0x361b, 0x0078, 0x1562, 0xa18c, 0x0700, 0x00c0, 0x1571, + 0x2001, 0xa828, 0x2003, 0x0100, 0x7007, 0x0000, 0x1078, 0x1408, + 0x007c, 0x2011, 0x8004, 0x1078, 0x361b, 0x0078, 0x1575, 0x127e, + 0x2091, 0x2100, 0x2079, 0x0030, 0x2071, 0xa9e7, 0x7803, 0x0004, + 0x7003, 0x0000, 0x700f, 0xa9ed, 0x7013, 0xa9ed, 0x780f, 0x0076, + 0x7803, 0x0004, 0x127f, 0x007c, 0x6934, 0xa184, 0x0007, 0x0079, + 0x1591, 0x1599, 0x15df, 0x1599, 0x1599, 0x1599, 0x15c4, 0x15a8, + 0x159d, 0xa085, 0x0001, 0x0078, 0x15f9, 0x684c, 0xd0bc, 0x0040, + 0x1599, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x0078, 0x15e7, + 0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x1599, 0x684c, 0xd0bc, + 0x0040, 0x1599, 0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a, + 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, + 0x6832, 0x6858, 0x0078, 0x15ef, 0xa18c, 0x00ff, 0xa186, 0x0015, + 0x00c0, 0x1599, 0x684c, 0xd0ac, 0x0040, 0x1599, 0x6804, 0x681a, + 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, + 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078, 0x15ef, 0x684c, + 0xd0ac, 0x0040, 0x1599, 0xa006, 0x682e, 0x682a, 0x6858, 0xa18c, + 0x000f, 0xa188, 0x206a, 0x210c, 0x6932, 0x2d08, 0x691a, 0x6826, + 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, 0x6912, 0x6980, + 0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a, + 0x2004, 0x82ff, 0x0040, 0x161c, 0xa280, 0x0004, 0x0d7e, 0x206c, + 0x684c, 0xd0dc, 0x00c0, 0x1618, 0x1078, 0x158c, 0x0040, 0x1618, + 0x0d7f, 0xa280, 0x0000, 0x2003, 0x0002, 0xa016, 0x0078, 0x161c, + 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e, 0x037e, 0x027e, + 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000, 0xa005, 0x00c0, + 0x1630, 0x7206, 0x2001, 0x1651, 0x007e, 0x2260, 0x0078, 0x17e0, + 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182, + 0xaa08, 0x0048, 0x163d, 0x2009, 0xa9ed, 0x710e, 0x7010, 0xa102, + 0xa082, 0x0009, 0x0040, 0x1648, 0xa080, 0x001b, 0x00c0, 0x164b, + 0x2009, 0x0138, 0x200a, 0x7000, 0xa005, 0x00c0, 0x1651, 0x1078, + 0x17c1, 0x127f, 0x007c, 0x127e, 0x027e, 0x037e, 0x0c7e, 0x007e, + 0x2091, 0x2100, 0x007f, 0x047f, 0x037f, 0x027f, 0x0d7e, 0x0c7e, + 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, 0xa005, 0x0040, 0x16dd, + 0x6808, 0xa005, 0x0040, 0x174a, 0x7000, 0xa005, 0x00c0, 0x1672, + 0x0078, 0x16d2, 0x700c, 0x7110, 0xa106, 0x00c0, 0x1753, 0x7004, + 0xa406, 0x00c0, 0x16d2, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040, + 0x168f, 0x047e, 0x1078, 0x1913, 0x047f, 0x2460, 0x6010, 0xa080, + 0x0002, 0x2004, 0xa005, 0x0040, 0x174a, 0x0078, 0x166c, 0x2001, + 0x0207, 0x2004, 0xd09c, 0x00c0, 0x167b, 0x7804, 0xa084, 0x6000, + 0x0040, 0x16a0, 0xa086, 0x6000, 0x0040, 0x16a0, 0x0078, 0x167b, + 0x7100, 0xa186, 0x0002, 0x00c0, 0x16c0, 0x0e7e, 0x2b68, 0x6818, + 0x2060, 0x1078, 0x203f, 0x2804, 0xac70, 0x6034, 0xd09c, 0x00c0, + 0x16b5, 0x7108, 0x720c, 0x0078, 0x16b7, 0x7110, 0x7214, 0x6810, + 0xa100, 0x6812, 0x6814, 0xa201, 0x6816, 0x0e7f, 0x0078, 0x16c4, + 0xa186, 0x0001, 0x00c0, 0x16cc, 0x7820, 0x6910, 0xa100, 0x6812, + 0x7824, 0x6914, 0xa101, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, + 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x00c0, 0x1753, 0x2009, + 0x0048, 0x1078, 0x775c, 0x0078, 0x1753, 0x6808, 0xa005, 0x0040, + 0x174a, 0x7000, 0xa005, 0x00c0, 0x16e7, 0x0078, 0x174a, 0x700c, + 0x7110, 0xa106, 0x00c0, 0x16f0, 0x7004, 0xa406, 0x00c0, 0x174a, + 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040, 0x1704, 0x047e, 0x1078, + 0x1913, 0x047f, 0x2460, 0x6010, 0xa080, 0x0002, 0x2004, 0xa005, + 0x0040, 0x174a, 0x0078, 0x16e1, 0x2001, 0x0207, 0x2004, 0xd09c, + 0x00c0, 0x16f0, 0x2001, 0x0005, 0x2004, 0xd08c, 0x00c0, 0x16f6, + 0x7804, 0xa084, 0x6000, 0x0040, 0x171b, 0xa086, 0x6000, 0x0040, + 0x171b, 0x0078, 0x16f0, 0x7007, 0x0000, 0xa016, 0x2218, 0x7000, + 0xa08e, 0x0001, 0x0040, 0x173c, 0xa08e, 0x0002, 0x00c0, 0x174a, + 0x0c7e, 0x0e7e, 0x6818, 0x2060, 0x1078, 0x203f, 0x2804, 0xac70, + 0x6034, 0xd09c, 0x00c0, 0x1738, 0x7308, 0x720c, 0x0078, 0x173a, + 0x7310, 0x7214, 0x0e7f, 0x0c7f, 0x7820, 0xa318, 0x7824, 0xa211, + 0x6810, 0xa300, 0x6812, 0x6814, 0xa201, 0x6816, 0x7803, 0x0004, + 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x00c0, 0x1753, 0x2009, + 0x0048, 0x1078, 0x775c, 0x0c7f, 0x0d7f, 0x127f, 0x007c, 0x0f7e, + 0x0e7e, 0x027e, 0x037e, 0x047e, 0x057e, 0x2071, 0xa9e7, 0x7000, + 0xa086, 0x0000, 0x0040, 0x17ba, 0x7004, 0xac06, 0x00c0, 0x17ab, + 0x2079, 0x0030, 0x7000, 0xa086, 0x0003, 0x0040, 0x17ab, 0x7804, + 0xd0fc, 0x00c0, 0x17a7, 0x20e1, 0x6000, 0x2011, 0x0032, 0x2001, + 0x0208, 0x200c, 0x2001, 0x0209, 0x2004, 0xa106, 0x00c0, 0x176f, + 0x8211, 0x00c0, 0x1777, 0x7804, 0xd0fc, 0x00c0, 0x17a7, 0x1078, + 0x1b22, 0x027e, 0x057e, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0, + 0x178d, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007, + 0x0000, 0x057f, 0x027f, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, + 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0078, 0x17ab, 0x1078, + 0x1913, 0x0078, 0x175f, 0x157e, 0x20a9, 0x0009, 0x2009, 0xa9ed, + 0x2104, 0xac06, 0x00c0, 0x17b5, 0x200a, 0xa188, 0x0003, 0x00f0, + 0x17b0, 0x157f, 0x057f, 0x047f, 0x037f, 0x027f, 0x0e7f, 0x0f7f, + 0x007c, 0x700c, 0x7110, 0xa106, 0x00c0, 0x17c9, 0x7003, 0x0000, + 0x007c, 0x2104, 0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, + 0x8108, 0xa182, 0xaa08, 0x0048, 0x17d7, 0x2009, 0xa9ed, 0x7112, + 0x700c, 0xa106, 0x00c0, 0x17e0, 0x2001, 0x0138, 0x2003, 0x0008, + 0x8cff, 0x00c0, 0x17e7, 0x1078, 0x1b4d, 0x0078, 0x1854, 0x6010, + 0x2068, 0x2d58, 0x6828, 0xa406, 0x00c0, 0x17f2, 0x682c, 0xa306, + 0x0040, 0x182f, 0x601c, 0xa086, 0x0008, 0x0040, 0x182f, 0x6024, + 0xd0f4, 0x00c0, 0x181c, 0xd0d4, 0x0040, 0x1818, 0x6038, 0xa402, + 0x6034, 0xa303, 0x0040, 0x1806, 0x00c8, 0x1818, 0x643a, 0x6336, + 0x6c2a, 0x6b2e, 0x047e, 0x037e, 0x2400, 0x6c7c, 0xa402, 0x6812, + 0x2300, 0x6b80, 0xa303, 0x6816, 0x037f, 0x047f, 0x0078, 0x181c, + 0x1078, 0x9063, 0x0040, 0x17e3, 0x2001, 0xa774, 0x2004, 0xd0b4, + 0x00c0, 0x182b, 0x6018, 0x2004, 0xd0bc, 0x00c0, 0x182b, 0x6817, + 0x7fff, 0x6813, 0xffff, 0x1078, 0x208a, 0x00c0, 0x17e3, 0x0c7e, + 0x7004, 0x2060, 0x6024, 0xc0d4, 0x6026, 0x0c7f, 0x684c, 0xd0f4, + 0x0040, 0x1840, 0x6817, 0xffff, 0x6813, 0xffff, 0x0078, 0x17e3, + 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, + 0x000f, 0x2009, 0x0011, 0x1078, 0x1855, 0x0040, 0x1853, 0x2009, + 0x0001, 0x1078, 0x1855, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x18ec, + 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1877, 0xd0f4, 0x00c0, + 0x1887, 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1867, 0x18ce, + 0x188e, 0x188e, 0x18ce, 0x18ce, 0x18c6, 0x18ce, 0x188e, 0x18ce, + 0x1894, 0x1894, 0x18ce, 0x18ce, 0x18ce, 0x18bd, 0x1894, 0xc0fc, + 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x0d7e, 0xd99c, 0x0040, + 0x18d1, 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x18d1, 0xc0f4, + 0x6852, 0x6b6c, 0x6a70, 0x0d7e, 0x0078, 0x18d8, 0x6b08, 0x6a0c, + 0x6d00, 0x6c04, 0x0078, 0x18d1, 0x7b0c, 0xd3bc, 0x0040, 0x18b5, + 0x7004, 0x0e7e, 0x2070, 0x701c, 0x0e7f, 0xa086, 0x0008, 0x00c0, + 0x18b5, 0x7b08, 0xa39c, 0x0fff, 0x2d20, 0x0d7f, 0x0d7e, 0x6a14, + 0x82ff, 0x00c0, 0x18b0, 0x6810, 0xa302, 0x0048, 0x18b0, 0x6b10, + 0x2011, 0x0000, 0x2468, 0x0078, 0x18b7, 0x6b10, 0x6a14, 0x6d00, + 0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x18d1, 0x0d7f, 0x0d7e, 0x6834, + 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x18ce, 0x0d7f, 0x1078, + 0x2026, 0x00c0, 0x1855, 0xa00e, 0x0078, 0x18ec, 0x0d7f, 0x1078, + 0x1332, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, + 0x7000, 0x8000, 0x7002, 0x0d7f, 0x6828, 0xa300, 0x682a, 0x682c, + 0xa201, 0x682e, 0x2300, 0x6b10, 0xa302, 0x6812, 0x2200, 0x6a14, + 0xa203, 0x6816, 0x1078, 0x2026, 0x007c, 0x1078, 0x1332, 0x1078, + 0x1c97, 0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x7003, 0x0000, + 0x1078, 0x1af4, 0x1078, 0x8d16, 0x0040, 0x190c, 0x6808, 0x8001, + 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f, + 0xffff, 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8a11, 0x0078, + 0x1adb, 0x1078, 0x1332, 0x127e, 0x2091, 0x2100, 0x007e, 0x017e, + 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, + 0x00c0, 0x18ef, 0xa184, 0x0003, 0xa086, 0x0003, 0x0040, 0x1911, + 0x7000, 0x0079, 0x192b, 0x1933, 0x1935, 0x1a34, 0x1ab2, 0x1ac9, + 0x1933, 0x1933, 0x1933, 0x1078, 0x1332, 0x8001, 0x7002, 0xa184, + 0x0880, 0x00c0, 0x194a, 0x8aff, 0x0040, 0x19d4, 0x2009, 0x0001, + 0x1078, 0x1855, 0x0040, 0x1adb, 0x2009, 0x0001, 0x1078, 0x1855, + 0x0078, 0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x00c0, + 0x19b2, 0x027e, 0x037e, 0x017e, 0x7808, 0xd0ec, 0x00c0, 0x1962, + 0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7803, 0x0009, 0x7003, 0x0004, + 0x0078, 0x1964, 0x1078, 0x1bd7, 0x017f, 0xd194, 0x0040, 0x196b, + 0x8aff, 0x0040, 0x19a1, 0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a, + 0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x0c7e, 0x7004, 0x2060, + 0x6024, 0xd0f4, 0x00c0, 0x197e, 0x633a, 0x6236, 0x0c7f, 0x2400, + 0x6910, 0xa100, 0x6812, 0x2500, 0x6914, 0xa101, 0x6816, 0x037f, + 0x027f, 0x2600, 0x681e, 0x2700, 0x6822, 0x1078, 0x203f, 0x2a00, + 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, + 0x6808, 0x8001, 0x680a, 0x00c0, 0x19a7, 0x684c, 0xd0e4, 0x0040, + 0x19a7, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x775c, 0x7000, + 0xa086, 0x0004, 0x0040, 0x1adb, 0x7003, 0x0000, 0x1078, 0x17c1, + 0x0078, 0x1adb, 0x057e, 0x7d0c, 0xd5bc, 0x00c0, 0x19b9, 0x1078, + 0xa58e, 0x057f, 0x1078, 0x1af4, 0x0f7e, 0x7004, 0x2078, 0x1078, + 0x4963, 0x0040, 0x19c6, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, + 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, + 0x6980, 0x6916, 0x0078, 0x1adb, 0x7004, 0x0c7e, 0x2060, 0x6024, + 0x0c7f, 0xd0f4, 0x0040, 0x19e1, 0x6808, 0x8001, 0x680a, 0x0078, + 0x19f5, 0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, 0x00c0, 0x19f9, + 0x7003, 0x0000, 0x6808, 0x8001, 0x680a, 0x00c0, 0x19f5, 0x7004, + 0x2060, 0x2009, 0x0048, 0x1078, 0x775c, 0x1078, 0x17c1, 0x0078, + 0x1adb, 0x7814, 0x6910, 0xa102, 0x6812, 0x6914, 0xa183, 0x0000, + 0x6816, 0x7814, 0x7908, 0xa18c, 0x0fff, 0xa192, 0x0841, 0x00c8, + 0x18ef, 0xa188, 0x0007, 0x8114, 0x8214, 0x8214, 0xa10a, 0x8104, + 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, 0x1078, 0x1b5e, + 0x7803, 0x0004, 0x780f, 0xffff, 0x7803, 0x0001, 0x7804, 0xd0fc, + 0x0040, 0x1a1e, 0x7803, 0x0002, 0x7803, 0x0004, 0x780f, 0x0076, + 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048, 0x1078, 0x775c, + 0x1078, 0x1b92, 0x0040, 0x19f5, 0x8001, 0x7002, 0xd194, 0x0040, + 0x1a46, 0x7804, 0xd0fc, 0x00c0, 0x191b, 0x8aff, 0x0040, 0x1adb, + 0x2009, 0x0001, 0x1078, 0x1855, 0x0078, 0x1adb, 0xa184, 0x0880, + 0x00c0, 0x1a53, 0x8aff, 0x0040, 0x1adb, 0x2009, 0x0001, 0x1078, + 0x1855, 0x0078, 0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, + 0x00c0, 0x1a93, 0x027e, 0x037e, 0x7808, 0xd0ec, 0x00c0, 0x1a66, + 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1a68, 0x1078, 0x1bd7, + 0x6b28, 0x6a2c, 0x1078, 0x203f, 0x0d7e, 0x0f7e, 0x2d78, 0x2804, + 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1a83, 0x6808, 0x2008, 0xa31a, + 0x680c, 0xa213, 0x7810, 0xa100, 0x7812, 0x690c, 0x7814, 0xa101, + 0x7816, 0x0078, 0x1a8f, 0x6810, 0x2008, 0xa31a, 0x6814, 0xa213, + 0x7810, 0xa100, 0x7812, 0x6914, 0x7814, 0xa101, 0x7816, 0x0f7f, + 0x0d7f, 0x0078, 0x196d, 0x057e, 0x7d0c, 0x1078, 0xa58e, 0x057f, + 0x1078, 0x1af4, 0x0f7e, 0x7004, 0x2078, 0x1078, 0x4963, 0x0040, + 0x1aa4, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, 0xffff, 0x682f, + 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, + 0x0078, 0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, + 0x0040, 0x1ac5, 0x6808, 0x8001, 0x680a, 0x00c0, 0x1ac5, 0x7004, + 0x2060, 0x2009, 0x0048, 0x1078, 0x775c, 0x1078, 0x17c1, 0x0078, + 0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x6010, + 0xa005, 0x0040, 0x1ac5, 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28, + 0x6b2c, 0x1078, 0x17e0, 0x017f, 0x007f, 0x127f, 0x007c, 0x127e, + 0x2091, 0x2100, 0x7000, 0xa086, 0x0003, 0x00c0, 0x1af2, 0x700c, + 0x7110, 0xa106, 0x0040, 0x1af2, 0x20e1, 0x9028, 0x700f, 0xa9ed, + 0x7013, 0xa9ed, 0x127f, 0x007c, 0x0c7e, 0x1078, 0x1b22, 0x20e1, + 0x9028, 0x700c, 0x7110, 0xa106, 0x0040, 0x1b19, 0x2104, 0xa005, + 0x0040, 0x1b08, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a, + 0xa188, 0x0003, 0xa182, 0xaa08, 0x0048, 0x1b10, 0x2009, 0xa9ed, + 0x7112, 0x700c, 0xa106, 0x00c0, 0x1af9, 0x2011, 0x0008, 0x0078, + 0x1af9, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0138, 0x2202, + 0x0c7f, 0x007c, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, 0x2021, + 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x00c0, 0x1b3f, 0x2001, + 0x0109, 0x201c, 0xa39c, 0x0048, 0x00c0, 0x1b3f, 0x2001, 0x0111, + 0x201c, 0x83ff, 0x00c0, 0x1b3f, 0x8421, 0x00c0, 0x1b29, 0x007c, + 0x2011, 0x0201, 0x2009, 0x003c, 0x2204, 0xa005, 0x00c0, 0x1b4c, + 0x8109, 0x00c0, 0x1b44, 0x007c, 0x007c, 0x1078, 0x1b40, 0x0040, + 0x1b55, 0x780c, 0xd0a4, 0x0040, 0x1b5b, 0x1078, 0x1af4, 0xa085, + 0x0001, 0x0078, 0x1b5d, 0x1078, 0x1b92, 0x007c, 0x0e7e, 0x2071, + 0x0200, 0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1b22, 0x2019, + 0x5000, 0x8319, 0x0040, 0x1b7c, 0x2001, 0xaa08, 0x2004, 0xa086, + 0x0000, 0x0040, 0x1b7c, 0x2001, 0x0021, 0xd0fc, 0x0040, 0x1b69, + 0x1078, 0x1eaa, 0x0078, 0x1b67, 0x20e1, 0x7000, 0x7324, 0x7420, + 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, + 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001, 0x0138, 0x2202, + 0x0e7f, 0x007c, 0x027e, 0x2001, 0x015d, 0x2001, 0x0000, 0x7908, + 0xa18c, 0x0fff, 0xa182, 0x0ffd, 0x0048, 0x1ba0, 0x2009, 0x0000, + 0xa190, 0x0007, 0xa294, 0x1ff8, 0x8214, 0x8214, 0x8214, 0x2001, + 0x020a, 0x82ff, 0x0040, 0x1bb5, 0x20e1, 0x6000, 0x200c, 0x200c, + 0x200c, 0x200c, 0x8211, 0x00c0, 0x1bae, 0x20e1, 0x7000, 0x200c, + 0x200c, 0x7003, 0x0000, 0x20e1, 0x6000, 0x2001, 0x0208, 0x200c, + 0x2001, 0x0209, 0x2004, 0xa106, 0x0040, 0x1bd4, 0x1078, 0x1b40, + 0x0040, 0x1bd2, 0x7908, 0xd1ec, 0x00c0, 0x1bd4, 0x790c, 0xd1a4, + 0x0040, 0x1b97, 0x1078, 0x1af4, 0xa006, 0x027f, 0x007c, 0x7c20, + 0x7d24, 0x7e30, 0x7f34, 0x700c, 0x7110, 0xa106, 0x0040, 0x1c69, + 0x7004, 0x017e, 0x210c, 0xa106, 0x017f, 0x0040, 0x1c69, 0x0d7e, + 0x0c7e, 0x216c, 0x2d00, 0xa005, 0x0040, 0x1c67, 0x681c, 0xa086, + 0x0008, 0x0040, 0x1c67, 0x6824, 0xd0d4, 0x00c0, 0x1c67, 0x6810, + 0x2068, 0x6850, 0xd0fc, 0x0040, 0x1c29, 0x8108, 0x2104, 0x6b2c, + 0xa306, 0x00c0, 0x1c67, 0x8108, 0x2104, 0x6a28, 0xa206, 0x00c0, + 0x1c67, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, 0x6870, + 0x7826, 0x681c, 0x7832, 0x6820, 0x7836, 0x6818, 0x2060, 0x6034, + 0xd09c, 0x0040, 0x1c24, 0x6830, 0x2004, 0xac68, 0x6808, 0x783a, + 0x680c, 0x783e, 0x0078, 0x1c65, 0xa006, 0x783a, 0x783e, 0x0078, + 0x1c65, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1c67, 0x6b2c, 0xa306, + 0x00c0, 0x1c67, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1c67, 0x6a28, + 0xa206, 0x00c0, 0x1c67, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2004, + 0x6918, 0xa160, 0xa180, 0x000d, 0x2004, 0xd09c, 0x00c0, 0x1c57, + 0x6008, 0x7822, 0x686e, 0x600c, 0x7826, 0x6872, 0x6000, 0x7832, + 0x6004, 0x7836, 0xa006, 0x783a, 0x783e, 0x0078, 0x1c65, 0x6010, + 0x7822, 0x686e, 0x6014, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, + 0x7836, 0x6008, 0x783a, 0x600c, 0x783e, 0x7803, 0x0011, 0x0c7f, + 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0x027e, 0x2071, 0xa9e7, + 0x2079, 0x0030, 0x2011, 0x0050, 0x7000, 0xa086, 0x0000, 0x0040, + 0x1c92, 0x8211, 0x0040, 0x1c90, 0x2001, 0x0005, 0x2004, 0xd08c, + 0x0040, 0x1c79, 0x7904, 0xa18c, 0x0780, 0x017e, 0x1078, 0x1913, + 0x017f, 0x81ff, 0x00c0, 0x1c90, 0x2011, 0x0050, 0x0078, 0x1c74, + 0xa085, 0x0001, 0x027f, 0x017f, 0x0e7f, 0x0f7f, 0x007c, 0x7803, + 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac, 0x0040, 0x1ce8, 0x8109, + 0x00c0, 0x1c9b, 0x2009, 0x0100, 0x210c, 0xa18a, 0x0003, 0x1048, + 0x1332, 0x1078, 0x1fca, 0x0e7e, 0x0f7e, 0x2071, 0xa9d6, 0x2079, + 0x0010, 0x7004, 0xa086, 0x0000, 0x0040, 0x1ce0, 0x7800, 0x007e, + 0x7820, 0x007e, 0x7830, 0x007e, 0x7834, 0x007e, 0x7838, 0x007e, + 0x783c, 0x007e, 0x7803, 0x0004, 0x7823, 0x0000, 0x0005, 0x0005, + 0x2079, 0x0030, 0x7804, 0xd0ac, 0x10c0, 0x1332, 0x2079, 0x0010, + 0x007f, 0x783e, 0x007f, 0x783a, 0x007f, 0x7836, 0x007f, 0x7832, + 0x007f, 0x7822, 0x007f, 0x7802, 0x0f7f, 0x0e7f, 0x0078, 0x1ce6, + 0x0f7f, 0x0e7f, 0x7804, 0xd0ac, 0x10c0, 0x1332, 0x1078, 0x639b, + 0x007c, 0x0e7e, 0x2071, 0xaa08, 0x7003, 0x0000, 0x0e7f, 0x007c, + 0x0d7e, 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x00c0, 0x1d6b, + 0x6934, 0xa184, 0x0007, 0x0079, 0x1cfd, 0x1d05, 0x1d56, 0x1d05, + 0x1d05, 0x1d05, 0x1d3b, 0x1d18, 0x1d07, 0x1078, 0x1332, 0x684c, + 0xd0b4, 0x0040, 0x1e79, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, + 0x6812, 0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0078, 0x1d5e, + 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1d05, 0x684c, + 0xd0b4, 0x0040, 0x1e79, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, + 0x6812, 0x687c, 0x680a, 0x6880, 0x680e, 0x6804, 0x681a, 0xa080, + 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, 0x6832, + 0x6958, 0x0078, 0x1d67, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x00c0, + 0x1d6b, 0x684c, 0xd0b4, 0x0040, 0x1e79, 0x6804, 0x681a, 0xa080, + 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, 0x6832, + 0x6958, 0xa006, 0x682e, 0x682a, 0x0078, 0x1d67, 0x684c, 0xd0b4, + 0x0040, 0x18ed, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, 0x681a, + 0x6834, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, 0x6832, 0x6926, + 0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c, 0x0f7e, 0x2079, 0x0020, + 0x7804, 0xd0fc, 0x10c0, 0x1eaa, 0x0e7e, 0x0d7e, 0x2071, 0xaa08, + 0x7000, 0xa005, 0x00c0, 0x1df0, 0x0c7e, 0x7206, 0xa280, 0x0004, + 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x0d7e, 0x2068, + 0x686c, 0x7812, 0x6890, 0x0f7e, 0x20e1, 0x9040, 0x2079, 0x0200, + 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x0f7f, 0x0d7f, 0x2b68, + 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, + 0x000f, 0x6908, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0007, 0x0040, + 0x1db2, 0xa184, 0x0007, 0x0040, 0x1db2, 0x017e, 0x2009, 0x0008, + 0xa102, 0x017f, 0xa108, 0x791a, 0x7116, 0x701e, 0x680c, 0xa081, + 0x0000, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, 0x7004, 0x692c, + 0x6814, 0xa106, 0x00c0, 0x1dc9, 0x6928, 0x6810, 0xa106, 0x0040, + 0x1dd6, 0x037e, 0x047e, 0x6b14, 0x6c10, 0x1078, 0x208a, 0x047f, + 0x037f, 0x0040, 0x1dd6, 0x0c7f, 0x0078, 0x1df0, 0x8aff, 0x00c0, + 0x1dde, 0x0c7f, 0xa085, 0x0001, 0x0078, 0x1df0, 0x127e, 0x2091, + 0x8000, 0x2079, 0x0020, 0x2009, 0x0001, 0x1078, 0x1df4, 0x0040, + 0x1ded, 0x2009, 0x0001, 0x1078, 0x1df4, 0x127f, 0x0c7f, 0xa006, + 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e, 0x067e, 0x057e, 0x047e, + 0x037e, 0x027e, 0x8aff, 0x0040, 0x1e72, 0x700c, 0x7214, 0xa23a, + 0x7010, 0x7218, 0xa203, 0x0048, 0x1e71, 0xa705, 0x0040, 0x1e71, + 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1e24, 0x0d7e, 0x2804, + 0xac68, 0x2900, 0x0079, 0x1e14, 0x1e53, 0x1e34, 0x1e34, 0x1e53, + 0x1e53, 0x1e4b, 0x1e53, 0x1e34, 0x1e53, 0x1e3a, 0x1e3a, 0x1e53, + 0x1e53, 0x1e53, 0x1e42, 0x1e3a, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, + 0x6d1c, 0x6c20, 0xd99c, 0x0040, 0x1e57, 0x0d7e, 0x2804, 0xac68, + 0x6f08, 0x6e0c, 0x0078, 0x1e56, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, + 0x0078, 0x1e56, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, + 0x0078, 0x1e56, 0x0d7f, 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, + 0x001e, 0x00c0, 0x1e53, 0x0d7f, 0x1078, 0x2026, 0x00c0, 0x1dfa, + 0xa00e, 0x0078, 0x1e72, 0x0d7f, 0x1078, 0x1332, 0x0d7f, 0x7b22, + 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, + 0x7002, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x700c, + 0xa300, 0x700e, 0x7010, 0xa201, 0x7012, 0x1078, 0x2026, 0x0078, + 0x1e72, 0xa006, 0x027f, 0x037f, 0x047f, 0x057f, 0x067f, 0x077f, + 0x007c, 0x1078, 0x1332, 0x027e, 0x2001, 0x0105, 0x2003, 0x0010, + 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, + 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x1e92, 0x6850, + 0xc0bd, 0x6852, 0x0d7f, 0x0c7e, 0x1078, 0x8a11, 0x0c7f, 0x2001, + 0xa9c0, 0x2004, 0xac06, 0x00c0, 0x1ea7, 0x20e1, 0x9040, 0x1078, + 0x738a, 0x2011, 0x0000, 0x1078, 0x70ea, 0x1078, 0x639b, 0x027f, + 0x0078, 0x1f76, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x0f7e, + 0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020, 0x2071, 0xaa08, 0x2b68, + 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0, + 0x1e7b, 0x7000, 0x0079, 0x1ec4, 0x1f76, 0x1ec8, 0x1f43, 0x1f74, + 0x8001, 0x7002, 0xd19c, 0x00c0, 0x1edc, 0x8aff, 0x0040, 0x1efb, + 0x2009, 0x0001, 0x1078, 0x1df4, 0x0040, 0x1f76, 0x2009, 0x0001, + 0x1078, 0x1df4, 0x0078, 0x1f76, 0x7803, 0x0004, 0xd194, 0x0040, + 0x1eec, 0x6850, 0xc0fc, 0x6852, 0x8aff, 0x00c0, 0x1ef1, 0x684c, + 0xc0f5, 0x684e, 0x0078, 0x1ef1, 0x1078, 0x203f, 0x6850, 0xc0fd, + 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, + 0x0000, 0x0078, 0x1f76, 0x711c, 0x81ff, 0x0040, 0x1f11, 0x7918, + 0x7922, 0x7827, 0x0000, 0x7803, 0x0001, 0x7000, 0x8000, 0x7002, + 0x700c, 0xa100, 0x700e, 0x7010, 0xa081, 0x0000, 0x7012, 0x0078, + 0x1f76, 0x0f7e, 0x027e, 0x781c, 0x007e, 0x7818, 0x007e, 0x2079, + 0x0100, 0x7a14, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x037e, + 0x2019, 0x1000, 0x8319, 0x1040, 0x1332, 0x7820, 0xd0bc, 0x00c0, + 0x1f22, 0x037f, 0x79c8, 0x007f, 0xa102, 0x017f, 0x007e, 0x017e, + 0x79c4, 0x007f, 0xa103, 0x78c6, 0x007f, 0x78ca, 0xa284, 0x0004, + 0xa085, 0x0012, 0x7816, 0x027f, 0x0f7f, 0x7803, 0x0008, 0x7003, + 0x0000, 0x0078, 0x1f76, 0x8001, 0x7002, 0xd194, 0x0040, 0x1f58, + 0x7804, 0xd0fc, 0x00c0, 0x1eba, 0xd19c, 0x00c0, 0x1f72, 0x8aff, + 0x0040, 0x1f76, 0x2009, 0x0001, 0x1078, 0x1df4, 0x0078, 0x1f76, + 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x1078, 0x203f, 0x0d7e, 0x2804, + 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1f6b, 0x6808, 0xa31a, 0x680c, + 0xa213, 0x0078, 0x1f6f, 0x6810, 0xa31a, 0x6814, 0xa213, 0x0d7f, + 0x0078, 0x1eec, 0x0078, 0x1eec, 0x1078, 0x1332, 0x0c7f, 0x0d7f, + 0x0e7f, 0x0f7f, 0x017f, 0x007f, 0x127f, 0x007c, 0x0f7e, 0x0e7e, + 0x2071, 0xaa08, 0x7000, 0xa086, 0x0000, 0x0040, 0x1fc7, 0x2079, + 0x0020, 0x017e, 0x2009, 0x0207, 0x210c, 0xd194, 0x0040, 0x1fa4, + 0x2009, 0x020c, 0x210c, 0xa184, 0x0003, 0x0040, 0x1fa4, 0x1078, + 0xa5e2, 0x2001, 0x0133, 0x2004, 0xa005, 0x1040, 0x1332, 0x20e1, + 0x9040, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, + 0x0203, 0x210c, 0xa106, 0x00c0, 0x1faf, 0x20e1, 0x9040, 0x7804, + 0xd0fc, 0x0040, 0x1f8a, 0x1078, 0x1eaa, 0x7000, 0xa086, 0x0000, + 0x00c0, 0x1f8a, 0x017f, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0, + 0x1fbd, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x0e7f, + 0x0f7f, 0x007c, 0x027e, 0x0c7e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071, + 0xaa08, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0040, 0x2003, + 0x7004, 0x2060, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x1fed, + 0x6850, 0xc0b5, 0x6852, 0x680c, 0x7a1c, 0xa206, 0x00c0, 0x1fed, + 0x6808, 0x7a18, 0xa206, 0x0040, 0x2009, 0x2001, 0x0105, 0x2003, + 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, + 0x2060, 0x1078, 0x8a11, 0x20e1, 0x9040, 0x1078, 0x738a, 0x2011, + 0x0000, 0x1078, 0x70ea, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x027f, + 0x007c, 0x6810, 0x6a14, 0xa205, 0x00c0, 0x1fed, 0x684c, 0xc0dc, + 0x684e, 0x2c10, 0x1078, 0x1cf0, 0x2001, 0x0105, 0x2003, 0x0010, + 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x2069, 0xa9b1, + 0x6833, 0x0000, 0x683f, 0x0000, 0x0078, 0x2003, 0x8840, 0x2804, + 0xa005, 0x00c0, 0x203a, 0x6004, 0xa005, 0x0040, 0x203c, 0x681a, + 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x206a, 0x2044, 0x88ff, + 0x1040, 0x1332, 0x8a51, 0x007c, 0x2051, 0x0000, 0x007c, 0x8a50, + 0x8841, 0x2804, 0xa005, 0x00c0, 0x2059, 0x2c00, 0xad06, 0x0040, + 0x204e, 0x6000, 0xa005, 0x00c0, 0x204e, 0x2d00, 0x2060, 0x681a, + 0x6034, 0xa084, 0x000f, 0xa080, 0x207a, 0x2044, 0x88ff, 0x1040, + 0x1332, 0x007c, 0x0000, 0x0011, 0x0015, 0x0019, 0x001d, 0x0021, + 0x0025, 0x0029, 0x0000, 0x000f, 0x0015, 0x001b, 0x0021, 0x0027, + 0x0000, 0x0000, 0x0000, 0x205f, 0x205b, 0x0000, 0x0000, 0x2069, + 0x0000, 0x205f, 0x0000, 0x2066, 0x2063, 0x0000, 0x0000, 0x0000, + 0x2069, 0x2066, 0x0000, 0x2061, 0x2061, 0x0000, 0x0000, 0x2069, + 0x0000, 0x2061, 0x0000, 0x2067, 0x2067, 0x0000, 0x0000, 0x0000, + 0x2069, 0x2067, 0x0a7e, 0x097e, 0x087e, 0x6b2e, 0x6c2a, 0x6858, + 0xa055, 0x0040, 0x212d, 0x2d60, 0x6034, 0xa0cc, 0x000f, 0xa9c0, + 0x206a, 0xa986, 0x0007, 0x0040, 0x20a5, 0xa986, 0x000e, 0x0040, + 0x20a5, 0xa986, 0x000f, 0x00c0, 0x20a9, 0x605c, 0xa422, 0x6060, + 0xa31b, 0x2804, 0xa045, 0x00c0, 0x20b7, 0x0050, 0x20b1, 0x0078, + 0x212d, 0x6004, 0xa065, 0x0040, 0x212d, 0x0078, 0x2094, 0x2804, + 0xa005, 0x0040, 0x20d5, 0xac68, 0xd99c, 0x00c0, 0x20c5, 0x6808, + 0xa422, 0x680c, 0xa31b, 0x0078, 0x20c9, 0x6810, 0xa422, 0x6814, + 0xa31b, 0x0048, 0x20f4, 0x2300, 0xa405, 0x0040, 0x20db, 0x8a51, + 0x0040, 0x212d, 0x8840, 0x0078, 0x20b7, 0x6004, 0xa065, 0x0040, + 0x212d, 0x0078, 0x2094, 0x8a51, 0x0040, 0x212d, 0x8840, 0x2804, + 0xa005, 0x00c0, 0x20ee, 0x6004, 0xa065, 0x0040, 0x212d, 0x6034, + 0xa0cc, 0x000f, 0xa9c0, 0x206a, 0x2804, 0x2040, 0x2b68, 0x6850, + 0xc0fc, 0x6852, 0x0078, 0x2121, 0x8422, 0x8420, 0x831a, 0xa399, + 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72, 0x0d7f, 0xd99c, 0x00c0, + 0x210f, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x1048, + 0x1332, 0x6800, 0xa420, 0x6804, 0xa319, 0x0078, 0x211b, 0x6910, + 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x1048, 0x1332, 0x6800, + 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22, 0x6850, 0xc0fd, + 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, 0x2a00, 0x6826, 0x007f, + 0x007f, 0x007f, 0xa006, 0x0078, 0x2132, 0x087f, 0x097f, 0x0a7f, + 0xa085, 0x0001, 0x007c, 0x2001, 0x0005, 0x2004, 0xa084, 0x0007, + 0x0079, 0x213a, 0x2142, 0x2143, 0x2146, 0x2149, 0x214e, 0x2151, + 0x2156, 0x215b, 0x007c, 0x1078, 0x1eaa, 0x007c, 0x1078, 0x1913, + 0x007c, 0x1078, 0x1913, 0x1078, 0x1eaa, 0x007c, 0x1078, 0x14be, + 0x007c, 0x1078, 0x1eaa, 0x1078, 0x14be, 0x007c, 0x1078, 0x1913, + 0x1078, 0x14be, 0x007c, 0x1078, 0x1913, 0x1078, 0x1eaa, 0x1078, + 0x14be, 0x007c, 0x127e, 0x2091, 0x2300, 0x2079, 0x0200, 0x2071, + 0xac80, 0x2069, 0xa700, 0x2009, 0x0004, 0x7912, 0x7817, 0x0004, + 0x1078, 0x251f, 0x781b, 0x0002, 0x20e1, 0x8700, 0x127f, 0x007c, + 0x127e, 0x2091, 0x2300, 0x781c, 0xa084, 0x0007, 0x0079, 0x2180, + 0x21a4, 0x2188, 0x218c, 0x2190, 0x2196, 0x219a, 0x219e, 0x21a2, + 0x1078, 0x548e, 0x0078, 0x21a4, 0x1078, 0x54da, 0x0078, 0x21a4, + 0x1078, 0x548e, 0x1078, 0x54da, 0x0078, 0x21a4, 0x1078, 0x21a6, + 0x0078, 0x21a4, 0x1078, 0x21a6, 0x0078, 0x21a4, 0x1078, 0x21a6, + 0x0078, 0x21a4, 0x1078, 0x21a6, 0x127f, 0x007c, 0x007e, 0x017e, + 0x027e, 0x1078, 0xa5e2, 0x7930, 0xa184, 0x0003, 0x0040, 0x21c9, + 0x2001, 0xa9c0, 0x2004, 0xa005, 0x0040, 0x21c5, 0x2001, 0x0133, + 0x2004, 0xa005, 0x1040, 0x1332, 0x0c7e, 0x2001, 0xa9c0, 0x2064, + 0x1078, 0x8a11, 0x0c7f, 0x0078, 0x21f2, 0x20e1, 0x9040, 0x0078, + 0x21f2, 0xa184, 0x0030, 0x0040, 0x21da, 0x6a00, 0xa286, 0x0003, + 0x00c0, 0x21d4, 0x0078, 0x21d6, 0x1078, 0x4224, 0x20e1, 0x9010, + 0x0078, 0x21f2, 0xa184, 0x00c0, 0x0040, 0x21ec, 0x0e7e, 0x037e, + 0x047e, 0x057e, 0x2071, 0xa9e7, 0x1078, 0x1af4, 0x057f, 0x047f, + 0x037f, 0x0e7f, 0x0078, 0x21f2, 0xa184, 0x0300, 0x0040, 0x21f2, + 0x20e1, 0x9020, 0x7932, 0x027f, 0x017f, 0x007f, 0x007c, 0x017e, + 0x0e7e, 0x0f7e, 0x2071, 0xa700, 0x7128, 0x2001, 0xa990, 0x2102, + 0x2001, 0xa998, 0x2102, 0xa182, 0x0211, 0x00c8, 0x220b, 0x2009, + 0x0008, 0x0078, 0x2235, 0xa182, 0x0259, 0x00c8, 0x2213, 0x2009, + 0x0007, 0x0078, 0x2235, 0xa182, 0x02c1, 0x00c8, 0x221b, 0x2009, + 0x0006, 0x0078, 0x2235, 0xa182, 0x0349, 0x00c8, 0x2223, 0x2009, + 0x0005, 0x0078, 0x2235, 0xa182, 0x0421, 0x00c8, 0x222b, 0x2009, + 0x0004, 0x0078, 0x2235, 0xa182, 0x0581, 0x00c8, 0x2233, 0x2009, + 0x0003, 0x0078, 0x2235, 0x2009, 0x0002, 0x2079, 0x0200, 0x7912, + 0x7817, 0x0004, 0x1078, 0x251f, 0x0f7f, 0x0e7f, 0x017f, 0x007c, + 0x127e, 0x2091, 0x2200, 0x2061, 0x0100, 0x2071, 0xa700, 0x6024, + 0x6026, 0x6053, 0x0030, 0x6033, 0x00ef, 0x60e7, 0x0000, 0x60eb, + 0x00ef, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, + 0x0080, 0x602f, 0x0000, 0x6007, 0x0eaf, 0x600f, 0x00ff, 0x602b, + 0x002f, 0x127f, 0x007c, 0x2001, 0xa730, 0x2003, 0x0000, 0x2001, + 0xa72f, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091, 0x2200, 0x007e, + 0x017e, 0x027e, 0x6124, 0xa184, 0x002c, 0x00c0, 0x227b, 0xa184, + 0x0007, 0x0079, 0x2281, 0xa195, 0x0004, 0xa284, 0x0007, 0x0079, + 0x2281, 0x22ad, 0x2289, 0x228d, 0x2291, 0x2297, 0x229b, 0x22a1, + 0x22a7, 0x1078, 0x5c56, 0x0078, 0x22ad, 0x1078, 0x5d45, 0x0078, + 0x22ad, 0x1078, 0x5d45, 0x1078, 0x5c56, 0x0078, 0x22ad, 0x1078, + 0x22b2, 0x0078, 0x22ad, 0x1078, 0x5c56, 0x1078, 0x22b2, 0x0078, + 0x22ad, 0x1078, 0x5d45, 0x1078, 0x22b2, 0x0078, 0x22ad, 0x1078, + 0x5d45, 0x1078, 0x5c56, 0x1078, 0x22b2, 0x027f, 0x017f, 0x007f, + 0x127f, 0x007c, 0x6124, 0xd1ac, 0x0040, 0x23ac, 0x017e, 0x047e, + 0x0c7e, 0x644c, 0xa486, 0xf0f0, 0x00c0, 0x22c5, 0x2061, 0x0100, + 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74c6, 0xa48c, 0xff00, + 0x7034, 0xd084, 0x0040, 0x22dd, 0xa186, 0xf800, 0x00c0, 0x22dd, + 0x703c, 0xd084, 0x00c0, 0x22dd, 0xc085, 0x703e, 0x037e, 0x2418, + 0x2011, 0x8016, 0x1078, 0x361b, 0x037f, 0xa196, 0xff00, 0x0040, + 0x231f, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa116, 0x0040, 0x231f, + 0x7130, 0xd184, 0x00c0, 0x231f, 0x2011, 0xa753, 0x2214, 0xd2ec, + 0x0040, 0x22fa, 0xc18d, 0x7132, 0x2011, 0xa753, 0x2214, 0xd2ac, + 0x00c0, 0x231f, 0x6240, 0xa294, 0x0010, 0x0040, 0x2306, 0x6248, + 0xa294, 0xff00, 0xa296, 0xff00, 0x0040, 0x231f, 0x7030, 0xd08c, + 0x0040, 0x2371, 0x7034, 0xd08c, 0x00c0, 0x2316, 0x2001, 0xa70c, + 0x200c, 0xd1ac, 0x00c0, 0x2371, 0xc1ad, 0x2102, 0x037e, 0x73c4, + 0x2011, 0x8013, 0x1078, 0x361b, 0x037f, 0x0078, 0x2371, 0x7034, + 0xd08c, 0x00c0, 0x232b, 0x2001, 0xa70c, 0x200c, 0xd1ac, 0x00c0, + 0x2371, 0xc1ad, 0x2102, 0x037e, 0x73c4, 0x2011, 0x8013, 0x1078, + 0x361b, 0x037f, 0x7130, 0xc185, 0x7132, 0x2011, 0xa753, 0x220c, + 0xd1a4, 0x0040, 0x2355, 0x017e, 0x2009, 0x0001, 0x2011, 0x0100, + 0x1078, 0x5bf1, 0x2019, 0x000e, 0x1078, 0xa1a5, 0xa484, 0x00ff, + 0xa080, 0x29c0, 0x200c, 0xa18c, 0xff00, 0x810f, 0x8127, 0xa006, + 0x2009, 0x000e, 0x1078, 0xa22d, 0x017f, 0xd1ac, 0x00c0, 0x2362, + 0x017e, 0x2009, 0x0000, 0x2019, 0x0004, 0x1078, 0x284f, 0x017f, + 0x0078, 0x2371, 0x157e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x1078, + 0x45c4, 0x00c0, 0x236d, 0x1078, 0x42f8, 0x8108, 0x00f0, 0x2367, + 0x157f, 0x0c7f, 0x047f, 0x0f7e, 0x2079, 0xa9c4, 0x783c, 0xa086, + 0x0000, 0x0040, 0x2383, 0x6027, 0x0004, 0x783f, 0x0000, 0x2079, + 0x0140, 0x7803, 0x0000, 0x0f7f, 0x2011, 0x0003, 0x1078, 0x70e0, + 0x2011, 0x0002, 0x1078, 0x70ea, 0x1078, 0x6fc4, 0x037e, 0x2019, + 0x0000, 0x1078, 0x7058, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001, + 0xa700, 0x2014, 0xa296, 0x0004, 0x00c0, 0x23a4, 0xd19c, 0x00c0, + 0x23ac, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xa722, + 0x2003, 0x0000, 0x6027, 0x0020, 0xd194, 0x0040, 0x2490, 0x0f7e, + 0x2079, 0xa9c4, 0x783c, 0xa086, 0x0001, 0x00c0, 0x23d0, 0x017e, + 0x6027, 0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x1000, + 0x7803, 0x0000, 0x2079, 0xa9b1, 0x7807, 0x0000, 0x7833, 0x0000, + 0x1078, 0x62d1, 0x1078, 0x639b, 0x017f, 0x0f7f, 0x0078, 0x2490, + 0x0f7f, 0x017e, 0x3900, 0xa082, 0xaae3, 0x00c8, 0x23db, 0x017e, + 0x1078, 0x747a, 0x017f, 0x6220, 0xd2b4, 0x0040, 0x2446, 0x1078, + 0x5acb, 0x1078, 0x6e0f, 0x6027, 0x0004, 0x0f7e, 0x2019, 0xa9ba, + 0x2304, 0xa07d, 0x0040, 0x241c, 0x7804, 0xa086, 0x0032, 0x00c0, + 0x241c, 0x0d7e, 0x0c7e, 0x0e7e, 0x2069, 0x0140, 0x618c, 0x6288, + 0x7818, 0x608e, 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, + 0x8001, 0x00c0, 0x2400, 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, + 0x0000, 0x618e, 0x628a, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x7810, + 0x2070, 0x7037, 0x0103, 0x2f60, 0x1078, 0x772d, 0x0e7f, 0x0c7f, + 0x0d7f, 0x0f7f, 0x017f, 0x007c, 0x0f7f, 0x0d7e, 0x2069, 0x0140, + 0x6804, 0xa084, 0x4000, 0x0040, 0x2429, 0x6803, 0x1000, 0x6803, + 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa9b1, 0x6028, 0xa09a, 0x00c8, + 0x00c8, 0x2439, 0x8000, 0x602a, 0x0c7f, 0x1078, 0x6e01, 0x0078, + 0x248f, 0x2019, 0xa9ba, 0x2304, 0xa065, 0x0040, 0x2443, 0x2009, + 0x0027, 0x1078, 0x775c, 0x0c7f, 0x0078, 0x248f, 0xd2bc, 0x0040, + 0x248f, 0x1078, 0x5ad8, 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e, + 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x245b, 0x6803, + 0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa9b1, 0x6044, + 0xa09a, 0x00c8, 0x00c8, 0x247e, 0x8000, 0x6046, 0x603c, 0x0c7f, + 0xa005, 0x0040, 0x248f, 0x2009, 0x07d0, 0x1078, 0x5ad0, 0xa080, + 0x0007, 0x2004, 0xa086, 0x0006, 0x00c0, 0x247a, 0x6017, 0x0012, + 0x0078, 0x248f, 0x6017, 0x0016, 0x0078, 0x248f, 0x037e, 0x2019, + 0x0001, 0x1078, 0x7058, 0x037f, 0x2019, 0xa9c0, 0x2304, 0xa065, + 0x0040, 0x248e, 0x2009, 0x004f, 0x1078, 0x775c, 0x0c7f, 0x017f, + 0xd19c, 0x0040, 0x24e4, 0x7034, 0xd0ac, 0x00c0, 0x24c1, 0x017e, + 0x157e, 0x6027, 0x0008, 0x602f, 0x0020, 0x20a9, 0x000a, 0x00f0, + 0x249f, 0x602f, 0x0000, 0x6150, 0xa185, 0x1400, 0x6052, 0x20a9, + 0x0320, 0x00e0, 0x24a9, 0x2091, 0x6000, 0x6020, 0xd09c, 0x00c0, + 0x24b8, 0x157f, 0x6152, 0x017f, 0x6027, 0x0008, 0x0078, 0x24e4, + 0x1078, 0x2577, 0x00f0, 0x24a9, 0x157f, 0x6152, 0x017f, 0x6027, + 0x0008, 0x017e, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x1078, + 0x70e0, 0x2011, 0x0002, 0x1078, 0x70ea, 0x1078, 0x6fc4, 0x037e, + 0x2019, 0x0000, 0x1078, 0x7058, 0x037f, 0x60e3, 0x0000, 0x1078, + 0xa5bd, 0x1078, 0xa5db, 0x2001, 0xa700, 0x2003, 0x0004, 0x6027, + 0x0008, 0x1078, 0x1246, 0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c, + 0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000, + 0x2071, 0xa700, 0x71bc, 0x70be, 0xa116, 0x0040, 0x2518, 0x81ff, + 0x0040, 0x2500, 0x2011, 0x8011, 0x1078, 0x361b, 0x0078, 0x2518, + 0x2011, 0x8012, 0x1078, 0x361b, 0x2001, 0xa772, 0x2004, 0xd0fc, + 0x00c0, 0x2518, 0x037e, 0x0c7e, 0x1078, 0x6f9f, 0x2061, 0x0100, + 0x2019, 0x0028, 0x2009, 0x0000, 0x1078, 0x284f, 0x0c7f, 0x037f, + 0x127f, 0x0f7f, 0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, 0x0c7e, + 0x0f7e, 0x007e, 0x027e, 0x2061, 0x0100, 0xa190, 0x253b, 0x2204, + 0x60f2, 0x2011, 0x2548, 0x6000, 0xa082, 0x0003, 0x00c8, 0x2534, + 0x2001, 0x00ff, 0x0078, 0x2535, 0x2204, 0x60ee, 0x027f, 0x007f, + 0x0f7f, 0x0c7f, 0x007c, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420, + 0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, + 0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, + 0x2130, 0xa094, 0xff00, 0x00c0, 0x2558, 0x81ff, 0x0040, 0x255c, + 0x1078, 0x5761, 0x0078, 0x2563, 0xa080, 0x29c0, 0x200c, 0xa18c, + 0xff00, 0x810f, 0xa006, 0x007c, 0xa080, 0x29c0, 0x200c, 0xa18c, + 0x00ff, 0x007c, 0x0c7e, 0x2061, 0xa700, 0x6030, 0x0040, 0x2573, + 0xc09d, 0x0078, 0x2574, 0xc09c, 0x6032, 0x0c7f, 0x007c, 0x007e, + 0x157e, 0x0f7e, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c, + 0x00c0, 0x2584, 0x00f0, 0x257e, 0x0f7f, 0x157f, 0x007f, 0x007c, + 0x0c7e, 0x007e, 0x2061, 0x0100, 0x6030, 0x007e, 0x6048, 0x007e, + 0x60e4, 0x007e, 0x60e8, 0x007e, 0x6050, 0x007e, 0x60f0, 0x007e, + 0x60ec, 0x007e, 0x600c, 0x007e, 0x6004, 0x007e, 0x6028, 0x007e, + 0x60e0, 0x007e, 0x602f, 0x0100, 0x602f, 0x0000, 0x0005, 0x0005, + 0x0005, 0x0005, 0x602f, 0x0040, 0x602f, 0x0000, 0x007f, 0x60e2, + 0x007f, 0x602a, 0x007f, 0x6006, 0x007f, 0x600e, 0x007f, 0x60ee, + 0x007f, 0x60f2, 0x007f, 0x6052, 0x007f, 0x60ea, 0x007f, 0x60e6, + 0x007f, 0x604a, 0x007f, 0x6032, 0x007f, 0x0c7f, 0x007c, 0x25e7, + 0x25eb, 0x25ef, 0x25f5, 0x25fb, 0x2601, 0x2607, 0x260f, 0x2617, + 0x261d, 0x2623, 0x262b, 0x2633, 0x263b, 0x2643, 0x264d, 0x2657, + 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, + 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x107e, + 0x007e, 0x0078, 0x2670, 0x107e, 0x007e, 0x0078, 0x2670, 0x107e, + 0x007e, 0x1078, 0x226c, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, + 0x226c, 0x0078, 0x2670, 0x107e, 0x007e... [truncated message content] |