Ticket #16: ada.diff

File ada.diff, 6.7 KB (added by agapon, 11 years ago)

initial diff

  • os_freebsd.cpp

     
    7171#define CONTROLLER_3WARE_9000_CHAR      0x05  // set by guess_device_type()
    7272#define CONTROLLER_3WARE_678K_CHAR      0x06  // set by guess_device_type()
    7373#define CONTROLLER_HPT                  0x09  // SATA drives behind HighPoint Raid controllers
    74 #define CONTROLLER_CCISS  0x10  // CCISS controller
     74#define CONTROLLER_CCISS                0x0a  // CCISS controller
     75#define CONTROLLER_ATACAM               0x0b
    7576
    7677static __unused const char *filenameandversion="$Id$";
    7778
     
    315316// osst, nosst and sg.
    316317static const char * fbsd_dev_prefix = _PATH_DEV;
    317318static const char * fbsd_dev_ata_disk_prefix = "ad";
     319static const char * fbsd_dev_atacam_disk_prefix = "ada";
    318320static const char * fbsd_dev_scsi_disk_plus = "da";
    319321static const char * fbsd_dev_scsi_pass = "pass";
    320322static const char * fbsd_dev_scsi_tape1 = "sa";
     
    332334  // No Autodetection if device type was specified by user
    333335  if (*type){
    334336    if(!strcmp(type,"ata")) return CONTROLLER_ATA;
     337    if(!strcmp(type,"atacam")) return CONTROLLER_ATACAM;
    335338    if(!strcmp(type,"cciss")) return CONTROLLER_CCISS;
    336339    if(!strcmp(type,"scsi") || !strcmp(type,"sat")) goto handlescsi;
    337340    if(!strcmp(type,"3ware")){
     
    354357    // else advance pointer to following characters
    355358    dev_name += dev_prefix_len;
    356359  }
     360
     361  // form /dev/ada* or ada*
     362  if (!strncmp(fbsd_dev_atacam_disk_prefix, dev_name,
     363               strlen(fbsd_dev_atacam_disk_prefix))) {
     364    return CONTROLLER_ATACAM;
     365  }
     366
    357367  // form /dev/ad* or ad*
    358368  if (!strncmp(fbsd_dev_ata_disk_prefix, dev_name,
    359369    strlen(fbsd_dev_ata_disk_prefix))) {
     
    488498      return false;
    489499    }
    490500  }
     501  if (parse_ok == CONTROLLER_ATACAM) {
     502    if ((fdchan->camdev = ::cam_open_device(dev,O_RDWR)) == NULL) {
     503      perror("cam_open_device");
     504      free(fdchan);
     505      errno = ENOENT;
     506      return false;
     507    }
     508  }
    491509
    492510  if (parse_ok == CONTROLLER_3WARE_678K_CHAR) {
    493511    char buf[512];
     
    575593    failed=::close(fdchan->atacommand);
    576594#endif
    577595
     596  if (fdchan->camdev != NULL)
     597    cam_close_device(fdchan->camdev);
     598
    578599  // if close succeeded, then remove from device list
    579600  // Eduard, should we also remove it from list if close() fails?  I'm
    580601  // not sure. Here I only remove it from list if close() worked.
     
    602623
    603624protected:
    604625  virtual int ata_command_interface(smart_command_set command, int select, char * data);
     626
     627  #ifdef IOCATAREQUEST
     628        virtual int do_cmd(struct freebsd_dev_channel* con, struct ata_ioc_request* request);
     629  #endif
    605630};
    606631
    607632freebsd_ata_device::freebsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
     
    610635{
    611636}
    612637
     638int freebsd_ata_device::do_cmd(struct freebsd_dev_channel* con, struct ata_ioc_request* request)
     639{
     640  return ioctl(con->device, IOCATAREQUEST, request);
     641}
     642
     643#if __FreeBSD_version > 800100
     644class freebsd_atacam_device : public freebsd_ata_device
     645{
     646public:
     647  freebsd_atacam_device(smart_interface * intf, const char * dev_name, const char * req_type)
     648  : smart_device(intf, dev_name, "atacam", req_type), freebsd_ata_device(intf, dev_name, req_type)
     649  {}
     650
     651protected:
     652        virtual int do_cmd(struct freebsd_dev_channel* con, struct ata_ioc_request* request);
     653};
     654
     655int freebsd_atacam_device::do_cmd(struct freebsd_dev_channel* con, struct ata_ioc_request* request)
     656{
     657  union ccb ccb;
     658  int camflags;
     659
     660  memset(&ccb, 0, sizeof(ccb));
     661
     662  if (request->count == 0)
     663    camflags = CAM_DIR_NONE;
     664  else if (request->flags == ATA_CMD_READ)
     665    camflags = CAM_DIR_IN;
     666  else
     667    camflags = CAM_DIR_OUT;
     668
     669  cam_fill_ataio(&ccb.ataio,
     670                 0,
     671                 NULL,
     672                 camflags,
     673                 MSG_SIMPLE_Q_TAG,
     674                 (u_int8_t*)request->data,
     675                 request->count,
     676                 request->timeout);
     677
     678  // ata_28bit_cmd
     679  ccb.ataio.cmd.flags = 0;
     680  ccb.ataio.cmd.command = request->u.ata.command;
     681  ccb.ataio.cmd.features = request->u.ata.feature;
     682  ccb.ataio.cmd.lba_low = request->u.ata.lba;
     683  ccb.ataio.cmd.lba_mid = request->u.ata.lba >> 8;
     684  ccb.ataio.cmd.lba_high = request->u.ata.lba >> 16;
     685  ccb.ataio.cmd.device = 0x40 | ((request->u.ata.lba >> 24) & 0x0f);
     686  ccb.ataio.cmd.sector_count = request->u.ata.count;
     687
     688  ccb.ccb_h.flags |= CAM_DEV_QFRZDIS;
     689
     690  if (cam_send_ccb(con->camdev, &ccb) < 0) {
     691    err(1, "cam_send_ccb");
     692    return -1;
     693  }
     694
     695  if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
     696    return 0;
     697
     698  cam_error_print(con->camdev, &ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
     699  return -1;
     700}
     701
     702#endif
     703
    613704int freebsd_ata_device::ata_command_interface(smart_command_set command, int select, char * data)
    614705{
    615706 int fd=get_fd();
     
    754845  unsigned char low,high;
    755846
    756847#ifdef IOCATAREQUEST
    757   if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error)
     848  if ((retval=do_cmd(con, &request)) || request.error)
    758849#else
    759850  if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error)
    760851#endif
     
    790881 }
    791882
    792883#ifdef IOCATAREQUEST
    793  if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error)
     884 if ((retval=do_cmd(con, &request)) || request.error)
    794885#else
    795886 if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error)
    796887#endif
     
    15831674protected:
    15841675  virtual ata_device * get_ata_device(const char * name, const char * type);
    15851676
     1677  virtual ata_device * get_atacam_device(const char * name, const char * type);
     1678
    15861679  virtual scsi_device * get_scsi_device(const char * name, const char * type);
    15871680
    15881681  virtual smart_device * autodetect_smart_device(const char * name);
     
    16141707  return new freebsd_ata_device(this, name, type);
    16151708}
    16161709
     1710ata_device * freebsd_smart_interface::get_atacam_device(const char * name, const char * type)
     1711{
     1712  return new freebsd_atacam_device(this, name, type);
     1713}
     1714
    16171715scsi_device * freebsd_smart_interface::get_scsi_device(const char * name, const char * type)
    16181716{
    16191717  return new freebsd_scsi_device(this, name, type);
     
    21762274  switch (guess) {
    21772275  case CONTROLLER_ATA :
    21782276    return new freebsd_ata_device(this, name, "");
     2277  case CONTROLLER_ATACAM :
     2278    return new freebsd_atacam_device(this, name, "");
    21792279  case CONTROLLER_SCSI:
    21802280    // Try to detect possible USB->(S)ATA bridge
    21812281    if (get_usb_id(name, vendor_id, product_id, version)) {
  • os_freebsd.h

     
    9292#endif
    9393  char* devname;                // the SCSI device name
    9494  int   unitnum;                // the SCSI unit number
     95  struct cam_device *camdev;
    9596};
    9697
    9798#define FREEBSD_MAXDEV 64