📄 sd53c8xx.n
字号:
// NCR 53c8xx driver for Plan 9// Nigel Roles (ngr@cotswold.demon.co.uk)//// Microcode// 05/10/98 Small fix to handle command length being greater than expected by device//extern scsi_id_bufextern msg_out_bufextern cmd_bufextern data_bufextern status_bufextern msgin_bufextern dsa_0extern dsa_1extern dsa_headSIR_MSG_IO_COMPLETE = 0error_not_cmd_complete = 1error_disconnected = 2error_reselected = 3error_unexpected_phase = 4error_weird_message = 5SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT = 6error_not_identify_after_reselect = 7error_too_much_data = 8error_too_little_data = 9SIR_MSG_REJECT = 10SIR_MSG_SDTR = 11SIR_EV_RESPONSE_OK = 12error_sigp_set = 13SIR_EV_PHASE_SWITCH_AFTER_ID = 14SIR_MSG_WDTR = 15SIR_MSG_IGNORE_WIDE_RESIDUE = 16SIR_NOTIFY_DISC = 100SIR_NOTIFY_RESELECT = 101SIR_NOTIFY_MSG_IN = 102SIR_NOTIFY_STATUS = 103SIR_NOTIFY_DUMP = 104SIR_NOTIFY_DUMP2 = 105SIR_NOTIFY_SIGP = 106SIR_NOTIFY_ISSUE = 107SIR_NOTIFY_WAIT_RESELECT = 108SIR_NOTIFY_ISSUE_CHECK = 109SIR_NOTIFY_DUMP_NEXT_CODE = 110SIR_NOTIFY_COMMAND = 111SIR_NOTIFY_DATA_IN = 112SIR_NOTIFY_DATA_OUT = 113SIR_NOTIFY_BLOCK_DATA_IN = 114SIR_NOTIFY_WSR = 115SIR_NOTIFY_LOAD_SYNC = 116SIR_NOTIFY_RESELECTED_ON_SELECT = 117STATE_FREE = 0STATE_ALLOCATED = 1STATE_ISSUE = 2STATE_DISCONNECTED = 3STATE_DONE = 4RESULT_OK = 0 MSG_IDENTIFY = 0x80MSG_DISCONNECT = 0x04MSG_SAVE_DATA_POINTER = 0x02MSG_RESTORE_POINTERS = 0x03MSG_IGNORE_WIDE_RESIDUE = 0x23X_MSG = 0x01X_MSG_SDTR = 0x01X_MSG_WDTR = 0x03MSG_REJECT = 0x07BSIZE = 512//BSIZE=4096idle: jump wait_for_reselection start: call load_sync// move 13 to ctest0// int SIR_NOTIFY_ISSUE clear target select atn from scsi_id_buf, reselected_on_select // do I need to clear ATN here? jump start1, when msg_instart1:// move 14 to ctest0 move from msg_out_buf, when msg_outid_out_mismatch: jump start1, when msg_out // repeat on parity grounds jump to_decisions, when not cmdcmd_phase:// int SIR_NOTIFY_COMMAND clear atn move from cmd_buf, when cmdcmd_out_mismatch: jump to_decisions, when not data_indata_in_phase: move memory 4, state, scratcha move memory 4, dmaaddr, scratchb// int SIR_NOTIFY_DATA_INdata_in_block_loop: move scratcha2 to sfbr jump data_in_normal, if 0// int SIR_NOTIFY_BLOCK_DATA_IN move BSIZE, ptr dmaaddr, when data_in // transfer BSIZE bytesdata_in_block_mismatch: move scratchb1 + BSIZE / 256 to scratchb1 // add BSIZE to scratchb move scratchb2 + 0 to scratchb2 with carry move scratchb3 + 0 to scratchb3 with carry move scratcha2 + 255 to scratcha2 // sub one from block count move memory 4, scratchb, dmaaddr // save latest dmaddr jump data_in_block_loop, when data_in move memory 4, scratcha, state // save latest state call save_state jump to_decisionsdata_block_mismatch_recover: move memory 4, scratchb, dmaaddr // save latest dmaddr move memory 4, scratcha, state // save latest state jump to_decisions // no need to save // as interrupt routine // did thisdata_in_normal: move scratcha3 to sfbr int error_too_much_data, if not 0 move from data_buf, when data_indata_in_mismatch: move 1 to scratcha3 move memory 4, scratcha, state call save_state jump post_data_to_decisionsdata_out_phase:// int SIR_NOTIFY_DATA_OUT move memory 4, state, scratcha move memory 4, dmaaddr, scratchbdata_out_block_loop: move scratcha2 to sfbr jump data_out_normal, if 0 move memory 4, dmaaddr, scratchb move BSIZE, ptr dmaaddr, when data_out // transfer BSIZE bytesdata_out_block_mismatch: move scratchb1 + BSIZE / 256 to scratchb1 // add BSIZE to scratchb move scratchb2 + 0 to scratchb2 with carry move scratchb3 + 0 to scratchb3 with carry move scratcha2 + 255 to scratcha2 // sub one from block count move memory 4, scratchb, dmaaddr // save latest dmaddr jump data_out_block_loop, when data_out move memory 4, scratcha, state // save latest state jump to_decisionsdata_out_normal: move scratcha3 to sfbr int error_too_little_data, if not 0 move from data_buf, when data_outdata_out_mismatch: move 1 to scratcha3 move memory 4, scratcha, state call save_state jump post_data_to_decisionsstatus_phase: move from status_buf, when status// int SIR_NOTIFY_STATUS int error_unexpected_phase, when not msg_inmsg_in_phase: move 1, scratcha, when msg_in// int SIR_NOTIFY_MSG_IN jump rejected, if MSG_REJECTmsg_in_not_reject: jump disconnected, if MSG_DISCONNECT jump msg_in_skip, if MSG_SAVE_DATA_POINTER jump msg_in_skip, if MSG_RESTORE_POINTERS jump ignore_wide, if MSG_IGNORE_WIDE_RESIDUE jump extended, if X_MSG int error_not_cmd_complete, if not 0 move scntl2&0x7e to scntl2 // take care not to clear WSR clear ack wait disconnect // update state move memory 4, state, scratcha move STATE_DONE to scratcha0 move RESULT_OK to scratcha1 move memory 4, scratcha, state call save_state// int SIR_MSG_IO_COMPLETE intfly 0 jump issue_checkrejected: int SIR_MSG_REJECT clear ack jump to_decisionsmsg_in_skip: clear ack jump to_decisions extended: clear ack int error_unexpected_phase, when not msg_in move 1, scratcha1, when msg_in jump ext_3, if 3 jump ext_2, if 2 int error_weird_message, if not 1ext_1: clear ack int error_unexpected_phase, when not msg_in move 1, scratcha1, when msg_in jump ext_doneext_3: clear ack int error_unexpected_phase, when not msg_in move 1, scratcha1, when msg_in clear ack int error_unexpected_phase, when not msg_in move 1, scratcha2, when msg_in clear ack int error_unexpected_phase, when not msg_in move 1, scratcha3, when msg_in move scratcha1 to sfbr jump ext_done, if not X_MSG_SDTR// the target sent SDTR - leave ACK asserted and signal kernel// kernel will either restart at reject, or continuesdtr: int SIR_MSG_SDTR clear ack jump to_decisionsext_2: clear ack int error_unexpected_phase, when not msg_in move 1, scratcha1, when msg_in clear ack int error_unexpected_phase, when not msg_in move 1, scratcha2, when msg_in move scratcha1 to sfbr jump ext_done, if not X_MSG_WDTRwdtr: int SIR_MSG_WDTR clear ack jump to_decisionsext_done:// ought to check message here, but instead reject all// NB ATN setreject: set atn // get target's ATN clear ack // finish ACK move MSG_REJECT to scratcha // prepare message int error_unexpected_phase, when not msg_out// didn't get ATN clear atn // last byte coming move 1, scratcha, when msg_out // send byte clear ack // finish ACK jump reject, when msg_out // parity error jump to_decisions ignore_wide: clear ack int error_unexpected_phase, when not msg_in move 1, scratcha1, when msg_in int SIR_MSG_IGNORE_WIDE_RESIDUE clear ack jump to_decisions// sends a response to a messageresponse: set atn clear ack int error_unexpected_phase, when not msg_outresponse_repeat: move from msg_out_buf, when msg_out jump response_repeat, when msg_out // repeat on parity grounds// now look for response// msg_in could be a REJECT// anything other message is something else so signal kernel first jump response_msg_in, when msg_in int SIR_EV_RESPONSE_OK // not a MSG_IN so OK jump to_decisionsresponse_msg_in: move 1, scratcha, when msg_in jump rejected, if MSG_REJECT // go and generate rej interrupt int SIR_EV_RESPONSE_OK // not a REJECT so OK jump msg_in_not_reject // try othersdisconnected:// move 5 to ctest0 move scntl2&0x7e to scntl2 // don't clear WSR clear ack wait disconnect // UPDATE state to disconnected move memory 4, state, scratcha move STATE_DISCONNECTED to scratcha0 move memory 4, scratcha, state call save_statewsr_check: move scntl2&0x01 to sfbr int SIR_NOTIFY_WSR, if not 0// int SIR_NOTIFY_DISC jump issue_checkreselected_on_select: int SIR_NOTIFY_RESELECTED_ON_SELECT jump reselectedwait_for_reselection:// move 11 to ctest0// int SIR_NOTIFY_WAIT_RESELECT wait reselect sigp_setreselected:// move 12 to ctest0 clear target int SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT, when not msg_in move 1, scratchb, when msg_in int error_not_identify_after_reselect, if not MSG_IDENTIFY and mask 0x1f// int SIR_NOTIFY_RESELECT // now locate the right DSA - note do not clear ACK, so target doesn't start // synchronous transfer until we are readyfind_dsa:// move 6 to ctest0 move memory 4, dsa_head, dsafind_dsa_loop:// move 7 to ctest0 move dsa0 to sfbr jump find_dsa_1, if not 0 move dsa1 to sfbr jump find_dsa_1, if not 0 move dsa2 to sfbr jump find_dsa_1, if not 0 move dsa3 to sfbr int error_reselected, if 0 // couldn't match dsa (panic)find_dsa_1:// move 8 to ctest0 // load state from DSA into dsa_copy call load_state move memory 4, state, scratcha // get dsastate in scratcha move scratcha0 to sfbr // and state variable in sfbr jump find_dsa_next, if not STATE_DISCONNECTED // wrong state move ssid & 7 to sfbr // get target ID move memory 1, targ, find_dsa_smc1 // forge target comparison instructionfind_dsa_smc1: jump find_dsa_next, if not 255 // jump if not matched move memory 1, lun, find_dsa_smc2 // forge lun comparison instruction move scratchb0 to sfbr // recover IDENTIFY messagefind_dsa_smc2: jump reload_sync, if 255 and mask ~7 // off we jolly well gofind_dsa_next: move memory 4, next, dsa // find next jump find_dsa_loop// id_out terminated early// most likely the message wasn't recognised// clear ATN and accept the message inid_out_mismatch_recover: clear atn jump msg_in_phase, when msg_in int SIR_MSG_REJECT jump to_decisions// Reload synchronous registers after a reconnect. If the transfer is a synchronous read, then// as soon as we clear ACK, the target will switch to data_in and start blasting data into the// fifo. We need to be executing the 'jump when data_in' instruction before the target stops REQing// since it is the REQ which latches the 'when'. The target will do 16 REQs before stopping, so// we have 16 bytes (160uS) plus delays to do this after clearing ACK. Once the jump is executing,// the target will wait, so as much debugging as you like can happen in data_in_phase, just don't// stick any delays between 'clear ack' and 'jump data_in_phase, when data_in'.reload_sync: call load_sync clear ackto_decisions: jump data_in_phase, when data_in jump cmd_phase, if cmd jump data_out_phase, if data_out jump status_phase, if status jump msg_in_phase, if msg_in int error_unexpected_phasepost_data_to_decisions: jump status_phase, when status jump msg_in_phase, if msg_in int error_unexpected_phase //// MULTI_TARGET//// following must mirror top of dsa structure// the first section is loaded and saved, the// second section loaded onlydsa_copy:state: defw 0 // a0 is state, a1 result, a2 dma block countdmaaddr: defw 0 // dma address for block movesdsa_save_end:targ: defw 0 // lsb is targetlun: defw 0 // lsb is lunsync: defw 0 // lsb is scntl3, sxfernext: defw 0dsa_load_end:dsa_load_len = dsa_load_end - dsa_copydsa_save_len = dsa_save_end - dsa_copyload_state: // load state from DSA into dsa_copy// move 9 to ctest0 move memory 4, dsa, load_state_smc0 + 4load_state_smc0: move memory dsa_load_len, 0, dsa_copy// move 20 to ctest0 returnsave_state: move memory 4, dsa, save_state_smc0 + 8save_state_smc0: move memory dsa_save_len, dsa_copy, 0 returnsigp_set:// int SIR_NOTIFY_SIGP move ctest2 to sfbr // clear SIGPissue_check:// int SIR_NOTIFY_ISSUE_CHECK// move 1 to ctest0 move memory 4, dsa_head, dsaissue_check_loop:// move 2 to ctest0 move dsa0 to sfbr jump issue_check_1, if not 0 move dsa1 to sfbr jump issue_check_1, if not 0 move dsa2 to sfbr jump issue_check_1, if not 0 move dsa3 to sfbr jump wait_for_reselection, if 0 // nothing to doissue_check_1:// move 3 to ctest0 call load_state move memory 4, state, scratcha // get dsastate in scratcha move scratcha0 to sfbr // and state variable in sfbr jump start, if STATE_ISSUE // right stateissue_check_next:// move 4 to ctest0 move memory 4, next, dsa // find next jump issue_check_loopload_sync: move memory 4, sync, scratcha // load the sync stuff move scratcha0 to sfbr // assuming load_state has been called move sfbr to scntl3 move scratcha1 to sfbr move sfbr to sxfer// int SIR_NOTIFY_LOAD_SYNC return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -