* leaf driver to use this function to send a request to the remote side (RMC) * get the soft state struct (instance 0) "rmc_comm_request_response")) ==
NULL)
* leaf driver to use this function to send a request to the remote side (RMC) * without waiting for a reply. If flag is RMC_COMM_DREQ_URGENT, the request * message is sent once-off (an eventual pending request is aborted). This * flag must only be used when try to send a request in critical condition * (while the system is shutting down for instance and the CPU signature * has to be sent). Otherwise, the request is stored in a temporary location * and delivered by a thread. * get the soft state struct (instance 0) "rmc_comm_request_response")) ==
NULL)
"reqnowait, ctrl msg not allowed! req type=%x\n",
* Send this request with high priority i.e. abort eventual * Handle the case where we are called during panic * processing. If that occurs, then another thread in * rmc_comm might have been idled by panic() while * holding dp_mutex. As a result, do not unconditionally * send the request only if the protocol data link is up. * it is pointless to send it in the other case. * (save its current status) * send the request message * wait for fifos to drain * clean up the current session * abort an old session (if any) * Get an 'independent' thread (rmc_comm_send_pend_req) * to send this request (since the calling thread does not * want to wait). Copy the request in the drvintf state * structure and signal the thread. * copy the request in a temporary location * (drvinf_state structure) and signal the thread * that a request message has to be delivered * not enough space to hold the request * only one request per time can be processed. * the thread is either busy (RMC_COMM_DREQ_ST_PROCESS) * or terminating (RMC_COMM_DREQ_ST_EXIT) * Function used to send a request and (eventually) wait for a response. * It can be called from a leaf driver (via rmc_comm_request_response) or * from the thread in charge of sending 'no-wait' requests * (rmc_comm_send_pend_req). * drivers cannot send control messages at all. They are meant to * be used at low level only. "reqresp, ctrl msg not allowed! req type=%x\n",
* Handle the case where we are called during panic * processing. If that occurs, then another thread in * rmc_comm might have been idled by panic() while * holding dp_mutex. As a result, do not unconditionally * if the data link set up is suspended, just return. * the only time that this can happen is during firmware download * (see rmc_comm_request_response_bp). Basically, the data link is * down and the timer for setting up the data link is not running. * We now have control of the RMC. * Place a lower limit on the shortest amount of time to be * waited before timing out while communicating with the RMC * set the 'expected reply' buffer: get the buffer already allocated * for the response (if a reply is expected!) * send the request message * send the message and wait for the reply or ACKnowledgment * re-send the message if reply/ACK is not received in the * wait for a reply or an acknowledgement "reqresp send status: flags=%02x req=%x resp=%x tick=%ld\n",
* Check for error condition first * Then, check if it has timeout and if there is any * time left to resend the message. * get the actual length of the msg * a negative value means that the reply message * was too big for the receiver buffer * yes! message has been acknowledged * no more time left. set the error code, * Function used to send a BP (Boot Prom) message and get the reply. * BP protocol is provided only to support firmware download. * This function will look for the following key BP protocol commands: * sessions cannot be started. The reason why is that this command will cause * RMC fw to jump to the boot monitor (BOOTMON_FLASH) and data protocol is not * operational. In this context, RMC fw will only be using the BP protocol. * BP_OBP_RESET: data link setup timer is resumed. This command cause the RMC * to reboot and hence become operational. * get the soft state struct (instance 0) "rmc_comm_request_response_bp")) ==
NULL)
* sanity check: request_bp buffer must always be provided * only BP message can be sent "reqresp_bp, only BP msg are allowed! type=%x\n",
* Now, before sending the message, just check what it is being sent * and take action accordingly. * is it BP_OBP_BOOTINIT or BP_OBP_RESET command? * bring down the protocol data link * restart the data link set up timer. RMC is coming up... * set the reply buffer: get the buffer already allocated * send the BP message and wait for the reply * place a lower limit on the shortest amount of time to be * waited before timing out while communicating with the RMC * get the actual length of the msg * a negative value means that the reply message * was too big for the receiver buffer * BOOTINIT cmd may fail. In this is the case, * the RMC is still operational. Hence, we * try (once) to set up the data link * to register for an asynchronous (via soft interrupt) notification * of a message from the remote side (RMC) * lock is required. If it is not defined, the * interrupt handler routine cannot be registered. * only one interrupt handler can be registered. * To unregister for asynchronous notifications * To send raw data (firmware s-records) down to the RMC. * It is provided only to support firmware download. * get the soft state struct (instance 0) "rmc_comm_request_response_bp")) ==
NULL)
* sanity check: response_bp buffer must always be provided * set the reply buffer: get the buffer already allocated * send raw data (s-record) and wait for the reply (BP message) * place a lower limit on the shortest amount of time to be * waited before timing out while communicating with the RMC * get the actual length of the msg * a negative value means that the reply message * was too big for the receiver buffer * To wait for (any) BP message to be received. * (dp_mutex must be held) "reqresp_bp, send: flags=%02x, clktick left=%ld\n",
* Check for error condition first. * Then, check if it has timeout. * Then, check if the command has been replied. * Wait for the pending_request flag to be cleared and acquire it for our * Note that all send-receive actions to the RMC include a time-out, so * the pending-request must eventually go away - even if the RMC is down. * Hence there is no need to timeout the wait action of this function. * (dp_mutex must be held on entry). * A new message can actually grab the lock before the thread * that has just been signaled. Therefore, we need to double * check to make sure that pending_request is not already set * Potentially this could mean starvation for certain unfortunate * threads that keep getting woken up and putting back to sleep. * But the window of such contention is very small to begin with. * just 'sit and wait' until there are no pending requests * else will be able to send anything. * To wake up one of the threads (if any) waiting for starting a * (dp_mutex must be held) * wake up eventual waiting threads... * thread which delivers pending request message to the rmc. Some leaf drivers * cannot afford to wait for a request to be replied/ACKed. Hence, a request * message is stored temporarily in the state structure and this thread * gets woken up to deliver it. "rmc_comm_send_pend_req");
* Wait for someone to tell me to continue. /* RMC_COMM_DREQ_ST_EXIT implies signal by _detach(). */ /* dis->dreq_mutex is held at this point! */ * deliver the request (and wait...) * start thread to deal with pending requests to be delivered asynchronously * stop the thread (to deliver pending request messages) * Wait for rmc_comm_send_pend_req() to finish * init function - start thread to deal with pending requests (no-wait requests) * fini function - kill thread to deal with pending requests (no-wait requests)