/* Check a drive to see if it is a CD-ROM */ static int CheckDrive(char *drive, struct stat *stbuf) { int is_cd = 0, cdfd; char *p; /* If it doesn't exist, return -1 */ if ( stat(drive, stbuf) < 0 ) { return(-1); } /* If it does exist, verify that it's an available CD-ROM */ cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); if ( cdfd >= 0 ) { p = Inquiry(cdfd); if (*p == TYPE_ROM) is_cd = 1; close(cdfd); } return(is_cd); }
static int CheckDrive(char *drive, struct stat *stbuf) { int is_cd = 0, cdfd; char *p; if ( stat(drive, stbuf) < 0 ) { return(-1); } cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); if ( cdfd >= 0 ) { p = Inquiry(cdfd); if (*p == TYPE_ROM) is_cd = 1; close(cdfd); } return(is_cd); }
/*----------------------------------------* * OpenDisk * This will report the build version. * There are some functions that are not * supported on all platforms. * *----------------------------------------*/ void OpenDisk(char* progname,char* diskname) { #if defined(_MSC_VER) bool failed(false); char string[256],buffer[1024],*temp; if (GetVersion() >= 0x80000000) { sprintf(string,"\\\\.\\PHYSICALDRIVE%d",atoi(diskname)); /* we want to open a drive */ gDeviceHandle = CreateFile( string, GENERIC_WRITE | GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (gDeviceHandle == INVALID_HANDLE_VALUE) { printf("%s: Failed to open file %s\n",progname,diskname); failed = true; }else{ Inquiry(gDeviceHandle,buffer,0,96); printf("Device is name is : %s\n",&((PINQUIRY_DATA)buffer)->ProductID[0]); ReadCapacity(gDeviceHandle,0,buffer); temp = (char*) &(((PREAD_CAPACITY_DATA)buffer)->LogicalBlockAddr[0]); gFileSize = MakeInt4(temp[0],temp[1],temp[2],temp[3]); gDriveMode = 1; gDiskSector = 0; } } #endif }
/* State behaviour */ void behaviour_h2h_start_connect(state_ptr state) { uint8_t i; /* Set events to react to */ state->back = h2h_start_connect_to_main; state->h2h_start_connect = h2h_start_connect_to_h2h_ongoing; /* Do state actions */ /*Clean devices names */ for( i = 1; i < 5;i++) { item_area_set_text(&menu_h2h_devices.items[i].item.area," "); menu_h2h_devices.items[i].item.area.is_active = GUI_INACTIVE; } item_area_set_text(&menu_h2h_devices.items[6].item.area,"Searching for devices..."); /* Set menu */ osMutexWait(mutex_menuHandle, osWaitForever); menu_copy(&menu_h2h_devices, ¤t_menu); osMutexRelease(mutex_menuHandle); /* Display menu */ for (i = 0; i < menu_h2h_devices.item_num; i++) { while (osMailPut(queue_lcdHandle, (void *) &menu_h2h_devices.items[i]) != osOK) { osDelay(1); } } /* Do state actions */ /* We close and reopen the spp port in case of "zombie" connection*/ CloseServer(); OpenServer(); Inquiry(TIMEOUT); }
void scan_bus(tBusInfo Bus) {{{ tInqData InqData; tDevInfo Dev; tHandle handle; ULONG MaxLen; WORD ret; char Name[20]; UWORD Features; /* handle = scsicall->Open(1, 0, &MaxLen);*/ SuperOn(); ret = scsicall->InquireBus(cInqFirst, Bus.BusNo, &Dev); SuperOff(); while (ret == 0) { printf(" Id %2ld ", Dev.Id.lo); #if TRUE SuperOn(); ret = scsicall->CheckDev(Bus.BusNo, &Dev.Id, Name, &Features); SuperOff(); if (ret == 0) { printf("%s ", Name); if (Features & cArbit) printf(" arbit,"); if (Features & cAllCmds) printf(" all cmds,"); if (Features & cTargCtrl) printf(" target controlled,"); if (Features & cTarget) printf(" target installable,"); if (Features & cCanDisconnect) printf(" Disconnect possible,"); if (Features & cScatterGather) printf(" scatter gather,"); printf("\b \n "); } else { } #endif memset (&InqData, 0, sizeof (tInqData)); SuperOn(); handle = (tHandle) scsicall->Open(Bus.BusNo, &Dev.Id, &MaxLen); if (handle >= 0) { SetScsiUnit(handle, 0, MaxLen); /* erst den Header */ ret = Inquiry(&InqData, FALSE, 0, 5); if (ret == 0L) { ret = Inquiry(&InqData, FALSE, 0, (WORD) MIN((WORD)5 + (WORD)InqData.AddLen, (WORD)sizeof(InqData))); } scsicall->Close(handle); } SuperOff(); if (handle >= 0) { printf(" handle $%lx", handle); } printf(" MaxLen $%lx", MaxLen); if ((handle >= 0) && (ret == 0L)) { InqData.Revision[0] = 0; printf(" %s ", InqData.Vendor); switch (InqData.Device & 0x1F) { case 0: printf ("direct access device"); break; case 1: printf ("sequential access device"); break; case 2: printf ("printer device"); break; case 3: printf ("processor device"); break; case 4: printf ("write-once device"); break; case 5: printf ("CD-ROM device"); break; case 6: printf ("scanner device"); break; case 7: printf ("optical memory device"); break; case 8: printf ("medium changer device"); break; case 9: printf ("communications device"); break; case 10: case 11: printf ("ASC IT 8 (graphic arts pre-press device)"); break; case 0x1f: printf ("unknown device"); break; default : printf(" reserved device tpye %h", InqData.Device); } } else { if (handle < 0) printf(": no Handle"); else printf(": no Device ($%x)", ret); } printf("\n"); SuperOn(); ret = scsicall->InquireBus(cInqNext, Bus.BusNo, &Dev); SuperOff(); } /* while */ }}}
/** * * @param parent (not used) * @param port (not used) * @param lowspeed true if device is low speed * @return 0 for success */ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) { uint8_t rcode; uint8_t num_of_conf = epInfo[1].epAddr; // number of configurations epInfo[1].epAddr = 0; USBTRACE("MS Init\r\n"); AddressPool &addrPool = pUsb->GetAddressPool(); UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); if(!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; // Assign new address to the device delay(2000); rcode = pUsb->setAddr(0, 0, bAddress); if(rcode) { p->lowspeed = false; addrPool.FreeAddress(bAddress); bAddress = 0; USBTRACE2("setAddr:", rcode); return rcode; } USBTRACE2("Addr:", bAddress); p->lowspeed = false; p = addrPool.GetUsbDevicePtr(bAddress); if(!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; p->lowspeed = lowspeed; // Assign epInfo to epinfo pointer rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); if(rcode) goto FailSetDevTblEntry; USBTRACE2("NC:", num_of_conf); for(uint8_t i = 0; i < num_of_conf; i++) { ConfigDescParser< USB_CLASS_MASS_STORAGE, MASS_SUBCLASS_SCSI, MASS_PROTO_BBB, CP_MASK_COMPARE_CLASS | CP_MASK_COMPARE_SUBCLASS | CP_MASK_COMPARE_PROTOCOL > BulkOnlyParser(this); rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser); if(rcode) goto FailGetConfDescr; if(bNumEP > 1) break; } if(bNumEP < 3) return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; // Assign epInfo to epinfo pointer pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); USBTRACE2("Conf:", bConfNum); // Set Configuration Value rcode = pUsb->setConf(bAddress, 0, bConfNum); if(rcode) goto FailSetConfDescr; //Linux does a 1sec delay after this. delay(1000); rcode = GetMaxLUN(&bMaxLUN); if(rcode) goto FailGetMaxLUN; if(bMaxLUN >= MASS_MAX_SUPPORTED_LUN) bMaxLUN = MASS_MAX_SUPPORTED_LUN - 1; ErrorMessage<uint8_t > (PSTR("MaxLUN"), bMaxLUN); delay(1000); // Delay a bit for slow firmware. for(uint8_t lun = 0; lun <= bMaxLUN; lun++) { InquiryResponse response; rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response); if(rcode) { ErrorMessage<uint8_t > (PSTR("Inquiry"), rcode); } else { #if 0 printf("LUN %i `", lun); uint8_t *buf = response.VendorID; for(int i = 0; i < 28; i++) printf("%c", buf[i]); printf("'\r\nQualifier %1.1X ", response.PeripheralQualifier); printf("Device type %2.2X ", response.DeviceType); printf("RMB %1.1X ", response.Removable); printf("SSCS %1.1X ", response.SCCS); uint8_t sv = response.Version; printf("SCSI version %2.2X\r\nDevice conforms to ", sv); switch(sv) { case 0: printf("No specific"); break; case 1: printf("ANSI X3.131-1986 (ANSI 1)"); break; case 2: printf("ANSI X3.131-1994 (ANSI 2)"); break; case 3: printf("ANSI INCITS 301-1997 (SPC)"); break; case 4: printf("ANSI INCITS 351-2001 (SPC-2)"); break; case 5: printf("ANSI INCITS 408-2005 (SPC-4)"); break; case 6: printf("T10/1731-D (SPC-4)"); break; default: printf("unknown"); } printf(" standards.\r\n"); #endif uint8_t tries = 0xf0; while((rcode = TestUnitReady(lun))) { if(rcode == 0x08) break; // break on no media, this is OK to do. // try to lock media and spin up if(tries < 14) { LockMedia(lun, 1); MediaCTL(lun, 1); // I actually have a USB stick that needs this! } else delay(2 * (tries + 1)); tries++; if(!tries) break; } if(!rcode) { delay(1000); LUNOk[lun] = CheckLUN(lun); if(!LUNOk[lun]) LUNOk[lun] = CheckLUN(lun); } } } CheckMedia(); rcode = OnInit(); if(rcode) goto FailOnInit; #ifdef DEBUG_USB_HOST USBTRACE("MS configured\r\n\r\n"); #endif bPollEnable = true; //USBTRACE("Poll enabled\r\n"); return 0; FailSetConfDescr: #ifdef DEBUG_USB_HOST NotifyFailSetConfDescr(); goto Fail; #endif FailOnInit: #ifdef DEBUG_USB_HOST USBTRACE("OnInit:"); goto Fail; #endif FailGetMaxLUN: #ifdef DEBUG_USB_HOST USBTRACE("GetMaxLUN:"); goto Fail; #endif //#ifdef DEBUG_USB_HOST //FailInvalidSectorSize: // USBTRACE("Sector Size is NOT VALID: "); // goto Fail; //#endif FailSetDevTblEntry: #ifdef DEBUG_USB_HOST NotifyFailSetDevTblEntry(); goto Fail; #endif FailGetConfDescr: #ifdef DEBUG_USB_HOST NotifyFailGetConfDescr(); #endif #ifdef DEBUG_USB_HOST Fail: NotifyFail(rcode); #endif Release(); return rcode; }
uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) { const uint8_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR); uint8_t buf[constBufSize]; uint8_t rcode; UsbDevice *p = NULL; EpInfo *oldep_ptr = NULL; uint8_t num_of_conf; // number of configurations AddressPool &addrPool = pUsb->GetAddressPool(); USBTRACE("MS Init\r\n"); if (bAddress) return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; // Get pointer to pseudo device with address 0 assigned p = addrPool.GetUsbDevicePtr(0); if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; if (!p->epinfo) { USBTRACE("epinfo\r\n"); return USB_ERROR_EPINFO_IS_NULL; } // Save old pointer to EP_RECORD of address 0 oldep_ptr = p->epinfo; // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence p->epinfo = epInfo; p->lowspeed = lowspeed; // Get device descriptor rcode = pUsb->getDevDescr( 0, 0, constBufSize, (uint8_t*)buf ); // Restore p->epinfo p->epinfo = oldep_ptr; if( rcode ) goto FailGetDevDescr; // Allocate new address according to device class bAddress = addrPool.AllocAddress(parent, false, port); if (!bAddress) return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; // Extract Max Packet Size from the device descriptor epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; // Assign new address to the device rcode = pUsb->setAddr( 0, 0, bAddress ); if (rcode) { p->lowspeed = false; addrPool.FreeAddress(bAddress); bAddress = 0; USBTRACE2("setAddr:",rcode); return rcode; } USBTRACE2("Addr:", bAddress); p->lowspeed = false; p = addrPool.GetUsbDevicePtr(bAddress); if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; p->lowspeed = lowspeed; num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; // Assign epInfo to epinfo pointer rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); if (rcode) goto FailSetDevTblEntry; USBTRACE2("NC:", num_of_conf); for (uint8_t i=0; i<num_of_conf; i++) { HexDumper<USBReadParser, uint16_t, uint16_t> HexDump; ConfigDescParser< USB_CLASS_MASS_STORAGE, MASS_SUBCLASS_SCSI, MASS_PROTO_BBB, CP_MASK_COMPARE_CLASS | CP_MASK_COMPARE_SUBCLASS | CP_MASK_COMPARE_PROTOCOL> BulkOnlyParser(this); rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump); rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser); if (bNumEP > 1) break; } // for if (bNumEP < 3) return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; // Assign epInfo to epinfo pointer rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); USBTRACE2("Conf:", bConfNum); // Set Configuration Value rcode = pUsb->setConf(bAddress, 0, bConfNum); if (rcode) goto FailSetConf; delay(5000); //rcode = pAsync->OnInit(this); //if (rcode) // goto FailOnInit; rcode = GetMaxLUN(&bMaxLUN); if (rcode) goto FailGetMaxLUN; delay(10); { InquiryResponse response; rcode = Inquiry(bMaxLUN, sizeof(InquiryResponse), (uint8_t*)&response); if (rcode) goto FailInquiry; //if (response.DeviceType != 0) // goto FailInvalidDevice; } delay(10); USBTRACE("MS configured\r\n"); bPollEnable = true; //USBTRACE("Poll enabled\r\n"); return 0; FailGetDevDescr: USBTRACE("getDevDescr:"); goto Fail; FailSetDevTblEntry: USBTRACE("setDevTblEn:"); goto Fail; FailGetConfDescr: USBTRACE("getConf:"); goto Fail; FailSetConf: USBTRACE("setConf:"); goto Fail; FailOnInit: USBTRACE("OnInit:"); goto Fail; FailGetMaxLUN: USBTRACE("GetMaxLUN:"); goto Fail; FailInquiry: USBTRACE("Inquiry:"); goto Fail; Fail: Serial.println(rcode, HEX); Release(); return rcode; }
/** * * @param parent (not used) * @param port (not used) * @param lowspeed true if device is low speed * @return 0 for success */ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) { uint8_t rcode; uint8_t num_of_conf = epInfo[1].epAddr; // number of configurations epInfo[1].epAddr = 0; USBTRACE("MS Init\r\n"); AddressPool &addrPool = pUsb->GetAddressPool(); UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; // Assign new address to the device delay(2000); rcode = pUsb->setAddr(0, 0, bAddress); if (rcode) { p->lowspeed = false; addrPool.FreeAddress(bAddress); bAddress = 0; USBTRACE2("setAddr:", rcode); return rcode; } USBTRACE2("Addr:", bAddress); p->lowspeed = false; p = addrPool.GetUsbDevicePtr(bAddress); if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; p->lowspeed = lowspeed; // Assign epInfo to epinfo pointer rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); if (rcode) goto FailSetDevTblEntry; USBTRACE2("NC:", num_of_conf); for (uint8_t i = 0; i < num_of_conf; i++) { ConfigDescParser< USB_CLASS_MASS_STORAGE, MASS_SUBCLASS_SCSI, MASS_PROTO_BBB, CP_MASK_COMPARE_CLASS | CP_MASK_COMPARE_SUBCLASS | CP_MASK_COMPARE_PROTOCOL > BulkOnlyParser(this); rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser); if (rcode) goto FailGetConfDescr; if (bNumEP > 1) break; } // for if (bNumEP < 3) return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; // Assign epInfo to epinfo pointer pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); USBTRACE2("Conf:", bConfNum); // Set Configuration Value rcode = pUsb->setConf(bAddress, 0, bConfNum); if (rcode) goto FailSetConfDescr; //Linux does a 1sec delay after this. delay(1000); rcode = GetMaxLUN(&bMaxLUN); if (rcode) goto FailGetMaxLUN; if (bMaxLUN >= MASS_MAX_SUPPORTED_LUN) bMaxLUN = MASS_MAX_SUPPORTED_LUN - 1; ErrorMessage<uint8_t > (PSTR("MaxLUN"), bMaxLUN); delay(1000); // Delay a bit for slow firmware. //bTheLUN = bMaxLUN; for (uint8_t lun = 0; lun <= bMaxLUN; lun++) { InquiryResponse response; rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response); if (rcode) { ErrorMessage<uint8_t > (PSTR("Inquiry"), rcode); } else { uint8_t tries = 0xf0; while (rcode = TestUnitReady(lun)) { if (rcode == 0x08) break; // break on no media, this is OK to do. // try to lock media and spin up if (tries < 14) { LockMedia(lun, 1); MediaCTL(lun, 1); // I actually have a USB stick that needs this! } else delay(2 * (tries + 1)); tries++; if (!tries) break; } if (!rcode) { delay(1000); LUNOk[lun] = CheckLUN(lun); if (!LUNOk[lun]) LUNOk[lun] = CheckLUN(lun); } } } #if 0 { bool good; for (uint8_t i = 1; i == 0; i++) { good = false; CheckMedia(); for (uint8_t lun = 0; lun <= bMaxLUN; lun++) good |= LUNOk[lun]; if (good) break; delay(118); // 255 loops =~ 30 seconds to allow for spin up, as per SCSI spec. } } #else CheckMedia(); #endif rcode = OnInit(); if (rcode) goto FailOnInit; USBTRACE("MS configured\r\n\r\n"); bPollEnable = true; //USBTRACE("Poll enabled\r\n"); return 0; FailSetConfDescr: #ifdef DEBUG_USB_HOST NotifyFailSetConfDescr(); goto Fail; #endif FailOnInit: #ifdef DEBUG_USB_HOST USBTRACE("OnInit:"); goto Fail; #endif FailGetMaxLUN: #ifdef DEBUG_USB_HOST USBTRACE("GetMaxLUN:"); goto Fail; #endif FailInvalidSectorSize: #ifdef DEBUG_USB_HOST USBTRACE("Sector Size is NOT VALID: "); goto Fail; #endif FailSetDevTblEntry: #ifdef DEBUG_USB_HOST NotifyFailSetDevTblEntry(); goto Fail; #endif FailGetConfDescr: #ifdef DEBUG_USB_HOST NotifyFailGetConfDescr(); #endif Fail: #ifdef DEBUG_USB_HOST NotifyFail(rcode); #endif Release(); return rcode; }