|  | @@ -73,7 +73,8 @@ byte          m_msg;                     // Message bytes
 | 
	
		
			
				|  |  |  byte          m_buf[MAX_BLOCKSIZE];      // General purpose buffer
 | 
	
		
			
				|  |  |  byte          m_scsi_buf[SCSI_BUF_SIZE]; // Buffer for SCSI READ/WRITE Buffer
 | 
	
		
			
				|  |  |  byte          m_msb[256];                // Command storage bytes
 | 
	
		
			
				|  |  | -SCSI_DEVICE scsi_device_list[NUM_SCSIID][MAX_SCSILUN]; // Maximum number
 | 
	
		
			
				|  |  | +SCSI_DEVICE scsi_device_list[NUM_SCSIID][NUM_SCSILUN]; // Maximum number
 | 
	
		
			
				|  |  | +SCSI_INQUIRY_DATA default_hdd, default_optical;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static byte onUnimplemented(SCSI_DEVICE *dev, const byte *cdb)
 | 
	
		
			
				|  |  |  {
 | 
	
	
		
			
				|  | @@ -150,7 +151,7 @@ void readSCSIDeviceConfig(SCSI_DEVICE *dev) {
 | 
	
		
			
				|  |  |    if (!config_file.isOpen()) {
 | 
	
		
			
				|  |  |      return;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  SCSI_INQUIRY_DATA *iq = &dev->inquiry_block;
 | 
	
		
			
				|  |  | +  SCSI_INQUIRY_DATA *iq = dev->inquiry_block;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    char vendor[9];
 | 
	
		
			
				|  |  |    memset(vendor, 0, sizeof(vendor));
 | 
	
	
		
			
				|  | @@ -295,6 +296,30 @@ void setup()
 | 
	
		
			
				|  |  |    scsi_command_table[SCSI_SEND_DIAG] = onSendDiagnostic;
 | 
	
		
			
				|  |  |    scsi_command_table[SCSI_READ_DEFECT_DATA] = onReadDefectData;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  // clear and initialize default inquiry blocks
 | 
	
		
			
				|  |  | +  // default SCSI HDD
 | 
	
		
			
				|  |  | +  memset(&default_hdd, 0, sizeof(default_hdd));
 | 
	
		
			
				|  |  | +  default_hdd.ansi_version = 1;
 | 
	
		
			
				|  |  | +  default_hdd.response_format = 1;
 | 
	
		
			
				|  |  | +  default_hdd.additional_length = 31;
 | 
	
		
			
				|  |  | +  memcpy(&default_hdd.vendor, "QUANTUM", 7);
 | 
	
		
			
				|  |  | +  memcpy(&default_hdd.product, "FIREBALL1", 9);
 | 
	
		
			
				|  |  | +  memcpy(&default_hdd.revision, "1.0", 3);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // default SCSI CDROM
 | 
	
		
			
				|  |  | +  memset(&default_optical, 0, sizeof(default_optical));
 | 
	
		
			
				|  |  | +  default_optical.peripheral_device_type = 5;
 | 
	
		
			
				|  |  | +  default_optical.rmb = 1;
 | 
	
		
			
				|  |  | +  default_optical.ansi_version = 1;
 | 
	
		
			
				|  |  | +  default_optical.response_format = 1;
 | 
	
		
			
				|  |  | +  default_optical.additional_length = 42;
 | 
	
		
			
				|  |  | +  default_optical.sync = 1;
 | 
	
		
			
				|  |  | +  memcpy(&default_optical.vendor, "BLUESCSI", 8);
 | 
	
		
			
				|  |  | +  memcpy(&default_optical.product, "CD-ROM CDU-55S", 14);
 | 
	
		
			
				|  |  | +  memcpy(&default_optical.revision, "1.9a", 4);
 | 
	
		
			
				|  |  | +  default_optical.release = 0x20;
 | 
	
		
			
				|  |  | +  memcpy(&default_optical.revision_date, "1995", 4);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    // Serial initialization
 | 
	
		
			
				|  |  |  #if DEBUG > 0
 | 
	
		
			
				|  |  |    Serial.begin(9600);
 | 
	
	
		
			
				|  | @@ -521,27 +546,12 @@ void findDriveImages(FsFile root) {
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                case SCSI_DEVICE_HDD:
 | 
	
		
			
				|  |  |                // default SCSI HDD
 | 
	
		
			
				|  |  | -              dev->inquiry_block.ansi_version = 1;
 | 
	
		
			
				|  |  | -              dev->inquiry_block.response_format = 1;
 | 
	
		
			
				|  |  | -              dev->inquiry_block.additional_length = 31;
 | 
	
		
			
				|  |  | -              memcpy(dev->inquiry_block.vendor, "QUANTUM", 7);
 | 
	
		
			
				|  |  | -              memcpy(dev->inquiry_block.product, "BLUESCSI F1", 11);
 | 
	
		
			
				|  |  | -              memcpy(dev->inquiry_block.revision, "1.1", 3);
 | 
	
		
			
				|  |  | +              dev->inquiry_block = &default_hdd;        
 | 
	
		
			
				|  |  |                break;
 | 
	
		
			
				|  |  |                
 | 
	
		
			
				|  |  |                case SCSI_DEVICE_OPTICAL:
 | 
	
		
			
				|  |  |                // default SCSI CDROM
 | 
	
		
			
				|  |  | -              dev->inquiry_block.peripheral_device_type = 5;
 | 
	
		
			
				|  |  | -              dev->inquiry_block.rmb = 1;
 | 
	
		
			
				|  |  | -              dev->inquiry_block.ansi_version = 1;
 | 
	
		
			
				|  |  | -              dev->inquiry_block.response_format = 1;
 | 
	
		
			
				|  |  | -              dev->inquiry_block.additional_length = 42;
 | 
	
		
			
				|  |  | -              dev->inquiry_block.sync = 1;
 | 
	
		
			
				|  |  | -              memcpy(dev->inquiry_block.vendor, "BLUESCSI", 8);
 | 
	
		
			
				|  |  | -              memcpy(dev->inquiry_block.product, "CD-ROM CDU-55S", 14);
 | 
	
		
			
				|  |  | -              memcpy(dev->inquiry_block.revision, "1.9a", 4);
 | 
	
		
			
				|  |  | -              dev->inquiry_block.release = 0x20;
 | 
	
		
			
				|  |  | -              memcpy(dev->inquiry_block.revision_date, "1995", 4);
 | 
	
		
			
				|  |  | +              dev->inquiry_block = &default_optical;
 | 
	
		
			
				|  |  |                break;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -968,7 +978,7 @@ void verifyDataPhaseSD(SCSI_DEVICE *dev, uint32_t adds, uint32_t len)
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  byte onInquiry(SCSI_DEVICE *dev, const byte *cdb)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  writeDataPhase(cdb[4] < 36 ? cdb[4] : 36, dev->inquiry_block.raw);
 | 
	
		
			
				|  |  | +  writeDataPhase(cdb[4] < 36 ? cdb[4] : 36, dev->inquiry_block->raw);
 | 
	
		
			
				|  |  |    return SCSI_STATUS_GOOD;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1547,14 +1557,6 @@ void loop()
 | 
	
		
			
				|  |  |        // IDENTIFY
 | 
	
		
			
				|  |  |        if (m_msb[i] >= 0x80) {
 | 
	
		
			
				|  |  |          m_lun = m_msb[i] & 0x1f;
 | 
	
		
			
				|  |  | -        if(m_lun >= NUM_SCSILUN)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -          SCSI_DEVICE *d = &scsi_device_list[m_id][m_lun];
 | 
	
		
			
				|  |  | -          d->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
 | 
	
		
			
				|  |  | -          d->m_additional_sense_code = SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED;
 | 
	
		
			
				|  |  | -          m_sts |= SCSI_STATUS_CHECK_CONDITION;
 | 
	
		
			
				|  |  | -          goto Status;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |        // Extended message
 | 
	
		
			
				|  |  |        if (m_msb[i] == 0x01) {
 | 
	
	
		
			
				|  | @@ -1615,11 +1617,10 @@ void loop()
 | 
	
		
			
				|  |  |      LOGHEX(cmd[i]);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    // LUN confirmation
 | 
	
		
			
				|  |  | -  m_sts = cmd[1]&0xe0;      // Preset LUN in status byte
 | 
	
		
			
				|  |  |    // if it wasn't set in the IDENTIFY then grab it from the CDB
 | 
	
		
			
				|  |  | -  if(m_lun > NUM_SCSILUN)
 | 
	
		
			
				|  |  | +  if(m_lun > MAX_SCSILUN)
 | 
	
		
			
				|  |  |    {
 | 
	
		
			
				|  |  | -      m_lun = m_sts>>5;
 | 
	
		
			
				|  |  | +      m_lun = (cmd[1] & 0xe0) >> 5;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    LOG(":ID ");
 | 
	
	
		
			
				|  | @@ -1628,39 +1629,59 @@ void loop()
 | 
	
		
			
				|  |  |    LOG(m_lun);
 | 
	
		
			
				|  |  |    LOGN("");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  dev = &(scsi_device_list[m_id][m_lun]);
 | 
	
		
			
				|  |  |    // HDD Image selection
 | 
	
		
			
				|  |  | -  if(m_lun >= NUM_SCSILUN || !dev->m_file)
 | 
	
		
			
				|  |  | +  if(m_lun >= NUM_SCSILUN)
 | 
	
		
			
				|  |  |    {
 | 
	
		
			
				|  |  | -    // REQUEST SENSE and INQUIRY are handled different with invalid LUNs
 | 
	
		
			
				|  |  | -    if(cmd[0] != SCSI_REQUEST_SENSE || cmd[0] != SCSI_INQUIRY)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -      dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
 | 
	
		
			
				|  |  | -      dev->m_additional_sense_code = SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED;
 | 
	
		
			
				|  |  | -      m_sts = SCSI_STATUS_CHECK_CONDITION;
 | 
	
		
			
				|  |  | -      goto Status;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +    m_sts = SCSI_STATUS_GOOD;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // REQUEST SENSE and INQUIRY are handled different with invalid LUNs
 | 
	
		
			
				|  |  |      if(cmd[0] == SCSI_INQUIRY)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |        // Special INQUIRY handling for invalid LUNs
 | 
	
		
			
				|  |  |        LOGN("onInquiry - InvalidLUN");
 | 
	
		
			
				|  |  |        dev = &(scsi_device_list[m_id][0]);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -      byte temp = dev->inquiry_block.raw[0];
 | 
	
		
			
				|  |  | +      byte temp = dev->inquiry_block->raw[0];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        // If the LUN is invalid byte 0 of inquiry block needs to be 7fh
 | 
	
		
			
				|  |  | -      dev->inquiry_block.raw[0] = 0x7f;
 | 
	
		
			
				|  |  | +      dev->inquiry_block->raw[0] = 0x7f;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        // only write back what was asked for
 | 
	
		
			
				|  |  | -      writeDataPhase(cmd[4], dev->inquiry_block.raw);
 | 
	
		
			
				|  |  | +      writeDataPhase(cmd[4], dev->inquiry_block->raw);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        // return it back to normal if it was altered
 | 
	
		
			
				|  |  | -      dev->inquiry_block.raw[0] = temp;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      m_sts = SCSI_STATUS_GOOD;
 | 
	
		
			
				|  |  | -      goto Status;
 | 
	
		
			
				|  |  | +      dev->inquiry_block->raw[0] = temp;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else if(cmd[0] == SCSI_REQUEST_SENSE)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +      byte buf[18] = {
 | 
	
		
			
				|  |  | +        0x70,   //CheckCondition
 | 
	
		
			
				|  |  | +        0,      //Segment number
 | 
	
		
			
				|  |  | +        SCSI_SENSE_ILLEGAL_REQUEST,   //Sense key
 | 
	
		
			
				|  |  | +        0, 0, 0, 0,  //information
 | 
	
		
			
				|  |  | +        10,   //Additional data length
 | 
	
		
			
				|  |  | +        0, 0, 0, 0, // command specific information bytes
 | 
	
		
			
				|  |  | +        (byte)(SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED >> 8),
 | 
	
		
			
				|  |  | +        (byte)SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED,
 | 
	
		
			
				|  |  | +        0, 0, 0, 0,
 | 
	
		
			
				|  |  | +      };
 | 
	
		
			
				|  |  | +      writeDataPhase(cmd[4] < 18 ? cmd[4] : 18, buf);      
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    else
 | 
	
		
			
				|  |  | +    {    
 | 
	
		
			
				|  |  | +      m_sts = SCSI_STATUS_CHECK_CONDITION;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    goto Status;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  dev = &(scsi_device_list[m_id][m_lun]);
 | 
	
		
			
				|  |  | +  if(!dev->m_file)
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
 | 
	
		
			
				|  |  | +    dev->m_additional_sense_code = SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED;
 | 
	
		
			
				|  |  | +    m_sts = SCSI_STATUS_CHECK_CONDITION;
 | 
	
		
			
				|  |  | +    goto Status;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    LED_ON();
 |