2017-05-30 03:38:38 +02:00
/*
* 86 Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus .
*
* Emulation of SCSI fixed and removable disks .
*
2017-10-11 01:17:41 +02:00
* Version : @ ( # ) scsi_disk . c 1.0 .13 2017 / 10 / 10
2017-05-30 03:38:38 +02:00
*
* Author : Miran Grca , < mgrca8 @ gmail . com >
2017-08-24 01:14:39 -04:00
* Copyright 2017 Miran Grca .
2017-05-30 03:38:38 +02:00
*/
2017-06-16 03:18:59 +02:00
# include <stdio.h>
2017-09-25 04:31:20 -04:00
# include <stdint.h>
# include <string.h>
2017-09-04 01:52:29 -04:00
# include <stdlib.h>
2017-08-15 19:49:25 +02:00
# include <stdarg.h>
2017-09-25 04:31:20 -04:00
# include <wchar.h>
2017-08-27 00:58:44 +02:00
# include "../86box.h"
# include "../ibm.h"
2017-09-04 01:52:29 -04:00
# include "../timer.h"
2017-10-01 16:29:15 -04:00
# include "../device.h"
2017-10-08 05:04:38 +02:00
# include "../nvr.h"
2017-09-04 01:52:29 -04:00
# include "../piix.h"
# include "../cdrom/cdrom.h"
2017-10-02 02:15:35 -04:00
# include "../disk/hdd.h"
# include "../disk/hdc.h"
# include "../disk/hdc_ide.h"
2017-10-10 03:07:29 -04:00
# include "../plat.h"
# include "../ui.h"
2017-05-05 01:49:42 +02:00
# include "scsi.h"
2017-05-27 03:53:32 +02:00
# include "scsi_disk.h"
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
/* Bits of 'status' */
# define ERR_STAT 0x01
# define DRQ_STAT 0x08 /* Data request */
# define DSC_STAT 0x10
# define SERVICE_STAT 0x10
# define READY_STAT 0x40
# define BUSY_STAT 0x80
/* Bits of 'error' */
# define ABRT_ERR 0x04 /* Command aborted */
# define MCR_ERR 0x08 /* Media change request */
# define MAX_BLOCKS_AT_ONCE 340
# define scsi_hd_sense_error shdc[id].sense[0]
# define scsi_hd_sense_key shdc[id].sense[2]
# define scsi_hd_asc shdc[id].sense[12]
# define scsi_hd_ascq shdc[id].sense[13]
2017-05-27 03:53:32 +02:00
2017-09-30 16:56:38 -04:00
scsi_hard_disk_t shdc [ HDD_NUM ] ;
FILE * shdf [ HDD_NUM ] ;
2017-05-29 01:18:32 +02:00
2017-08-24 01:14:39 -04:00
uint8_t scsi_hard_disks [ 16 ] [ 8 ] = {
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF }
} ;
2017-05-05 01:49:42 +02:00
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
2017-08-24 01:14:39 -04:00
uint8_t scsi_hd_command_flags [ 0x100 ] = {
IMPLEMENTED | CHECK_READY | NONDATA , /* 0x00 */
IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY , /* 0x01 */
0 ,
IMPLEMENTED | ALLOW_UA , /* 0x03 */
IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY , /* 0x04 */
0 , 0 , 0 ,
IMPLEMENTED | CHECK_READY , /* 0x08 */
0 ,
IMPLEMENTED | CHECK_READY , /* 0x0A */
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
IMPLEMENTED | ALLOW_UA , /* 0x12 */
IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY , /* 0x13 */
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
IMPLEMENTED | CHECK_READY , /* 0x1B */
0 , 0 ,
IMPLEMENTED | CHECK_READY , /* 0x1E */
0 , 0 , 0 , 0 , 0 , 0 ,
IMPLEMENTED | CHECK_READY , /* 0x25 */
0 , 0 ,
IMPLEMENTED | CHECK_READY , /* 0x28 */
0 ,
IMPLEMENTED | CHECK_READY , /* 0x2A */
0 , 0 , 0 , 0 ,
IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY , /* 0x2F */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
IMPLEMENTED | CHECK_READY , /* 0xA8 */
0 ,
IMPLEMENTED | CHECK_READY , /* 0xAA */
0 , 0 , 0 , 0 ,
IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY , /* 0xAF */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
IMPLEMENTED , /* 0xBD */
0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
2017-05-05 01:49:42 +02:00
} ;
2017-08-24 01:14:39 -04:00
2017-10-08 05:04:38 +02:00
uint64_t scsi_hd_mode_sense_page_flags [ HDD_NUM ] = { ( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) ,
( 1LL < < 0x03 ) | ( 1LL < < 0x04 ) | ( 1LL < < 0x30 ) | ( 1LL < < GPMODE_ALL_PAGES ) } ;
/* This should be done in a better way but for time being, it's been done this way so it's not as huge and more readable. */
const uint8_t scsi_hd_mode_sense_pages_default [ HDD_NUM ] [ 0x40 ] [ 0x40 ] =
{
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } }
} ;
uint8_t scsi_hd_mode_sense_pages_changeable [ HDD_NUM ] [ 0x40 ] [ 0x40 ] =
{
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } }
} ;
uint8_t scsi_hd_mode_sense_pages_saved [ HDD_NUM ] [ 0x40 ] [ 0x40 ] =
{
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } ,
{ [ 0x03 ] = { 0x03 , 0x16 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
[ 0x04 ] = { 0x04 , 0x16 , 0 , 0x10 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x10 , 0 , 0 , 0 } ,
[ 0x30 ] = { 0xB0 , 0x16 , ' 8 ' , ' 6 ' , ' B ' , ' o ' , ' x ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } }
} ;
# define ENABLE_SCSI_HD_LOG 0
2017-05-05 01:49:42 +02:00
int scsi_hd_do_log = 0 ;
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
void scsi_hd_log ( const char * format , . . . )
{
2017-08-15 19:49:25 +02:00
# ifdef ENABLE_SCSI_HD_LOG
2017-05-05 01:49:42 +02:00
if ( scsi_hd_do_log )
{
va_list ap ;
va_start ( ap , format ) ;
vprintf ( format , ap ) ;
va_end ( ap ) ;
fflush ( stdout ) ;
}
# endif
}
2017-08-24 01:14:39 -04:00
2017-10-08 05:04:38 +02:00
int scsi_hd_mode_select_terminate ( uint8_t id , int force ) ;
2017-05-05 01:49:42 +02:00
/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */
int scsi_hd_err_stat_to_scsi ( uint8_t id )
{
if ( shdc [ id ] . status & ERR_STAT )
{
return SCSI_STATUS_CHECK_CONDITION ;
}
else
{
return SCSI_STATUS_OK ;
}
return SCSI_STATUS_OK ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */
int scsi_hd_phase_to_scsi ( uint8_t id )
{
if ( shdc [ id ] . status & 8 )
{
switch ( shdc [ id ] . phase & 3 )
{
case 0 :
return 0 ;
case 1 :
return 2 ;
case 2 :
return 1 ;
case 3 :
return 7 ;
}
}
else
{
if ( ( shdc [ id ] . phase & 3 ) = = 3 )
{
return 3 ;
}
else
{
/* Translate reserved ATAPI phase to reserved SCSI phase. */
return 4 ;
}
}
return 0 ;
}
2017-08-24 01:14:39 -04:00
2017-09-30 16:56:38 -04:00
int find_hdd_for_scsi_id ( uint8_t scsi_id , uint8_t scsi_lun )
2017-05-05 01:49:42 +02:00
{
uint8_t i = 0 ;
2017-09-30 16:56:38 -04:00
for ( i = 0 ; i < HDD_NUM ; i + + )
2017-05-05 01:49:42 +02:00
{
2017-09-30 16:56:38 -04:00
if ( ( wcslen ( hdd [ i ] . fn ) = = 0 ) & & ( hdd [ i ] . bus ! = HDD_BUS_SCSI_REMOVABLE ) )
2017-05-27 03:53:32 +02:00
{
continue ;
}
2017-09-30 16:56:38 -04:00
if ( ( ( hdd [ i ] . spt = = 0 ) | | ( hdd [ i ] . hpc = = 0 ) | | ( hdd [ i ] . tracks = = 0 ) ) & & ( hdd [ i ] . bus ! = HDD_BUS_SCSI_REMOVABLE ) )
2017-05-27 03:53:32 +02:00
{
continue ;
}
2017-09-30 16:56:38 -04:00
if ( ( ( hdd [ i ] . bus = = HDD_BUS_SCSI ) | | ( hdd [ i ] . bus = = HDD_BUS_SCSI_REMOVABLE ) ) & & ( hdd [ i ] . scsi_id = = scsi_id ) & & ( hdd [ i ] . scsi_lun = = scsi_lun ) )
2017-05-05 01:49:42 +02:00
{
return i ;
}
}
return 0xff ;
}
2017-08-24 01:14:39 -04:00
2017-05-27 03:53:32 +02:00
void scsi_disk_insert ( uint8_t id )
{
2017-09-30 16:56:38 -04:00
shdc [ id ] . unit_attention = ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE ) ? 1 : 0 ;
2017-10-08 05:04:38 +02:00
scsi_hd_mode_select_terminate ( id , 1 ) ;
2017-05-27 03:53:32 +02:00
}
2017-08-24 01:14:39 -04:00
2017-05-27 03:53:32 +02:00
void scsi_loadhd ( int scsi_id , int scsi_lun , int id )
2017-05-05 01:49:42 +02:00
{
2017-09-30 16:56:38 -04:00
if ( ! hdd_image_load ( id ) ) {
if ( hdd [ id ] . bus ! = HDD_BUS_SCSI_REMOVABLE )
2017-05-27 03:53:32 +02:00
{
scsi_hard_disks [ scsi_id ] [ scsi_lun ] = 0xff ;
}
}
else
{
scsi_disk_insert ( id ) ;
}
}
2017-08-24 01:14:39 -04:00
2017-05-27 03:53:32 +02:00
void scsi_reloadhd ( int id )
{
2017-06-16 03:18:59 +02:00
int ret = 0 ;
2017-05-27 03:53:32 +02:00
2017-09-30 16:56:38 -04:00
if ( wcslen ( hdd [ id ] . prev_fn ) = = 0 )
2017-05-27 03:53:32 +02:00
{
return ;
}
else
{
2017-09-30 16:56:38 -04:00
wcscpy ( hdd [ id ] . fn , hdd [ id ] . prev_fn ) ;
memset ( hdd [ id ] . prev_fn , 0 , sizeof ( hdd [ id ] . prev_fn ) ) ;
2017-05-27 03:53:32 +02:00
}
2017-06-16 03:18:59 +02:00
ret = hdd_image_load ( id ) ;
2017-05-27 03:53:32 +02:00
2017-06-16 03:18:59 +02:00
if ( ret )
2017-05-27 03:53:32 +02:00
{
scsi_disk_insert ( id ) ;
}
}
2017-08-24 01:14:39 -04:00
2017-05-27 03:53:32 +02:00
void scsi_unloadhd ( int scsi_id , int scsi_lun , int id )
{
2017-06-16 03:18:59 +02:00
hdd_image_unload ( id , 1 ) ;
2017-05-05 01:49:42 +02:00
}
2017-08-24 01:14:39 -04:00
void build_scsi_hd_map ( void )
2017-05-05 01:49:42 +02:00
{
uint8_t i = 0 ;
uint8_t j = 0 ;
for ( i = 0 ; i < 16 ; i + + )
{
memset ( scsi_hard_disks [ i ] , 0xff , 8 ) ;
}
for ( i = 0 ; i < 16 ; i + + )
{
for ( j = 0 ; j < 8 ; j + + )
{
2017-09-30 16:56:38 -04:00
scsi_hard_disks [ i ] [ j ] = find_hdd_for_scsi_id ( i , j ) ;
2017-05-05 01:49:42 +02:00
if ( scsi_hard_disks [ i ] [ j ] ! = 0xff )
{
2017-05-27 03:53:32 +02:00
memset ( & ( shdc [ scsi_hard_disks [ i ] [ j ] ] ) , 0 , sizeof ( shdc [ scsi_hard_disks [ i ] [ j ] ] ) ) ;
2017-09-30 16:56:38 -04:00
if ( wcslen ( hdd [ scsi_hard_disks [ i ] [ j ] ] . fn ) > 0 )
2017-05-27 03:53:32 +02:00
{
scsi_loadhd ( i , j , scsi_hard_disks [ i ] [ j ] ) ;
}
2017-05-05 01:49:42 +02:00
}
}
}
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
int scsi_hd_read_capacity ( uint8_t id , uint8_t * cdb , uint8_t * buffer , uint32_t * len )
{
int size = 0 ;
2017-06-16 03:18:59 +02:00
size = hdd_image_get_last_sector ( id ) ;
2017-05-05 01:49:42 +02:00
memset ( buffer , 0 , 8 ) ;
buffer [ 0 ] = ( size > > 24 ) & 0xff ;
buffer [ 1 ] = ( size > > 16 ) & 0xff ;
buffer [ 2 ] = ( size > > 8 ) & 0xff ;
buffer [ 3 ] = size & 0xff ;
buffer [ 6 ] = 2 ; /* 512 = 0x0200 */
* len = 8 ;
2017-08-26 04:38:12 +02:00
2017-10-08 05:04:38 +02:00
return 1 ;
}
/*SCSI Mode Sense 6/10*/
uint8_t scsi_hd_mode_sense_read ( uint8_t id , uint8_t page_control , uint8_t page , uint8_t pos )
{
switch ( page_control )
{
case 0 :
case 3 :
return scsi_hd_mode_sense_pages_saved [ id ] [ page ] [ pos ] ;
break ;
case 1 :
return scsi_hd_mode_sense_pages_changeable [ id ] [ page ] [ pos ] ;
break ;
case 2 :
return scsi_hd_mode_sense_pages_default [ id ] [ page ] [ pos ] ;
break ;
}
return 0 ;
}
uint32_t scsi_hd_mode_sense ( uint8_t id , uint8_t * buf , uint32_t pos , uint8_t type , uint8_t block_descriptor_len )
{
uint8_t page_control = ( type > > 6 ) & 3 ;
int i = 0 ;
int j = 0 ;
uint8_t msplen ;
type & = 0x3f ;
if ( block_descriptor_len )
{
buf [ pos + + ] = 1 ; /* Density code. */
buf [ pos + + ] = 0 ; /* Number of blocks (0 = all). */
buf [ pos + + ] = 0 ;
buf [ pos + + ] = 0 ;
buf [ pos + + ] = 0 ; /* Reserved. */
buf [ pos + + ] = 0 ; /* Block length (0x800 = 2048 bytes). */
buf [ pos + + ] = 8 ;
buf [ pos + + ] = 0 ;
}
for ( i = 0 ; i < 0x40 ; i + + )
{
if ( ( type = = GPMODE_ALL_PAGES ) | | ( type = = i ) )
{
if ( scsi_hd_mode_sense_page_flags [ id ] & ( 1LL < < shdc [ id ] . current_page_code ) )
{
buf [ pos + + ] = scsi_hd_mode_sense_read ( id , page_control , i , 0 ) ;
msplen = scsi_hd_mode_sense_read ( id , page_control , i , 1 ) ;
buf [ pos + + ] = msplen ;
scsi_hd_log ( " SCSI HDD %i: MODE SENSE: Page [%02X] length %i \n " , id , i , msplen ) ;
for ( j = 0 ; j < msplen ; j + + )
{
buf [ pos + + ] = scsi_hd_mode_sense_read ( id , page_control , i , 2 + j ) ;
}
}
}
}
return pos ;
}
2017-08-26 04:38:12 +02:00
2017-10-08 05:04:38 +02:00
void scsi_hd_mode_sense_load ( uint8_t id )
{
FILE * f ;
wchar_t temp [ 512 ] ;
memset ( temp , 0 , 1024 ) ;
_swprintf ( temp , L " scsi_hd_%02i_mode_sense.bin " , id ) ;
f = _wfopen ( nvr_path ( temp ) , L " rb " ) ;
if ( ! f )
{
return ;
}
fread ( scsi_hd_mode_sense_pages_saved [ id ] [ 0x30 ] , 1 , 0x18 , f ) ;
fclose ( f ) ;
}
void scsi_hd_mode_sense_save ( uint8_t id )
{
FILE * f ;
wchar_t temp [ 512 ] ;
memset ( temp , 0 , 1024 ) ;
_swprintf ( temp , L " scsi_hd_%02i_mode_sense.bin " , id ) ;
f = _wfopen ( nvr_path ( temp ) , L " wb " ) ;
if ( ! f )
{
return ;
}
fwrite ( scsi_hd_mode_sense_pages_saved [ id ] [ 0x30 ] , 1 , 0x18 , f ) ;
fclose ( f ) ;
}
int scsi_hd_mode_select_init ( uint8_t id , uint8_t command , uint16_t pl_length , uint8_t do_save )
{
switch ( command )
{
case GPCMD_MODE_SELECT_6 :
shdc [ id ] . current_page_len = 4 ;
break ;
case GPCMD_MODE_SELECT_10 :
shdc [ id ] . current_page_len = 8 ;
break ;
default :
scsi_hd_log ( " SCSI HDD %i: Attempting to initialize MODE SELECT with unrecognized command: %02X \n " , id , command ) ;
return - 1 ;
}
if ( pl_length = = 0 )
{
scsi_hd_log ( " SCSI HDD %i: Attempting to initialize MODE SELECT with zero parameter list length: %02X \n " , id , command ) ;
return - 2 ;
}
shdc [ id ] . current_page_pos = 0 ;
shdc [ id ] . mode_select_phase = MODE_SELECT_PHASE_HEADER ;
shdc [ id ] . total_length = pl_length ;
shdc [ id ] . written_length = 0 ;
shdc [ id ] . do_page_save = do_save ;
2017-05-05 01:49:42 +02:00
return 1 ;
}
2017-10-08 05:04:38 +02:00
int scsi_hd_mode_select_terminate ( uint8_t id , int force )
{
if ( ( ( shdc [ id ] . written_length > = shdc [ id ] . total_length ) | | force ) & & ( shdc [ id ] . mode_select_phase ! = MODE_SELECT_PHASE_IDLE ) )
{
scsi_hd_log ( " SCSI HDD %i: MODE SELECT terminate: %i \n " , id , force ) ;
shdc [ id ] . current_page_pos = shdc [ id ] . current_page_len = shdc [ id ] . block_descriptor_len = 0 ;
shdc [ id ] . total_length = shdc [ id ] . written_length = 0 ;
shdc [ id ] . mode_select_phase = MODE_SELECT_PHASE_IDLE ;
if ( force )
{
scsi_hd_mode_sense_load ( id ) ;
}
return 1 ;
}
else
{
return 0 ;
}
}
int scsi_hd_mode_select_header ( uint8_t id , uint8_t val )
{
if ( shdc [ id ] . current_page_pos = = 0 )
{
shdc [ id ] . block_descriptor_len = 0 ;
}
else if ( shdc [ id ] . current_page_pos = = ( shdc [ id ] . current_page_len - 2 ) )
{
if ( shdc [ id ] . current_page_len = = 8 )
{
shdc [ id ] . block_descriptor_len | = ( ( uint16_t ) val ) < < 8 ;
scsi_hd_log ( " SCSI HDD %i: Position: %02X, value: %02X, block descriptor length: %02X \n " , id , shdc [ id ] . current_page_pos , val , shdc [ id ] . block_descriptor_len ) ;
}
}
else if ( shdc [ id ] . current_page_pos = = ( shdc [ id ] . current_page_len - 1 ) )
{
shdc [ id ] . block_descriptor_len | = ( uint16_t ) val ;
scsi_hd_log ( " SCSI HDD %i: Position: %02X, value: %02X, block descriptor length: %02X \n " , id , shdc [ id ] . current_page_pos , val , shdc [ id ] . block_descriptor_len ) ;
}
shdc [ id ] . current_page_pos + + ;
if ( shdc [ id ] . current_page_pos > = shdc [ id ] . current_page_len )
{
shdc [ id ] . current_page_pos = 0 ;
if ( shdc [ id ] . block_descriptor_len )
{
shdc [ id ] . mode_select_phase = MODE_SELECT_PHASE_BLOCK_DESC ;
}
else
{
shdc [ id ] . mode_select_phase = MODE_SELECT_PHASE_PAGE_HEADER ;
}
}
return 1 ;
}
int scsi_hd_mode_select_block_desc ( uint8_t id )
{
shdc [ id ] . current_page_pos + + ;
if ( shdc [ id ] . current_page_pos > = 8 )
{
shdc [ id ] . current_page_pos = 0 ;
shdc [ id ] . mode_select_phase = MODE_SELECT_PHASE_PAGE_HEADER ;
}
return 1 ;
}
static void scsi_hd_invalid_field_pl ( uint8_t id ) ;
int scsi_hd_mode_select_page_header ( uint8_t id , uint8_t val )
{
if ( shdc [ id ] . current_page_pos = = 0 )
{
shdc [ id ] . current_page_code = val & 0x3f ;
if ( ! ( scsi_hd_mode_sense_page_flags [ id ] & ( 1LL < < shdc [ id ] . current_page_code ) ) )
{
scsi_hd_log ( " SCSI HDD %i: Trying to modify an unimplemented page: %02X \n " , id , shdc [ id ] . current_page_code ) ;
scsi_hd_mode_select_terminate ( id , 1 ) ;
scsi_hd_invalid_field_pl ( id ) ;
}
shdc [ id ] . current_page_pos + + ;
}
else if ( shdc [ id ] . current_page_pos = = 1 )
{
shdc [ id ] . current_page_pos = 0 ;
shdc [ id ] . current_page_len = val ;
shdc [ id ] . mode_select_phase = MODE_SELECT_PHASE_PAGE ;
}
return 1 ;
}
int scsi_hd_mode_select_page ( uint8_t id , uint8_t val )
{
if ( scsi_hd_mode_sense_pages_changeable [ id ] [ shdc [ id ] . current_page_code ] [ shdc [ id ] . current_page_pos + 2 ] ! = 0xFF )
{
if ( val ! = scsi_hd_mode_sense_pages_saved [ id ] [ shdc [ id ] . current_page_code ] [ shdc [ id ] . current_page_pos + 2 ] )
{
/* Trying to change an unchangeable value. */
scsi_hd_log ( " SCSI HDD %i: Trying to change an unchangeable value: [%02X][%02X] = %02X (new: %02X) \n " , id , shdc [ id ] . current_page_code , shdc [ id ] . current_page_pos + 2 , scsi_hd_mode_sense_pages_saved [ id ] [ shdc [ id ] . current_page_code ] [ shdc [ id ] . current_page_pos + 2 ] , val ) ;
scsi_hd_mode_select_terminate ( id , 1 ) ;
scsi_hd_invalid_field_pl ( id ) ;
return 0 ;
}
}
else
{
if ( shdc [ id ] . current_page_code = = 0xE )
{
if ( ( shdc [ id ] . current_page_pos = = 6 ) | | ( shdc [ id ] . current_page_pos = = 8 ) )
{
if ( val > 3 )
{
/* Trying to set an unsupported audio channel. */
scsi_hd_log ( " SCSI HDD %i: Trying to set an unsupported value: [%02X][%02X] = %02X (new: %02X) \n " , id , shdc [ id ] . current_page_code , shdc [ id ] . current_page_pos , scsi_hd_mode_sense_pages_saved [ id ] [ shdc [ id ] . current_page_code ] [ shdc [ id ] . current_page_pos + 2 ] , val ) ;
return 0 ;
}
}
}
scsi_hd_mode_sense_pages_saved [ id ] [ shdc [ id ] . current_page_code ] [ shdc [ id ] . current_page_pos + 2 ] = val ;
}
shdc [ id ] . current_page_pos + + ;
if ( shdc [ id ] . current_page_pos > = shdc [ id ] . current_page_len )
{
shdc [ id ] . current_page_pos = 0 ;
shdc [ id ] . mode_select_phase = MODE_SELECT_PHASE_PAGE_HEADER ;
}
return 1 ;
}
static void scsi_hd_command_complete ( uint8_t id ) ;
int scsi_hd_mode_select_write ( uint8_t id , uint8_t val )
{
int ret = 0 ;
int ret2 = 0 ;
if ( id > HDD_NUM )
{
scsi_hd_log ( " MODE SELECT: attempted write to wrong SCSI HDD drive \n " , val ) ;
return - 6 ;
}
if ( shdc [ id ] . total_length = = 0 )
{
scsi_hd_log ( " SCSI HDD %i: MODE SELECT: attempted write when not initialized (%02X) \n " , id , val ) ;
return - 3 ;
}
shdc [ id ] . written_length + + ;
switch ( shdc [ id ] . mode_select_phase )
{
case MODE_SELECT_PHASE_IDLE :
scsi_hd_log ( " SCSI HDD %i: MODE SELECT idle (%02X) \n " , id , val ) ;
ret = 1 ;
break ;
case MODE_SELECT_PHASE_HEADER :
scsi_hd_log ( " SCSI HDD %i: MODE SELECT header (%02X) \n " , id , val ) ;
ret = scsi_hd_mode_select_header ( id , val ) ;
break ;
case MODE_SELECT_PHASE_BLOCK_DESC :
scsi_hd_log ( " SCSI HDD %i: MODE SELECT block descriptor (%02X) \n " , id , val ) ;
ret = scsi_hd_mode_select_block_desc ( id ) ;
break ;
case MODE_SELECT_PHASE_PAGE_HEADER :
scsi_hd_log ( " SCSI HDD %i: MODE SELECT page header (%02X) \n " , id , val ) ;
ret = scsi_hd_mode_select_page_header ( id , val ) ;
break ;
case MODE_SELECT_PHASE_PAGE :
scsi_hd_log ( " SCSI HDD %i: MODE SELECT page (%02X) \n " , id , val ) ;
ret = scsi_hd_mode_select_page ( id , val ) ;
if ( shdc [ id ] . mode_select_phase = = MODE_SELECT_PHASE_PAGE_HEADER )
{
if ( shdc [ id ] . do_page_save & & ( scsi_hd_mode_sense_pages_default [ id ] [ shdc [ id ] . current_page_code ] [ 0 ] & 0x80 ) )
{
scsi_hd_log ( " SCSI HDD %i: Page %i finished, saving it... \n " , id , shdc [ id ] . current_page_code ) ;
scsi_hd_mode_sense_save ( id ) ;
}
}
break ;
default :
scsi_hd_log ( " SCSI HDD %i: MODE SELECT unknown phase (%02X) \n " , id , val ) ;
ret = - 4 ;
break ;
}
/* On termination, override the return value, but only if it is 1. */
ret2 = scsi_hd_mode_select_terminate ( id , 0 ) ;
if ( ret2 )
{
scsi_hd_command_complete ( id ) ;
}
if ( ret2 & & ( ret = = 1 ) )
{
ret = - 5 ;
}
return ret ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
void scsi_hd_update_request_length ( uint8_t id , int len , int block_len )
{
/* For media access commands, make sure the requested DRQ length matches the block length. */
switch ( shdc [ id ] . current_cdb [ 0 ] )
{
case 0x08 :
case 0x0a :
case 0x28 :
case 0x2a :
case 0xa8 :
case 0xaa :
if ( shdc [ id ] . request_length < block_len )
{
shdc [ id ] . request_length = block_len ;
}
/* Make sure we respect the limit of how many blocks we can transfer at once. */
if ( shdc [ id ] . requested_blocks > shdc [ id ] . max_blocks_at_once )
{
shdc [ id ] . requested_blocks = shdc [ id ] . max_blocks_at_once ;
}
shdc [ id ] . block_total = ( shdc [ id ] . requested_blocks * block_len ) ;
if ( len > shdc [ id ] . block_total )
{
len = shdc [ id ] . block_total ;
}
break ;
default :
shdc [ id ] . packet_len = len ;
break ;
}
/* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */
if ( ( shdc [ id ] . request_length & 1 ) & & ( shdc [ id ] . request_length < len ) )
{
shdc [ id ] . request_length & = 0xfffe ;
}
/* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */
if ( len < = shdc [ id ] . request_length )
{
shdc [ id ] . request_length = len ;
}
return ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
static void scsi_hd_command_common ( uint8_t id )
{
shdc [ id ] . status = BUSY_STAT ;
shdc [ id ] . phase = 1 ;
shdc [ id ] . pos = 0 ;
if ( shdc [ id ] . packet_status = = CDROM_PHASE_COMPLETE )
{
shdc [ id ] . callback = 20 * SCSI_TIME ;
}
else
{
shdc [ id ] . callback = 60 * SCSI_TIME ;
}
}
2017-08-24 01:14:39 -04:00
2017-08-15 19:49:25 +02:00
void scsi_hd_command_complete ( uint8_t id )
2017-05-05 01:49:42 +02:00
{
shdc [ id ] . packet_status = CDROM_PHASE_COMPLETE ;
scsi_hd_command_common ( id ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
static void scsi_hd_command_read_dma ( uint8_t id )
{
shdc [ id ] . packet_status = CDROM_PHASE_DATA_IN_DMA ;
scsi_hd_command_common ( id ) ;
shdc [ id ] . total_read = 0 ;
}
2017-08-24 01:14:39 -04:00
2017-10-08 05:04:38 +02:00
static void scsi_hd_command_write ( uint8_t id )
{
shdc [ id ] . packet_status = CDROM_PHASE_DATA_OUT ;
scsi_hd_command_common ( id ) ;
}
2017-05-05 01:49:42 +02:00
static void scsi_hd_command_write_dma ( uint8_t id )
{
shdc [ id ] . packet_status = CDROM_PHASE_DATA_OUT_DMA ;
scsi_hd_command_common ( id ) ;
}
2017-08-24 01:14:39 -04:00
2017-08-15 19:49:25 +02:00
void scsi_hd_data_command_finish ( uint8_t id , int len , int block_len , int alloc_len , int direction )
2017-05-05 01:49:42 +02:00
{
scsi_hd_log ( " SCSI HD %i: Finishing command (%02X): %i, %i, %i, %i, %i \n " , id , shdc [ id ] . current_cdb [ 0 ] , len , block_len , alloc_len , direction , shdc [ id ] . request_length ) ;
shdc [ id ] . pos = 0 ;
if ( alloc_len > = 0 )
{
if ( alloc_len < len )
{
len = alloc_len ;
}
}
if ( len = = 0 )
{
scsi_hd_command_complete ( id ) ;
}
else
{
if ( direction = = 0 )
{
scsi_hd_command_read_dma ( id ) ;
}
else
{
scsi_hd_command_write_dma ( id ) ;
}
}
scsi_hd_log ( " SCSI HD %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i \n " , id , shdc [ id ] . packet_status , shdc [ id ] . request_length , shdc [ id ] . packet_len , shdc [ id ] . pos , shdc [ id ] . phase ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
static void scsi_hd_sense_clear ( int id , int command )
{
shdc [ id ] . previous_command = command ;
scsi_hd_sense_key = scsi_hd_asc = scsi_hd_ascq = 0 ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
static void scsi_hd_cmd_error ( uint8_t id )
{
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
2017-05-05 01:49:42 +02:00
shdc [ id ] . error = ( ( scsi_hd_sense_key & 0xf ) < < 4 ) | ABRT_ERR ;
2017-05-27 03:53:32 +02:00
if ( shdc [ id ] . unit_attention & 3 )
2017-05-19 01:16:04 +02:00
{
shdc [ id ] . error | = MCR_ERR ;
}
2017-05-05 01:49:42 +02:00
shdc [ id ] . status = READY_STAT | ERR_STAT ;
shdc [ id ] . phase = 3 ;
shdc [ id ] . packet_status = 0x80 ;
shdc [ id ] . callback = 50 * SCSI_TIME ;
scsi_hd_log ( " SCSI HD %i: ERROR: %02X/%02X/%02X \n " , id , scsi_hd_sense_key , scsi_hd_asc , scsi_hd_ascq ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-19 01:16:04 +02:00
static void scsi_hd_unit_attention ( uint8_t id )
{
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
2017-05-27 03:53:32 +02:00
shdc [ id ] . error = ( SENSE_NOT_READY < < 4 ) | ABRT_ERR ;
if ( shdc [ id ] . unit_attention & 3 )
2017-05-19 01:16:04 +02:00
{
shdc [ id ] . error | = MCR_ERR ;
}
shdc [ id ] . status = READY_STAT | ERR_STAT ;
shdc [ id ] . phase = 3 ;
shdc [ id ] . packet_status = 0x80 ;
shdc [ id ] . callback = 50 * CDROM_TIME ;
scsi_hd_log ( " SCSI HD %i: UNIT ATTENTION \n " , id ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-19 01:16:04 +02:00
static void scsi_hd_not_ready ( uint8_t id )
{
scsi_hd_sense_key = SENSE_NOT_READY ;
scsi_hd_asc = ASC_MEDIUM_NOT_PRESENT ;
scsi_hd_ascq = 0 ;
scsi_hd_cmd_error ( id ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-27 03:53:32 +02:00
static void scsi_hd_write_protected ( uint8_t id )
{
scsi_hd_sense_key = SENSE_UNIT_ATTENTION ;
scsi_hd_asc = ASC_WRITE_PROTECTED ;
scsi_hd_ascq = 0 ;
scsi_hd_cmd_error ( id ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
static void scsi_hd_invalid_lun ( uint8_t id )
{
scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST ;
scsi_hd_asc = ASC_INV_LUN ;
scsi_hd_ascq = 0 ;
2017-10-08 05:04:38 +02:00
SCSIPhase = BUS_CD | BUS_IO ;
2017-05-05 01:49:42 +02:00
scsi_hd_cmd_error ( id ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
static void scsi_hd_illegal_opcode ( uint8_t id )
{
scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST ;
scsi_hd_asc = ASC_ILLEGAL_OPCODE ;
scsi_hd_ascq = 0 ;
scsi_hd_cmd_error ( id ) ;
}
2017-08-24 01:14:39 -04:00
2017-08-15 19:49:25 +02:00
void scsi_hd_lba_out_of_range ( uint8_t id )
2017-05-05 01:49:42 +02:00
{
scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST ;
scsi_hd_asc = ASC_LBA_OUT_OF_RANGE ;
scsi_hd_ascq = 0 ;
scsi_hd_cmd_error ( id ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
static void scsi_hd_invalid_field ( uint8_t id )
{
scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST ;
scsi_hd_asc = ASC_INV_FIELD_IN_CMD_PACKET ;
scsi_hd_ascq = 0 ;
scsi_hd_cmd_error ( id ) ;
shdc [ id ] . status = 0x53 ;
}
2017-08-24 01:14:39 -04:00
2017-10-08 05:04:38 +02:00
static void scsi_hd_invalid_field_pl ( uint8_t id )
{
scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST ;
scsi_hd_asc = ASC_INV_FIELD_IN_PARAMETER_LIST ;
scsi_hd_ascq = 0 ;
scsi_hd_cmd_error ( id ) ;
shdc [ id ] . status = 0x53 ;
}
2017-05-05 01:49:42 +02:00
static void scsi_hd_data_phase_error ( uint8_t id )
{
scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST ;
scsi_hd_asc = ASC_DATA_PHASE_ERROR ;
scsi_hd_ascq = 0 ;
scsi_hd_cmd_error ( id ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
/*SCSI Sense Initialization*/
void scsi_hd_sense_code_ok ( uint8_t id )
{
scsi_hd_sense_key = SENSE_NONE ;
scsi_hd_asc = 0 ;
scsi_hd_ascq = 0 ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
int scsi_hd_pre_execution_check ( uint8_t id , uint8_t * cdb )
{
2017-05-19 01:16:04 +02:00
int ready = 1 ;
2017-09-30 16:56:38 -04:00
if ( ( ( shdc [ id ] . request_length > > 5 ) & 7 ) ! = hdd [ id ] . scsi_lun )
2017-05-05 01:49:42 +02:00
{
scsi_hd_log ( " SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i \n " , id , ( ( shdc [ id ] . request_length > > 5 ) & 7 ) ) ;
scsi_hd_invalid_lun ( id ) ;
return 0 ;
}
if ( ! ( scsi_hd_command_flags [ cdb [ 0 ] ] & IMPLEMENTED ) )
{
scsi_hd_log ( " SCSI HD %i: Attempting to execute unknown command %02X \n " , id , cdb [ 0 ] ) ;
scsi_hd_illegal_opcode ( id ) ;
return 0 ;
}
2017-09-30 16:56:38 -04:00
if ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE )
2017-05-19 01:16:04 +02:00
{
/* Removable disk, set ready state. */
2017-09-30 16:56:38 -04:00
if ( wcslen ( hdd [ id ] . fn ) > 0 )
2017-05-19 01:16:04 +02:00
{
ready = 1 ;
}
else
{
ready = 0 ;
}
}
else
{
/* Fixed disk, clear UNIT ATTENTION, just in case it might have been set when the disk was removable). */
shdc [ id ] . unit_attention = 0 ;
}
if ( ! ready & & shdc [ id ] . unit_attention )
{
/* If the drive is not ready, there is no reason to keep the
UNIT ATTENTION condition present , as we only use it to mark
disc changes . */
shdc [ id ] . unit_attention = 0 ;
}
/* If the UNIT ATTENTION condition is set and the command does not allow
execution under it , error out and report the condition . */
if ( shdc [ id ] . unit_attention = = 1 )
{
/* Only increment the unit attention phase if the command can not pass through it. */
if ( ! ( scsi_hd_command_flags [ cdb [ 0 ] ] & ALLOW_UA ) )
{
/* scsi_hd_log("SCSI HD %i: Unit attention now 2\n", id); */
shdc [ id ] . unit_attention = 2 ;
scsi_hd_log ( " SCSI HD %i: UNIT ATTENTION: Command %02X not allowed to pass through \n " , id , cdb [ 0 ] ) ;
scsi_hd_unit_attention ( id ) ;
return 0 ;
}
}
else if ( shdc [ id ] . unit_attention = = 2 )
{
if ( cdb [ 0 ] ! = GPCMD_REQUEST_SENSE )
{
/* scsi_hd_log("SCSI HD %i: Unit attention now 0\n", id); */
shdc [ id ] . unit_attention = 0 ;
}
}
2017-05-05 01:49:42 +02:00
/* Unless the command is REQUEST SENSE, clear the sense. This will *NOT*
the UNIT ATTENTION condition if it ' s set . */
if ( cdb [ 0 ] ! = GPCMD_REQUEST_SENSE )
{
scsi_hd_sense_clear ( id , cdb [ 0 ] ) ;
}
2017-05-19 01:16:04 +02:00
/* Next it's time for NOT READY. */
if ( ( scsi_hd_command_flags [ cdb [ 0 ] ] & CHECK_READY ) & & ! ready )
{
scsi_hd_log ( " SCSI HD %i: Not ready (%02X) \n " , id , cdb [ 0 ] ) ;
scsi_hd_not_ready ( id ) ;
return 0 ;
}
2017-05-05 01:49:42 +02:00
scsi_hd_log ( " SCSI HD %i: Continuing with command \n " , id ) ;
return 1 ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
static void scsi_hd_seek ( uint8_t id , uint32_t pos )
{
/* scsi_hd_log("SCSI HD %i: Seek %08X\n", id, pos); */
2017-06-16 03:18:59 +02:00
hdd_image_seek ( id , pos ) ;
2017-05-05 01:49:42 +02:00
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
static void scsi_hd_rezero ( uint8_t id )
{
2017-05-27 03:53:32 +02:00
if ( id = = 255 )
{
return ;
}
2017-05-05 01:49:42 +02:00
shdc [ id ] . sector_pos = shdc [ id ] . sector_len = 0 ;
scsi_hd_seek ( id , 0 ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
void scsi_hd_reset ( uint8_t id )
{
scsi_hd_rezero ( id ) ;
shdc [ id ] . status = 0 ;
shdc [ id ] . callback = 0 ;
shdc [ id ] . packet_status = 0xff ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
void scsi_hd_request_sense ( uint8_t id , uint8_t * buffer , uint8_t alloc_length )
{
/*Will return 18 bytes of 0*/
if ( alloc_length ! = 0 )
{
memset ( buffer , 0 , alloc_length ) ;
memcpy ( buffer , shdc [ id ] . sense , alloc_length ) ;
}
buffer [ 0 ] = 0x70 ;
2017-05-19 01:16:04 +02:00
if ( shdc [ id ] . unit_attention & & ( scsi_hd_sense_key = = 0 ) )
{
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
2017-05-19 01:16:04 +02:00
buffer [ 2 ] = SENSE_UNIT_ATTENTION ;
buffer [ 12 ] = ASC_MEDIUM_MAY_HAVE_CHANGED ;
2017-05-27 03:53:32 +02:00
buffer [ 13 ] = 0x00 ;
2017-05-19 01:16:04 +02:00
}
2017-10-08 05:04:38 +02:00
scsi_hd_log ( " SCSI HD %i: Reporting sense: %02X %02X %02X \n " , id , buffer [ 2 ] , buffer [ 12 ] , buffer [ 13 ] ) ;
2017-05-05 01:49:42 +02:00
2017-05-19 01:16:04 +02:00
if ( buffer [ 2 ] = = SENSE_UNIT_ATTENTION )
{
/* If the last remaining sense is unit attention, clear
that condition . */
shdc [ id ] . unit_attention = 0 ;
}
2017-05-05 01:49:42 +02:00
/* Clear the sense stuff as per the spec. */
scsi_hd_sense_clear ( id , GPCMD_REQUEST_SENSE ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
void scsi_hd_request_sense_for_scsi ( uint8_t id , uint8_t * buffer , uint8_t alloc_length )
{
2017-05-19 01:16:04 +02:00
int ready = 1 ;
2017-09-30 16:56:38 -04:00
if ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE )
2017-05-19 01:16:04 +02:00
{
/* Removable disk, set ready state. */
2017-09-30 16:56:38 -04:00
if ( wcslen ( hdd [ id ] . fn ) > 0 )
2017-05-19 01:16:04 +02:00
{
ready = 1 ;
}
else
{
ready = 0 ;
}
}
else
{
/* Fixed disk, clear UNIT ATTENTION, just in case it might have been set when the disk was removable). */
shdc [ id ] . unit_attention = 0 ;
}
if ( ! ready & & shdc [ id ] . unit_attention )
{
/* If the drive is not ready, there is no reason to keep the
UNIT ATTENTION condition present , as we only use it to mark
disc changes . */
shdc [ id ] . unit_attention = 0 ;
}
2017-05-05 01:49:42 +02:00
/* Do *NOT* advance the unit attention phase. */
scsi_hd_request_sense ( id , buffer , alloc_length ) ;
}
2017-08-24 01:14:39 -04:00
2017-05-05 01:49:42 +02:00
void scsi_hd_command ( uint8_t id , uint8_t * cdb )
{
2017-05-29 01:18:32 +02:00
/* uint8_t *hdbufferb = (uint8_t *) shdc[id].buffer; */
2017-09-30 16:56:38 -04:00
uint8_t * hdbufferb = SCSIDevices [ hdd [ id ] . scsi_id ] [ hdd [ id ] . scsi_lun ] . CmdBuffer ;
2017-05-05 01:49:42 +02:00
uint32_t len ;
int pos = 0 ;
int max_len ;
unsigned idx = 0 ;
unsigned size_idx ;
unsigned preamble_len ;
uint32_t alloc_length ;
2017-05-27 03:53:32 +02:00
char device_identify [ 9 ] = { ' 8 ' , ' 6 ' , ' B ' , ' _ ' , ' H ' , ' D ' , ' 0 ' , ' 0 ' , 0 } ;
char device_identify_ex [ 15 ] = { ' 8 ' , ' 6 ' , ' B ' , ' _ ' , ' H ' , ' D ' , ' 0 ' , ' 0 ' , ' ' , ' v ' , ' 1 ' , ' . ' , ' 0 ' , ' 0 ' , 0 } ;
2017-06-16 03:18:59 +02:00
uint8_t * tempbuffer ;
uint32_t last_sector = 0 ;
2017-10-08 05:04:38 +02:00
int block_desc = 0 ;
2017-05-05 01:49:42 +02:00
#if 0
int CdbLength ;
# endif
2017-06-16 03:18:59 +02:00
last_sector = hdd_image_get_last_sector ( id ) ;
2017-05-05 01:49:42 +02:00
shdc [ id ] . status & = ~ ERR_STAT ;
shdc [ id ] . packet_len = 0 ;
shdc [ id ] . request_pos = 0 ;
2017-05-27 03:53:32 +02:00
device_identify [ 6 ] = ( id / 10 ) + 0x30 ;
device_identify [ 7 ] = ( id % 10 ) + 0x30 ;
device_identify_ex [ 6 ] = ( id / 10 ) + 0x30 ;
device_identify_ex [ 7 ] = ( id % 10 ) + 0x30 ;
2017-06-04 02:11:19 -04:00
device_identify_ex [ 10 ] = EMU_VERSION [ 0 ] ;
device_identify_ex [ 12 ] = EMU_VERSION [ 2 ] ;
device_identify_ex [ 13 ] = EMU_VERSION [ 3 ] ;
2017-05-27 03:53:32 +02:00
2017-09-30 16:56:38 -04:00
if ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE )
2017-05-27 03:53:32 +02:00
{
device_identify [ 4 ] = ' R ' ;
device_identify_ex [ 4 ] = ' R ' ;
}
2017-05-05 01:49:42 +02:00
shdc [ id ] . data_pos = 0 ;
2017-06-16 03:18:59 +02:00
memcpy ( shdc [ id ] . current_cdb , cdb , 12 ) ;
2017-05-05 01:49:42 +02:00
if ( cdb [ 0 ] ! = 0 )
{
scsi_hd_log ( " SCSI HD %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i \n " , id , cdb [ 0 ] , scsi_hd_sense_key , scsi_hd_asc , scsi_hd_ascq , ins ) ;
scsi_hd_log ( " SCSI HD %i: Request length: %04X \n " , id , shdc [ id ] . request_length ) ;
#if 0
2017-06-16 03:18:59 +02:00
for ( CdbLength = 1 ; CdbLength < 12 ; CdbLength + + )
2017-05-05 01:49:42 +02:00
{
2017-10-08 05:04:38 +02:00
scsi_hd_log ( " SCSI HD %i: CDB[%d] = %d \n " , id , CdbLength , cdb [ CdbLength ] ) ;
2017-05-05 01:49:42 +02:00
}
# endif
}
shdc [ id ] . sector_len = 0 ;
2017-10-09 02:35:12 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
2017-05-05 01:49:42 +02:00
/* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */
if ( scsi_hd_pre_execution_check ( id , cdb ) = = 0 )
{
return ;
}
switch ( cdb [ 0 ] )
{
case GPCMD_TEST_UNIT_READY :
2017-05-05 22:36:10 +02:00
case GPCMD_FORMAT_UNIT :
2017-05-05 01:49:42 +02:00
case GPCMD_VERIFY_6 :
case GPCMD_VERIFY_10 :
case GPCMD_VERIFY_12 :
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
2017-05-05 01:49:42 +02:00
scsi_hd_command_complete ( id ) ;
break ;
case GPCMD_REZERO_UNIT :
shdc [ id ] . sector_pos = shdc [ id ] . sector_len = 0 ;
scsi_hd_seek ( id , 0 ) ;
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
2017-05-05 01:49:42 +02:00
break ;
case GPCMD_REQUEST_SENSE :
/* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE
should forget about the not ready , and report unit attention straight away . */
2017-10-11 01:17:41 +02:00
if ( ( SCSI_BufferLength = = - 1 ) | | ( cdb [ 4 ] < SCSI_BufferLength ) )
2017-10-08 05:04:38 +02:00
{
SCSI_BufferLength = cdb [ 4 ] ;
}
if ( SCSI_BufferLength < cdb [ 4 ] )
2017-09-02 05:41:19 +02:00
{
2017-10-08 05:04:38 +02:00
cdb [ 4 ] = SCSI_BufferLength ;
2017-09-02 05:41:19 +02:00
}
2017-05-05 01:49:42 +02:00
scsi_hd_request_sense ( id , hdbufferb , cdb [ 4 ] ) ;
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_DATA_IN ;
2017-05-05 01:49:42 +02:00
scsi_hd_data_command_finish ( id , 18 , 18 , cdb [ 4 ] , 0 ) ;
break ;
case GPCMD_MECHANISM_STATUS :
2017-07-30 17:09:56 -04:00
len = ( cdb [ 7 ] < < 16 ) | ( cdb [ 8 ] < < 8 ) | cdb [ 9 ] ;
2017-05-05 01:49:42 +02:00
2017-10-11 01:17:41 +02:00
if ( ( SCSI_BufferLength = = - 1 ) | | ( len < SCSI_BufferLength ) )
2017-10-08 05:04:38 +02:00
{
SCSI_BufferLength = len ;
}
2017-05-05 01:49:42 +02:00
memset ( hdbufferb , 0 , 8 ) ;
hdbufferb [ 5 ] = 1 ;
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_DATA_IN ;
2017-05-05 01:49:42 +02:00
scsi_hd_data_command_finish ( id , 8 , 8 , len , 0 ) ;
break ;
case GPCMD_READ_6 :
case GPCMD_READ_10 :
case GPCMD_READ_12 :
switch ( cdb [ 0 ] )
{
case GPCMD_READ_6 :
shdc [ id ] . sector_len = cdb [ 4 ] ;
shdc [ id ] . sector_pos = ( ( ( ( uint32_t ) cdb [ 1 ] ) & 0x1f ) < < 16 ) | ( ( ( uint32_t ) cdb [ 2 ] ) < < 8 ) | ( ( uint32_t ) cdb [ 3 ] ) ;
break ;
case GPCMD_READ_10 :
shdc [ id ] . sector_len = ( cdb [ 7 ] < < 8 ) | cdb [ 8 ] ;
shdc [ id ] . sector_pos = ( cdb [ 2 ] < < 24 ) | ( cdb [ 3 ] < < 16 ) | ( cdb [ 4 ] < < 8 ) | cdb [ 5 ] ;
break ;
case GPCMD_READ_12 :
shdc [ id ] . sector_len = ( ( ( uint32_t ) cdb [ 6 ] ) < < 24 ) | ( ( ( uint32_t ) cdb [ 7 ] ) < < 16 ) | ( ( ( uint32_t ) cdb [ 8 ] ) < < 8 ) | ( ( uint32_t ) cdb [ 9 ] ) ;
shdc [ id ] . sector_pos = ( ( ( uint32_t ) cdb [ 2 ] ) < < 24 ) | ( ( ( uint32_t ) cdb [ 3 ] ) < < 16 ) | ( ( ( uint32_t ) cdb [ 4 ] ) < < 8 ) | ( ( uint32_t ) cdb [ 5 ] ) ;
break ;
}
2017-06-16 03:18:59 +02:00
if ( ( shdc [ id ] . sector_pos > last_sector ) | | ( ( shdc [ id ] . sector_pos + shdc [ id ] . sector_len - 1 ) > last_sector ) )
2017-05-29 06:17:13 +02:00
{
scsi_hd_lba_out_of_range ( id ) ;
return ;
}
2017-10-08 05:04:38 +02:00
if ( ( ! shdc [ id ] . sector_len ) | | ( SCSI_BufferLength = = 0 ) )
2017-05-05 01:49:42 +02:00
{
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
scsi_hd_log ( " SCSI HD %i: All done - callback set \n " , id ) ;
2017-05-05 01:49:42 +02:00
shdc [ id ] . packet_status = CDROM_PHASE_COMPLETE ;
shdc [ id ] . callback = 20 * SCSI_TIME ;
break ;
}
max_len = shdc [ id ] . sector_len ;
shdc [ id ] . requested_blocks = max_len ;
2017-05-29 06:17:13 +02:00
alloc_length = shdc [ id ] . packet_len = max_len < < 9 ;
2017-10-11 01:17:41 +02:00
if ( ( SCSI_BufferLength = = - 1 ) | | ( alloc_length < SCSI_BufferLength ) )
2017-10-08 05:04:38 +02:00
{
SCSI_BufferLength = alloc_length ;
}
if ( ( shdc [ id ] . requested_blocks > 0 ) & & ( SCSI_BufferLength > 0 ) )
2017-05-05 01:49:42 +02:00
{
2017-10-08 05:04:38 +02:00
if ( alloc_length > SCSI_BufferLength )
2017-05-29 06:17:13 +02:00
{
2017-10-08 05:04:38 +02:00
hdd_image_read ( id , shdc [ id ] . sector_pos , SCSI_BufferLength > > 9 , hdbufferb ) ;
2017-05-29 06:17:13 +02:00
}
else
{
2017-06-16 03:18:59 +02:00
hdd_image_read ( id , shdc [ id ] . sector_pos , max_len , hdbufferb ) ;
2017-05-29 06:17:13 +02:00
}
2017-05-05 01:49:42 +02:00
}
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_DATA_IN ;
2017-05-05 01:49:42 +02:00
if ( shdc [ id ] . requested_blocks > 1 )
{
scsi_hd_data_command_finish ( id , alloc_length , alloc_length / shdc [ id ] . requested_blocks , alloc_length , 0 ) ;
}
else
{
scsi_hd_data_command_finish ( id , alloc_length , alloc_length , alloc_length , 0 ) ;
}
shdc [ id ] . all_blocks_total = shdc [ id ] . block_total ;
if ( shdc [ id ] . packet_status ! = CDROM_PHASE_COMPLETE )
{
2017-10-10 03:07:29 -04:00
ui_sb_update_icon ( ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE ) ? ( SB_RDISK | id ) : ( SB_HDD | HDD_BUS_SCSI ) , 1 ) ;
2017-05-05 01:49:42 +02:00
}
else
{
2017-10-10 03:07:29 -04:00
ui_sb_update_icon ( ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE ) ? ( SB_RDISK | id ) : ( SB_HDD | HDD_BUS_SCSI ) , 0 ) ;
2017-05-05 01:49:42 +02:00
}
return ;
2017-10-08 05:04:38 +02:00
case GPCMD_MODE_SENSE_6 :
case GPCMD_MODE_SENSE_10 :
SCSIPhase = SCSI_PHASE_DATA_IN ;
block_desc = ( ( cdb [ 1 ] > > 3 ) & 1 ) ? 0 : 1 ;
if ( cdb [ 0 ] = = GPCMD_MODE_SENSE_6 )
{
len = cdb [ 4 ] ;
}
else
{
len = ( cdb [ 8 ] | ( cdb [ 7 ] < < 8 ) ) ;
}
shdc [ id ] . current_page_code = cdb [ 2 ] & 0x3F ;
if ( ! ( scsi_hd_mode_sense_page_flags [ id ] & ( 1LL < < shdc [ id ] . current_page_code ) ) )
{
scsi_hd_invalid_field ( id ) ;
return ;
}
memset ( hdbufferb , 0 , len ) ;
alloc_length = len ;
if ( cdb [ 0 ] = = GPCMD_MODE_SENSE_6 )
{
len = scsi_hd_mode_sense ( id , hdbufferb , 4 , cdb [ 2 ] , block_desc ) ;
if ( len > alloc_length )
{
len = alloc_length ;
}
hdbufferb [ 0 ] = len - 1 ;
hdbufferb [ 1 ] = 0 ;
if ( block_desc )
{
hdbufferb [ 3 ] = 8 ;
}
}
else
{
len = scsi_hd_mode_sense ( id , hdbufferb , 8 , cdb [ 2 ] , block_desc ) ;
if ( len > alloc_length )
{
len = alloc_length ;
}
hdbufferb [ 0 ] = ( len - 2 ) > > 8 ;
hdbufferb [ 1 ] = ( len - 2 ) & 255 ;
hdbufferb [ 2 ] = 0 ;
if ( block_desc )
{
hdbufferb [ 6 ] = 0 ;
hdbufferb [ 7 ] = 8 ;
}
}
if ( len > alloc_length )
{
len = alloc_length ;
}
else if ( len < alloc_length )
{
alloc_length = len ;
}
2017-10-11 01:17:41 +02:00
if ( ( SCSI_BufferLength = = - 1 ) | | ( alloc_length < SCSI_BufferLength ) )
2017-10-08 05:04:38 +02:00
{
SCSI_BufferLength = alloc_length ;
}
scsi_hd_log ( " SCSI HDD %i: Reading mode page: %02X... \n " , id , cdb [ 2 ] ) ;
scsi_hd_data_command_finish ( id , len , len , alloc_length , 0 ) ;
return ;
case GPCMD_MODE_SELECT_6 :
case GPCMD_MODE_SELECT_10 :
SCSIPhase = SCSI_PHASE_DATA_OUT ;
if ( cdb [ 0 ] = = GPCMD_MODE_SELECT_6 )
{
len = cdb [ 4 ] ;
}
else
{
len = ( cdb [ 7 ] < < 8 ) | cdb [ 8 ] ;
}
2017-10-11 01:17:41 +02:00
if ( ( SCSI_BufferLength = = - 1 ) | | ( len < SCSI_BufferLength ) )
2017-10-08 05:04:38 +02:00
{
SCSI_BufferLength = len ;
}
scsi_hd_mode_select_init ( id , cdb [ 0 ] , len , cdb [ 1 ] & 1 ) ;
scsi_hd_data_command_finish ( id , len , len , len , 1 ) ;
return ;
2017-05-05 01:49:42 +02:00
case GPCMD_WRITE_6 :
case GPCMD_WRITE_10 :
case GPCMD_WRITE_12 :
2017-09-30 16:56:38 -04:00
if ( ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE ) & & hdd [ id ] . wp )
2017-05-27 03:53:32 +02:00
{
scsi_hd_write_protected ( id ) ;
return ;
}
2017-05-05 01:49:42 +02:00
switch ( cdb [ 0 ] )
{
case GPCMD_WRITE_6 :
shdc [ id ] . sector_len = cdb [ 4 ] ;
shdc [ id ] . sector_pos = ( ( ( ( uint32_t ) cdb [ 1 ] ) & 0x1f ) < < 16 ) | ( ( ( uint32_t ) cdb [ 2 ] ) < < 8 ) | ( ( uint32_t ) cdb [ 3 ] ) ;
2017-10-08 05:04:38 +02:00
scsi_hd_log ( " SCSI HD %i: Length: %i, LBA: %i \n " , id , shdc [ id ] . sector_len , shdc [ id ] . sector_pos ) ;
2017-05-05 01:49:42 +02:00
break ;
case GPCMD_WRITE_10 :
shdc [ id ] . sector_len = ( cdb [ 7 ] < < 8 ) | cdb [ 8 ] ;
shdc [ id ] . sector_pos = ( cdb [ 2 ] < < 24 ) | ( cdb [ 3 ] < < 16 ) | ( cdb [ 4 ] < < 8 ) | cdb [ 5 ] ;
scsi_hd_log ( " SCSI HD %i: Length: %i, LBA: %i \n " , id , shdc [ id ] . sector_len , shdc [ id ] . sector_pos ) ;
break ;
case GPCMD_WRITE_12 :
shdc [ id ] . sector_len = ( ( ( uint32_t ) cdb [ 6 ] ) < < 24 ) | ( ( ( uint32_t ) cdb [ 7 ] ) < < 16 ) | ( ( ( uint32_t ) cdb [ 8 ] ) < < 8 ) | ( ( uint32_t ) cdb [ 9 ] ) ;
shdc [ id ] . sector_pos = ( ( ( uint32_t ) cdb [ 2 ] ) < < 24 ) | ( ( ( uint32_t ) cdb [ 3 ] ) < < 16 ) | ( ( ( uint32_t ) cdb [ 4 ] ) < < 8 ) | ( ( uint32_t ) cdb [ 5 ] ) ;
break ;
}
2017-06-16 03:18:59 +02:00
if ( ( shdc [ id ] . sector_pos > last_sector ) | | ( ( shdc [ id ] . sector_pos + shdc [ id ] . sector_len - 1 ) > last_sector ) )
2017-05-29 06:17:13 +02:00
{
scsi_hd_lba_out_of_range ( id ) ;
return ;
}
2017-10-08 05:04:38 +02:00
if ( ( ! shdc [ id ] . sector_len ) | | ( SCSI_BufferLength = = 0 ) )
2017-05-05 01:49:42 +02:00
{
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
scsi_hd_log ( " SCSI HD %i: All done - callback set \n " , id ) ;
2017-05-05 01:49:42 +02:00
shdc [ id ] . packet_status = CDROM_PHASE_COMPLETE ;
shdc [ id ] . callback = 20 * SCSI_TIME ;
break ;
}
max_len = shdc [ id ] . sector_len ;
shdc [ id ] . requested_blocks = max_len ;
2017-10-08 05:04:38 +02:00
2017-05-29 06:17:13 +02:00
alloc_length = shdc [ id ] . packet_len = max_len < < 9 ;
2017-10-11 01:17:41 +02:00
if ( ( SCSI_BufferLength = = - 1 ) | | ( alloc_length < SCSI_BufferLength ) )
2017-05-05 01:49:42 +02:00
{
2017-10-08 05:04:38 +02:00
SCSI_BufferLength = alloc_length ;
2017-05-05 01:49:42 +02:00
}
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_DATA_OUT ;
2017-05-05 01:49:42 +02:00
if ( shdc [ id ] . requested_blocks > 1 )
{
scsi_hd_data_command_finish ( id , alloc_length , alloc_length / shdc [ id ] . requested_blocks , alloc_length , 1 ) ;
}
else
{
scsi_hd_data_command_finish ( id , alloc_length , alloc_length , alloc_length , 1 ) ;
}
shdc [ id ] . all_blocks_total = shdc [ id ] . block_total ;
2017-10-10 03:07:29 -04:00
ui_sb_update_icon ( ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE ) ? ( SB_RDISK | id ) : ( SB_HDD | HDD_BUS_SCSI ) , 1 ) ;
2017-05-05 01:49:42 +02:00
return ;
2017-05-19 01:16:04 +02:00
case GPCMD_START_STOP_UNIT :
2017-09-30 16:56:38 -04:00
if ( hdd [ id ] . bus ! = HDD_BUS_SCSI_REMOVABLE )
2017-05-19 01:16:04 +02:00
{
scsi_hd_illegal_opcode ( id ) ;
break ;
}
2017-05-19 04:35:59 +02:00
switch ( cdb [ 4 ] & 3 )
2017-05-19 01:16:04 +02:00
{
case 0 : /* Stop the disc. */
case 1 : /* Start the disc and read the TOC. */
break ;
case 2 : /* Eject the disc if possible. */
2017-05-27 03:53:32 +02:00
removable_disk_eject ( id ) ;
2017-05-19 01:16:04 +02:00
break ;
case 3 : /* Load the disc (close tray). */
2017-05-27 03:53:32 +02:00
removable_disk_reload ( id ) ;
2017-05-19 01:16:04 +02:00
break ;
}
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
2017-05-19 01:16:04 +02:00
scsi_hd_command_complete ( id ) ;
break ;
2017-05-05 01:49:42 +02:00
case GPCMD_INQUIRY :
max_len = cdb [ 3 ] ;
max_len < < = 8 ;
max_len | = cdb [ 4 ] ;
2017-10-08 05:04:38 +02:00
if ( ( ! max_len ) | | ( SCSI_BufferLength = = 0 ) )
2017-05-29 06:17:13 +02:00
{
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
2017-05-29 06:17:13 +02:00
/* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */
shdc [ id ] . packet_status = CDROM_PHASE_COMPLETE ;
shdc [ id ] . callback = 20 * SCSI_TIME ;
break ;
2017-10-08 05:04:38 +02:00
}
2017-05-29 06:17:13 +02:00
tempbuffer = malloc ( 1024 ) ;
2017-05-05 01:49:42 +02:00
if ( cdb [ 1 ] & 1 )
{
preamble_len = 4 ;
size_idx = 3 ;
2017-05-29 06:17:13 +02:00
tempbuffer [ idx + + ] = 05 ;
tempbuffer [ idx + + ] = cdb [ 2 ] ;
tempbuffer [ idx + + ] = 0 ;
2017-05-05 01:49:42 +02:00
idx + + ;
switch ( cdb [ 2 ] )
{
case 0x00 :
2017-05-29 06:17:13 +02:00
tempbuffer [ idx + + ] = 0x00 ;
tempbuffer [ idx + + ] = 0x83 ;
2017-05-05 01:49:42 +02:00
break ;
case 0x83 :
if ( idx + 24 > max_len )
{
scsi_hd_data_phase_error ( id ) ;
return ;
}
2017-05-29 06:17:13 +02:00
tempbuffer [ idx + + ] = 0x02 ;
tempbuffer [ idx + + ] = 0x00 ;
tempbuffer [ idx + + ] = 0x00 ;
tempbuffer [ idx + + ] = 20 ;
2017-05-05 01:49:42 +02:00
ide_padstr8 ( hdbufferb + idx , 20 , " 53R141 " ) ; /* Serial */
idx + = 20 ;
if ( idx + 72 > cdb [ 4 ] )
{
goto atapi_out ;
}
2017-05-29 06:17:13 +02:00
tempbuffer [ idx + + ] = 0x02 ;
tempbuffer [ idx + + ] = 0x01 ;
tempbuffer [ idx + + ] = 0x00 ;
tempbuffer [ idx + + ] = 68 ;
2017-06-04 02:11:19 -04:00
ide_padstr8 ( tempbuffer + idx , 8 , EMU_NAME ) ; /* Vendor */
2017-05-05 01:49:42 +02:00
idx + = 8 ;
2017-05-29 06:17:13 +02:00
ide_padstr8 ( tempbuffer + idx , 40 , device_identify_ex ) ; /* Product */
2017-05-05 01:49:42 +02:00
idx + = 40 ;
2017-05-29 06:17:13 +02:00
ide_padstr8 ( tempbuffer + idx , 20 , " 53R141 " ) ; /* Product */
2017-05-05 01:49:42 +02:00
idx + = 20 ;
break ;
default :
scsi_hd_log ( " INQUIRY: Invalid page: %02X \n " , cdb [ 2 ] ) ;
scsi_hd_invalid_field ( id ) ;
return ;
}
}
else
{
preamble_len = 5 ;
size_idx = 4 ;
2017-05-29 06:17:13 +02:00
memset ( tempbuffer , 0 , 8 ) ;
tempbuffer [ 0 ] = 0 ; /*SCSI HD*/
2017-09-30 16:56:38 -04:00
if ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE )
2017-05-19 01:16:04 +02:00
{
2017-05-29 06:17:13 +02:00
tempbuffer [ 1 ] = 0x80 ; /*Removable*/
2017-05-19 01:16:04 +02:00
}
else
{
2017-05-29 06:17:13 +02:00
tempbuffer [ 1 ] = 0 ; /*Fixed*/
2017-05-19 01:16:04 +02:00
}
2017-05-29 06:17:13 +02:00
tempbuffer [ 2 ] = 0x02 ; /*SCSI-2 compliant*/
tempbuffer [ 3 ] = 0x02 ;
tempbuffer [ 4 ] = 31 ;
2017-05-05 01:49:42 +02:00
2017-06-04 02:11:19 -04:00
ide_padstr8 ( tempbuffer + 8 , 8 , EMU_NAME ) ; /* Vendor */
2017-05-29 06:17:13 +02:00
ide_padstr8 ( tempbuffer + 16 , 16 , device_identify ) ; /* Product */
2017-06-04 02:11:19 -04:00
ide_padstr8 ( tempbuffer + 32 , 4 , EMU_VERSION ) ; /* Revision */
2017-05-05 01:49:42 +02:00
idx = 36 ;
}
atapi_out :
2017-05-29 06:17:13 +02:00
tempbuffer [ size_idx ] = idx - preamble_len ;
2017-05-05 01:49:42 +02:00
len = idx ;
2017-10-08 05:04:38 +02:00
2017-05-29 06:17:13 +02:00
if ( len > max_len )
{
len = max_len ;
}
2017-10-08 05:04:38 +02:00
2017-10-11 01:17:41 +02:00
if ( ( SCSI_BufferLength = = - 1 ) | | ( len < SCSI_BufferLength ) )
2017-05-29 06:17:13 +02:00
{
2017-10-08 05:04:38 +02:00
SCSI_BufferLength = len ;
2017-05-29 06:17:13 +02:00
}
2017-10-08 05:04:38 +02:00
if ( len > SCSI_BufferLength )
{
len = SCSI_BufferLength ;
}
2017-05-29 06:17:13 +02:00
memcpy ( hdbufferb , tempbuffer , len ) ;
free ( tempbuffer ) ;
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_DATA_IN ;
2017-05-05 01:49:42 +02:00
scsi_hd_data_command_finish ( id , len , len , max_len , 0 ) ;
break ;
case GPCMD_PREVENT_REMOVAL :
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
2017-05-05 01:49:42 +02:00
scsi_hd_command_complete ( id ) ;
break ;
case GPCMD_SEEK_6 :
case GPCMD_SEEK_10 :
switch ( cdb [ 0 ] )
{
case GPCMD_SEEK_6 :
pos = ( cdb [ 2 ] < < 8 ) | cdb [ 3 ] ;
break ;
case GPCMD_SEEK_10 :
pos = ( cdb [ 2 ] < < 24 ) | ( cdb [ 3 ] < < 16 ) | ( cdb [ 4 ] < < 8 ) | cdb [ 5 ] ;
break ;
}
scsi_hd_seek ( id , pos ) ;
2017-10-08 05:04:38 +02:00
SCSIPhase = SCSI_PHASE_STATUS ;
2017-05-05 01:49:42 +02:00
scsi_hd_command_complete ( id ) ;
break ;
case GPCMD_READ_CDROM_CAPACITY :
if ( scsi_hd_read_capacity ( id , shdc [ id ] . current_cdb , hdbufferb , & len ) = = 0 )
{
return ;
}
2017-10-11 01:17:41 +02:00
if ( ( SCSI_BufferLength = = - 1 ) | | ( len < SCSI_BufferLength ) )
2017-10-08 05:04:38 +02:00
{
SCSI_BufferLength = len ;
}
SCSIPhase = SCSI_PHASE_DATA_IN ;
2017-05-05 01:49:42 +02:00
scsi_hd_data_command_finish ( id , len , len , len , 0 ) ;
break ;
default :
scsi_hd_illegal_opcode ( id ) ;
break ;
}
2017-10-08 05:04:38 +02:00
2017-05-05 01:49:42 +02:00
/* scsi_hd_log("SCSI HD %i: Phase: %02X, request length: %i\n", shdc[id].phase, shdc[id].request_length); */
}
2017-10-08 05:04:38 +02:00
/* 0 = Continue transfer; 1 = Continue transfer, IRQ; -1 = Terminate transfer; -2 = Terminate transfer with error */
int scsi_hd_mode_select_return ( uint8_t id , int ret )
{
switch ( ret )
{
case 0 :
/* Invalid field in parameter list. */
case - 6 :
/* Attempted to write to a non-existent SCSI HDD drive (should never occur, but you never know). */
scsi_hd_invalid_field_pl ( id ) ;
return - 2 ;
case 1 :
/* Successful, more data needed. */
if ( shdc [ id ] . pos > = ( shdc [ id ] . packet_len + 2 ) )
{
shdc [ id ] . pos = 0 ;
scsi_hd_command_write ( id ) ;
return 1 ;
}
return 0 ;
case 2 :
/* Successful, more data needed, second byte not yet processed. */
return 0 ;
case - 3 :
/* Not initialized. */
case - 4 :
/* Unknown phase. */
scsi_hd_illegal_opcode ( id ) ;
return - 2 ;
case - 5 :
/* Command terminated successfully. */
/* scsi_hd_command_complete(id); */
return - 1 ;
default :
return - 15 ;
}
}
void scsi_hd_phase_data_out ( uint8_t id )
{
int ret = 0 ;
uint8_t * hdbufferb = SCSIDevices [ hdd [ id ] . scsi_id ] [ hdd [ id ] . scsi_lun ] . CmdBuffer ;
int in_data_length = 0 ;
int i ;
switch ( shdc [ id ] . current_cdb [ 0 ] )
{
case GPCMD_MODE_SELECT_6 :
case GPCMD_MODE_SELECT_10 :
in_data_length = SCSI_BufferLength ;
for ( i = 0 ; i < in_data_length ; i + + )
{
ret = scsi_hd_mode_select_write ( id , hdbufferb [ i ] ) ;
ret = scsi_hd_mode_select_return ( id , ret ) ;
if ( ret = = - 1 )
{
return ;
}
else if ( ret = = - 2 )
{
scsi_hd_callback ( id ) ;
return ;
}
}
break ;
case GPCMD_WRITE_6 :
case GPCMD_WRITE_10 :
case GPCMD_WRITE_12 :
if ( ( shdc [ id ] . requested_blocks > 0 ) & & ( SCSI_BufferLength > 0 ) )
{
if ( shdc [ id ] . packet_len > SCSI_BufferLength )
{
hdd_image_write ( id , shdc [ id ] . sector_pos , SCSI_BufferLength > > 9 , hdbufferb ) ;
}
else
{
hdd_image_write ( id , shdc [ id ] . sector_pos , shdc [ id ] . requested_blocks , hdbufferb ) ;
}
}
scsi_hd_log ( " HDD image written \n " ) ;
SCSIPhase = SCSI_PHASE_STATUS ;
2017-10-10 03:07:29 -04:00
ui_sb_update_icon ( ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE ) ? ( SB_RDISK | id ) : ( SB_HDD | HDD_BUS_SCSI ) , 0 ) ;
2017-10-08 05:04:38 +02:00
break ;
default :
fatal ( " SCSI HDD %i: Bad Command for phase 2 (%02X) \n " , shdc [ id ] . current_cdb [ 0 ] ) ;
break ;
}
}
2017-05-05 01:49:42 +02:00
/* If the result is 1, issue an IRQ, otherwise not. */
void scsi_hd_callback ( uint8_t id )
{
switch ( shdc [ id ] . packet_status )
{
case CDROM_PHASE_IDLE :
scsi_hd_log ( " SCSI HD %i: PHASE_IDLE \n " , id ) ;
shdc [ id ] . pos = 0 ;
shdc [ id ] . phase = 1 ;
shdc [ id ] . status = READY_STAT | DRQ_STAT | ( shdc [ id ] . status & ERR_STAT ) ;
return ;
case CDROM_PHASE_COMPLETE :
scsi_hd_log ( " SCSI HD %i: PHASE_COMPLETE \n " , id ) ;
shdc [ id ] . status = READY_STAT ;
shdc [ id ] . phase = 3 ;
shdc [ id ] . packet_status = 0xFF ;
2017-10-10 03:07:29 -04:00
ui_sb_update_icon ( ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE ) ? ( SB_RDISK | id ) : ( SB_HDD | HDD_BUS_SCSI ) , 0 ) ;
2017-05-05 01:49:42 +02:00
return ;
case CDROM_PHASE_DATA_OUT :
scsi_hd_log ( " SCSI HD %i: PHASE_DATA_OUT \n " , id ) ;
shdc [ id ] . status = READY_STAT | DRQ_STAT | ( shdc [ id ] . status & ERR_STAT ) ;
shdc [ id ] . phase = 0 ;
return ;
case CDROM_PHASE_DATA_OUT_DMA :
scsi_hd_log ( " SCSI HD %i: PHASE_DATA_OUT_DMA \n " , id ) ;
2017-10-08 05:04:38 +02:00
scsi_hd_phase_data_out ( id ) ;
2017-05-05 01:49:42 +02:00
shdc [ id ] . packet_status = CDROM_PHASE_COMPLETE ;
shdc [ id ] . status = READY_STAT ;
shdc [ id ] . phase = 3 ;
2017-10-10 03:07:29 -04:00
ui_sb_update_icon ( ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE ) ? ( SB_RDISK | id ) : ( SB_HDD | HDD_BUS_SCSI ) , 0 ) ;
2017-05-05 01:49:42 +02:00
return ;
case CDROM_PHASE_DATA_IN :
scsi_hd_log ( " SCSI HD %i: PHASE_DATA_IN \n " , id ) ;
shdc [ id ] . status = READY_STAT | DRQ_STAT | ( shdc [ id ] . status & ERR_STAT ) ;
shdc [ id ] . phase = 2 ;
return ;
case CDROM_PHASE_DATA_IN_DMA :
scsi_hd_log ( " SCSI HD %i: PHASE_DATA_IN_DMA \n " , id ) ;
shdc [ id ] . packet_status = CDROM_PHASE_COMPLETE ;
shdc [ id ] . status = READY_STAT ;
shdc [ id ] . phase = 3 ;
2017-10-10 03:07:29 -04:00
ui_sb_update_icon ( ( hdd [ id ] . bus = = HDD_BUS_SCSI_REMOVABLE ) ? ( SB_RDISK | id ) : ( SB_HDD | HDD_BUS_SCSI ) , 0 ) ;
2017-05-05 01:49:42 +02:00
return ;
case CDROM_PHASE_ERROR :
scsi_hd_log ( " SCSI HD %i: PHASE_ERROR \n " , id ) ;
shdc [ id ] . status = READY_STAT | ERR_STAT ;
shdc [ id ] . phase = 3 ;
return ;
}
}