The translation is temporarily closed for contributions due to maintenance, please come back later.


(itstool) path: sect1/para
Context English Spanish State
async_flags - bitmask of installed Async handler, unused now
hpath_id - highest Path ID in the subsystem, unused now
unit_number - the controller unit number, cam_sim_unit(sim)
bus_id - the bus number, cam_sim_bus(sim)
initiator_id - the SCSI ID of the controller itself
base_transfer_speed - nominal transfer speed in KB/s for asynchronous narrow transfers, equals to 3300 for SCSI
sim_vid - SIM driver's vendor id, a zero-terminated string of maximal length SIM_IDLEN including the terminating zero
hba_vid - SCSI controller's vendor id, a zero-terminated string of maximal length HBA_IDLEN including the terminating zero
dev_name - device driver name, a zero-terminated string of maximal length DEV_IDLEN including the terminating zero, equal to cam_sim_name(sim)
The recommended way of setting the string fields is using strncpy, like:
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
After setting the values set the status to CAM_REQ_CMP and mark the CCB as done.
The poll function is used to simulate the interrupts when the interrupt subsystem is not functioning (for example, when the system has crashed and is creating the system dump). The CAM subsystem sets the proper interrupt level before calling the poll routine. So all it needs to do is to call the interrupt routine (or the other way around, the poll routine may be doing the real action and the interrupt routine would just call the poll routine). Why bother about a separate function then? Due to different calling conventions. The <function>xxx_poll</function> routine gets the struct cam_sim pointer as its argument when the PCI interrupt routine by common convention gets pointer to the struct <varname remap="structname">xxx_softc</varname> and the ISA interrupt routine gets just the device unit number. So the poll routine would normally look as:
static void
xxx_poll(struct cam_sim *sim)
xxx_intr((struct xxx_softc *)cam_sim_softc(sim)); /* for PCI device */
static void
xxx_poll(struct cam_sim *sim)
xxx_intr(cam_sim_unit(sim)); /* for ISA device */
Asynchronous Events
If an asynchronous event callback has been set up then the callback function should be defined.
static void
ahc_async(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
callback_arg - the value supplied when registering the callback
code - identifies the type of event
path - identifies the devices to which the event applies
arg - event-specific argument
Implementation for a single type of event, AC_LOST_DEVICE, looks like:
struct xxx_softc *softc;
struct cam_sim *sim;
int targ;
struct ccb_trans_settings neg;

sim = (struct cam_sim *)callback_arg;
softc = (struct xxx_softc *)cam_sim_softc(sim);
switch (code) {
targ = xpt_path_target_id(path);
clean_negotiations(softc, targ);
/* send indication to CAM */
neg.bus_width = 8;
neg.sync_period = neg.sync_offset = 0;
xpt_async(AC_TRANSFER_NEG, path, &amp;neg);
The exact type of the interrupt routine depends on the type of the peripheral bus (PCI, ISA and so on) to which the SCSI controller is connected.
The interrupt routines of the SIM drivers run at the interrupt level splcam. So <function>splcam()</function> should be used in the driver to synchronize activity between the interrupt routine and the rest of the driver (for a multiprocessor-aware driver things get yet more interesting but we ignore this case here). The pseudo-code in this document happily ignores the problems of synchronization. The real code must not ignore them. A simple-minded approach is to set <function>splcam()</function> on the entry to the other routines and reset it on return thus protecting them by one big critical section. To make sure that the interrupt level will be always restored a wrapper function can be defined, like:
static void
xxx_action(struct cam_sim *sim, union ccb *ccb)
int s;
s = splcam();
xxx_action1(sim, ccb);

static void
xxx_action1(struct cam_sim *sim, union ccb *ccb)
... process the request ...
This approach is simple and robust but the problem with it is that interrupts may get blocked for a relatively long time and this would negatively affect the system's performance. On the other hand the functions of the <function>spl()</function> family have rather high overhead, so vast amount of tiny critical sections may not be good either.
Component Translation Difference to current string
This translation Not translated FreeBSD Doc (Archived)/books_arch-handbook
The following strings have the same context and source.
Translated FreeBSD Doc (Archived)/articles_contributing o
Not translated FreeBSD Doc (Archived)/books_handbook
Translated FreeBSD Doc (Archived)/books_porters-handbook o
Translated FreeBSD Doc (Archived)/books_developers-handbook o
Not translated FreeBSD Doc (Archived)/books_fdp-primer
Translated FreeBSD Doc (Archived)/articles_new-users o


No matching activity found.

Browse all component changes


English Spanish
No related strings found in the glossary.

Source information

Source string comment
(itstool) path: sect1/para
Source string location
String age
2 months ago
Source string age
a year ago
Translation file
books/es/arch-handbook.po, string 2338