📄 sd53c8xx.n
字号:
// NCR 53c8xx driver for Plan 9// Nigel Roles (nigel@9fs.org)//// Microcode//// 27/5/02 Fixed problems with transfers >= 256 * 512//// 13/3/01 Fixed microcode to support targets > 7//extern scsi_id_bufextern msg_out_bufextern cmd_bufextern data_bufextern status_bufextern msgin_bufextern dsa_0extern dsa_1extern dsa_headextern ssid_maskSIR_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 = 117SIR_NOTIFY_LOAD_STATE = 118STATE_FREE = 0STATE_ALLOCATED = 1STATE_ISSUE = 2STATE_DISCONNECTED = 3STATE_DONE = 4STATE_END = 5RESULT_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=4096 // idle: 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_in // why is this here?start1:// 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 dmaddrdata_mismatch_recover: 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 2 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 2 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 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 int error_reselected, if STATE_END move ssid & ssid_mask 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 in// called from sd53c8xx.c directlyid_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:// int SIR_NOTIFY_LOAD_STATE jump load_state_okay move dsa0 to sfbr jump load_state_okay, if not 0 move dsa1 to sfbr jump load_state_okay, if not 0 move dsa2 to sfbr jump load_state_okay, if not 0 move dsa3 to sfbr jump load_state_okay, if not 0 // dsa is 0 move memory 4, dsa, dmaaddr move memory 4, dsa, targ move memory 4, dsa, lun move memory 4, dsa, sync move memory 4, dsa, next move memory 4, dsa, scratcha move STATE_END to sfbr move sfbr to scratcha0 move memory 4, scratcha, state returnload_state_okay: // 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: 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 state jump wait_for_reselection, if STATE_END // 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 + -