📄 hwc_rw.c
字号:
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); HWC_EBCASC_STR (start, count); if (hwc_data.ioctls.echo) do_hwc_write (0, start, count, IMMEDIATE_WRITE); if (hwc_data.calls != NULL) if (hwc_data.calls->move_input != NULL) (hwc_data.calls->move_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; int retval = 0; subvec = start; while (((void *) subvec) < end) { subvec = find_gds_subvector ( subvec, end, GDS_KEY_SelfDefTextMsg); if (!subvec) break; subvec_data = (gds_subvector_t *) (((unsigned long) subvec) + sizeof (gds_subvector_t)); subvec_end = (void *) (((unsigned long) subvec) + subvec->length); retval += eval_selfdeftextmsg (subvec_data, subvec_end); subvec = (gds_subvector_t *) subvec_end; } return retval;}inline static int eval_cpmsu (gds_vector_t * start, void *end){ gds_vector_t *vec; gds_subvector_t *vec_data; void *vec_end; int retval = 0; vec = start; while (((void *) vec) < end) { vec = find_gds_vector (vec, end, GDS_ID_TextCmd); if (!vec) break; vec_data = (gds_subvector_t *) (((unsigned long) vec) + sizeof (gds_vector_t)); vec_end = (void *) (((unsigned long) vec) + vec->length); retval += eval_textcmd (vec_data, vec_end); vec = (gds_vector_t *) vec_end; } return retval;}inline static int eval_mdsmu (gds_vector_t * start, void *end){ gds_vector_t *vec; gds_vector_t *vec_data; void *vec_end; int retval = 0; vec = find_gds_vector (start, end, GDS_ID_CPMSU); if (vec) { vec_data = (gds_vector_t *) (((unsigned long) vec) + sizeof (gds_vector_t)); vec_end = (void *) (((unsigned long) vec) + vec->length); retval = eval_cpmsu (vec_data, vec_end); } return retval;}static int eval_evbuf (gds_vector_t * start, void *end){ gds_vector_t *vec; gds_vector_t *vec_data; void *vec_end; int retval = 0; vec = find_gds_vector (start, end, GDS_ID_MDSMU); if (vec) { vec_data = (gds_vector_t *) (((unsigned long) vec) + sizeof (gds_vector_t)); vec_end = (void *) (((unsigned long) vec) + vec->length); retval = eval_mdsmu (vec_data, vec_end); } return retval;}static inline int eval_hwc_receive_mask (_hwcb_mask_t mask){ hwc_data.write_nonprio = ((mask & ET_Msg_Mask) == ET_Msg_Mask); hwc_data.write_prio = ((mask & ET_PMsgCmd_Mask) == ET_PMsgCmd_Mask); if (hwc_data.write_prio || hwc_data.write_nonprio) { internal_print ( DELAYED_WRITE, HWC_RW_PRINT_HEADER "can write messages\n"); return 0; } else { internal_print ( DELAYED_WRITE, HWC_RW_PRINT_HEADER "can not write messages\n"); return -1; }}static inline int eval_hwc_send_mask (_hwcb_mask_t mask){ hwc_data.read_statechange = ((mask & ET_StateChange_Mask) == ET_StateChange_Mask); if (hwc_data.read_statechange) internal_print ( DELAYED_WRITE, HWC_RW_PRINT_HEADER "can read state change notifications\n"); else internal_print ( DELAYED_WRITE, HWC_RW_PRINT_HEADER "can not read state change notifications\n"); hwc_data.read_nonprio = ((mask & ET_OpCmd_Mask) == ET_OpCmd_Mask); if (hwc_data.read_nonprio) internal_print ( DELAYED_WRITE, HWC_RW_PRINT_HEADER "can read commands\n"); hwc_data.read_prio = ((mask & ET_PMsgCmd_Mask) == ET_PMsgCmd_Mask); if (hwc_data.read_prio) internal_print ( DELAYED_WRITE, HWC_RW_PRINT_HEADER "can read priority commands\n"); if (hwc_data.read_prio || hwc_data.read_nonprio) { return 0; } else { internal_print ( DELAYED_WRITE, HWC_RW_PRINT_HEADER "can not read commands from operator\n"); return -1; }}static int eval_statechangebuf (statechangebuf_t * scbuf){ int retval = 0; internal_print ( DELAYED_WRITE, HWC_RW_PRINT_HEADER "HWC state change detected\n"); if (scbuf->validity_hwc_active_facility_mask) { } if (scbuf->validity_hwc_receive_mask) { if (scbuf->mask_length != 4) {#ifdef DUMP_HWC_INIT_ERROR __asm__ ("LHI 1,0xe50\n\t" "LRA 2,0(%0)\n\t" "J .+0 \n\t" : : "a" (scbuf) : "1", "2");#endif } else { retval += eval_hwc_receive_mask (scbuf->hwc_receive_mask); } } if (scbuf->validity_hwc_send_mask) { if (scbuf->mask_length != 4) {#ifdef DUMP_HWC_INIT_ERROR __asm__ ("LHI 1,0xe51\n\t" "LRA 2,0(%0)\n\t" "J .+0 \n\t" : : "a" (scbuf) : "1", "2");#endif } else { retval += eval_hwc_send_mask (scbuf->hwc_send_mask); } } if (scbuf->validity_read_data_function_mask) { } return retval;}static int process_evbufs (void *start, void *end){ int retval = 0; evbuf_t *evbuf; void *evbuf_end; gds_vector_t *evbuf_data; evbuf = (evbuf_t *) start; while (((void *) evbuf) < end) { evbuf_data = (gds_vector_t *) (((unsigned long) evbuf) + sizeof (evbuf_t)); evbuf_end = (void *) (((unsigned long) evbuf) + evbuf->length); switch (evbuf->type) { case ET_OpCmd: case ET_CntlProgOpCmd: case ET_PMsgCmd:#ifdef DUMP_HWCB_INPUT internal_print ( DELAYED_WRITE, HWC_RW_PRINT_HEADER "event buffer " "at 0x%x up to 0x%x, length: %d\n", (unsigned long) evbuf, (unsigned long) (evbuf_end - 1), evbuf->length); dump_storage_area ((void *) evbuf, evbuf->length);#endif retval += eval_evbuf (evbuf_data, evbuf_end); break; case ET_StateChange: retval += eval_statechangebuf ((statechangebuf_t *) evbuf); break; default: internal_print ( DELAYED_WRITE, HWC_RW_PRINT_HEADER "unconditional read: " "unknown event buffer found, " "type 0x%x", evbuf->type); retval = -ENOSYS; } evbuf = (evbuf_t *) evbuf_end; } return retval;}static int unconditional_read_1 (void){ unsigned short int condition_code; read_hwcb_t *hwcb = (read_hwcb_t *) hwc_data.page; int retval;#if 0 if ((!hwc_data.read_prio) && (!hwc_data.read_nonprio)) return -EOPNOTSUPP; if (hwc_data.current_servc) return -EBUSY;#endif memset (hwcb, 0x00, PAGE_SIZE); memcpy (hwcb, &read_hwcb_template, sizeof (read_hwcb_t)); condition_code = service_call (HWC_CMDW_READDATA, hwc_data.page);#ifdef DUMP_HWC_READ_ERROR if (condition_code == HWC_NOT_OPERATIONAL) __asm__ ("LHI 1,0xe40\n\t" "L 2,0(%0)\n\t" "LRA 3,0(%1)\n\t" "J .+0 \n\t" : : "a" (&condition_code), "a" (hwc_data.page) : "1", "2", "3");#endif switch (condition_code) { case HWC_COMMAND_INITIATED: hwc_data.current_servc = HWC_CMDW_READDATA; hwc_data.current_hwcb = hwc_data.page; retval = condition_code; break; case HWC_BUSY: retval = -EBUSY; break; default: retval = -EIO; } return retval;}static int unconditional_read_2 (u32 ext_int_param){ read_hwcb_t *hwcb = (read_hwcb_t *) hwc_data.page;#ifdef DUMP_HWC_READ_ERROR if ((hwcb->response_code != 0x0020) && (hwcb->response_code != 0x0220) && (hwcb->response_code != 0x60F0) && (hwcb->response_code != 0x62F0)) __asm__ ("LHI 1,0xe41\n\t" "LRA 2,0(%0)\n\t" "L 3,0(%1)\n\t" "J .+0\n\t" : : "a" (hwc_data.page), "a" (&(hwcb->response_code)) : "1", "2", "3");#endif hwc_data.current_servc = 0; hwc_data.current_hwcb = NULL; switch (hwcb->response_code) { case 0x0020: case 0x0220: return process_evbufs ( (void *) (((unsigned long) hwcb) + sizeof (read_hwcb_t)), (void *) (((unsigned long) hwcb) + hwcb->length)); case 0x60F0: case 0x62F0: internal_print ( IMMEDIATE_WRITE, HWC_RW_PRINT_HEADER "unconditional read: " "got interrupt and tried to read input, " "but nothing found (response code=0x%x).\n", hwcb->response_code); return 0; case 0x0100: internal_print ( IMMEDIATE_WRITE, HWC_RW_PRINT_HEADER "unconditional read: HWCB boundary violation - this " "must not occur in a correct driver, please contact " "author\n"); return -EIO; case 0x0300: internal_print ( IMMEDIATE_WRITE, HWC_RW_PRINT_HEADER "unconditional read: " "insufficient HWCB length - this must not occur in a " "correct driver, please contact author\n"); return -EIO; case 0x01F0: internal_print ( IMMEDIATE_WRITE, HWC_RW_PRINT_HEADER "unconditional read: " "invalid command - this must not occur in a correct " "driver, please contact author\n"); return -EIO; case 0x40F0: internal_print ( IMMEDIATE_WRITE, HWC_RW_PRINT_HEADER "unconditional read: invalid function code\n"); return -EIO; case 0x70F0: internal_print ( IMMEDIATE_WRITE, HWC_RW_PRINT_HEADER "unconditional read: invalid selection mask\n"); return -EIO; case 0x0040: internal_print ( IMMEDIATE_WRITE, HWC_RW_PRINT_HEADER "unconditional read: HWC equipment check\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -