示例#1
0
/** 
 *  Bit shift the data out
 *
 *  \param   data: input data
 *  \return  Received data
 */
uint8_t BbspiClass::transfer(uint8_t data) {
    uint8_t recv_data = 0;

    pioWrite(bb_clk, bb_cpol);
    pioWrite(bb_mosi, 0);

    for (int i = 0; i < 8; i++) {
        recv_data = recv_data << 1;
        if (data > 127)
            pioWrite(bb_mosi, 1);
        else
            pioWrite(bb_mosi, 0);

        pioWrite(bb_clk, !bb_cpol);
        if (bb_cpha == 0)
            recv_data |= pioRead(bb_miso);
        data = data << 1;
        pioWrite(bb_clk, bb_cpol);
        if (bb_cpha == 1)
            recv_data |= pioRead(bb_miso);
    }
    return recv_data;
}
示例#2
0
bool X86AtaDevice::performPioAtapiOperation(const AtapiCommand &cmd, uint16_t *buf, size_t bufSize) const
{
    uint8_t status = 0;

    // Set PIO
    outb(_ioPort + kAtaRegisterFeatureInfo, 0x00);

    // set maximum size for requested data
    outb(_ioPort + kAtaRegisterLbaMid, static_cast<uint8_t>(bufSize & 0xFF));
    outb(_ioPort + kAtaRegisterLbaHigh, static_cast<uint8_t>(bufSize >> 8));

    // send PACKET cmd
    outb(_ioPort + kAtaRegisterCommand, 0xA0);

    // poll
    while (1) {
        status = inb(_ioPort + kAtaRegisterStatus);
        if ((status & kAtaStatusBitError)) { puts("ATAPI early error; unsure"); return false; }
        if (!(status & kAtaStatusBitBusy) && (status & kAtaStatusBitReady)) break;
    }

    // send the ATAPI command packet
    for (int i = 0; i < 6; ++i) {
        outw(_ioPort, cmd.packet().words[i]);
    }

    // poll
    while (1) {
        status = inb(_ioPort + kAtaRegisterStatus);
        if ((status & kAtaStatusBitError)) { puts("ATAPI error; no medium?"); return false; }
        if (!(status & kAtaStatusBitBusy) && (status & kAtaStatusBitReady)) break;
        if ((status & kAtaStatusBitDRQ)) break;
    }

    // check if there's data to read
    if ((status & kAtaStatusBitDRQ)) {
        // get actual size of data. We could optimize our buffer size a bit here, but whatever.
        uint16_t readSizeBytes = inb(_ioPort + kAtaRegisterLbaHigh) << 8;
        readSizeBytes = readSizeBytes | inb(_ioPort + kAtaRegisterLbaMid);
        pioRead(buf, readSizeBytes);
    } else if (bufSize) {
        puts("No data to read but we made a buffer. Really makes you think...");
    }

    return true;
}
示例#3
0
void X86AtaDevice::identify() const
{
    // Set features register. 0 = PIO, 1 = DMA.
    outb(_ioPort + 1, 0);
    outb(_controlPort, 0);

    // select device
    outb(_ioPort + kAtaRegisterDriveSelect, 0xA0 | _slaveBit << 4);
    ioWait();

    switch (type()) {
        case Type::PATAPI:
        case Type::SATAPI:
            // send IDENTIFY PACKET DEVICE
            outb(_ioPort + 0x07, 0xA1); break;
        case Type::PATA:
        case Type::SATA:
            // send IDENTIFY DEVICE
            outb(_ioPort + 0x07, 0xEC); break;
        case Type::Unknown:
            return;
    }
    ioWait();

    // read in status
    waitUntilReady(false);

    // read in device information
    uint16_t identity[256];
    pioRead(identity, 256);

    _descriptor.readIdentity(identity);
    _identified = true;

    if (type() == Type::PATAPI) {
        uint16_t data[4];
        performPioAtapiOperation(AtapiCommand::readCapacityCommand(), data, sizeof(data));
        _descriptor.readAtapiCapacity(data);
    }
}
示例#4
0
int gptReadNext(GPTServer* server, PIODatatype datatype, void** buffer,
                int* nLabels, int** labels)
{
    int number = -1;
    int numberOfLabels = -1;
    int i, r;

    if (!DAT_AVAILABLE(*server))
    {
        server->eof = 1;
        return -1;
    }

    // if last timerange is processed, go to first timerange of next file
    if (server->current_timerange_index == DAT_NTIMERANGES(*server,
            server->current_file_index))
    {
        if (PIODatasetIsValid(server->current_dataset))
            pioCloseDataset(&(server->current_dataset));
        if (PIOFileIsValid(server->current_file))
            pioCloseFile(&(server->current_file));
        server->current_timerange_index = 0;
        server->current_file_index++;
    }

    // if last file is processed, stop
    if (server->current_file_index == DAT_NFILES(*server))
    {
        server->current_file_index = 0;
        server->current_timerange_index = 0;
        server->eof = 1;
        return -1;
    }

    // open next file/dataset if necessary
    if (server->current_timerange_index == 0)
    {
        server->current_file = pioOpenFile(DAT_PATH(*server, server->current_file_index),
                                           PINOCCHIO_READONLY);
        server->current_dataset = pioOpenDataset(PIOMakeObject(server->current_file),
                                  DAT_DATASET(*server));
    }

    // if not filtered, read next data
    if (DAT_FILTERED(*server, server->current_file_index, server->current_timerange_index))
    {
        number = pioRead(&(server->current_dataset),
                         server->current_timerange_index,
                         datatype,
                         buffer);

        // get total number of corresponding labels
        // (as the sum of number of labels for each corresponding timeranges)
        if (nLabels || labels)
        {
            if (LBL_AVAILABLE(*server))
            {
                numberOfLabels = 0;
                for (i=0;
                        i<server->numberOfCorrespondingLabelTimerange[server->current_file_index][server->current_timerange_index];
                        i++)
                {
                    numberOfLabels += LBL_NLABELS(*server,
                                                  server->current_file_index,
                                                  i+server->firstCorrespondingLabelTimerange[server->current_file_index][server->current_timerange_index]);
                }
            }
        }

        if (nLabels)
        {
            if (LBL_AVAILABLE(*server)) *nLabels = numberOfLabels;
            else *nLabels = 0;
        }

        if (labels)
        {
            if (LBL_AVAILABLE(*server))
            {
                if (numberOfLabels > server->current_data_labels_number)
                {
                    server->current_data_labels_number = numberOfLabels;
                    server->current_data_labels = (int*) realloc(server->current_data_labels,
                                                  server->current_data_labels_number*sizeof(int));
                }

                numberOfLabels = 0;
                for (i=0;
                        i<server->numberOfCorrespondingLabelTimerange[server->current_file_index][server->current_timerange_index];
                        i++)
                {
                    for (r=0;
                            r<LBL_NLABELS(*server,
                                          server->current_file_index,
                                          i+server->firstCorrespondingLabelTimerange[server->current_file_index][server->current_timerange_index]);
                            r++)
                    {
                        server->current_data_labels[numberOfLabels] = LBL_LABEL(*server,
                                server->current_file_index,
                                i+server->firstCorrespondingLabelTimerange[server->current_file_index][server->current_timerange_index],
                                r);
                        numberOfLabels++;
                    }
                }

                *labels = server->current_data_labels;
            }
            else *labels = NULL;
        }

        server->current_timerange_index++;
    }
    // otherwise, go to next timerange
    else
    {
        server->current_timerange_index++;
        number = gptReadNext(server, datatype, buffer, nLabels, labels);
    }

    // return number of data
    return number;
}