void scsi_scan_host(struct Scsi_Host *host) { struct scsi_cmnd *cmnd; struct scsi_device *sdev; struct scsi_target *target; struct completion compl; void *result; init_completion(&compl); sdev = (struct scsi_device *)kmalloc(sizeof(struct scsi_device), GFP_KERNEL); target = (struct scsi_target *)kmalloc(sizeof(struct scsi_target), GFP_KERNEL); cmnd = _scsi_alloc_command(); /* init device */ sdev->sdev_target = target; sdev->host = host; sdev->id = 0; sdev->lun = 0; host->hostt->slave_alloc(sdev); host->hostt->slave_configure(sdev); /* inquiry (36 bytes for usb) */ scsi_alloc_buffer(sdev->inquiry_len, cmnd); cmnd->cmnd[0] = INQUIRY; cmnd->cmnd[4] = sdev->inquiry_len; cmnd->device = sdev; cmnd->cmd_len = 6; cmnd->sc_data_direction = DMA_FROM_DEVICE; cmnd->back = &compl; cmnd->scsi_done = inquiry_done; host->hostt->queuecommand(host, cmnd); wait_for_completion(&compl); /* if PQ and PDT are zero we have a direct access block device conntected */ result = scsi_buffer_data(cmnd); if (!((char*)result)[0]) scsi_add_device(sdev); else { kfree(sdev); kfree(target); } scsi_free_buffer(cmnd); _scsi_free_command(cmnd); }
/*--------------------------------------------------------------------------- * *--------------------------------------------------------------------------*/ int scsi_init(char *devname) { char *inq_buf; #ifdef DIXTRAC_LINUX_SG #ifdef SG_NONBLOCKING int ictl_val; #endif #ifdef SG_NONBLOCKING int fd = open(devname, O_RDWR | O_NONBLOCK); #else int fd = open(devname, O_RDWR); #endif if (fd < 0) { error_handler("Device %s not defined or no R/W permmissions.\n",devname); } #ifdef SG_NONBLOCKING ictl_val = 1; if ( 0 > ioctl(fd,SG_SET_COMMAND_Q,&ictl_val)) { if (errno == ENOTTY) ictl_val = 0; else error_handler("Problems with ioctl on device %s \n",devname); } /* #ifndef SILENT */ #if 0 printf("Command queueing%s allowed.\n",(ictl_val == 1 ? "" : " not")); #endif ictl_val = 0; /* if ( 0 > ioctl(fd,SG_SET_FORCE_PACK_ID,&ictl_val)) { error_handler("Could not set FORCE_PACK_ID on device %s \n",devname); } */ ictl_val = BIG_BUF_SIZE; if ( 0 > ioctl(fd,SG_SET_RESERVED_SIZE,&ictl_val)) { error_handler("Problems with ioctl on device %s!\n",devname); } ioctl(fd,SG_GET_RESERVED_SIZE,&ictl_val); /* #ifndef SILENT */ #if 0 fprintf(stderr, "*** The size of the RESERVED kernel buffer: %d\n",ictl_val); /* ioctl(fd,SG_GET_SG_TABLESIZE,&ictl_val); */ /* printf("TABLESIZE: %d\n",ictl_val); */ #endif #endif #ifdef STATE_THREADS if (st_init()) { error_handler("Problems with st_init!\n"); } if (!(scsidev_fd = st_netfd_open(fd))) { error_handler("Opening sthread fd failed\n", devname); } #else scsidev_fd = fd; #endif /* DIXTRAC_LINUX_SG */ #endif #ifdef DIXTRAC_FREEBSD_CAM if (cam_open_pass(devname, O_RDWR, &cam_device) == NULL) { error_handler("Opening pass device (%s) failed\n", devname); } #endif inq_buf = scsi_alloc_buffer(); /* get_scsi_version */ send_scsi_command(inq_buf, SCSI_inq_command(),0); recv_scsi_command(inq_buf); scsi_version = ((u_int8_t) inq_buf[2]); /* get the device block size (not all disks use 512-byte sector) */ exec_scsi_command(inq_buf,SCSI_read_capacity(0,0)); /* this is a global that is accessed through te SECT_SIZE macro */ blksize = _4btol((u_int8_t *) &inq_buf[4]); return(0); }