!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/usb/storage/   drwxr-xr-x
Free 318.32 GB of 458.09 GB (69.49%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     shuttle_usbat.c (25.59 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* Driver for SCM Microsystems USB-ATAPI cable
 *
 * $Id: shuttle_usbat.c,v 1.15 2001/12/08 23:32:48 mdharm Exp $
 *
 * Current development and maintenance by:
 *   (c) 2000, 2001 Robert Baruch (autophile@starband.net)
 *
 * Many originally ATAPI devices were slightly modified to meet the USB
 * market by using some kind of translation from ATAPI to USB on the host,
 * and the peripheral would translate from USB back to ATAPI.
 *
 * SCM Microsystems (www.scmmicro.com) makes a device, sold to OEM's only, 
 * which does the USB-to-ATAPI conversion.  By obtaining the data sheet on
 * their device under nondisclosure agreement, I have been able to write
 * this driver for Linux.
 *
 * The chip used in the device can also be used for EPP and ISA translation
 * as well. This driver is only guaranteed to work with the ATAPI
 * translation.
 *
 * The only peripheral that I know of (as of 27 Mar 2001) that uses this
 * device is the Hewlett-Packard 8200e/8210e/8230e CD-Writer Plus.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "transport.h"
#include "protocol.h"
#include "usb.h"
#include "debug.h"
#include "shuttle_usbat.h"

#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/slab.h>

extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
    u8 request, u8 requesttype, u16 value, u16 index,
    void *data, u16 size);
extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
    unsigned int len, unsigned int *act_len);

#define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) )
#define LSB_of(s) ((s)&0xFF)
#define MSB_of(s) ((s)>>8)

int transferred = 0;

/*
 * Send a control message and wait for the response.
 *
 * us - the pointer to the us_data structure for the device to use
 *
 * request - the URB Setup Packet's first 6 bytes. The first byte always
 *  corresponds to the request type, and the second byte always corresponds
 *  to the request.  The other 4 bytes do not correspond to value and index,
 *  since they are used in a custom way by the SCM protocol.
 *
 * xfer_data - a buffer from which to get, or to which to store, any data
 *  that gets send or received, respectively, with the URB. Even though
 *  it looks like we allocate a buffer in this code for the data, xfer_data
 *  must contain enough allocated space.
 *
 * xfer_len - the number of bytes to send or receive with the URB.
 *
 */

static int usbat_send_control(struct us_data *us,
        int pipe,
        unsigned char request,
        unsigned char requesttype,
        unsigned short value,
        unsigned short index,
        unsigned char *xfer_data,
        unsigned int xfer_len) {

    int result;

    // Send the URB to the device and wait for a response.

    /* Why are request and request type reversed in this call? */

    result = usb_stor_control_msg(us, pipe,
            request, requesttype, value, index,
            xfer_data, xfer_len);


    // Check the return code for the command.

    if (result < 0) {
        /* if the command was aborted, indicate that */
        if (result == -ENOENT)
            return USB_STOR_TRANSPORT_ABORTED;

        /* a stall is a fatal condition from the device */
        if (result == -EPIPE) {
            US_DEBUGP("-- Stall on control pipe. Clearing\n");
            result = usb_clear_halt(us->pusb_dev, pipe);
            US_DEBUGP("-- usb_clear_halt() returns %d\n", result);
            return USB_STOR_TRANSPORT_FAILED;
        }

        /* Uh oh... serious problem here */
        return USB_STOR_TRANSPORT_ERROR;
    }

    return USB_STOR_TRANSPORT_GOOD;
}

static int usbat_raw_bulk(struct us_data *us, 
        int direction,
        unsigned char *data,
        unsigned short len) {

    int result;
    int act_len;
    int pipe;

    if (direction == SCSI_DATA_READ)
        pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
    else
        pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);

    result = usb_stor_bulk_msg(us, data, pipe, len, &act_len);

        /* if we stall, we need to clear it before we go on */
        if (result == -EPIPE) {
                   US_DEBUGP("EPIPE: clearing endpoint halt for"
            " pipe 0x%x, stalled at %d bytes\n",
            pipe, act_len);
                   usb_clear_halt(us->pusb_dev, pipe);
        }

    if (result) {

                /* NAK - that means we've retried a few times already */
                   if (result == -ETIMEDOUT) {
                        US_DEBUGP("usbat_raw_bulk():"
                " device NAKed\n");
                        return US_BULK_TRANSFER_FAILED;
                }

                /* -ENOENT -- we canceled this transfer */
                if (result == -ENOENT) {
                        US_DEBUGP("usbat_raw_bulk():"
                " transfer aborted\n");
                        return US_BULK_TRANSFER_ABORTED;
                }

        if (result == -EPIPE) {
            US_DEBUGP("usbat_raw_bulk():"
                " output pipe stalled\n");
            return US_BULK_TRANSFER_SHORT;
        }

                /* the catch-all case */
                US_DEBUGP("us_transfer_partial(): unknown error\n");
                return US_BULK_TRANSFER_FAILED;
        }

    if (act_len != len) {
        US_DEBUGP("Warning: Transferred only %d bytes\n",
            act_len);
        return US_BULK_TRANSFER_SHORT;
    }

    US_DEBUGP("Transferred %s %d of %d bytes\n", 
        direction==SCSI_DATA_READ ? "in" : "out", act_len, len);

    return US_BULK_TRANSFER_GOOD;
}

/*
 * Note: direction must be set if command_len == 0.
 */

static int usbat_bulk_transport(struct us_data *us,
              unsigned char *command,
              unsigned short command_len,
              int direction,
              unsigned char *data,
              unsigned short len,
              int use_sg) {

    int result = USB_STOR_TRANSPORT_GOOD;
    int transferred = 0;
    int i;
    struct scatterlist *sg;

    if (len==0)
        return USB_STOR_TRANSPORT_GOOD;

    /* transfer the data payload for the command, if there is any */

    if (command_len != 0)
        direction = (command[0]&0x80) ? SCSI_DATA_READ :
            SCSI_DATA_WRITE;

    if (!use_sg)
        result = usbat_raw_bulk(us, direction, data, len);
    else {
        sg = (struct scatterlist *)data;
        for (i=0; i<use_sg && transferred<len; i++) {
            result = usbat_raw_bulk(us, direction,
                sg[i].address, 
                len-transferred > sg[i].length ?
                    sg[i].length : len-transferred);
            if (result!=US_BULK_TRANSFER_GOOD)
                break;
            transferred += sg[i].length;
        }
    }

    return result;
}

int usbat_read(struct us_data *us,
         unsigned char access,
         unsigned char reg, 
         unsigned char *content) {

    int result;

    result = usbat_send_control(us,
        usb_rcvctrlpipe(us->pusb_dev,0),
        access,
        0xC0,
        (u16)reg,
        0,
        content,
        1);

    return result;
}

int usbat_write(struct us_data *us,
         unsigned char access,
         unsigned char reg, 
         unsigned char content) {

    int result;

    result = usbat_send_control(us,
        usb_sndctrlpipe(us->pusb_dev,0),
        access|0x01,
        0x40,
        short_pack(reg, content),
        0,
        NULL,
        0);

    return result;
}

int usbat_set_shuttle_features(struct us_data *us,
         unsigned char external_trigger,
         unsigned char epp_control, 
         unsigned char mask_byte, 
         unsigned char test_pattern, 
         unsigned char subcountH, 
         unsigned char subcountL) {

    int result;
    unsigned char command[8] = {
        0x40, 0x81, epp_control, external_trigger,
        test_pattern, mask_byte, subcountL, subcountH
    };

    result = usbat_send_control(us,
        usb_sndctrlpipe(us->pusb_dev,0),
        0x80,
        0x40,
        0,
        0,
        command,
        8);

    return result;
}

int usbat_read_block(struct us_data *us,
         unsigned char access,
         unsigned char reg, 
         unsigned char *content,
         unsigned short len,
         int use_sg) {

    int result;
    unsigned char command[8] = {
        0xC0, access|0x02, reg, 0x00, 0x00, 0x00, 
        LSB_of(len), MSB_of(len)
    };

    result = usbat_send_control(us,
        usb_sndctrlpipe(us->pusb_dev,0),
        0x80,
        0x40,
        0,
        0,
        command,
        8);

    if (result != USB_STOR_TRANSPORT_GOOD)
        return result;

    result = usbat_bulk_transport(us,
        NULL, 0, SCSI_DATA_READ, content, len, use_sg);

    return result;
}

/*
 * Block, waiting for an ATA device to become not busy or to report
 * an error condition.
 */

int usbat_wait_not_busy(struct us_data *us, int minutes) {

    int i;
    int result;
    unsigned char status;

    /* Synchronizing cache on a CDR could take a heck of a long time,
     * but probably not more than 10 minutes or so. On the other hand,
     * doing a full blank on a CDRW at speed 1 will take about 75
     * minutes!
     */

    for (i=0; i<1200+minutes*60; i++) {

         result = usbat_read(us, USBAT_ATA, 0x17, &status);

        if (result!=USB_STOR_TRANSPORT_GOOD)
            return result;
        if (status&0x01) { // check condition
            result = usbat_read(us, USBAT_ATA, 0x10, &status);
            return USB_STOR_TRANSPORT_FAILED;
        }
        if (status&0x20) // device fault
            return USB_STOR_TRANSPORT_FAILED;

        if ((status&0x80)==0x00) { // not busy
            US_DEBUGP("Waited not busy for %d steps\n", i);
            return USB_STOR_TRANSPORT_GOOD;
        }

        if (i<500)
            wait_ms(10); // 5 seconds
        else if (i<700)
            wait_ms(50); // 10 seconds
        else if (i<1200)
            wait_ms(100); // 50 seconds
        else
            wait_ms(1000); // X minutes
    }

    US_DEBUGP("Waited not busy for %d minutes, timing out.\n",
        minutes);
    return USB_STOR_TRANSPORT_FAILED;
}

int usbat_write_block(struct us_data *us,
         unsigned char access,
         unsigned char reg, 
         unsigned char *content,
         unsigned short len,
         int use_sg,
         int minutes) {

    int result;
    unsigned char command[8] = {
        0x40, access|0x03, reg, 0x00, 0x00, 0x00, 
        LSB_of(len), MSB_of(len)
    };

    result = usbat_send_control(us,
        usb_sndctrlpipe(us->pusb_dev,0),
        0x80,
        0x40,
        0,
        0,
        command,
        8);

    if (result != USB_STOR_TRANSPORT_GOOD)
        return result;

    result = usbat_bulk_transport(us,
        NULL, 0, SCSI_DATA_WRITE, content, len, use_sg);

    if (result != USB_STOR_TRANSPORT_GOOD)
        return result;

    return usbat_wait_not_busy(us, minutes);
}

int usbat_rw_block_test(struct us_data *us,
         unsigned char access,
         unsigned char *registers,
         unsigned char *data_out,
         unsigned short num_registers,
         unsigned char data_reg, 
         unsigned char status_reg, 
         unsigned char timeout, 
         unsigned char qualifier, 
         int direction,
         unsigned char *content,
         unsigned short len,
         int use_sg,
         int minutes) {

    int result;

    // Not really sure the 0x07, 0x17, 0xfc, 0xe7 is necessary here,
    // but that's what came out of the trace every single time.

    unsigned char command[16] = {
        0x40, access|0x07, 0x07, 0x17, 0xfc, 0xe7,
        LSB_of(num_registers*2), MSB_of(num_registers*2),
        (direction==SCSI_DATA_WRITE ? 0x40 : 0xC0), 
        access|(direction==SCSI_DATA_WRITE ? 0x05 : 0x04), 
        data_reg, status_reg,
        timeout, qualifier, LSB_of(len), MSB_of(len)
    };

    int i;
    unsigned char data[num_registers*2];
    unsigned char status;

    for (i=0; i<num_registers; i++) {
        data[i<<1] = registers[i];
        data[1+(i<<1)] = data_out[i];
    }

    for (i=0; i<20; i++) {

        /*
         * The first time we send the full command, which consists
         * of downloading the SCSI command followed by downloading
         * the data via a write-and-test.  Any other time we only
         * send the command to download the data -- the SCSI command
         * is still 'active' in some sense in the device.
         * 
         * We're only going to try sending the data 10 times. After
         * that, we just return a failure.
         */

        result = usbat_send_control(us,
              usb_sndctrlpipe(us->pusb_dev,0),
            0x80,
            0x40,
            0,
            0,
            (i==0 ? command : command+8),
            (i==0 ? 16 : 8));

        if (result != USB_STOR_TRANSPORT_GOOD)
            return result;

        if (i==0) {

            result = usbat_bulk_transport(us,
                NULL, 0, SCSI_DATA_WRITE, 
                data, num_registers*2, 0);

            if (result!=USB_STOR_TRANSPORT_GOOD)
                return result;

        }


        //US_DEBUGP("Transfer %s %d bytes, sg buffers %d\n",
        //    direction == SCSI_DATA_WRITE ? "out" : "in",
        //    len, use_sg);

        result = usbat_bulk_transport(us,
            NULL, 0, direction, content, len, use_sg);

        /*
         * If we get a stall on the bulk download, we'll retry
         * the bulk download -- but not the SCSI command because
         * in some sense the SCSI command is still 'active' and
         * waiting for the data. Don't ask me why this should be;
         * I'm only following what the Windoze driver did.
         *
         * Note that a stall for the test-and-read/write command means
         * that the test failed. In this case we're testing to make
         * sure that the device is error-free
         * (i.e. bit 0 -- CHK -- of status is 0). The most likely
         * hypothesis is that the USBAT chip somehow knows what
         * the device will accept, but doesn't give the device any
         * data until all data is received. Thus, the device would
         * still be waiting for the first byte of data if a stall
         * occurs, even if the stall implies that some data was
         * transferred.
         */

        if (result == US_BULK_TRANSFER_SHORT) {

            /*
             * If we're reading and we stalled, then clear
             * the bulk output pipe only the first time.
             */

            if (direction==SCSI_DATA_READ && i==0)
                usb_clear_halt(us->pusb_dev,
                    usb_sndbulkpipe(us->pusb_dev,
                      us->ep_out));
            /*
             * Read status: is the device angry, or just busy?
             */

             result = usbat_read(us, USBAT_ATA, 
                direction==SCSI_DATA_WRITE ? 0x17 : 0x0E, 
                &status);

            if (result!=USB_STOR_TRANSPORT_GOOD)
                return result;
            if (status&0x01) // check condition
                return USB_STOR_TRANSPORT_FAILED;
            if (status&0x20) // device fault
                return USB_STOR_TRANSPORT_FAILED;

            US_DEBUGP("Redoing %s\n",
              direction==SCSI_DATA_WRITE ? "write" : "read");

        } else if (result != US_BULK_TRANSFER_GOOD)
            return result;
        else
            return usbat_wait_not_busy(us, minutes);

    }

    US_DEBUGP("Bummer! %s bulk data 20 times failed.\n",
        direction==SCSI_DATA_WRITE ? "Writing" : "Reading");

    return USB_STOR_TRANSPORT_FAILED;
}

/*
 * Write data to multiple registers at once. Not meant for large
 * transfers of data!
 */

int usbat_multiple_write(struct us_data *us, 
            unsigned char access,
            unsigned char *registers,
            unsigned char *data_out,
            unsigned short num_registers) {

    int result;
    unsigned char data[num_registers*2];
    int i;
    unsigned char command[8] = {
        0x40, access|0x07, 0x00, 0x00, 0x00, 0x00,
        LSB_of(num_registers*2), MSB_of(num_registers*2)
    };

    for (i=0; i<num_registers; i++) {
        data[i<<1] = registers[i];
        data[1+(i<<1)] = data_out[i];
    }

    result = usbat_send_control(us,
        usb_sndctrlpipe(us->pusb_dev,0),
        0x80,
        0x40,
        0,
        0,
        command,
        8);

    if (result != USB_STOR_TRANSPORT_GOOD)
        return result;

    result = usbat_bulk_transport(us,
        NULL, 0, SCSI_DATA_WRITE, data, num_registers*2, 0);

    if (result!=USB_STOR_TRANSPORT_GOOD)
        return result;

    return usbat_wait_not_busy(us, 0);
}

int usbat_read_user_io(struct us_data *us,
        unsigned char *data_flags) {

    int result;

    result = usbat_send_control(us,
        usb_rcvctrlpipe(us->pusb_dev,0),
        0x82,
        0xC0,
        0,
        0,
        data_flags,
        1);

    return result;
}

int usbat_write_user_io(struct us_data *us,
        unsigned char enable_flags,
        unsigned char data_flags) {

    int result;

    result = usbat_send_control(us,
        usb_sndctrlpipe(us->pusb_dev,0),
        0x82,
        0x40,
        short_pack(enable_flags, data_flags),
        0,
        NULL,
        0);

    return result;
}

/*
 * Squeeze a potentially huge (> 65535 byte) read10 command into
 * a little ( <= 65535 byte) ATAPI pipe
 */

int usbat_handle_read10(struct us_data *us,
        unsigned char *registers,
        unsigned char *data,
        Scsi_Cmnd *srb) {

    int result = USB_STOR_TRANSPORT_GOOD;
    unsigned char *buffer;
    unsigned int len;
    unsigned int sector;
    unsigned int amount;
    struct scatterlist *sg = NULL;
    int sg_segment = 0;
    int sg_offset = 0;

    US_DEBUGP("handle_read10: transfersize %d\n",
        srb->transfersize);

    if (srb->request_bufflen < 0x10000) {

        result = usbat_rw_block_test(us, USBAT_ATA, 
            registers, data, 19,
            0x10, 0x17, 0xFD, 0x30,
            SCSI_DATA_READ,
            srb->request_buffer, 
            srb->request_bufflen, srb->use_sg, 1);

        return result;
    }

    /*
     * Since we're requesting more data than we can handle in
     * a single read command (max is 64k-1), we will perform
     * multiple reads, but each read must be in multiples of
     * a sector.  Luckily the sector size is in srb->transfersize
     * (see linux/drivers/scsi/sr.c).
     */

    if (data[7+0] == GPCMD_READ_CD) {
        len = short_pack(data[7+9], data[7+8]);
        len <<= 16;
        len |= data[7+7];
        srb->transfersize = srb->request_bufflen/len;
    }


    len = (65535/srb->transfersize) * srb->transfersize;
    US_DEBUGP("Max read is %d bytes\n", len);
    buffer = kmalloc(len, GFP_NOIO);
    if (buffer == NULL) // bloody hell!
        return USB_STOR_TRANSPORT_FAILED;
    sector = short_pack(data[7+3], data[7+2]);
    sector <<= 16;
    sector |= short_pack(data[7+5], data[7+4]);
    transferred = 0;

    if (srb->use_sg) {
        sg = (struct scatterlist *)srb->request_buffer;
        sg_segment = 0; // for keeping track of where we are in
        sg_offset = 0;  // the scatter/gather list
    }

    while (transferred != srb->request_bufflen) {

        if (len > srb->request_bufflen - transferred)
            len = srb->request_bufflen - transferred;

        data[3] = len&0xFF;       // (cylL) = expected length (L)
        data[4] = (len>>8)&0xFF;  // (cylH) = expected length (H)

        // Fix up the SCSI command sector and num sectors

        data[7+2] = MSB_of(sector>>16); // SCSI command sector
        data[7+3] = LSB_of(sector>>16);
        data[7+4] = MSB_of(sector&0xFFFF);
        data[7+5] = LSB_of(sector&0xFFFF);
        if (data[7+0] == GPCMD_READ_CD)
            data[7+6] = 0;
        data[7+7] = MSB_of(len / srb->transfersize); // SCSI command
        data[7+8] = LSB_of(len / srb->transfersize); // num sectors

        result = usbat_rw_block_test(us, USBAT_ATA, 
            registers, data, 19,
            0x10, 0x17, 0xFD, 0x30,
            SCSI_DATA_READ,
            buffer,
            len, 0, 1);

        if (result != USB_STOR_TRANSPORT_GOOD)
            break;

        // Transfer the received data into the srb buffer

        if (!srb->use_sg) {
            memcpy(srb->request_buffer+transferred, buffer, len);
        } else {
            amount = 0;
            while (amount<len) {
                if (len - amount >= 
                      sg[sg_segment].length-sg_offset) {
                  memcpy(sg[sg_segment].address + sg_offset,
                    buffer + amount,
                    sg[sg_segment].length - sg_offset);
                  amount += 
                      sg[sg_segment].length-sg_offset;
                  sg_segment++;
                  sg_offset=0;
                } else {
                  memcpy(sg[sg_segment].address + sg_offset,
                    buffer + amount,
                    len - amount);
                  sg_offset += (len - amount);
                  amount = len;
                }
            }
        }

        // Update the amount transferred and the sector number

        transferred += len;
        sector += len / srb->transfersize;

    } // while transferred != srb->request_bufflen

    kfree(buffer);
    return result;
}

static int hp_8200e_select_and_test_registers(struct us_data *us) {

    int result;
    int selector;
    unsigned char status;

    // try device = master, then device = slave.

    for (selector = 0xA0; selector <= 0xB0; selector += 0x10) {

        if ( (result = usbat_write(us, USBAT_ATA, 0x16, selector)) != 
                USB_STOR_TRANSPORT_GOOD)
            return result;

        if ( (result = usbat_read(us, USBAT_ATA, 0x17, &status)) != 
                USB_STOR_TRANSPORT_GOOD)
            return result;

        if ( (result = usbat_read(us, USBAT_ATA, 0x16, &status)) != 
                USB_STOR_TRANSPORT_GOOD)
            return result;

        if ( (result = usbat_read(us, USBAT_ATA, 0x14, &status)) != 
                USB_STOR_TRANSPORT_GOOD)
            return result;

        if ( (result = usbat_read(us, USBAT_ATA, 0x15, &status)) != 
                USB_STOR_TRANSPORT_GOOD)
            return result;

        if ( (result = usbat_write(us, USBAT_ATA, 0x14, 0x55)) != 
                USB_STOR_TRANSPORT_GOOD)
            return result;

        if ( (result = usbat_write(us, USBAT_ATA, 0x15, 0xAA)) != 
                USB_STOR_TRANSPORT_GOOD)
            return result;

        if ( (result = usbat_read(us, USBAT_ATA, 0x14, &status)) != 
                USB_STOR_TRANSPORT_GOOD)
            return result;

        if ( (result = usbat_read(us, USBAT_ATA, 0x15, &status)) != 
                USB_STOR_TRANSPORT_GOOD)
            return result;
    }

    return result;
}

int init_8200e(struct us_data *us) {

    int result;
    unsigned char status;

    // Enable peripheral control signals

    if ( (result = usbat_write_user_io(us,
      USBAT_UIO_OE1 | USBAT_UIO_OE0,
      USBAT_UIO_EPAD | USBAT_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 1\n");

    wait_ms(2000);

    if ( (result = usbat_read_user_io(us, &status)) !=
            USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 2\n");

    if ( (result = usbat_read_user_io(us, &status)) !=
            USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 3\n");

    // Reset peripheral, enable periph control signals
    // (bring reset signal up)

    if ( (result = usbat_write_user_io(us,
      USBAT_UIO_DRVRST | USBAT_UIO_OE1 | USBAT_UIO_OE0,
      USBAT_UIO_EPAD | USBAT_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 4\n");

    // Enable periph control signals
    // (bring reset signal down)

    if ( (result = usbat_write_user_io(us,
      USBAT_UIO_OE1 | USBAT_UIO_OE0,
      USBAT_UIO_EPAD | USBAT_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 5\n");

    wait_ms(250);

    // Write 0x80 to ISA port 0x3F

    if ( (result = usbat_write(us, USBAT_ISA, 0x3F, 0x80)) !=
            USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 6\n");

    // Read ISA port 0x27

    if ( (result = usbat_read(us, USBAT_ISA, 0x27, &status)) !=
            USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 7\n");

    if ( (result = usbat_read_user_io(us, &status)) !=
            USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 8\n");

    if ( (result = hp_8200e_select_and_test_registers(us)) !=
             USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 9\n");

    if ( (result = usbat_read_user_io(us, &status)) !=
            USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 10\n");

    // Enable periph control signals and card detect

    if ( (result = usbat_write_user_io(us,
      USBAT_UIO_ACKD |USBAT_UIO_OE1 | USBAT_UIO_OE0,
      USBAT_UIO_EPAD | USBAT_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 11\n");

    if ( (result = usbat_read_user_io(us, &status)) !=
            USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 12\n");

    wait_ms(1400);

    if ( (result = usbat_read_user_io(us, &status)) !=
            USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 13\n");

    if ( (result = hp_8200e_select_and_test_registers(us)) !=
             USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 14\n");

    if ( (result = usbat_set_shuttle_features(us, 
            0x83, 0x00, 0x88, 0x08, 0x15, 0x14)) !=
             USB_STOR_TRANSPORT_GOOD)
        return result;

    US_DEBUGP("INIT 15\n");

    return result;
}

/*
 * Transport for the HP 8200e
 */
int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us)
{
    int result;
    unsigned char status;
    unsigned char registers[32];
    unsigned char data[32];
    unsigned int len;
    int i;
    char string[64];

    len = srb->request_bufflen;

    /* Send A0 (ATA PACKET COMMAND).
       Note: I guess we're never going to get any of the ATA
       commands... just ATA Packet Commands.
      */

    registers[0] = 0x11;
    registers[1] = 0x12;
    registers[2] = 0x13;
    registers[3] = 0x14;
    registers[4] = 0x15;
    registers[5] = 0x16;
    registers[6] = 0x17;
    data[0] = 0x00;
    data[1] = 0x00;
    data[2] = 0x00;
    data[3] = len&0xFF;         // (cylL) = expected length (L)
    data[4] = (len>>8)&0xFF;     // (cylH) = expected length (H)
    data[5] = 0xB0;         // (device sel) = slave
    data[6] = 0xA0;         // (command) = ATA PACKET COMMAND

    for (i=7; i<19; i++) {
        registers[i] = 0x10;
        data[i] = (i-7 >= srb->cmd_len) ? 0 : srb->cmnd[i-7];
    }

    result = usbat_read(us, USBAT_ATA, 0x17, &status);
    US_DEBUGP("Status = %02X\n", status);

    if (srb->cmnd[0] == TEST_UNIT_READY)
        transferred = 0;

    if (srb->sc_data_direction == SCSI_DATA_WRITE) {

        result = usbat_rw_block_test(us, USBAT_ATA, 
            registers, data, 19,
            0x10, 0x17, 0xFD, 0x30,
            SCSI_DATA_WRITE,
            srb->request_buffer, 
            len, srb->use_sg, 10);

        if (result == USB_STOR_TRANSPORT_GOOD) {
            transferred += len;
            US_DEBUGP("Wrote %08X bytes\n", transferred);
        }

        return result;

    } else if (srb->cmnd[0] == READ_10 ||
           srb->cmnd[0] == GPCMD_READ_CD) {

        return usbat_handle_read10(us, registers, data, srb);

    }

    if (len > 0xFFFF) {
        US_DEBUGP("Error: len = %08X... what do I do now?\n",
            len);
        return USB_STOR_TRANSPORT_ERROR;
    }

    if ( (result = usbat_multiple_write(us, 
            USBAT_ATA,
            registers, data, 7)) != USB_STOR_TRANSPORT_GOOD) {
        return result;
    }

    // Write the 12-byte command header.

    // If the command is BLANK then set the timer for 75 minutes.
    // Otherwise set it for 10 minutes.

    // NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW
    // AT SPEED 4 IS UNRELIABLE!!!

    if ( (result = usbat_write_block(us, 
            USBAT_ATA, 0x10, srb->cmnd, 12, 0,
            srb->cmnd[0]==GPCMD_BLANK ? 75 : 10)) !=
                USB_STOR_TRANSPORT_GOOD) {
        return result;
    }

    // If there is response data to be read in 
    // then do it here.

    if (len != 0 && (srb->sc_data_direction == SCSI_DATA_READ)) {

        // How many bytes to read in? Check cylL register

        if ( (result = usbat_read(us, USBAT_ATA, 0x14, &status)) != 
            USB_STOR_TRANSPORT_GOOD) {
            return result;
        }

        if (len>0xFF) { // need to read cylH also
            len = status;
            if ( (result = usbat_read(us, USBAT_ATA, 0x15,
                &status)) !=
                    USB_STOR_TRANSPORT_GOOD) {
                return result;
            }
            len += ((unsigned int)status)<<8;
        }
        else
            len = status;


        result = usbat_read_block(us, USBAT_ATA, 0x10, 
            srb->request_buffer, len, srb->use_sg);

        /* Debug-print the first 32 bytes of the transfer */

        if (!srb->use_sg) {
            string[0] = 0;
            for (i=0; i<len && i<32; i++) {
                sprintf(string+strlen(string), "%02X ",
                  ((unsigned char *)srb->request_buffer)[i]);
                if ((i%16)==15) {
                    US_DEBUGP("%s\n", string);
                    string[0] = 0;
                }
            }
            if (string[0]!=0)
                US_DEBUGP("%s\n", string);
        }
    }

    return result;
}



:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0232 ]--