diff options
Diffstat (limited to 'qemu/roms/openbios/arch/ppc/mol/osi-scsi.c')
-rw-r--r-- | qemu/roms/openbios/arch/ppc/mol/osi-scsi.c | 271 |
1 files changed, 0 insertions, 271 deletions
diff --git a/qemu/roms/openbios/arch/ppc/mol/osi-scsi.c b/qemu/roms/openbios/arch/ppc/mol/osi-scsi.c deleted file mode 100644 index 18f3dc577..000000000 --- a/qemu/roms/openbios/arch/ppc/mol/osi-scsi.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Creation Date: <2003/12/11 21:23:54 samuel> - * Time-stamp: <2004/01/07 19:38:45 samuel> - * - * <osi-scsi.c> - * - * SCSI device node - * - * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 - * - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "mol/mol.h" -#include "scsi_sh.h" -#include "osi_calls.h" - -#define MAX_TARGETS 32 - -typedef struct { - int probed; - int valid; /* a useable device found */ - - int is_cd; - int blocksize; -} target_info_t; - -static target_info_t scsi_devs[ MAX_TARGETS ]; - -typedef struct { - int target; - target_info_t *info; -} instance_data_t; - - -DECLARE_NODE( scsi, INSTALL_OPEN, sizeof(instance_data_t), - "/pci/pci-bridge/mol-scsi/sd", "/mol/mol-scsi/sd" ); - - -static int -scsi_cmd_( instance_data_t *sd, const char *cmd, int cmdlen, char *dest, - int len, int prelen, int postlen ) -{ - char prebuf[4096], postbuf[4096]; - scsi_req_t r[2]; /* the [2] is a hack to get space for the sg-list */ - char sb[32]; - - /* memset( dest, 0, len ); */ - - if( (unsigned int)prelen > sizeof(prebuf) || (unsigned int)postlen > sizeof(postbuf) ) { - printk("bad pre/post len %d %d\n", prelen, postlen ); - return 1; - } - - memset( r, 0, sizeof(r[0]) ); - r->lun = 0; - r->target = sd->target; - r->is_write = 0; - memcpy( r->cdb, cmd, cmdlen ); - r->client_addr = (int)&r; - r->cdb_len = cmdlen; - r->sense[0].base = (int)&sb; - r->sense[0].size = sizeof(sb); - r->size = prelen + len + postlen; - r->n_sg = 3; - r->sglist.n_el = 3; - r->sglist.vec[0].base = (int)prebuf; - r->sglist.vec[0].size = prelen; - r->sglist.vec[1].base = (int)dest; - r->sglist.vec[1].size = len; - r->sglist.vec[2].base = (int)postbuf; - r->sglist.vec[2].size = postlen; - - if( OSI_SCSISubmit((int)&r) ) { - printk("OSI_SCSISubmit: error!\n"); - return 1; - } - while( !OSI_SCSIAck() ) - OSI_USleep( 10 ); - - if( r->adapter_status ) - return -1; - if( r->scsi_status ) - return ((sb[2] & 0xf) << 16) | (sb[12] << 8) | sb[13]; - return 0; -} - -static int -scsi_cmd( instance_data_t *sd, const char *cmd, int cmdlen ) -{ - return scsi_cmd_( sd, cmd, cmdlen, NULL, 0, 0, 0 ); -} - -/* ( buf blk nblks -- actual ) */ -static void -scsi_read_blocks( instance_data_t *sd ) -{ - int nblks = POP(); - int blk = POP(); - char *dest = (char*)POP(); - unsigned char cmd[10]; - int len = nblks * sd->info->blocksize; - - memset( dest, 0, len ); - - /* printk("READ: blk: %d length %d\n", blk, len ); */ - memset( cmd, 0, sizeof(cmd) ); - cmd[0] = 0x28; /* READ_10 */ - cmd[2] = blk >> 24; - cmd[3] = blk >> 16; - cmd[4] = blk >> 8; - cmd[5] = blk; - cmd[7] = nblks >> 8; - cmd[8] = nblks; - - if( scsi_cmd_(sd, cmd, 10, dest, len, 0, 0) ) { - printk("read: scsi_cmd failed\n"); - RET( -1 ); - } - PUSH( nblks ); -} - -static int -inquiry( instance_data_t *sd ) -{ - char inquiry_cmd[6] = { 0x12, 0, 0, 0, 32, 0 }; - char start_stop_unit_cmd[6] = { 0x1b, 0, 0, 0, 1, 0 }; - char test_unit_ready_cmd[6] = { 0x00, 0, 0, 0, 0, 0 }; - char prev_allow_medium_removal[6] = { 0x1e, 0, 0, 0, 1, 0 }; - char set_cd_speed_cmd[12] = { 0xbb, 0, 0xff, 0xff, 0xff, 0xff, - 0, 0, 0, 0, 0, 0 }; - target_info_t *info = &scsi_devs[sd->target]; - char ret[32]; - int i, sense; - - if( sd->target >= MAX_TARGETS ) - return -1; - sd->info = info; - - if( info->probed ) - return info->valid ? 0:-1; - info->probed = 1; - - if( (sense=scsi_cmd_(sd, inquiry_cmd, 6, ret, 2, 0, 0)) ) { - if( sense < 0 ) - return -1; - printk("INQUIRY failed\n"); - return -1; - } - - /* medium present? */ - if( (scsi_cmd(sd, test_unit_ready_cmd, 6) >> 8) == 0x23a ) { - printk("no media\n"); - return -1; - } - - info->is_cd = 0; - info->blocksize = 512; - - if( ret[0] == 5 /* CD/DVD */ ) { - info->blocksize = 2048; - info->is_cd = 1; - - scsi_cmd( sd, prev_allow_medium_removal, 6 ); - scsi_cmd( sd, set_cd_speed_cmd, 12 ); - scsi_cmd( sd, start_stop_unit_cmd, 6 ); - - } else if( ret[0] == 0 /* DISK */ ) { - scsi_cmd( sd, test_unit_ready_cmd, 6 ); - scsi_cmd( sd, start_stop_unit_cmd, 6 ); - } else { - /* don't boot from this device (could be a scanner :-)) */ - return -1; - } - - /* wait for spin-up (or whatever) to complete */ - for( i=0; ; i++ ) { - if( i > 300 ) { - printk("SCSI timeout (sense %x)\n", sense ); - return -1; - } - sense = scsi_cmd( sd, test_unit_ready_cmd, 6 ); - if( (sense & 0xf0000) == 0x20000 ) { - OSI_USleep( 10000 ); - continue; - } - break; - } - - info->valid = 1; - return 0; -} - -/* ( -- success? ) */ -static void -scsi_open( instance_data_t *sd ) -{ - static int once = 0; - phandle_t ph; - - fword("my-unit"); - sd->target = POP(); - - if( !once ) { - once++; - OSI_SCSIControl( SCSI_CTRL_INIT, 0 ); - } - - /* obtiain device information */ - if( inquiry(sd) ) - RET(0); - - selfword("open-deblocker"); - - /* interpose disk-label */ - ph = find_dev("/packages/disk-label"); - fword("my-args"); - PUSH_ph( ph ); - fword("interpose"); - - PUSH( -1 ); -} - -/* ( -- ) */ -static void -scsi_close( instance_data_t *pb ) -{ - selfword("close-deblocker"); -} - - -/* ( -- bs ) */ -static void -scsi_block_size( instance_data_t *sd ) -{ - PUSH( sd->info->blocksize ); -} - -/* ( -- maxbytes ) */ -static void -scsi_max_transfer( instance_data_t *sd ) -{ - PUSH( 1024*1024 ); -} - -static void -scsi_initialize( instance_data_t *sd ) -{ - fword("is-deblocker"); -} - - -NODE_METHODS( scsi ) = { - { NULL, scsi_initialize }, - { "open", scsi_open }, - { "close", scsi_close }, - { "read-blocks", scsi_read_blocks }, - { "block-size", scsi_block_size }, - { "max-transfer", scsi_max_transfer }, -}; - -void -osiscsi_init( void ) -{ - REGISTER_NODE( scsi ); -} |