smart_device * legacy_scsi_device::autodetect_open() { // Open device if (!open()) return this; // No Autodetection if device type was specified by user if (*get_req_type()) return this; // The code below is based on smartd.cpp:SCSIFilterKnown() // Get INQUIRY unsigned char req_buff[64] = {0, }; int req_len = 36; if (scsiStdInquiry(this, req_buff, req_len)) { // Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices // watch this spot ... other devices could lock up here req_len = 64; if (scsiStdInquiry(this, req_buff, req_len)) { // device doesn't like INQUIRY commands close(); set_err(EIO, "INQUIRY failed"); return this; } } int avail_len = req_buff[4] + 5; int len = (avail_len < req_len ? avail_len : req_len); if (len < 36) return this; // Use INQUIRY to detect type // SAT or USB ? { smart_device * newdev = smi()->autodetect_sat_device(this, req_buff, len); if (newdev) // NOTE: 'this' is now owned by '*newdev' return newdev; } // Nothing special found return this; }
thread_safe_page *original_io_request::complete_req(thread_safe_page *p, bool lock) { if (get_req_type() == io_request::BASIC_REQ) { int page_off; thread_safe_page *ret = NULL; char *req_buf; int req_size; if (within_1page()) { page_off = get_offset() - ROUND_PAGE(get_offset()); req_buf = get_buf(); req_size = get_size(); } else { io_request extracted; extract(p->get_offset(), PAGE_SIZE, extracted); page_off = extracted.get_offset() - ROUND_PAGE(extracted.get_offset()); req_buf = extracted.get_buf(); req_size = extracted.get_size(); } if (lock) p->lock(); if (get_access_method() == WRITE) { memcpy((char *) p->get_data() + page_off, req_buf, req_size); if (!p->set_dirty(true)) ret = p; } else /* I assume the data I read never crosses the page boundary */ memcpy(req_buf, (char *) p->get_data() + page_off, req_size); if (lock) p->unlock(); return ret; } else { p->inc_ref(); get_page_status(p).pg = p; return NULL; } }