questions about camcontrol eject

Raviprakash Darbha rdarbha at juniper.net
Tue Jul 7 18:30:50 UTC 2015


Hello All

I am trying to get cam control eject working on my router with 2 drives for sometime and have some observations from the code.

While allocating memory for ccb we either have a malloc option or a memory pool. In the eject case we choose the memory pool as its low priority.
After getting the ccb and setting the relevant fields it is submitted to the ata_action routine but then it fails there returning an error code .

//Code snippets
from sys/cam/scsi/scsi-pass.c


                /*
                 * Non-immediate CCBs need a CCB from the per-device pool
                 * of CCBs, which is scheduled by the transport layer.
                 * Immediate CCBs and user-supplied CCBs should just be
                 * malloced.
                 */
                if ((inccb->ccb_h.func_code & XPT_FC_QUEUED)
                 && ((inccb->ccb_h.func_code & XPT_FC_USER_CCB) == 0)) {
                        ccb = cam_periph_getccb(periph, priority);
                        ccb_malloced = 0;

                } else {
                        ccb = xpt_alloc_ccb_nowait();

                        if (ccb != NULL)
                                xpt_setup_ccb(&ccb->ccb_h, periph->path,
                                              priority);
                        ccb_malloced = 1;

                }

                if (ccb == NULL) {
                        xpt_print(periph->path, "unable to allocate CCB\n");
                        error = ENOMEM;
                        break;
                }

                error = passsendccb(periph, ccb, inccb);


from sys/cam/ata/ata/xpt.c

  {
                struct cam_ed *device;
                u_int   maxlen = 0;

                device = start_ccb->ccb_h.path->device;
                if (device->protocol == PROTO_SCSI &&
                    (device->flags & CAM_DEV_IDENTIFY_DATA_VALID)) {
                        uint16_t p =
                            device->ident_data.config & ATA_PROTO_MASK;

                        maxlen =
                            (device->ident_data.config == ATA_PROTO_CFA) ? 0 :
                            (p == ATA_PROTO_ATAPI_16) ? 16 :
                            (p == ATA_PROTO_ATAPI_12) ? 12 : 0;
///// maxlen is still set to 0.
               }
                if (start_ccb->csio.cdb_len > maxlen) {
                        start_ccb->ccb_h.status = CAM_REQ_INVALID;
                        xpt_done(start_ccb);
                        break;
///// hence returning from  here.
                }
                xpt_action_default(start_ccb);
                break;
        }


My question is if this is a code path thats expected to run this way in which case I am missing something or is this a bug ? In the later case I am assuming the ccb_hdr is not set correctly in case we get the ccb from the pool so i m considering to set it by calling  xpt_ccb_setup in that case too to get the right values in the device structure.

Any help is greatly appreciated here. Please let me know if more information is needed.

Thanks
Ravi


More information about the freebsd-scsi mailing list