Advertisement
fflorens

vhba_sim

Dec 13th, 2017
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.38 KB | None | 0 0
  1. # If you have any idea of what is going wrong, please email me to florian <dot> florensa <at> gmail <dot> com
  2.  
  3. #include <sys/cdefs.h>
  4. #include <sys/param.h>
  5. #include <sys/systm.h>
  6. #include <sys/endian.h>
  7. #include <sys/lock.h>
  8. #include <sys/kernel.h>
  9. #include <sys/queue.h>
  10. #include <sys/queue.h>
  11. #include <sys/malloc.h>
  12. #include <sys/taskqueue.h>
  13. #include <sys/mutex.h>
  14. #include <sys/condvar.h>
  15.  
  16. #include <sys/proc.h>
  17.  
  18. #include <machine/bus.h>
  19. #include <machine/cpu.h>
  20. #include <machine/stdarg.h>
  21.  
  22. #include <cam/cam.h>
  23. #include <cam/cam_debug.h>
  24. #include <cam/cam_ccb.h>
  25. #include <cam/cam_sim.h>
  26. #include <cam/cam_xpt.h>
  27. #include <cam/cam_xpt_sim.h>
  28. #include <cam/cam_debug.h>
  29. #include <cam/scsi/scsi_all.h>
  30. #include <cam/scsi/scsi_message.h>
  31.  
  32.  
  33. #include <sys/unistd.h>
  34. #include <sys/kthread.h>
  35. #include <sys/conf.h>
  36. #include <sys/module.h>
  37. #include <sys/ioccom.h>
  38. #include <sys/devicestat.h>
  39. #include <cam/cam_periph.h>
  40. #include <cam/cam_xpt_periph.h>
  41.  
  42. #include "platform.h"
  43. #include "freebsd.h"
  44. #include "os.h"
  45.  
  46. #define vhba_SIMQ_SIZE 255
  47.  
  48. static void vhba_cam_done(vhba_scsi_cmd_t *scsi_cmd)
  49. {
  50.     union ccb *ccb;
  51.     struct vhba_cmd *cmd;
  52.  
  53.     cmd = (struct vhba_cmd *)scsi_cmd->private;
  54.     ccb = cmd->ccb;
  55.     ccb->ccb_h.status = CAM_REQ_CMP;
  56.     os_free(cmd); //free wrapper
  57.     xpt_done(ccb);
  58. }
  59.  
  60. static void vhba_cam_action(struct cam_sim *sim, union ccb *ccb)
  61. {
  62.     struct ccb_trans_settings *cts;
  63.     struct vhba_softc *vhba_softc;
  64.     struct ccb_scsiio *csio = &ccb->csio;
  65.     vhba_device_t *scsi_dev;
  66.     vhba_scsi_cmd_t *scsi_cmd;
  67.     struct vhba_cmd *cmd;
  68.  
  69.     vhba_softc = cam_sim_softc(sim);
  70.     scsi_dev = vhba_softc->scsi_dev;
  71.     if (scsi_dev == NULL) {
  72.         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
  73.         xpt_done(ccb);
  74.         return;
  75.     }
  76.     switch (ccb->ccb_h.func_code) {
  77.         case XPT_SCSI_IO:
  78.             ccb->ccb_h.status &= ~CAM_STATUS_MASK;
  79.             ccb->ccb_h.status |= CAM_REQ_INPROG;
  80.             cmd = os_alloc(sizeof(struct vhba_cmd)); //malloc wrapper
  81.             if (cmd == NULL) {
  82.                 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
  83.                 break;
  84.             }
  85.             cmd->vhba_softc = vhba_softc;
  86.             cmd->fini = 0;
  87.             cmd->ccb = ccb;
  88.             scsi_cmd = &cmd->scsi_cmd;
  89.             scsi_cmd->addr = vhba_softc->scsi_dev->asd_addr;
  90.             scsi_cmd->private = cmd;
  91.             scsi_cmd->comp_func = vhba_cam_done;
  92.             scsi_cmd->timeout = ccb->ccb_h.timeout;
  93.             //Copy only the header of the scsi_cmd, and get needed information later
  94.             if (csio->ccb_h.flags & CAM_CDB_POINTER)
  95.                 memcpy(&scsi_cmd->scsi_cmd_buf, csio->cdb_io.cdb_ptr, MIN(csio->dxfer_len, 16));
  96.             else
  97.                 memcpy(&scsi_cmd->scsi_cmd_buf, &csio->cdb_io.cdb_bytes, MIN(csio->dxfer_len, 16));
  98.             if (vhba_scsi_start(scsi_cmd) < 0) { //vhba_scsi_start processes the command, copy back the result and call the comp_func
  99.                 os_free(cmd); //free wrapper
  100.                 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
  101.                 break;
  102.             }
  103.             return;
  104.  
  105.         case XPT_RESET_DEV:
  106.             ccb->ccb_h.status = CAM_REQ_CMP;
  107.             break;
  108.  
  109.         case XPT_GET_TRAN_SETTINGS:
  110.             cts = &ccb->cts;
  111.             cts->protocol_version = SCSI_REV_SPC3;
  112.             cts->protocol = PROTO_SCSI;
  113.             cts->transport_version = 0;
  114.             cts->transport = XPORT_PPB;
  115.             ccb->ccb_h.status = CAM_REQ_CMP;
  116.             break;
  117.  
  118.         case XPT_CALC_GEOMETRY:
  119.             cam_calc_geometry(&ccb->ccg, 1);
  120.             break;
  121.  
  122.         case XPT_RESET_BUS:     /* Reset the specified bus */
  123.             ccb->ccb_h.status = CAM_REQ_CMP;
  124.             break;
  125.  
  126.         case XPT_PATH_INQ:      /* Path routing inquiry */
  127.             {
  128.                 struct ccb_pathinq *cpi = &ccb->cpi;
  129.  
  130.                 cpi->version_num = 1;
  131.                 cpi->max_target = 63;
  132.                 cpi->max_lun = 16383;
  133.                 cpi->hba_misc = PIM_NOBUSRESET;
  134.                 cpi->initiator_id = cpi->max_target + 1;
  135.                 cpi->transport = XPORT_PPB;
  136.                 cpi->base_transfer_speed = 1000000;
  137.                 cpi->protocol = PROTO_SCSI;
  138.                 cpi->protocol_version = SCSI_REV_SPC3;
  139.                 strlcpy(cpi->sim_vid, "vhba_sim", SIM_IDLEN);
  140.                 strlcpy(cpi->hba_vid, "vhba_hba", HBA_IDLEN);
  141.                 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
  142.                 cpi->unit_number = cam_sim_unit(sim);
  143.                 cpi->ccb_h.status = CAM_REQ_CMP;
  144.                 break;
  145.             }
  146.         default:
  147.             ccb->ccb_h.status = CAM_REQ_INVALID;
  148.             break;
  149.     }
  150.     xpt_done(ccb);
  151. }
  152.  
  153. static void vhba_cam_poll(struct cam_sim *sim)
  154. {
  155.     //FIXME ?
  156.     (void)sim;
  157. }
  158.  
  159. void    vhba_cam_fini(struct vhba_softc *vhba_softc)
  160. {
  161.     xpt_free_path(vhba_softc->path);
  162.     xpt_bus_deregister(cam_sim_path(vhba_softc->sim));
  163.     cam_sim_free(vhba_softc->sim, TRUE);
  164.     os_free(vhba_softc);
  165. }
  166.  
  167. struct vhba_softc   *vhba_cam_init(target_id_t target_id, lun_id_t lun_id)
  168. {
  169.     struct vhba_softc   *vhba_softc = NULL;
  170.     struct cam_devq *devq = NULL;
  171.  
  172.     devq = cam_simq_alloc(vhba_SIMQ_SIZE);
  173.     if (devq == NULL)
  174.         goto err;
  175.     vhba_softc = os_alloc(sizeof(struct vhba_softc));
  176.     if (vhba_softc == NULL)
  177.         goto err;
  178.  
  179.     (void)snprintf(&vhba_softc->name[0], 16, "vhba_t%dl%lu", target_id, lun_id);
  180.     mtx_init(&vhba_softc->cam_mtx, "vhba-cam", NULL, MTX_DEF);
  181.     vhba_softc->sim = cam_sim_alloc(vhba_cam_action, vhba_cam_poll, vhba_softc->name, vhba_softc, 0, &vhba_softc->cam_mtx, vhba_MAX_CMDS, vhba_MAX_CMDS, devq);
  182.     if (vhba_softc->sim == NULL)
  183.         goto err;
  184.     if (xpt_bus_register(vhba_softc->sim, *(device_t *)vhba_softc, 0) != CAM_SUCCESS)
  185.         goto err;
  186.     if (xpt_create_path(&vhba_softc->path, NULL, cam_sim_path(vhba_softc->sim), target_id, lun_id) != CAM_REQ_CMP)
  187.         goto pathfailed;
  188.  
  189.     return vhba_softc;
  190.  
  191. pathfailed:
  192.     xpt_bus_deregister(cam_sim_path(vhba_softc->sim));
  193. err:
  194.     if (vhba_softc && vhba_softc->sim) {
  195.         cam_sim_free(vhba_softc->sim, TRUE);
  196.         os_free(vhba_softc);
  197.     } else if (vhba_softc) {
  198.         cam_simq_free(devq);
  199.         os_free(vhba_softc);
  200.     } else if (devq)
  201.         cam_simq_free(devq);
  202.     return NULL;
  203. }
  204.  
  205.  
  206.  
  207. void
  208. online_device(void *v)
  209. {
  210.     vhba_device_t       *scsi_dev;
  211.     struct vhba_softc   *vhba_softc;
  212.     union ccb           *done_ccb;
  213.  
  214.  
  215.     scsi_dev = (vhba_device_t *) v;
  216.     vhba_softc = vhba_cam_init(SCSI2TGT(scsi_dev->addr), SCSI2LUN(scsi_dev->addr));
  217.     if (vhba_softc == NULL)
  218.         return ;
  219.     scsi_dev->softc = vhba_softc;
  220.     done_ccb = xpt_alloc_ccb_nowait();
  221.     xpt_setup_ccb(&done_ccb->ccb_h, vhba_softc->path, CAM_PRIORITY_NORMAL);
  222.     done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
  223.     xpt_action(done_ccb);
  224.     xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb);
  225. }
  226.  
  227. void
  228. offline_device(void *v)
  229. {
  230.     vhba_device_t       *scsi_dev;
  231.     struct vhba_softc   *vhba_softc;
  232.  
  233.     scsi_dev = (vhba_device_t *) v;
  234.     vhba_softc = (struct vhba_softc *) scsi_dev->softc;
  235.     if (vhba_softc == NULL)
  236.         return ;
  237.     xpt_async(AC_LOST_DEVICE, vhba_softc->path, NULL);
  238.     vhba_cam_fini(vhba_softc);
  239.     asi_free_scsi_dev(scsi_dev);
  240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement