"Fossies" - the Fresh Open Source Software Archive

Member "dvdisaster-0.79.5/scsi-netbsd.c" (4 Oct 2015, 5903 Bytes) of package /linux/misc/dvdisaster-0.79.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "scsi-netbsd.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes reports: 0.79.3_vs_0.79.5 or 0.72.6_vs_0.79.5.

    1 /*  dvdisaster: Additional error correction for optical media.
    2  *  Copyright (C) 2004-2015 Carsten Gnoerlich.
    3  *
    4  *  Email: carsten@dvdisaster.org  -or-  cgnoerlich@fsfe.org
    5  *  Project homepage: http://www.dvdisaster.org
    6  *
    7  *  This file is part of dvdisaster.
    8  *
    9  *  dvdisaster is free software: you can redistribute it and/or modify
   10  *  it under the terms of the GNU General Public License as published by
   11  *  the Free Software Foundation, either version 3 of the License, or
   12  *  (at your option) any later version.
   13  *
   14  *  dvdisaster is distributed in the hope that it will be useful,
   15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17  *  GNU General Public License for more details.
   18  *
   19  *  You should have received a copy of the GNU General Public License
   20  *  along with dvdisaster. If not, see <http://www.gnu.org/licenses/>.
   21  */
   22 
   23 /* NetBSD support by Sergey Svishchev <svs@ropnet.ru>. 
   24  */
   25 
   26 #include "dvdisaster.h"
   27 
   28 #include "scsi-layer.h"
   29 #include "udf.h"
   30 
   31 #ifdef SYS_NETBSD
   32 
   33 #include <sys/device.h>
   34 #include <sys/param.h>
   35 #include <sys/sysctl.h>
   36 #include <sys/scsiio.h>
   37 #include <util.h>
   38 
   39 
   40 char* DefaultDevice()
   41 {  DeviceHandle *dh;
   42    char *disknames, *p, raw;
   43    int dev_type, sysctl_mib[2];
   44    size_t sysctl_len;
   45 
   46    /* As a convenience, add the simulated drive first. */
   47 
   48    InitSimulatedCD();
   49 
   50    /* Now probe the physical drives. */
   51 
   52    raw = 'a' + getrawpartition();
   53 
   54    sysctl_mib[0] = CTL_HW;
   55    sysctl_mib[1] = HW_DISKNAMES;
   56    if (-1 == sysctl(sysctl_mib, 2, NULL, &sysctl_len, NULL, 0)) {
   57      PrintLog("Failed to get value of sysctl `hw.disknames'\n");
   58      return g_strdup("no_drives");
   59    }
   60    if (!(disknames = g_malloc(sysctl_len))) {
   61      PrintLog("Out of memory constructing scan device list\n");
   62      return g_strdup("no_drives");
   63    }
   64    if (-1 == sysctl(sysctl_mib, 2, disknames, &sysctl_len, NULL, 0)) {
   65      PrintLog("Failed to get value of sysctl `hw.disknames'\n");
   66      g_free(disknames);
   67      return g_strdup("no_drives");
   68    }
   69 
   70    dh = g_malloc(sizeof(DeviceHandle));
   71 
   72    for (p = strtok(disknames, " "); p; p = strtok(NULL, " "))
   73    {  
   74      if(!strncmp(p,"cd",2))
   75      { char buf[80];
   76 
   77        sprintf(buf,"/dev/r%s%c", p, raw);
   78 
   79        memset(dh, 0, sizeof(DeviceHandle));
   80        dh->fd = open(buf, O_RDONLY | O_NONBLOCK);
   81        dh->device = buf;
   82 
   83        if(dh->fd < 0)   /* device not even present */
   84      continue;
   85 
   86        dev_type = InquireDevice(dh, 1);
   87        close(dh->fd);
   88 
   89        if(dev_type != 5)  /* not a CD/DVD ROM */
   90      continue;
   91 
   92        g_ptr_array_add(Closure->deviceNodes, g_strdup(buf));
   93        sprintf(buf, "%s (/dev/r%s%c)", dh->devinfo, p, raw);
   94        g_ptr_array_add(Closure->deviceNames, g_strdup(buf));
   95      }
   96    }
   97 
   98    g_free(dh);
   99 
  100    if(Closure->deviceNodes->len)
  101      return g_strdup(g_ptr_array_index(Closure->deviceNodes, 0));
  102    else
  103    {  PrintLog(_("No optical drives found.\n"
  104           "No drives will be pre-selected.\n"));
  105 
  106       return g_strdup("no_drives");
  107    }
  108 }
  109 
  110 DeviceHandle* OpenDevice(char *device)
  111 {  DeviceHandle *dh; 
  112 
  113    dh = g_malloc0(sizeof(DeviceHandle));
  114    dh->senseSize = sizeof(Sense);
  115 
  116    if(!strcmp(device, "sim-cd"))
  117    {  if(!Closure->simulateCD) /* can happen via resource file / last-device */
  118       {  g_free(dh);
  119          return NULL;
  120       }
  121      
  122       dh->simImage = LargeOpen(Closure->simulateCD, O_RDONLY, IMG_PERMS);
  123       if(!dh->simImage)
  124       {  g_free(dh);
  125 
  126      Stop(_("Could not open %s: %s"), Closure->simulateCD, strerror(errno));
  127      return NULL;
  128       }
  129    }
  130    else
  131    {  dh->fd = open(device, O_RDWR | O_NONBLOCK);
  132 
  133       if(dh->fd < 0)
  134       {  g_free(dh);
  135 
  136      Stop(_("Could not open %s: %s"),device, strerror(errno));
  137      return NULL;
  138       }
  139    }
  140 
  141    dh->device = g_strdup(device);
  142 
  143    return dh;
  144 }
  145 
  146 void CloseDevice(DeviceHandle *dh)
  147 {
  148   if(dh->canReadDefective)
  149     SetRawMode(dh, MODE_PAGE_UNSET);
  150 
  151   if(dh->rawBuffer)
  152      FreeRawBuffer(dh->rawBuffer);
  153 
  154   if(dh->fd)
  155     close(dh->fd);
  156   if(dh->device)
  157     g_free(dh->device);
  158   if(dh->typeDescr) 
  159     g_free(dh->typeDescr);
  160   if(dh->mediumDescr) 
  161     g_free(dh->mediumDescr);
  162   if(dh->defects)
  163     FreeBitmap(dh->defects);
  164   g_free(dh);
  165 }
  166 
  167 int SendPacket(DeviceHandle *dh, unsigned char *cmd, int cdb_size, unsigned char *buf, int size, Sense *sense, int data_mode)
  168 {  struct scsireq sc;
  169    int sense_len;
  170    int rc;
  171 
  172    if(dh->simImage)
  173       return SimulateSendPacket(dh, cmd, cdb_size, buf, size, sense, data_mode);
  174 
  175    /* prepare the scsi request */
  176 
  177    memset(&sc, 0, sizeof(sc));
  178    memcpy(sc.cmd, cmd, cdb_size);
  179    sc.cmdlen = cdb_size;
  180    sc.databuf = (char *)buf;
  181    sc.datalen = size;
  182    sc.senselen = 24;            /* Maybe SENSEBUFLEN would be better? -cg */
  183    sc.timeout = 60000;          /* linux uses 5000 = 5 * HZ */
  184 
  185    switch(data_mode)
  186    {  case DATA_READ:
  187         sc.flags = SCCMD_READ;
  188     break;
  189       case DATA_WRITE:
  190         sc.flags = SCCMD_WRITE;
  191     break;
  192       case DATA_NONE:
  193     sc.flags = 0;
  194     break;
  195       default:
  196     Stop("illegal data_mode: %d", data_mode);
  197    }
  198 
  199    /* Send the request and save the sense data. */
  200 
  201    rc = ioctl(dh->fd, SCIOCCOMMAND, &sc);
  202 
  203    sense_len = sc.senselen_used;
  204    if(sense_len > dh->senseSize)
  205       sense_len = dh->senseSize;
  206    memcpy(sense, sc.sense, sense_len);
  207 
  208    /* See what we've got back */
  209 
  210    if(rc<0) return rc;    /* does not happen on SCSI errors */
  211 
  212    switch(sc.retsts)
  213    {  case SCCMD_OK:      /* everything went fine */  
  214           return 0;     
  215       case SCCMD_TIMEOUT: /* we don't know how to handle that yet */
  216       PrintLog("SendPacket() - SCSI timeout\n");
  217       return -1;
  218       case SCCMD_BUSY:    /* same here */
  219       PrintLog("SendPacket() - target busy\n");
  220       return -1;
  221       case SCCMD_SENSE:   /* SCSI error occurred, sense data available */
  222       return -1;
  223       default:            /* something other went wrong */
  224       return -1;
  225    }
  226 
  227    return -1; /* unreachable */
  228 }
  229 #endif /* SYS_NETBSD */