Esempio n. 1
0
int
tws_ioctl(struct cdev *dev, u_long cmd, caddr_t buf, int flags, 
                                                    d_thread_t *proc)
{
    struct tws_softc *sc = (struct tws_softc *)(dev->si_drv1);
    int error;

    TWS_TRACE_DEBUG(sc, "entry", sc, cmd);
    sc->stats.ioctls++;
    switch(cmd) {
        case TWS_IOCTL_FIRMWARE_PASS_THROUGH :
            error = tws_passthru(sc, (void *)buf);
            break;
        case TWS_IOCTL_SCAN_BUS :
            TWS_TRACE_DEBUG(sc, "scan-bus", 0, 0);
            error = tws_bus_scan(sc);
            break;
        default :
            TWS_TRACE_DEBUG(sc, "ioctl-aen", cmd, buf);
            error = tws_ioctl_aen(sc, cmd, (void *)buf);
            break;

    }
    return(error);
}
Esempio n. 2
0
int 
tws_init_ctlr(struct tws_softc *sc)
{
    u_int64_t reg;
    u_int32_t regh, regl;

    TWS_TRACE_DEBUG(sc, "entry", sc, sc->is64bit);
    sc->obfl_q_overrun = false;
    if ( tws_init_connect(sc, tws_queue_depth) )
    {
        TWS_TRACE_DEBUG(sc, "initConnect failed", 0, sc->is64bit);
        return(FAILURE);
        
    }


    while( 1 ) {
        regh = tws_read_reg(sc, TWS_I2O0_IOPOBQPH, 4);
        regl = tws_read_reg(sc, TWS_I2O0_IOPOBQPL, 4);
        reg = (((u_int64_t)regh) << 32) | regl;
        TWS_TRACE_DEBUG(sc, "host outbound cleanup",reg, regl);
        if ( regh == TWS_FIFO_EMPTY32 )
            break;
    } 

    tws_init_obfl_q(sc);
    tws_display_ctlr_info(sc);
    tws_write_reg(sc, TWS_I2O0_HOBDBC, ~0, 4);
    tws_turn_on_interrupts(sc);
    return(SUCCESS);
}
Esempio n. 3
0
static void
tws_drain_reserved_reqs(struct tws_softc *sc)
{
    struct tws_request *r;

    r = &sc->reqs[TWS_REQ_TYPE_AEN_FETCH];
    if ( r->state != TWS_REQ_STATE_FREE ) {
        TWS_TRACE_DEBUG(sc, "reset aen req", 0, 0);
        untimeout(tws_timeout, r, r->thandle);
        tws_unmap_request(sc, r);
        free(r->data, M_TWS);
        r->state = TWS_REQ_STATE_FREE;
        r->error_code = TWS_REQ_RET_RESET;
    } 

    r = &sc->reqs[TWS_REQ_TYPE_PASSTHRU];
    if ( r->state == TWS_REQ_STATE_BUSY ) {
        TWS_TRACE_DEBUG(sc, "reset passthru req", 0, 0);
        r->error_code = TWS_REQ_RET_RESET;
    } 

    r = &sc->reqs[TWS_REQ_TYPE_GETSET_PARAM];
    if ( r->state != TWS_REQ_STATE_FREE ) {
        TWS_TRACE_DEBUG(sc, "reset setparam req", 0, 0);
        untimeout(tws_timeout, r, r->thandle);
        tws_unmap_request(sc, r);
        free(r->data, M_TWS);
        r->state = TWS_REQ_STATE_FREE;
        r->error_code = TWS_REQ_RET_RESET;
    } 
}
Esempio n. 4
0
int
tws_send_generic_cmd(struct tws_softc *sc, u_int8_t opcode)
{
    struct tws_request *req;
    struct tws_cmd_generic *cmd;

    TWS_TRACE_DEBUG(sc, "entry", sc, opcode);
    req = tws_get_request(sc, TWS_REQ_TYPE_INTERNAL_CMD);

    if ( req == NULL ) {
        TWS_TRACE_DEBUG(sc, "no requests", 0, 0);
        return(FAILURE);
    }

    cmd = &(req->cmd_pkt->cmd.pkt_g.generic);
    bzero(cmd, sizeof(struct tws_cmd_generic));
    /* req->cmd_pkt->hdr.header_desc.size_header = 128; */
    req->cb = tws_cmd_complete;

    cmd->sgl_off__opcode = BUILD_RES__OPCODE(0, opcode);
    cmd->size = 2;
    cmd->request_id = req->request_id;
    cmd->host_id__unit = 0;
    cmd->status = 0;
    cmd->flags = 0;
    cmd->count = 0;

    req->error_code = tws_submit_command(sc, req);

    return(SUCCESS);

}
Esempio n. 5
0
static void
tws_drain_busy_queue(struct tws_softc *sc)
{
    struct tws_request *req;
    union ccb          *ccb;
    TWS_TRACE_DEBUG(sc, "entry", 0, 0);

    mtx_lock(&sc->q_lock);
    req = tws_q_remove_tail(sc, TWS_BUSY_Q);
    mtx_unlock(&sc->q_lock);
    while ( req ) {
        TWS_TRACE_DEBUG(sc, "moved to TWS_COMPLETE_Q", 0, req->request_id);
        untimeout(tws_timeout, req, req->ccb_ptr->ccb_h.timeout_ch);

        req->error_code = TWS_REQ_RET_RESET;
        ccb = (union ccb *)(req->ccb_ptr);

        ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
        ccb->ccb_h.status |=  CAM_REQUEUE_REQ;
        ccb->ccb_h.status |=  CAM_SCSI_BUS_RESET;

        tws_unmap_request(req->sc, req);

        mtx_lock(&sc->sim_lock);
        xpt_done(req->ccb_ptr);
        mtx_unlock(&sc->sim_lock);

        mtx_lock(&sc->q_lock);
        tws_q_insert_tail(sc, req, TWS_FREE_Q);
        req = tws_q_remove_tail(sc, TWS_BUSY_Q);
        mtx_unlock(&sc->q_lock);
    } 
}
Esempio n. 6
0
int
tws_ioctl(struct dev_ioctl_args *ap)
{
    cdev_t dev = ap->a_head.a_dev;
    u_long cmd = ap->a_cmd;
    caddr_t buf = ap->a_data;
    struct tws_softc *sc = (struct tws_softc *)(dev->si_drv1);
    int error;

    TWS_TRACE_DEBUG(sc, "entry", sc, cmd);
    sc->stats.ioctls++;
    switch(cmd) {
        case TWS_IOCTL_FIRMWARE_PASS_THROUGH :
            error = tws_passthru(sc, (void *)buf);
            break;
        case TWS_IOCTL_SCAN_BUS :
            TWS_TRACE_DEBUG(sc, "scan-bus", 0, 0);
            lockmgr(&sc->sim_lock, LK_EXCLUSIVE);
            error = tws_bus_scan(sc);
            lockmgr(&sc->sim_lock, LK_RELEASE);
            break;
        default :
            TWS_TRACE_DEBUG(sc, "ioctl-aen", cmd, buf);
            error = tws_ioctl_aen(sc, cmd, (void *)buf);
            break;

    }
    return(error);
}
Esempio n. 7
0
void
tws_init_obfl_q(struct tws_softc *sc)
{
    int i=0;
    u_int64_t paddr;
    u_int32_t paddrh, paddrl, status;

    TWS_TRACE_DEBUG(sc, "entry", 0, sc->obfl_q_overrun);

    while ( i < tws_queue_depth ) {
        if ( !sc->sense_bufs[i].posted ) {
            paddr = sc->sense_bufs[i].hdr_pkt_phy;
            paddrh = (u_int32_t)( paddr>>32);
            paddrl = (u_int32_t) paddr;
            tws_write_reg(sc, TWS_I2O0_HOBQPH, paddrh, 4);
            tws_write_reg(sc, TWS_I2O0_HOBQPL, paddrl, 4);

            status = tws_read_reg(sc, TWS_I2O0_STATUS, 4);
            if ( status & TWS_BIT13 ) {
                TWS_TRACE_DEBUG(sc, "OBFL Overrun", status, TWS_I2O0_STATUS);
                sc->obfl_q_overrun = true;
                break;
            }
            sc->sense_bufs[i].posted = true;
        }
        i++;
    }
Esempio n. 8
0
static void
tws_drain_reserved_reqs(struct tws_softc *sc)
{

    struct tws_request *r;

    r = &sc->reqs[1];
    if ( r->state != TWS_REQ_STATE_FREE ) {
        TWS_TRACE_DEBUG(sc, "drained aen req", 0, 0);
	callout_stop(&r->thandle);
        tws_unmap_request(sc, r);
        kfree(r->data, M_TWS);
        lockmgr(&sc->gen_lock, LK_EXCLUSIVE);
        r->state = TWS_REQ_STATE_FREE;
        lockmgr(&sc->gen_lock, LK_RELEASE);
    }
    r = &sc->reqs[2];
    if ( r->state != TWS_REQ_STATE_FREE ) {
        TWS_TRACE_DEBUG(sc, "drained passthru req", 0, 0);
        r->error_code = TWS_REQ_REQUEUE;
        tws_passthru_complete(r);
    }
    r = &sc->reqs[3];
    if ( r->state != TWS_REQ_STATE_FREE ) {
        TWS_TRACE_DEBUG(sc, "drained set param req", 0, 0);
        tws_getset_param_complete(r);
    }

}
Esempio n. 9
0
static void
tws_drain_busy_queue(struct tws_softc *sc)
{

    struct tws_request *req;
    TWS_TRACE_DEBUG(sc, "entry", 0, 0);

    lockmgr(&sc->q_lock, LK_EXCLUSIVE);
    req = tws_q_remove_tail(sc, TWS_BUSY_Q);
    lockmgr(&sc->q_lock, LK_RELEASE);
    while ( req ) {
	callout_stop(req->ccb_ptr->ccb_h.timeout_ch);
        tws_unmap_request(req->sc, req);

        TWS_TRACE_DEBUG(sc, "drained", 0, req->request_id);

        lockmgr(&sc->sim_lock, LK_EXCLUSIVE);
        req->ccb_ptr->ccb_h.status = CAM_REQUEUE_REQ;
        xpt_done(req->ccb_ptr);
        lockmgr(&sc->sim_lock, LK_RELEASE);

        lockmgr(&sc->q_lock, LK_EXCLUSIVE);
        tws_q_insert_tail(sc, req, TWS_FREE_Q);
        req = tws_q_remove_tail(sc, TWS_BUSY_Q);
        lockmgr(&sc->q_lock, LK_RELEASE);
    }

}
Esempio n. 10
0
static void
tws_err_complete(struct tws_softc *sc, u_int64_t mfa)
{
    struct tws_command_header *hdr;
    struct tws_sense *sen;
    struct tws_request *req;
    u_int16_t req_id;
    u_int32_t reg, status;

    if ( !mfa ) {
        TWS_TRACE_DEBUG(sc, "null mfa", 0, mfa);
        return;
    } else {
        /* lookup the sense */
        sen = tws_find_sense_from_mfa(sc, mfa);
        if ( sen == NULL ) {
            TWS_TRACE_DEBUG(sc, "found null req", 0, mfa);
            return;
        }
        hdr = sen->hdr;
        TWS_TRACE_DEBUG(sc, "sen, hdr", sen, hdr);
        req_id = hdr->header_desc.request_id;
        req = &sc->reqs[req_id];
        TWS_TRACE_DEBUG(sc, "req, id", req, req_id);
        if ( req->error_code != TWS_REQ_RET_SUBMIT_SUCCESS )
            TWS_TRACE_DEBUG(sc, "submit failure?", 0, req->error_code);
    }

    switch (req->type) {
        case TWS_REQ_TYPE_PASSTHRU :
            tws_passthru_err_complete(req, hdr);
            break;
        case TWS_REQ_TYPE_GETSET_PARAM :
            tws_getset_param_complete(req);
            break;
        case TWS_REQ_TYPE_SCSI_IO :
            tws_scsi_err_complete(req, hdr);
            break;
            
    }

    mtx_lock(&sc->io_lock);
    hdr->header_desc.size_header = 128;
    reg = (u_int32_t)( mfa>>32);
    tws_write_reg(sc, TWS_I2O0_HOBQPH, reg, 4);
    reg = (u_int32_t)(mfa);
    tws_write_reg(sc, TWS_I2O0_HOBQPL, reg, 4);

    status = tws_read_reg(sc, TWS_I2O0_STATUS, 4);
    if ( status & TWS_BIT13 ) {
        device_printf(sc->tws_dev,  "OBFL Overrun\n");
        sc->obfl_q_overrun = true;
    }
    mtx_unlock(&sc->io_lock);
}
Esempio n. 11
0
static void
tws_scsi_err_complete(struct tws_request *req, struct tws_command_header *hdr)
{
    u_int8_t *sense_data;
    struct tws_softc *sc = req->sc;
    union ccb *ccb = req->ccb_ptr;

    TWS_TRACE_DEBUG(sc, "sbe, cmd_status", hdr->status_block.error,
                                 req->cmd_pkt->cmd.pkt_a.status);
    if ( hdr->status_block.error == TWS_ERROR_LOGICAL_UNIT_NOT_SUPPORTED ||
         hdr->status_block.error == TWS_ERROR_UNIT_OFFLINE ) {

        if ( ccb->ccb_h.target_lun ) {
            TWS_TRACE_DEBUG(sc, "invalid lun error",0,0);
            ccb->ccb_h.status |= CAM_LUN_INVALID;
        } else {
            TWS_TRACE_DEBUG(sc, "invalid target error",0,0);
            ccb->ccb_h.status |= CAM_TID_INVALID;
        }

    } else {
        TWS_TRACE_DEBUG(sc, "scsi status  error",0,0);
        ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
        if (((ccb->csio.cdb_io.cdb_bytes[0] == 0x1A) &&
              (hdr->status_block.error == TWS_ERROR_NOT_SUPPORTED))) {
            ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
            TWS_TRACE_DEBUG(sc, "page mode not supported",0,0);
        }
    }

    /* if there were no error simply mark complete error */
    if (ccb->ccb_h.status == 0)
        ccb->ccb_h.status = CAM_REQ_CMP_ERR;

    sense_data = (u_int8_t *)&ccb->csio.sense_data;
    if (sense_data) {
        memcpy(sense_data, hdr->sense_data, TWS_SENSE_DATA_LENGTH );
        ccb->csio.sense_len = TWS_SENSE_DATA_LENGTH;
        ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
    }
    ccb->csio.scsi_status = req->cmd_pkt->cmd.pkt_a.status;

    ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
    lockmgr(&sc->sim_lock, LK_EXCLUSIVE);
    xpt_done(ccb);
    lockmgr(&sc->sim_lock, LK_RELEASE);

    callout_stop(req->ccb_ptr->ccb_h.timeout_ch);
    tws_unmap_request(req->sc, req);
    lockmgr(&sc->q_lock, LK_EXCLUSIVE);
    tws_q_remove_request(sc, req, TWS_BUSY_Q);
    tws_q_insert_tail(sc, req, TWS_FREE_Q);
    lockmgr(&sc->q_lock, LK_RELEASE);

}
Esempio n. 12
0
void
tws_fetch_aen(void *arg)
{
    struct tws_softc *sc = (struct tws_softc *)arg;
    int error = 0;

    TWS_TRACE_DEBUG(sc, "entry", 0, 0);

    if ((error = tws_send_scsi_cmd(sc, 0x03 /* REQUEST_SENSE */))) {
        TWS_TRACE_DEBUG(sc, "aen fetch send in progress", 0, 0);
    }
}
Esempio n. 13
0
static void
tws_poll(struct cam_sim *sim)
{
    struct tws_softc *sc = (struct tws_softc *)cam_sim_softc(sim);
    TWS_TRACE_DEBUG(sc, "entry", 0, 0);
    tws_intr((void *) sc);
}
Esempio n. 14
0
int
tws_get_param(struct tws_softc *sc, u_int32_t table_id, u_int32_t param_id,
              u_int32_t param_size, void *data)
{
    struct tws_request *req;
    struct tws_command_packet *cmd_pkt;
    union tws_command_giga *cmd;
    struct tws_getset_param *param;
    u_int16_t reqid;
    u_int64_t mfa;
    int error = SUCCESS;


    req = tws_get_request(sc, TWS_REQ_TYPE_GETSET_PARAM);
    if ( req == NULL ) {
        TWS_TRACE_DEBUG(sc, "null req", 0, 0);
        return(FAILURE);
    }

    req->length = TWS_SECTOR_SIZE;
    req->data = malloc(TWS_SECTOR_SIZE, M_TWS, M_NOWAIT);
    if ( req->data == NULL )
        return(FAILURE);
    bzero(req->data, TWS_SECTOR_SIZE);
    param = (struct tws_getset_param *)req->data;

    req->cb = NULL;
    req->flags = TWS_DIR_IN;
    cmd_pkt = req->cmd_pkt;

    cmd = &cmd_pkt->cmd.pkt_g;
    cmd->param.sgl_off__opcode =
            BUILD_SGL_OFF__OPCODE(2, TWS_FW_CMD_GET_PARAM);
    cmd->param.request_id = (u_int8_t)req->request_id;
    cmd->param.host_id__unit = 0;
    cmd->param.param_count = 1;
    cmd->param.size = 2; /* map routine will add sgls */

    /* Specify which parameter we want to set. */
    param->table_id = (table_id | TWS_9K_PARAM_DESCRIPTOR);
    param->parameter_id = (u_int8_t)(param_id);
    param->parameter_size_bytes = (u_int16_t)param_size;
   
    error = tws_map_request(sc, req);
    if (!error) {
        reqid = tws_poll4_response(sc, &mfa);
        tws_unmap_request(sc, req);

        if ( reqid == TWS_REQ_TYPE_GETSET_PARAM ) {
            memcpy(data, param->data, param_size);
        } else {
            error = FAILURE;
        }
    }
  
    free(req->data, M_TWS);
    req->state = TWS_REQ_STATE_FREE;
    return(error);

}
Esempio n. 15
0
void
tws_intr(void *arg)
{
    struct tws_softc *sc = (struct tws_softc *)arg;
    u_int32_t histat=0, db=0;

    KASSERT(sc, ("null softc"));

    sc->stats.num_intrs++;
    histat = tws_read_reg(sc, TWS_I2O0_HISTAT, 4);
    if ( histat & TWS_BIT2 ) {
        TWS_TRACE_DEBUG(sc, "door bell :)", histat, TWS_I2O0_HISTAT);
        db = tws_read_reg(sc, TWS_I2O0_IOBDB, 4);
        if ( db & TWS_BIT21 ) {
            tws_intr_attn_error(sc);
            return;
        }
        if ( db & TWS_BIT18 ) {
            tws_intr_attn_aen(sc);
        }
    }

    if ( histat & TWS_BIT3 ) {
        tws_intr_resp(sc);
    }
}
Esempio n. 16
0
int
tws_bus_scan(struct tws_softc *sc)
{
    struct cam_path *path;
    union ccb       *ccb;

    TWS_TRACE_DEBUG(sc, "entry", sc, 0);
    KASSERT(sc->sim, ("sim not allocated"));
    KKASSERT(lockstatus(&sc->sim_lock, curthread) != 0);

    ccb = sc->scan_ccb;

    if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->sim),
                  CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
        /* lockmgr(&sc->sim_lock, LK_RELEASE); */
        return(EIO);
    }
    xpt_setup_ccb(&ccb->ccb_h, path, 5);
    ccb->ccb_h.func_code = XPT_SCAN_BUS;
    ccb->ccb_h.cbfcnp = tws_bus_scan_cb;
    ccb->crcn.flags = CAM_FLAG_NONE;
    xpt_action(ccb);

    return(0);
}
Esempio n. 17
0
void
tws_aen_synctime_with_host(struct tws_softc *sc)
{

    int error;
    long int sync_time;

    TWS_TRACE_DEBUG(sc, "entry", sc, 0);

    sync_time = (TWS_LOCAL_TIME - (3 * 86400)) % 604800;
    TWS_TRACE_DEBUG(sc, "sync_time,ts", sync_time, time_second);
    TWS_TRACE_DEBUG(sc, "utc_offset", utc_offset(), 0);
    error = tws_set_param(sc, TWS_PARAM_TIME_TABLE, TWS_PARAM_TIME_SCHED_TIME,
                           4, &sync_time);
    if ( error )
        TWS_TRACE_DEBUG(sc, "set param failed", sync_time, error);
}
Esempio n. 18
0
static void
tws_passthru_err_complete(struct tws_request *req, 
                                          struct tws_command_header *hdr)
{ 
    TWS_TRACE_DEBUG(req->sc, "entry", hdr, req->request_id);
    req->error_code = hdr->status_block.error;
    memcpy(&(req->cmd_pkt->hdr), hdr, sizeof(struct tws_command_header));
    tws_passthru_complete(req);
}
Esempio n. 19
0
/*
 * Device suspend routine.
 */
static int
tws_suspend(device_t dev)
{
    struct tws_softc *sc = device_get_softc(dev);

    if ( sc )
        TWS_TRACE_DEBUG(sc, "entry", 0, 0);
    return (0);
}
Esempio n. 20
0
int
tws_write(struct cdev *dev, struct uio *uio, int ioflag)
{
    struct tws_softc *sc = dev->si_drv1;

    if ( sc ) 
        TWS_TRACE_DEBUG(sc, "entry", dev, ioflag);
    return (0);
}
Esempio n. 21
0
int
tws_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td)
{
    struct tws_softc *sc = dev->si_drv1;

    if ( sc )
        TWS_TRACE_DEBUG(sc, "entry", dev, fflag);
    return (0);
}
Esempio n. 22
0
int
tws_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td)
{
    struct tws_softc *sc = dev->si_drv1;

    if ( sc ) 
        TWS_TRACE_DEBUG(sc, "entry", dev, oflags);
    return (0);
}
Esempio n. 23
0
void
tws_turn_off_interrupts(struct tws_softc *sc)
{

    TWS_TRACE_DEBUG(sc, "entry", 0, 0);
    
    tws_write_reg(sc, TWS_I2O0_HIMASK, ~0, 4);

}
Esempio n. 24
0
void
tws_turn_on_interrupts(struct tws_softc *sc)
{

    TWS_TRACE_DEBUG(sc, "entry", 0, 0);
    /* turn on responce and db interrupt only */
    tws_write_reg(sc, TWS_I2O0_HIMASK, TWS_BIT0, 4);

}
Esempio n. 25
0
int
tws_write(struct dev_write_args *ap)
{
    cdev_t dev = ap->a_head.a_dev;
    struct tws_softc *sc = dev->si_drv1;

    if ( sc )
        TWS_TRACE_DEBUG(sc, "entry", dev, ioflag);
    return (0);
}
Esempio n. 26
0
void
tws_assert_soft_reset(struct tws_softc *sc)
{
    u_int32_t reg;

    reg = tws_read_reg(sc, TWS_I2O0_HIBDB, 4);
    TWS_TRACE_DEBUG(sc, "in bound door bell read ", reg, TWS_I2O0_HIBDB);
    tws_write_reg(sc, TWS_I2O0_HIBDB, reg | TWS_BIT8, 4);

}
Esempio n. 27
0
void
tws_enable_db_intr(struct tws_softc *sc)
{
    u_int32_t reg;

    TWS_TRACE_DEBUG(sc, "entry", 0, 0);
    reg = tws_read_reg(sc, TWS_I2O0_HIMASK, 4);
    reg = reg & ~TWS_BIT2;
    tws_write_reg(sc, TWS_I2O0_HIMASK, reg, 4);
}
Esempio n. 28
0
void
tws_release_request(struct tws_request *req)
{

    struct tws_softc *sc = req->sc;

    TWS_TRACE_DEBUG(sc, "entry", sc, 0);
    lockmgr(&sc->q_lock, LK_EXCLUSIVE);
    tws_q_insert_tail(sc, req, TWS_FREE_Q);
    lockmgr(&sc->q_lock, LK_RELEASE);
}
Esempio n. 29
0
void
tws_release_request(struct tws_request *req)
{

    struct tws_softc *sc = req->sc;

    TWS_TRACE_DEBUG(sc, "entry", sc, 0);
    mtx_lock(&sc->q_lock);
    tws_q_insert_tail(sc, req, TWS_FREE_Q);
    mtx_unlock(&sc->q_lock);
}
Esempio n. 30
0
u_int16_t
tws_poll4_response(struct tws_softc *sc, u_int64_t *mfa)
{
    u_int16_t req_id;
    time_t endt;

    endt = TWS_LOCAL_TIME + TWS_POLL_TIMEOUT;
    do {
        if(tws_get_response(sc, &req_id, mfa)) {

            if ( req_id == TWS_INVALID_REQID ) {
                TWS_TRACE_DEBUG(sc, "invalid req_id", 0, req_id);
                return(TWS_INVALID_REQID);
            }
            return(req_id);
        }
    } while (TWS_LOCAL_TIME <= endt);
    TWS_TRACE_DEBUG(sc, "poll timeout", 0, 0);
    return(TWS_INVALID_REQID);
}