示例#1
0
文件: esp.c 项目: pleed/pyqemu
static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
{
    ESPState *s = opaque;
    uint32_t saddr;

    saddr = addr >> s->it_shift;
    DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr],
            val);
    switch (saddr) {
    case ESP_TCLO:
    case ESP_TCMID:
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
        break;
    case ESP_FIFO:
        if (s->do_cmd) {
            s->cmdbuf[s->cmdlen++] = val & 0xff;
        } else if (s->ti_size == TI_BUFSZ - 1) {
            ESP_ERROR("fifo overrun\n");
        } else {
            s->ti_size++;
            s->ti_buf[s->ti_wptr++] = val & 0xff;
        }
        break;
    case ESP_CMD:
        s->rregs[saddr] = val;
        if (val & CMD_DMA) {
            s->dma = 1;
            /* Reload DMA counter.  */
            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
        } else {
            s->dma = 0;
        }
        switch(val & CMD_CMD) {
        case CMD_NOP:
            DPRINTF("NOP (%2.2x)\n", val);
            break;
        case CMD_FLUSH:
            DPRINTF("Flush FIFO (%2.2x)\n", val);
            //s->ti_size = 0;
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSEQ] = 0;
            s->rregs[ESP_RFLAGS] = 0;
            break;
        case CMD_RESET:
            DPRINTF("Chip reset (%2.2x)\n", val);
            esp_soft_reset(&s->busdev.qdev);
            break;
        case CMD_BUSRESET:
            DPRINTF("Bus reset (%2.2x)\n", val);
            s->rregs[ESP_RINTR] = INTR_RST;
            if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
                esp_raise_irq(s);
            }
            break;
        case CMD_TI:
            handle_ti(s);
            break;
        case CMD_ICCS:
            DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
            write_response(s);
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSTAT] |= STAT_MI;
            break;
        case CMD_MSGACC:
            DPRINTF("Message Accepted (%2.2x)\n", val);
            s->rregs[ESP_RINTR] = INTR_DC;
            s->rregs[ESP_RSEQ] = 0;
            s->rregs[ESP_RFLAGS] = 0;
            esp_raise_irq(s);
            break;
        case CMD_PAD:
            DPRINTF("Transfer padding (%2.2x)\n", val);
            s->rregs[ESP_RSTAT] = STAT_TC;
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSEQ] = 0;
            break;
        case CMD_SATN:
            DPRINTF("Set ATN (%2.2x)\n", val);
            break;
        case CMD_SEL:
            DPRINTF("Select without ATN (%2.2x)\n", val);
            handle_s_without_atn(s);
            break;
        case CMD_SELATN:
            DPRINTF("Select with ATN (%2.2x)\n", val);
            handle_satn(s);
            break;
        case CMD_SELATNS:
            DPRINTF("Select with ATN & stop (%2.2x)\n", val);
            handle_satn_stop(s);
            break;
        case CMD_ENSEL:
            DPRINTF("Enable selection (%2.2x)\n", val);
            s->rregs[ESP_RINTR] = 0;
            break;
        default:
            ESP_ERROR("Unhandled ESP command (%2.2x)\n", val);
            break;
        }
        break;
    case ESP_WBUSID ... ESP_WSYNO:
        break;
    case ESP_CFG1:
        s->rregs[saddr] = val;
        break;
    case ESP_WCCF ... ESP_WTEST:
        break;
    case ESP_CFG2 ... ESP_RES4:
        s->rregs[saddr] = val;
        break;
    default:
        ESP_ERROR("invalid write of 0x%02x at [0x%x]\n", val, saddr);
        return;
    }
    s->wregs[saddr] = val;
}
示例#2
0
文件: esp.c 项目: Acidburn0zzz/qemu
void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
{
    trace_esp_mem_writeb(saddr, s->wregs[saddr], val);
    switch (saddr) {
    case ESP_TCLO:
    case ESP_TCMID:
    case ESP_TCHI:
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
        break;
    case ESP_FIFO:
        if (s->do_cmd) {
            s->cmdbuf[s->cmdlen++] = val & 0xff;
        } else if (s->ti_size == TI_BUFSZ - 1) {
            trace_esp_error_fifo_overrun();
        } else {
            s->ti_size++;
            s->ti_buf[s->ti_wptr++] = val & 0xff;
        }
        break;
    case ESP_CMD:
        s->rregs[saddr] = val;
        if (val & CMD_DMA) {
            s->dma = 1;
            /* Reload DMA counter.  */
            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
            s->rregs[ESP_TCHI] = s->wregs[ESP_TCHI];
        } else {
            s->dma = 0;
        }
        switch(val & CMD_CMD) {
        case CMD_NOP:
            trace_esp_mem_writeb_cmd_nop(val);
            break;
        case CMD_FLUSH:
            trace_esp_mem_writeb_cmd_flush(val);
            //s->ti_size = 0;
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSEQ] = 0;
            s->rregs[ESP_RFLAGS] = 0;
            break;
        case CMD_RESET:
            trace_esp_mem_writeb_cmd_reset(val);
            esp_soft_reset(s);
            break;
        case CMD_BUSRESET:
            trace_esp_mem_writeb_cmd_bus_reset(val);
            s->rregs[ESP_RINTR] = INTR_RST;
            if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
                esp_raise_irq(s);
            }
            break;
        case CMD_TI:
            handle_ti(s);
            break;
        case CMD_ICCS:
            trace_esp_mem_writeb_cmd_iccs(val);
            write_response(s);
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSTAT] |= STAT_MI;
            break;
        case CMD_MSGACC:
            trace_esp_mem_writeb_cmd_msgacc(val);
            s->rregs[ESP_RINTR] = INTR_DC;
            s->rregs[ESP_RSEQ] = 0;
            s->rregs[ESP_RFLAGS] = 0;
            esp_raise_irq(s);
            break;
        case CMD_PAD:
            trace_esp_mem_writeb_cmd_pad(val);
            s->rregs[ESP_RSTAT] = STAT_TC;
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSEQ] = 0;
            break;
        case CMD_SATN:
            trace_esp_mem_writeb_cmd_satn(val);
            break;
        case CMD_RSTATN:
            trace_esp_mem_writeb_cmd_rstatn(val);
            break;
        case CMD_SEL:
            trace_esp_mem_writeb_cmd_sel(val);
            handle_s_without_atn(s);
            break;
        case CMD_SELATN:
            trace_esp_mem_writeb_cmd_selatn(val);
            handle_satn(s);
            break;
        case CMD_SELATNS:
            trace_esp_mem_writeb_cmd_selatns(val);
            handle_satn_stop(s);
            break;
        case CMD_ENSEL:
            trace_esp_mem_writeb_cmd_ensel(val);
            s->rregs[ESP_RINTR] = 0;
            break;
        case CMD_DISSEL:
            trace_esp_mem_writeb_cmd_dissel(val);
            s->rregs[ESP_RINTR] = 0;
            esp_raise_irq(s);
            break;
        default:
            trace_esp_error_unhandled_command(val);
            break;
        }
        break;
    case ESP_WBUSID ... ESP_WSYNO:
        break;
    case ESP_CFG1:
    case ESP_CFG2: case ESP_CFG3:
    case ESP_RES3: case ESP_RES4:
        s->rregs[saddr] = val;
        break;
    case ESP_WCCF ... ESP_WTEST:
        break;
    default:
        trace_esp_error_invalid_write(val, saddr);
        return;
    }
    s->wregs[saddr] = val;
}
示例#3
0
/**
 * A thread that handles a client connection.
 */
void*
handle_client_thread( void* arg )
{
    const char* FNAME = __FUNCTION__;
    const SocketInfo_APtr pSocketInfo( (SocketInfo* ) arg );
    hoxResult result;

    hoxLog(LOG_INFO, "%s: ENTER. Client from = [%s].", FNAME, 
        inet_ntoa( pSocketInfo->iaFrom ));

    const int fd = pSocketInfo->nSocket;

    /* Set the socket's timeout on reading INPUT. */ 
    const int timeout = (365 * 24 * 3600 );  // forever =  1 year
    if ( hoxRC_OK != hoxSocketAPI::set_read_timeout( fd, timeout ) )
    {
        hoxLog(LOG_SYS_WARN, "%s: Fail to set socket's read timeout.", FNAME);
        // NOTE: *** Still allow to continue.
    }

    for (;;)
    {
        hoxRequest_SPtr  pRequest;
        hoxResponse_SPtr pResponse;

        /* Read the incoming request. */

        result = ::read_request( fd,
                                 &(pSocketInfo->iaFrom),
                                 pRequest );
        if ( result != hoxRC_OK )
        {
            if ( result != hoxRC_CLOSED ) // Not 'connection closed'?
            {
                hoxLog(LOG_INFO, "%s: Cannot read request.", FNAME);
            }
            break;
        }

        //hoxLog(LOG_DEBUG, "%s: Received [%s]", FNAME, pRequest->toString().c_str() );

        /* Handle the request. */

        result = ::handle_request( fd,
                                   pRequest,
                                   pResponse );
        if ( result != hoxRC_OK )
        {
            hoxLog(LOG_INFO, "%s: Failed to handle request.", FNAME);
            // TODO: Still allow to continue...
        }

        /* Write a response, if any. */

        if ( pResponse.get() != NULL )
        {
            result = write_response( fd, 
                                     pResponse );
            if ( result != hoxRC_OK )
            {
                hoxLog(LOG_WARN, "%s: Failed to write response", FNAME);
                break;
            }
        }

    } /* for(...) */
    
    /* Close connection. */
    close( fd );

    hoxLog(LOG_INFO, "%s: END.", FNAME);
    return NULL;
}
示例#4
0
void run_sqlite() {
	sqlite3 *db;
	char *zErrMsg = 0;
	int rc;
	td_t t1, t2;
	long evt1, evt2;
	unsigned int ret1, ret2;

	int a = 0, b = 0, c = 0;
	c = treadp(cos_spd_id(), 0, &a, &b);

	printc("%d %d %d\n", a, b, c);

	evt1 = evt_split(cos_spd_id(), 0, 0);
	evt2 = evt_split(cos_spd_id(), 0, 0);
	assert(evt1 > 0 && evt2 > 0);

	/* Open database */
	rc = sqlite3_open(":memory:", &db);
	if (rc) {
		printc("SQLITE: Can't open database: %s\n", sqlite3_errmsg(db));
		return;
	} else {
		printc("SQLITE: Opened database successfully\n");
	}
	
	/* Create Table */
	sql = "CREATE TABLE PEOPLE("  \
			"ID INT PRIMARY KEY     NOT NULL," \
			"NAME           TEXT    NOT NULL," \
			"AGE            INT     NOT NULL," \
			"ADDRESS        CHAR(50));";
	rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
	if( rc != SQLITE_OK ){
		printc("SQLITE: SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		printc("SQLITE: Table created successfully\n");
	}

	/*Insert Table Data*/
	printc("SQLITE: Insert 3 rows into the table (Joel, Kevin, Mike)\n");
	sql = "INSERT INTO PEOPLE (ID,NAME,AGE,ADDRESS) "	\
         "VALUES (1, 'Joel', 21, 'Washington DC');"	\
         "INSERT INTO PEOPLE (ID,NAME,AGE,ADDRESS) "	\
         "VALUES (2, 'Kevin', 30, 'Rio');"	\
         "INSERT INTO PEOPLE (ID,NAME,AGE,ADDRESS)"	\
         "VALUES (3, 'Mike', 23, 'New York');";
    rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
	if( rc != SQLITE_OK ){
		printc("SQLITE: SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		printc("SQLITE: Data inserted successfully\n");
	}

	/*Read Query*/
	rc = read_query();
	if (rc > 0) {
		printc("SQLITE: Failed Reading Query Torrent\n");
		return;
	}
	printc("%s\n", sql);

	rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
	if( rc != SQLITE_OK ){
		printc("SQLITE: SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		printc("SQLITE: Data Queried\n");	
	}

	write_response();
	if (rc > 0) {
		printc("SQLITE: Error Writing to Response Torrent\n");
		return;
	}

	sqlite3_close(db);
	return;
}
示例#5
0
void esp_reg_write(void *opaque, uint32_t saddr, uint64_t val)
{
	ESPState *s = (ESPState*)opaque;

	switch (saddr) {
    case ESP_TCLO:
    case ESP_TCMID:
    case ESP_TCHI:
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
        break;
    case ESP_FIFO:
        if (s->do_cmd) {
            s->cmdbuf[s->cmdlen++] = val & 0xff;
        } else if (s->ti_size == TI_BUFSZ - 1) {
            ;
        } else {
            s->ti_size++;
            s->ti_buf[s->ti_wptr++] = val & 0xff;
        }
        break;
    case ESP_CMD:
        s->rregs[saddr] = val;
        if (val & CMD_DMA) {
            s->dma = 1;
            /* Reload DMA counter.  */
            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
            s->rregs[ESP_TCHI] = s->wregs[ESP_TCHI];
        } else {
            s->dma = 0;
        }
        switch(val & CMD_CMD) {
        case CMD_NOP:
            break;
        case CMD_FLUSH:
            //s->ti_size = 0;
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSEQ] = 0;
            s->rregs[ESP_RFLAGS] = 0;
            break;
        case CMD_RESET:
            esp_soft_reset(s);
			// E-Matrix 530 detects existence of SCSI chip by
			// writing CMD_RESET and then immediately checking
			// if it reads back.
			s->rregs[saddr] = CMD_RESET;
            break;
        case CMD_BUSRESET:
            s->rregs[ESP_RINTR] = INTR_RST;
            if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
                esp_raise_irq(s);
            }
            break;
        case CMD_TI:
            handle_ti(s);
            break;
        case CMD_ICCS:
            write_response(s);
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSTAT] |= STAT_MI;
            break;
        case CMD_MSGACC:
            s->rregs[ESP_RINTR] = INTR_DC;
            s->rregs[ESP_RSEQ] = 0;
            s->rregs[ESP_RFLAGS] = 0;
			// Masoboshi driver expects phase=0!
			s->rregs[ESP_RSTAT] &= ~7;
            esp_raise_irq(s);
            break;
        case CMD_PAD:
            s->rregs[ESP_RSTAT] = STAT_TC;
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSEQ] = 0;
            break;
        case CMD_SATN:
            break;
        case CMD_RSTATN:
            break;
        case CMD_SEL:
            handle_s_without_atn(s);
            break;
        case CMD_SELATN:
            handle_satn(s);
            break;
        case CMD_SELATNS:
            handle_satn_stop(s);
            break;
        case CMD_ENSEL:
            s->rregs[ESP_RINTR] = 0;
            break;
        case CMD_DISSEL:
			// Masoboshi driver expects Function Complete.
            s->rregs[ESP_RINTR] = INTR_FC;
            esp_raise_irq(s);
            break;
        default:
            break;
        }
        break;
	case ESP_WBUSID:
	case ESP_WSEL:
	case ESP_WSYNTP:
	case ESP_WSYNO:
        break;
    case ESP_CFG1:
    case ESP_CFG2: case ESP_CFG3:
    case ESP_RES3: case ESP_RES4:
        s->rregs[saddr] = val;
        break;
	case ESP_WCCF:
	case ESP_WTEST:
        break;
    default:
		write_log("write unknown 53c94 register %02x\n", saddr);
		//activate_debugger();
        return;
    }
    s->wregs[saddr] = val;
}
示例#6
0
void errno_response() {
  int e = errno;
  write_response("errno", num_buf(e));
}
示例#7
0
int serve(char *path) {

    char absolute_path[MAX_PATH_LENGTH];

    ipaddr_t saddr;

    char request_buffer[REQUEST_BUFFER_SIZE];
    int request_buffer_size = 0;

    http_method method;
    char url[URL_LENGTH];
    char protocol[PROTOCOL_LENGTH];

    response_buffer_size = 0;
    alarm_went_off = 0;

    /* open new socket, because previous connection might not be closed */
    if (tcp_socket() != 0) {
        return 0;
    }

    /*
      If we are superuser, we can chroot for safety.
      This has to be done after tcp_socket, because
      it needs access to the ethernet device.
      Note that this will be done again for each
      connection, but that doesn't do any harm.
    */
    if (geteuid() == 0) {
        /* chroot doesn't accept relative paths */
        if (!make_absolute_path(path, absolute_path, MAX_PATH_LENGTH)
            || (chroot(absolute_path) < 0)
            || (chdir("/") < 0)) {
            return 0;
        }
    }

    if (tcp_listen(LISTEN_PORT, &saddr) < 0) {
        return 0;
    }

    request_buffer_size = get_request(request_buffer, REQUEST_BUFFER_SIZE);

    if (request_buffer_size < 0) {
        tcp_close();
        return 1;
    }

    if (parse_request(request_buffer, request_buffer_size,
                      &method,
                      url, URL_LENGTH,
                      protocol, PROTOCOL_LENGTH)) {
        if (!(write_response(method, url, protocol)
              && send_buffer())) {
            /*
              Don't call tcp_close in case of error,
              because the client may think all data
              was sent correctly because of that.
            */
            return 1;
        }
    } else {
        if (!(write_error(STATUS_BAD_REQUEST)
              && send_buffer())) {
            /*
              Don't call tcp_close in case of error,
              because the client may think all data
              was sent correctly because of that.
            */
            return 1;
        }
    }

    /* properly close connection */
    if (tcp_close() != 0) {
        return 0;
    }

    signal(SIGALRM, alarm_handler);
    alarm(TIME_OUT);
    while (tcp_read(request_buffer, REQUEST_BUFFER_SIZE) > 0) {}
    alarm(0);

    return 1;

}
void server_connection::write_stock_response(status const& status, std::string const& server, completion_handler&& handler)
{
    write_response(response::make_stock_response(status, server), std::forward<completion_handler>(handler));
}
示例#9
0
文件: uws_http.c 项目: codesaler/uws
void send_error_response(pConnInfo conn_info) {/*{{{*/
    int status_code = conn_info->status_code;
    bool with_page;
    int return_page_status[4] = {404, 502, 500, 403};
    if(in_int_array(return_page_status, status_code, 4) != -1) {
        with_page = true;
    } else {
        with_page = false;
    }
    char** error_pages = conn_info->running_server->error_page;
    int i;
    char *error_path = NULL;
    char *error_file_path;
    conn_info->status_code = status_code;
    while(*error_pages != NULL) {
        for(i = 0; i < strlen(*error_pages); i++) {
            if((*error_pages)[i] == '=') {
                (*error_pages)[i] = '\0';
                if(atoi(*error_pages) == status_code) {
                    error_path = uws_strdup(*error_pages + i + 1);
                    (*error_pages)[i] = '=';
                    break;
                }
                (*error_pages)[i] = '=';
            }
        }
        if(error_path != NULL) break;
        error_pages++;
    }
    int content_len;
    char *content;
    if(with_page) {
        error_file_path  = uws_strdup("/dev/null"); //just for test
        if(error_path != NULL) {
            char *tmp_path = strlcat(conn_info->running_server->root, error_path);
            if(access(tmp_path, F_OK) == 0) {
                uws_free(error_file_path);
                error_file_path = tmp_path;
                uws_free(error_path);
            } else {
                uws_free(tmp_path);
            }
        }
        FILE* file = fopen(error_file_path, "r");
        fseek(file, 0, SEEK_END);
        content_len = ftell(file);
        rewind(file);
        content = (char*) uws_malloc (content_len * sizeof(char));

        size_t read_size = fread(content, sizeof(char), content_len, file);
        fclose(file);
    } else {
        content_len = 0;
        content = uws_strdup("");
    }

    //go here
    char *time_string = get_time_string(NULL);

    conn_info->response_header->http_ver = "HTTP/1.1";
    conn_info->response_header->status_code = status_code;
    conn_info->response_header->status = get_by_code(status_code);
    add_header_param("Cache-Control", "private", conn_info->response_header);
    add_header_param("Connection", "Keep-Alive", conn_info->response_header);
    add_header_param("Server", UWS_SERVER, conn_info->response_header);
    add_header_param("Date", time_string, conn_info->response_header);
    add_header_param("Content-Type", "text/html", conn_info->response_header);


    if(with_page) {
        char *content_len_str = itoa(content_len);
        add_header_param("Content-Length", content_len_str, conn_info->response_header);
        uws_free(content_len_str);
    }


    struct response header_body;

    header_body.header = conn_info->response_header;
    header_body.content = content;
    header_body.content_len = content_len;

    uws_free(time_string);
    write_response(conn_info, &header_body);
    free_header_params(header_body.header);
    //uws_free(header_body.header); don't free this!!
    uws_free(header_body.content);
    //longjmp(conn_info->error_jmp_buf, 1);
}/*}}}*/
示例#10
0
文件: esp.c 项目: ft-/ox820-qemu
static void esp_mem_write(void *opaque, target_phys_addr_t addr,
                          uint64_t val, unsigned size)
{
    ESPState *s = opaque;
    uint32_t saddr;

    saddr = addr >> s->it_shift;
    trace_esp_mem_writeb(saddr, s->wregs[saddr], val);
    switch (saddr) {
    case ESP_TCLO:
    case ESP_TCMID:
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
        break;
    case ESP_FIFO:
        if (s->do_cmd) {
            s->cmdbuf[s->cmdlen++] = val & 0xff;
        } else if (s->ti_size == TI_BUFSZ - 1) {
            ESP_ERROR("fifo overrun\n");
        } else {
            s->ti_size++;
            s->ti_buf[s->ti_wptr++] = val & 0xff;
        }
        break;
    case ESP_CMD:
        s->rregs[saddr] = val;
        if (val & CMD_DMA) {
            s->dma = 1;
            /* Reload DMA counter.  */
            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
        } else {
            s->dma = 0;
        }
        switch(val & CMD_CMD) {
        case CMD_NOP:
            trace_esp_mem_writeb_cmd_nop(val);
            break;
        case CMD_FLUSH:
            trace_esp_mem_writeb_cmd_flush(val);
            //s->ti_size = 0;
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSEQ] = 0;
            s->rregs[ESP_RFLAGS] = 0;
            break;
        case CMD_RESET:
            trace_esp_mem_writeb_cmd_reset(val);
            esp_soft_reset(&s->busdev.qdev);
            break;
        case CMD_BUSRESET:
            trace_esp_mem_writeb_cmd_bus_reset(val);
            s->rregs[ESP_RINTR] = INTR_RST;
            if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
                esp_raise_irq(s);
            }
            break;
        case CMD_TI:
            handle_ti(s);
            break;
        case CMD_ICCS:
            trace_esp_mem_writeb_cmd_iccs(val);
            write_response(s);
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSTAT] |= STAT_MI;
            break;
        case CMD_MSGACC:
            trace_esp_mem_writeb_cmd_msgacc(val);
            s->rregs[ESP_RINTR] = INTR_DC;
            s->rregs[ESP_RSEQ] = 0;
            s->rregs[ESP_RFLAGS] = 0;
            esp_raise_irq(s);
            break;
        case CMD_PAD:
            trace_esp_mem_writeb_cmd_pad(val);
            s->rregs[ESP_RSTAT] = STAT_TC;
            s->rregs[ESP_RINTR] = INTR_FC;
            s->rregs[ESP_RSEQ] = 0;
            break;
        case CMD_SATN:
            trace_esp_mem_writeb_cmd_satn(val);
            break;
        case CMD_SEL:
            trace_esp_mem_writeb_cmd_sel(val);
            handle_s_without_atn(s);
            break;
        case CMD_SELATN:
            trace_esp_mem_writeb_cmd_selatn(val);
            handle_satn(s);
            break;
        case CMD_SELATNS:
            trace_esp_mem_writeb_cmd_selatns(val);
            handle_satn_stop(s);
            break;
        case CMD_ENSEL:
            trace_esp_mem_writeb_cmd_ensel(val);
            s->rregs[ESP_RINTR] = 0;
            break;
        default:
            ESP_ERROR("Unhandled ESP command (%2.2x)\n", (unsigned)val);
            break;
        }
        break;
    case ESP_WBUSID ... ESP_WSYNO:
        break;
    case ESP_CFG1:
        s->rregs[saddr] = val;
        break;
    case ESP_WCCF ... ESP_WTEST:
        break;
    case ESP_CFG2 ... ESP_RES4:
        s->rregs[saddr] = val;
        break;
    default:
        ESP_ERROR("invalid write of 0x%02x at [0x%x]\n", (unsigned)val, saddr);
        return;
    }
    s->wregs[saddr] = val;
}