📄 hwc_rw.c
字号:
switch (condition_code) { case HWC_COMMAND_INITIATED: hwc_data.current_servc = HWC_CMDW_WRITEDATA; hwc_data.current_hwcb = OUT_HWCB; retval = condition_code; break; case HWC_BUSY: retval = -EBUSY; break; default: retval = -EIO; } return retval;}static void flush_hwcbs (void){ while (hwc_data.hwcb_count > 1) release_write_hwcb (); release_write_hwcb (); hwc_data.flags &= ~FLUSH_HWCBS;}static int write_event_data_2 (void){ write_hwcb_t *hwcb; int retval; unsigned char *param; param = ext_int_param (); if (param != hwc_data.current_hwcb) return -EINVAL; hwcb = (write_hwcb_t *) OUT_HWCB;#ifdef DUMP_HWC_WRITE_ERROR#if 0 if (((unsigned char *) hwcb) != param) __asm__ ("LHI 1,0xe22\n\t" "LRA 2,0(0,%0)\n\t" "LRA 3,0(0,%1)\n\t" "LRA 4,0(0,%2)\n\t" "LRA 5,0(0,%3)\n\t" "J .+0 \n\t" : : "a" (OUT_HWCB), "a" (hwc_data.current_hwcb), "a" (BUF_HWCB), "a" (param) : "1", "2", "3", "4", "5");#endif if (hwcb->response_code != 0x0020)#if 0 internal_print (DELAYED_WRITE, HWC_RW_PRINT_HEADER "\n************************ error in write_event_data_2()\n" "OUT_HWCB: 0x%x\n" "BUF_HWCB: 0x%x\n" "response_code: 0x%x\n" "hwc_data.hwcb_count: %d\n" "hwc_data.kmem_pages: 0x%x\n" "hwc_data.ioctls.kmem_hwcb: %d\n" "hwc_data.ioctls.max_hwcb: %d\n" "hwc_data.kmem_start: 0x%x\n" "hwc_data.kmem_end: 0x%x\n" "*****************************************************\n", OUT_HWCB, BUF_HWCB, hwcb->response_code, hwc_data.hwcb_count, hwc_data.kmem_pages, hwc_data.ioctls.kmem_hwcb, hwc_data.ioctls.max_hwcb, hwc_data.kmem_start, hwc_data.kmem_end);#endif __asm__ ("LHI 1,0xe21\n\t" "LRA 2,0(0,%0)\n\t" "LRA 3,0(0,%1)\n\t" "LRA 4,0(0,%2)\n\t" "LH 5,0(0,%3)\n\t" "SRL 5,8(0)\n\t" "J .+0 \n\t" : : "a" (OUT_HWCB), "a" (hwc_data.current_hwcb), "a" (BUF_HWCB), "a" (&(hwc_data.hwcb_count)) : "1", "2", "3", "4", "5");#endif if (hwcb->response_code == 0x0020) { retval = OUT_HWCB_CHAR; release_write_hwcb (); } else retval = -EIO; hwc_data.current_servc = 0; hwc_data.current_hwcb = NULL; if (hwc_data.flags & FLUSH_HWCBS) flush_hwcbs (); return retval;}static void do_put_line ( unsigned char *message, unsigned short count){ if (add_mto (message, count) != count) { if (allocate_write_hwcb () < 0) reuse_write_hwcb ();#ifdef DUMP_HWC_WRITE_LIST_ERROR if (add_mto (message, count) != count) __asm__ ("LHI 1,0xe32\n\t" "LRA 2,0(0,%0)\n\t" "L 3,0(0,%1)\n\t" "LRA 4,0(0,%2)\n\t" "LRA 5,0(0,%3)\n\t" "J .+0 \n\t" : : "a" (message), "a" (&hwc_data.kmem_pages), "a" (BUF_HWCB), "a" (OUT_HWCB) : "1", "2", "3", "4", "5");#else add_mto (message, count);#endif }}static void put_line ( unsigned char *message, unsigned short count){ if ((!hwc_data.obuf_start) && (hwc_data.flags & HWC_TIMER_RUNS)) { del_timer (&hwc_data.write_timer); hwc_data.flags &= ~HWC_TIMER_RUNS; } hwc_data.obuf_start += count; do_put_line (message, count); hwc_data.obuf_start -= count;}static void set_alarm (void){ write_hwcb_t *hwcb; if ((!BUF_HWCB) || (BUF_HWCB == hwc_data.current_hwcb)) allocate_write_hwcb (); hwcb = (write_hwcb_t *) BUF_HWCB; hwcb->msgbuf.mdb.mdb_body.go.general_msg_flags |= GMF_SndAlrm;}static void hwc_write_timeout (unsigned long data){ unsigned long flags; spin_lock_irqsave (&hwc_data.lock, flags); hwc_data.obuf_start = hwc_data.obuf_count; if (hwc_data.obuf_count) put_line (hwc_data.obuf, hwc_data.obuf_count); hwc_data.obuf_start = 0; hwc_data.obuf_cursor = 0; hwc_data.obuf_count = 0; write_event_data_1 (); spin_unlock_irqrestore (&hwc_data.lock, flags);}static int do_hwc_write ( int from_user, unsigned char *msg, unsigned int count, unsigned char code, unsigned char write_time){ unsigned int i_msg = 0; unsigned short int spaces = 0; unsigned int processed_characters = 0; unsigned char ch, orig_ch; unsigned short int obuf_count; unsigned short int obuf_cursor; unsigned short int obuf_columns; if (hwc_data.obuf_start) { obuf_cursor = 0; obuf_count = 0; obuf_columns = MIN (hwc_data.ioctls.columns, MAX_MESSAGE_SIZE - hwc_data.obuf_start); } else { obuf_cursor = hwc_data.obuf_cursor; obuf_count = hwc_data.obuf_count; obuf_columns = hwc_data.ioctls.columns; } for (i_msg = 0; i_msg < count; i_msg++) { if (from_user) get_user (orig_ch, msg + i_msg); else orig_ch = msg[i_msg]; if (code == CODE_EBCDIC) ch = _ebcasc[orig_ch]; else ch = orig_ch; processed_characters++; if ((obuf_cursor == obuf_columns) && (ch != '\n') && (ch != '\t')) { put_line (&hwc_data.obuf[hwc_data.obuf_start], obuf_columns); obuf_cursor = 0; obuf_count = 0; } switch (ch) { case '\n': put_line (&hwc_data.obuf[hwc_data.obuf_start], obuf_count); obuf_cursor = 0; obuf_count = 0; break; case '\a': hwc_data.obuf_start += obuf_count; set_alarm (); hwc_data.obuf_start -= obuf_count; break; case '\t': do { if (obuf_cursor < obuf_columns) { hwc_data.obuf[hwc_data.obuf_start + obuf_cursor] = 0x20; obuf_cursor++; } else break; } while (obuf_cursor % hwc_data.ioctls.width_htab); break; case '\f': case '\v': spaces = obuf_cursor; put_line (&hwc_data.obuf[hwc_data.obuf_start], obuf_count); obuf_count = obuf_cursor; while (spaces) { hwc_data.obuf[hwc_data.obuf_start + obuf_cursor - spaces] = 0x20; spaces--; } break; case '\b': if (obuf_cursor) obuf_cursor--; break; case '\r': obuf_cursor = 0; break; case 0x00: put_line (&hwc_data.obuf[hwc_data.obuf_start], obuf_count); obuf_cursor = 0; obuf_count = 0; goto out; default: if (isprint (ch)) hwc_data.obuf[hwc_data.obuf_start + obuf_cursor++] = (code == CODE_ASCII) ? _ascebc[orig_ch] : orig_ch; } if (obuf_cursor > obuf_count) obuf_count = obuf_cursor; } if (obuf_cursor) { if (hwc_data.obuf_start || (hwc_data.ioctls.final_nl == 0)) { put_line (&hwc_data.obuf[hwc_data.obuf_start], obuf_count); obuf_cursor = 0; obuf_count = 0; } else { if (hwc_data.ioctls.final_nl > 0) { if (hwc_data.flags & HWC_TIMER_RUNS) { hwc_data.write_timer.expires = jiffies + hwc_data.ioctls.final_nl * HZ / 10; } else { init_timer (&hwc_data.write_timer); hwc_data.write_timer.function = hwc_write_timeout; hwc_data.write_timer.data = (unsigned long) NULL; hwc_data.write_timer.expires = jiffies + hwc_data.ioctls.final_nl * HZ / 10; add_timer (&hwc_data.write_timer); hwc_data.flags |= HWC_TIMER_RUNS; } } else; } } else; out: if (!hwc_data.obuf_start) { hwc_data.obuf_cursor = obuf_cursor; hwc_data.obuf_count = obuf_count; } if (write_time == IMMEDIATE_WRITE) write_event_data_1 (); return processed_characters;}signed int hwc_write (int from_user, const unsigned char *msg, unsigned int count){ unsigned long flags; int retval; spin_lock_irqsave (&hwc_data.lock, flags); retval = do_hwc_write (from_user, msg, count, hwc_data.ioctls.code, IMMEDIATE_WRITE); spin_unlock_irqrestore (&hwc_data.lock, flags); return retval;}unsigned int hwc_chars_in_buffer (unsigned char flag){ unsigned short int number = 0; unsigned long flags; spin_lock_irqsave (&hwc_data.lock, flags); if (flag & IN_HWCB) number += ALL_HWCB_CHAR; if (flag & IN_WRITE_BUF) number += hwc_data.obuf_cursor; spin_unlock_irqrestore (&hwc_data.lock, flags); return number;}static inline int nr_setbits (kmem_pages_t arg){ int i; int nr = 0; for (i = 0; i < (sizeof (arg) << 3); i++) { if (arg & 1) nr++; arg >>= 1; } return nr;}unsigned int hwc_write_room (unsigned char flag){ unsigned int number = 0; unsigned long flags; write_hwcb_t *hwcb; spin_lock_irqsave (&hwc_data.lock, flags); if (flag & IN_HWCB) { if (BUF_HWCB) { hwcb = (write_hwcb_t *) BUF_HWCB; number += MAX_HWCB_ROOM - hwcb->length; } number += (hwc_data.ioctls.kmem_hwcb - nr_setbits (hwc_data.kmem_pages)) * (MAX_HWCB_ROOM - (sizeof (write_hwcb_t) + sizeof (mto_t))); } if (flag & IN_WRITE_BUF) number += MAX_HWCB_ROOM - hwc_data.obuf_cursor; spin_unlock_irqrestore (&hwc_data.lock, flags); return number;}void hwc_flush_buffer (unsigned char flag){ unsigned long flags; spin_lock_irqsave (&hwc_data.lock, flags); if (flag & IN_HWCB) { if (hwc_data.current_servc != HWC_CMDW_WRITEDATA) flush_hwcbs (); else hwc_data.flags |= FLUSH_HWCBS; } if (flag & IN_WRITE_BUF) { hwc_data.obuf_cursor = 0; hwc_data.obuf_count = 0; } spin_unlock_irqrestore (&hwc_data.lock, flags);}unsigned short int seperate_cases (unsigned char *buf, unsigned short int count){ unsigned short int i_in; unsigned short int i_out = 0; unsigned char _case = 0; for (i_in = 0; i_in < count; i_in++) { if (buf[i_in] == hwc_data.ioctls.delim) { if ((i_in + 1 < count) && (buf[i_in + 1] == hwc_data.ioctls.delim)) { buf[i_out] = hwc_data.ioctls.delim; i_out++; i_in++; } else _case = ~_case; } else { if (_case) { if (hwc_data.ioctls.tolower) buf[i_out] = _ebc_toupper[buf[i_in]]; else buf[i_out] = _ebc_tolower[buf[i_in]]; } else buf[i_out] = buf[i_in]; i_out++; } } return i_out;}#ifdef DUMP_HWCB_INPUTstatic int gds_vector_name (u16 id, unsigned char name[]){ int retval = 0; switch (id) { case GDS_ID_MDSMU: name = "Multiple Domain Support Message Unit"; break; case GDS_ID_MDSRouteInfo: name = "MDS Routing Information"; break; case GDS_ID_AgUnWrkCorr: name = "Agent Unit of Work Correlator"; break; case GDS_ID_SNACondReport: name = "SNA Condition Report"; break; case GDS_ID_CPMSU: name = "CP Management Services Unit"; break; case GDS_ID_RoutTargInstr: name = "Routing and Targeting Instructions"; break; case GDS_ID_OpReq: name = "Operate Request"; break; case GDS_ID_TextCmd: name = "Text Command"; break; default: name = "unknown GDS variable"; retval = -EINVAL; } return retval;}#endifinline static gds_vector_t *find_gds_vector ( gds_vector_t * start, void *end, u16 id){ gds_vector_t *vec; gds_vector_t *retval = NULL; vec = start; while (((void *) vec) < end) { if (vec->gds_id == id) {#ifdef DUMP_HWCB_INPUT int retval_name; unsigned char name[64]; retval_name = gds_vector_name (id, name); internal_print ( DELAYED_WRITE, HWC_RW_PRINT_HEADER "%s at 0x%x up to 0x%x, length: %d", name, (unsigned long) vec, ((unsigned long) vec) + vec->length - 1, vec->length); if (retval_name < 0) internal_print ( IMMEDIATE_WRITE, ", id: 0x%x\n", vec->gds_id); else internal_print ( IMMEDIATE_WRITE, "\n");#endif retval = vec; break; } vec = (gds_vector_t *) (((unsigned long) vec) + vec->length); } return retval;}inline static gds_subvector_t *find_gds_subvector ( gds_subvector_t * start, void *end, u8 key){ gds_subvector_t *subvec; gds_subvector_t *retval = NULL; subvec = start; while (((void *) subvec) < end) { if (subvec->key == key) { retval = subvec; break; } subvec = (gds_subvector_t *) (((unsigned long) subvec) + subvec->length); } return retval;}inline static int get_input (void *start, void *end){ int count; count = ((unsigned long) end) - ((unsigned long) start); if (hwc_data.ioctls.tolower) EBC_TOLOWER (start, count); if (hwc_data.ioctls.delim) count = seperate_cases (start, count); if (hwc_data.ioctls.echo) do_hwc_write (0, start, count, CODE_EBCDIC, IMMEDIATE_WRITE); if (hwc_data.ioctls.code == CODE_ASCII) EBCASC (start, count); store_hwc_input (start, count); return count;}inline static int eval_selfdeftextmsg (gds_subvector_t * start, void *end){ gds_subvector_t *subvec; void *subvec_data; void *subvec_end; int retval = 0; subvec = start; while (((void *) subvec) < end) { subvec = find_gds_subvector (subvec, end, 0x30); if (!subvec) break; subvec_data = (void *) (((unsigned long) subvec) + sizeof (gds_subvector_t)); subvec_end = (void *) (((unsigned long) subvec) + subvec->length); retval += get_input (subvec_data, subvec_end); subvec = (gds_subvector_t *) subvec_end; } return retval;}inline static int eval_textcmd (gds_subvector_t * start, void *end){ gds_subvector_t *subvec; gds_subvector_t *subvec_data; void *subvec_end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -