static int mptsas_process_scsi_io_request(MPTSASState *s,

                                          MPIMsgSCSIIORequest *scsi_io,

                                          hwaddr addr)

{

    MPTSASRequest *req;

    MPIMsgSCSIIOReply reply;

    SCSIDevice *sdev;

    int status;



    mptsas_fix_scsi_io_endianness(scsi_io);



    trace_mptsas_process_scsi_io_request(s, scsi_io->Bus, scsi_io->TargetID,

                                         scsi_io->LUN[1], scsi_io->DataLength);



    status = mptsas_scsi_device_find(s, scsi_io->Bus, scsi_io->TargetID,

                                     scsi_io->LUN, &sdev);

    if (status) {

        goto bad;

    }



    req = g_new(MPTSASRequest, 1);

    QTAILQ_INSERT_TAIL(&s->pending, req, next);

    req->scsi_io = *scsi_io;

    req->dev = s;



    status = mptsas_build_sgl(s, req, addr);

    if (status) {

        goto free_bad;

    }



    if (req->qsg.size < scsi_io->DataLength) {

        trace_mptsas_sgl_overflow(s, scsi_io->MsgContext, scsi_io->DataLength,

                                  req->qsg.size);

        status = MPI_IOCSTATUS_INVALID_SGL;

        goto free_bad;

    }



    req->sreq = scsi_req_new(sdev, scsi_io->MsgContext,

                            scsi_io->LUN[1], scsi_io->CDB, req);



    if (req->sreq->cmd.xfer > scsi_io->DataLength) {

        goto overrun;

    }

    switch (scsi_io->Control & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK) {

    case MPI_SCSIIO_CONTROL_NODATATRANSFER:

        if (req->sreq->cmd.mode != SCSI_XFER_NONE) {

            goto overrun;

        }

        break;



    case MPI_SCSIIO_CONTROL_WRITE:

        if (req->sreq->cmd.mode != SCSI_XFER_TO_DEV) {

            goto overrun;

        }

        break;



    case MPI_SCSIIO_CONTROL_READ:

        if (req->sreq->cmd.mode != SCSI_XFER_FROM_DEV) {

            goto overrun;

        }

        break;

    }



    if (scsi_req_enqueue(req->sreq)) {

        scsi_req_continue(req->sreq);

    }

    return 0;



overrun:

    trace_mptsas_scsi_overflow(s, scsi_io->MsgContext, req->sreq->cmd.xfer,

                               scsi_io->DataLength);

    status = MPI_IOCSTATUS_SCSI_DATA_OVERRUN;

free_bad:

    mptsas_free_request(req);

bad:

    memset(&reply, 0, sizeof(reply));

    reply.TargetID          = scsi_io->TargetID;

    reply.Bus               = scsi_io->Bus;

    reply.MsgLength         = sizeof(reply) / 4;

    reply.Function          = scsi_io->Function;

    reply.CDBLength         = scsi_io->CDBLength;

    reply.SenseBufferLength = scsi_io->SenseBufferLength;

    reply.MsgContext        = scsi_io->MsgContext;

    reply.SCSIState         = MPI_SCSI_STATE_NO_SCSI_STATUS;

    reply.IOCStatus         = status;



    mptsas_fix_scsi_io_reply_endianness(&reply);

    mptsas_reply(s, (MPIDefaultReply *)&reply);



    return 0;

}

static int mptsas_process_scsi_io_request(MPTSASState *s,

                                          MPIMsgSCSIIORequest *scsi_io,

                                          hwaddr addr)

{

    MPTSASRequest *req;

    MPIMsgSCSIIOReply reply;

    SCSIDevice *sdev;

    int status;



    mptsas_fix_scsi_io_endianness(scsi_io);



    trace_mptsas_process_scsi_io_request(s, scsi_io->Bus, scsi_io->TargetID,

                                         scsi_io->LUN[1], scsi_io->DataLength);



    status = mptsas_scsi_device_find(s, scsi_io->Bus, scsi_io->TargetID,

                                     scsi_io->LUN, &sdev);

    if (status) {

        goto bad;

    }



    req = g_new(MPTSASRequest, 1);

    QTAILQ_INSERT_TAIL(&s->pending, req, next);

    req->scsi_io = *scsi_io;

    req->dev = s;



    status = mptsas_build_sgl(s, req, addr);

    if (status) {

        goto free_bad;

    }



    if (req->qsg.size < scsi_io->DataLength) {

        trace_mptsas_sgl_overflow(s, scsi_io->MsgContext, scsi_io->DataLength,

                                  req->qsg.size);

        status = MPI_IOCSTATUS_INVALID_SGL;

        goto free_bad;

    }



    req->sreq = scsi_req_new(sdev, scsi_io->MsgContext,

                            scsi_io->LUN[1], scsi_io->CDB, req);



    if (req->sreq->cmd.xfer > scsi_io->DataLength) {

        goto overrun;

    }

    switch (scsi_io->Control & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK) {

    case MPI_SCSIIO_CONTROL_NODATATRANSFER:

        if (req->sreq->cmd.mode != SCSI_XFER_NONE) {

            goto overrun;

        }

        break;



    case MPI_SCSIIO_CONTROL_WRITE:

        if (req->sreq->cmd.mode != SCSI_XFER_TO_DEV) {

            goto overrun;

        }

        break;



    case MPI_SCSIIO_CONTROL_READ:

        if (req->sreq->cmd.mode != SCSI_XFER_FROM_DEV) {

            goto overrun;

        }

        break;

    }



    if (scsi_req_enqueue(req->sreq)) {

        scsi_req_continue(req->sreq);

    }

    return 0;



overrun:

    trace_mptsas_scsi_overflow(s, scsi_io->MsgContext, req->sreq->cmd.xfer,

                               scsi_io->DataLength);

    status = MPI_IOCSTATUS_SCSI_DATA_OVERRUN;

free_bad:

    mptsas_free_request(req);

bad:

    memset(&reply, 0, sizeof(reply));

    reply.TargetID          = scsi_io->TargetID;

    reply.Bus               = scsi_io->Bus;

    reply.MsgLength         = sizeof(reply) / 4;

    reply.Function          = scsi_io->Function;

    reply.CDBLength         = scsi_io->CDBLength;

    reply.SenseBufferLength = scsi_io->SenseBufferLength;

    reply.MsgContext        = scsi_io->MsgContext;

    reply.SCSIState         = MPI_SCSI_STATE_NO_SCSI_STATUS;

    reply.IOCStatus         = status;



    mptsas_fix_scsi_io_reply_endianness(&reply);

    mptsas_reply(s, (MPIDefaultReply *)&reply);



    return 0;

}

static int FUNC_0(MPTSASState *VAR_0,

                                          MPIMsgSCSIIORequest *VAR_1,

                                          hwaddr VAR_2)

{

    MPTSASRequest *req;

    MPIMsgSCSIIOReply reply;

    SCSIDevice *sdev;

    int VAR_3;



    mptsas_fix_scsi_io_endianness(VAR_1);



    trace_mptsas_process_scsi_io_request(VAR_0, VAR_1->Bus, VAR_1->TargetID,

                                         VAR_1->LUN[1], VAR_1->DataLength);



    VAR_3 = mptsas_scsi_device_find(VAR_0, VAR_1->Bus, VAR_1->TargetID,

                                     VAR_1->LUN, &sdev);

    if (VAR_3) {

        goto bad;

    }



    req = g_new(MPTSASRequest, 1);

    QTAILQ_INSERT_TAIL(&VAR_0->pending, req, next);

    req->VAR_1 = *VAR_1;

    req->dev = VAR_0;



    VAR_3 = mptsas_build_sgl(VAR_0, req, VAR_2);

    if (VAR_3) {

        goto free_bad;

    }



    if (req->qsg.size < VAR_1->DataLength) {

        trace_mptsas_sgl_overflow(VAR_0, VAR_1->MsgContext, VAR_1->DataLength,

                                  req->qsg.size);

        VAR_3 = MPI_IOCSTATUS_INVALID_SGL;

        goto free_bad;

    }



    req->sreq = scsi_req_new(sdev, VAR_1->MsgContext,

                            VAR_1->LUN[1], VAR_1->CDB, req);



    if (req->sreq->cmd.xfer > VAR_1->DataLength) {

        goto overrun;

    }

    switch (VAR_1->Control & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK) {

    case MPI_SCSIIO_CONTROL_NODATATRANSFER:

        if (req->sreq->cmd.mode != SCSI_XFER_NONE) {

            goto overrun;

        }

        break;



    case MPI_SCSIIO_CONTROL_WRITE:

        if (req->sreq->cmd.mode != SCSI_XFER_TO_DEV) {

            goto overrun;

        }

        break;



    case MPI_SCSIIO_CONTROL_READ:

        if (req->sreq->cmd.mode != SCSI_XFER_FROM_DEV) {

            goto overrun;

        }

        break;

    }



    if (scsi_req_enqueue(req->sreq)) {

        scsi_req_continue(req->sreq);

    }

    return 0;



overrun:

    trace_mptsas_scsi_overflow(VAR_0, VAR_1->MsgContext, req->sreq->cmd.xfer,

                               VAR_1->DataLength);

    VAR_3 = MPI_IOCSTATUS_SCSI_DATA_OVERRUN;

free_bad:

    mptsas_free_request(req);

bad:

    memset(&reply, 0, sizeof(reply));

    reply.TargetID          = VAR_1->TargetID;

    reply.Bus               = VAR_1->Bus;

    reply.MsgLength         = sizeof(reply) / 4;

    reply.Function          = VAR_1->Function;

    reply.CDBLength         = VAR_1->CDBLength;

    reply.SenseBufferLength = VAR_1->SenseBufferLength;

    reply.MsgContext        = VAR_1->MsgContext;

    reply.SCSIState         = MPI_SCSI_STATE_NO_SCSI_STATUS;

    reply.IOCStatus         = VAR_3;



    mptsas_fix_scsi_io_reply_endianness(&reply);

    mptsas_reply(VAR_0, (MPIDefaultReply *)&reply);



    return 0;

}

static int FUNC_0(MPTSASState *VAR_0,
MPIMsgSCSIIORequest *VAR_1,
hwaddr VAR_2)
{ MPTSASRequest *req; MPIMsgSCSIIOReply reply; SCSIDevice *sdev; int VAR_3; mptsas_fix_scsi_io_endianness(VAR_1); trace_mptsas_process_scsi_io_request(VAR_0, VAR_1->Bus, VAR_1->TargetID,
VAR_1->LUN[1], VAR_1->DataLength); VAR_3 = mptsas_scsi_device_find(VAR_0, VAR_1->Bus, VAR_1->TargetID,
VAR_1->LUN, &sdev); if (VAR_3) { goto bad; } req = g_new(MPTSASRequest, 1); QTAILQ_INSERT_TAIL(&VAR_0->pending, req, next); req->VAR_1 = *VAR_1; req->dev = VAR_0; VAR_3 = mptsas_build_sgl(VAR_0, req, VAR_2); if (VAR_3) { goto free_bad; } if (req->qsg.size < VAR_1->DataLength) { trace_mptsas_sgl_overflow(VAR_0, VAR_1->MsgContext, VAR_1->DataLength,
req->qsg.size); VAR_3 = MPI_IOCSTATUS_INVALID_SGL; goto free_bad; } req->sreq = scsi_req_new(sdev, VAR_1->MsgContext,
VAR_1->LUN[1], VAR_1->CDB, req); if (req->sreq->cmd.xfer > VAR_1->DataLength) { goto overrun; } switch (VAR_1->Control & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK) { case MPI_SCSIIO_CONTROL_NODATATRANSFER:
if (req->sreq->cmd.mode != SCSI_XFER_NONE) { goto overrun; } break; case MPI_SCSIIO_CONTROL_WRITE:
if (req->sreq->cmd.mode != SCSI_XFER_TO_DEV) { goto overrun; } break; case MPI_SCSIIO_CONTROL_READ:
if (req->sreq->cmd.mode != SCSI_XFER_FROM_DEV) { goto overrun; } break; } if (scsi_req_enqueue(req->sreq)) { scsi_req_continue(req->sreq); } return 0; overrun:
trace_mptsas_scsi_overflow(VAR_0, VAR_1->MsgContext, req->sreq->cmd.xfer,
VAR_1->DataLength); VAR_3 = MPI_IOCSTATUS_SCSI_DATA_OVERRUN; free_bad:
mptsas_free_request(req); bad:
memset(&reply, 0, sizeof(reply)); reply.TargetID          = VAR_1->TargetID; reply.Bus               = VAR_1->Bus; reply.MsgLength         = sizeof(reply) / 4; reply.Function          = VAR_1->Function; reply.CDBLength         = VAR_1->CDBLength; reply.SenseBufferLength = VAR_1->SenseBufferLength; reply.MsgContext        = VAR_1->MsgContext; reply.SCSIState         = MPI_SCSI_STATE_NO_SCSI_STATUS; reply.IOCStatus         = VAR_3; mptsas_fix_scsi_io_reply_endianness(&reply); mptsas_reply(VAR_0, (MPIDefaultReply *)&reply); return 0; }