24 #include <linux/types.h>
28 #include <linux/slab.h>
29 #include <linux/module.h>
30 #include <asm/unaligned.h>
37 #include <scsi/scsi.h>
43 static int iscsi_dbg_lib_conn;
47 "Turn on debugging for connections in libiscsi module. "
48 "Set to 1 to turn on, and zero to turn off. Default is off.");
50 static int iscsi_dbg_lib_session;
54 "Turn on debugging for sessions in libiscsi module. "
55 "Set to 1 to turn on, and zero to turn off. Default is off.");
57 static int iscsi_dbg_lib_eh;
61 "Turn on debugging for error handling in libiscsi module. "
62 "Set to 1 to turn on, and zero to turn off. Default is off.");
64 #define ISCSI_DBG_CONN(_conn, dbg_fmt, arg...) \
66 if (iscsi_dbg_lib_conn) \
67 iscsi_conn_printk(KERN_INFO, _conn, \
72 #define ISCSI_DBG_SESSION(_session, dbg_fmt, arg...) \
74 if (iscsi_dbg_lib_session) \
75 iscsi_session_printk(KERN_INFO, _session, \
80 #define ISCSI_DBG_EH(_session, dbg_fmt, arg...) \
82 if (iscsi_dbg_lib_eh) \
83 iscsi_session_printk(KERN_INFO, _session, \
98 static void __iscsi_update_cmdsn(
struct iscsi_session *session,
105 if (iscsi_sna_lt(max_cmdsn, exp_cmdsn - 1))
109 !iscsi_sna_lt(exp_cmdsn, session->
exp_cmdsn))
113 !iscsi_sna_lt(max_cmdsn, session->
max_cmdsn)) {
119 if (!list_empty(&session->
leadconn->cmdqueue) ||
120 !list_empty(&session->
leadconn->mgmtqueue))
176 unsigned exp_len = task->
hdr_len + len;
191 static int iscsi_prep_ecdb_ahs(
struct iscsi_task *task)
195 unsigned short ahslength;
199 ecdb_ahdr = iscsi_next_hdr(task);
203 ahslength = rlen +
sizeof(ecdb_ahdr->
reserved);
205 pad_len = iscsi_padding(rlen);
207 rc = iscsi_add_hdr(task,
sizeof(ecdb_ahdr->
ahslength) +
208 sizeof(ecdb_ahdr->
ahstype) + ahslength + pad_len);
221 "iscsi_prep_ecdb_ahs: varlen_cdb_len %d "
222 "rlen %d pad_len %d ahs_length %d iscsi_headers_size "
223 "%u\n", cmd->
cmd_len, rlen, pad_len, ahslength,
228 static int iscsi_prep_bidi_ahs(
struct iscsi_task *task)
234 rlen_ahdr = iscsi_next_hdr(task);
235 rc = iscsi_add_hdr(task,
sizeof(*rlen_ahdr));
247 "bidi-in rlen_ahdr->read_length(%d) "
248 "rlen_ahdr->ahslength(%d)\n",
267 static int iscsi_check_tmf_restrictions(
struct iscsi_task *task,
int opcode)
271 unsigned int hdr_lun;
285 if (hdr_lun != task->
sc->device->lun)
294 "task [op %x/%x itt "
297 task->
hdr->opcode, opcode,
305 if (conn->
session->fast_abort) {
307 "task [op %x/%x itt "
308 "0x%x/0x%x] fast abort.\n",
309 task->
hdr->opcode, opcode,
324 "Preventing task %x/%x from sending "
325 "data-out due to abort task in "
326 "progress\n", task->
itt,
343 static int iscsi_prep_scsi_cmd_pdu(
struct iscsi_task *task)
357 if (conn->
session->tt->alloc_pdu) {
364 memset(hdr, 0,
sizeof(*hdr));
366 if (session->
tt->parse_pdu_itt)
370 task->
conn->session->age);
372 rc = iscsi_add_hdr(task,
sizeof(*hdr));
384 rc = iscsi_prep_ecdb_ahs(task);
392 if (scsi_bidi_cmnd(sc)) {
394 rc = iscsi_prep_bidi_ahs(task);
399 unsigned out_len = scsi_out(sc)->length;
418 memset(r2t, 0,
sizeof(*r2t));
452 hdrlength = task->
hdr_len -
sizeof(*hdr);
458 hdr->
hlength = hdrlength & 0xFF;
461 if (session->
tt->init_task && session->
tt->init_task(task))
469 "itt 0x%x len %d bidi_len %d cmdsn %d win %d]\n",
470 scsi_bidi_cmnd(sc) ?
"bidirectional" :
472 "write" :
"read", conn->
id, sc, sc->
cmnd[0],
473 task->
itt, scsi_bufflen(sc),
474 scsi_bidi_cmnd(sc) ? scsi_in(sc)->
length : 0,
488 static void iscsi_free_task(
struct iscsi_task *task)
493 int oldstate = task->
state;
498 session->
tt->cleanup_task(task);
531 iscsi_free_task(task);
539 spin_lock_bh(&session->
lock);
541 spin_unlock_bh(&session->
lock);
557 "complete task itt 0x%x state %d sc %p\n",
567 if (!list_empty(&task->
running))
570 if (conn->
task == task)
599 __iscsi_update_cmdsn(conn->
session, exp_cmdsn, max_cmdsn);
639 if (!scsi_bidi_cmnd(sc))
640 scsi_set_resid(sc, scsi_bufflen(sc));
642 scsi_out(sc)->resid = scsi_out(sc)->length;
643 scsi_in(sc)->resid = scsi_in(sc)->length;
646 iscsi_complete_task(task, state);
649 static int iscsi_prep_mgmt_task(
struct iscsi_conn *conn,
682 if (session->
tt->init_task && session->
tt->init_task(task))
717 "progress. Cannot start new task.\n");
730 (
void*)&task,
sizeof(
void*)))
741 INIT_LIST_HEAD(&task->
running);
750 if (conn->
session->tt->alloc_pdu) {
753 "pdu for mgmt task.\n");
758 itt = task->
hdr->itt;
763 if (session->
tt->parse_pdu_itt)
767 task->
conn->session->age);
771 if (iscsi_prep_mgmt_task(conn, task))
774 if (session->
tt->xmit_task(task))
795 spin_lock_bh(&session->
lock);
796 if (!__iscsi_conn_send_pdu(conn, hdr, data, data_size))
798 spin_unlock_bh(&session->
lock);
838 "Got CHECK_CONDITION but invalid data "
839 "buffer size of %d\n", datalen);
844 senselen = get_unaligned_be16(data);
845 if (datalen < senselen)
846 goto invalid_datalen;
859 if (scsi_bidi_cmnd(sc) && res_count > 0 &&
861 res_count <= scsi_in(sc)->
length))
873 res_count <= scsi_bufflen(sc)))
875 scsi_set_resid(sc, res_count);
911 res_count <= scsi_in(sc)->
length))
918 "[sc %p res %d itt 0x%x]\n",
962 task = __iscsi_conn_send_pdu(conn, (
struct iscsi_hdr *)&hdr,
NULL, 0);
972 static int iscsi_nop_out_rsp(
struct iscsi_task *task,
993 char *data,
int datalen)
1004 "pdu. Invalid data length (pdu dlength "
1012 switch (reject->
reason) {
1015 "pdu (op 0x%x itt 0x%x) rejected "
1016 "due to DataDigest error.\n",
1017 rejected_pdu.itt, opcode);
1021 "pdu (op 0x%x itt 0x%x) rejected. Too many "
1022 "immediate commands.\n",
1023 rejected_pdu.itt, opcode);
1040 iscsi_send_nopout(conn,
1051 "Invalid pdu reject. Could "
1052 "not lookup rejected task.\n");
1055 rc = iscsi_nop_out_rsp(task,
1062 "pdu (op 0x%x itt 0x%x) rejected. Reason "
1063 "code 0x%x\n", rejected_pdu.itt,
1064 rejected_pdu.opcode, reject->
reason);
1088 if (session->
tt->parse_pdu_itt)
1089 session->
tt->parse_pdu_itt(conn, itt, &i,
NULL);
1095 return session->
cmds[
i];
1111 char *data,
int datalen)
1129 opcode, conn->
id, itt, datalen);
1144 iscsi_send_nopout(conn, (
struct iscsi_nopin*)hdr);
1147 rc = iscsi_handle_reject(conn, hdr, data, datalen);
1189 iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen);
1192 iscsi_data_in_rsp(conn, hdr, task);
1217 iscsi_tmf_rsp(conn, hdr);
1228 rc = iscsi_nop_out_rsp(task, (
struct iscsi_nopin*)hdr,
1247 char *data,
int datalen)
1251 spin_lock(&conn->
session->lock);
1253 spin_unlock(&conn->
session->lock);
1266 if (session->
tt->parse_pdu_itt)
1267 session->
tt->parse_pdu_itt(conn, itt, &
i, &age);
1273 if (age != session->
age) {
1275 "received itt %x expected session age (%x)\n",
1282 "received invalid itt index %u (max cmds "
1307 if (!task || !task->
sc)
1310 if (task->
sc->SCp.phase != conn->
session->age) {
1312 "task's session age %d, expected %d\n",
1313 task->
sc->SCp.phase, conn->
session->age);
1327 spin_lock_bh(&session->
lock);
1330 spin_unlock_bh(&session->
lock);
1335 spin_unlock_bh(&session->
lock);
1355 spin_lock_bh(&session->
lock);
1357 spin_unlock_bh(&session->
lock);
1363 spin_unlock_bh(&session->
lock);
1371 static int iscsi_check_cmdsn_window_closed(
struct iscsi_conn *conn)
1380 "%u MaxCmdSN %u CmdSN %u/%u\n",
1388 static int iscsi_xmit_task(
struct iscsi_conn *conn)
1397 spin_unlock_bh(&conn->
session->lock);
1398 rc = conn->
session->tt->xmit_task(task);
1399 spin_lock_bh(&conn->
session->lock);
1425 if (list_empty(&task->
running))
1440 static int iscsi_data_xmit(
struct iscsi_conn *conn)
1445 spin_lock_bh(&conn->
session->lock);
1448 spin_unlock_bh(&conn->
session->lock);
1453 rc = iscsi_xmit_task(conn);
1467 list_del_init(&conn->
task->running);
1468 if (iscsi_prep_mgmt_task(conn, conn->
task)) {
1473 rc = iscsi_xmit_task(conn);
1479 while (!list_empty(&conn->
cmdqueue)) {
1482 list_del_init(&conn->
task->running);
1487 rc = iscsi_prep_scsi_cmd_pdu(conn->
task);
1498 rc = iscsi_xmit_task(conn);
1510 while (!list_empty(&conn->
requeue)) {
1523 list_del_init(&conn->
task->running);
1525 rc = iscsi_xmit_task(conn);
1531 spin_unlock_bh(&conn->
session->lock);
1535 spin_unlock_bh(&conn->
session->lock);
1548 rc = iscsi_data_xmit(conn);
1549 }
while (rc >= 0 || rc == -
EAGAIN);
1558 (
void *) &task,
sizeof(
void *)))
1562 sc->
SCp.ptr = (
char *) task;
1571 INIT_LIST_HEAD(&task->
running);
1600 ihost = shost_priv(host);
1603 session = cls_session->
dd_data;
1604 spin_lock_bh(&session->
lock);
1619 switch (session->
state) {
1657 if (iscsi_check_cmdsn_window_closed(conn)) {
1662 task = iscsi_alloc_task(conn, sc);
1668 if (!ihost->
workq) {
1669 reason = iscsi_prep_scsi_cmd_pdu(task);
1679 if (session->
tt->xmit_task(task)) {
1690 spin_unlock_bh(&session->
lock);
1696 spin_unlock_bh(&session->
lock);
1698 sc->
cmnd[0], reason);
1704 spin_unlock_bh(&session->
lock);
1706 sc->
cmnd[0], reason);
1707 if (!scsi_bidi_cmnd(sc))
1708 scsi_set_resid(sc, scsi_bufflen(sc));
1710 scsi_out(sc)->resid = scsi_out(sc)->length;
1711 scsi_in(sc)->resid = scsi_in(sc)->length;
1747 static void iscsi_tmf_timedout(
unsigned long data)
1752 spin_lock(&session->
lock);
1759 spin_unlock(&session->
lock);
1762 static int iscsi_exec_task_mgmt_fn(
struct iscsi_conn *conn,
1769 task = __iscsi_conn_send_pdu(conn, (
struct iscsi_hdr *)hdr,
1772 spin_unlock_bh(&session->
lock);
1775 spin_lock_bh(&session->
lock);
1780 conn->
tmf_timer.function = iscsi_tmf_timedout;
1785 spin_unlock_bh(&session->
lock);
1804 spin_lock_bh(&session->
lock);
1806 if (age != session->
age ||
1816 static void fail_scsi_tasks(
struct iscsi_conn *conn,
unsigned lun,
1822 for (i = 0; i < conn->
session->cmds_max; i++) {
1827 if (lun != -1 && lun != task->
sc->device->lun)
1831 "failing sc %p itt 0x%x state %d\n",
1833 fail_scsi_task(task, error);
1850 spin_lock_bh(&conn->
session->lock);
1852 spin_unlock_bh(&conn->
session->lock);
1867 struct iscsi_host *ihost = shost_priv(shost);
1875 static void iscsi_start_tx(
struct iscsi_conn *conn)
1887 static int iscsi_has_ping_timed_out(
struct iscsi_conn *conn)
1897 static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(
struct scsi_cmnd *sc)
1899 enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
1907 session = cls_session->
dd_data;
1911 spin_lock(&session->
lock);
1918 rc = BLK_EH_HANDLED;
1927 rc = BLK_EH_RESET_TIMER;
1934 rc = BLK_EH_RESET_TIMER;
1946 ISCSI_DBG_EH(session,
"Command making progress. Asking "
1947 "scsi-ml for more time to complete. "
1948 "Last data xfer at %lu. Last timeout was at "
1951 rc = BLK_EH_RESET_TIMER;
1961 if (iscsi_has_ping_timed_out(conn)) {
1962 rc = BLK_EH_RESET_TIMER;
1966 for (i = 0; i < conn->
session->cmds_max; i++) {
1967 running_task = conn->
session->cmds[
i];
1968 if (!running_task->sc || running_task == task ||
1976 if (
time_after(running_task->sc->jiffies_at_alloc,
1977 task->
sc->jiffies_at_alloc))
1992 "but commands ahead of it have. "
1993 "Asking scsi-ml for more time to "
1994 "complete. Our last xfer vs running task "
1995 "last xfer %lu/%lu. Last check %lu.\n",
1996 task->
last_xfer, running_task->last_xfer,
1998 rc = BLK_EH_RESET_TIMER;
2013 rc = BLK_EH_RESET_TIMER;
2018 iscsi_send_nopout(conn,
NULL);
2020 rc = BLK_EH_RESET_TIMER;
2025 spin_unlock(&session->
lock);
2026 ISCSI_DBG_EH(session,
"return %s\n", rc == BLK_EH_RESET_TIMER ?
2027 "timer reset" :
"nh");
2031 static void iscsi_check_transport_timeouts(
unsigned long data)
2035 unsigned long recv_timeout, next_timeout = 0, last_recv;
2037 spin_lock(&session->
lock);
2048 if (iscsi_has_ping_timed_out(conn)) {
2050 "expired, recv timeout %d, last rx %lu, "
2051 "last ping %lu, now %lu\n",
2054 spin_unlock(&session->
lock);
2062 iscsi_send_nopout(conn,
NULL);
2065 next_timeout = last_recv + recv_timeout;
2070 spin_unlock(&session->
lock);
2073 static void iscsi_prep_abort_task_pdu(
struct iscsi_task *task,
2076 memset(hdr, 0,
sizeof(*hdr));
2095 session = cls_session->
dd_data;
2100 spin_lock_bh(&session->
lock);
2106 ISCSI_DBG_EH(session,
"sc never reached iscsi layer or "
2108 spin_unlock_bh(&session->
lock);
2118 sc->
SCp.phase != session->
age) {
2119 spin_unlock_bh(&session->
lock);
2136 ISCSI_DBG_EH(session,
"sc completed while abort in progress\n");
2151 iscsi_prep_abort_task_pdu(task, hdr);
2153 if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->
abort_timeout)) {
2160 spin_unlock_bh(&session->
lock);
2171 spin_lock_bh(&session->
lock);
2174 memset(hdr, 0,
sizeof(*hdr));
2175 spin_unlock_bh(&session->
lock);
2176 iscsi_start_tx(conn);
2177 goto success_unlocked;
2179 spin_unlock_bh(&session->
lock);
2181 goto failed_unlocked;
2185 memset(hdr, 0,
sizeof(*hdr));
2198 spin_unlock_bh(&session->
lock);
2200 ISCSI_DBG_EH(session,
"abort success [sc %p itt 0x%x]\n",
2206 spin_unlock_bh(&session->
lock);
2208 ISCSI_DBG_EH(session,
"abort failed [sc %p itt 0x%x]\n", sc,
2209 task ? task->
itt : 0);
2215 static void iscsi_prep_lun_reset_pdu(
struct scsi_cmnd *sc,
struct iscsi_tm *hdr)
2217 memset(hdr, 0,
sizeof(*hdr));
2234 session = cls_session->
dd_data;
2239 spin_lock_bh(&session->
lock);
2254 iscsi_prep_lun_reset_pdu(sc, hdr);
2256 if (iscsi_exec_task_mgmt_fn(conn, hdr, session->
age,
2266 spin_unlock_bh(&session->
lock);
2275 spin_unlock_bh(&session->
lock);
2279 spin_lock_bh(&session->
lock);
2280 memset(hdr, 0,
sizeof(*hdr));
2283 spin_unlock_bh(&session->
lock);
2285 iscsi_start_tx(conn);
2289 spin_unlock_bh(&session->
lock);
2292 rc ==
SUCCESS ?
"SUCCESS" :
"FAILED");
2302 spin_lock_bh(&session->
lock);
2308 spin_unlock_bh(&session->
lock);
2326 session = cls_session->
dd_data;
2330 spin_lock_bh(&session->
lock);
2334 "failing session reset: Could not log back into "
2337 spin_unlock_bh(&session->
lock);
2342 spin_unlock_bh(&session->
lock);
2359 spin_lock_bh(&session->
lock);
2362 "session reset succeeded for %s,%s\n",
2366 spin_unlock_bh(&session->
lock);
2372 static void iscsi_prep_tgt_reset_pdu(
struct scsi_cmnd *sc,
struct iscsi_tm *hdr)
2374 memset(hdr, 0,
sizeof(*hdr));
2396 session = cls_session->
dd_data;
2398 ISCSI_DBG_EH(session,
"tgt Reset [sc %p tgt %s]\n", sc,
2402 spin_lock_bh(&session->
lock);
2417 iscsi_prep_tgt_reset_pdu(sc, hdr);
2419 if (iscsi_exec_task_mgmt_fn(conn, hdr, session->
age,
2429 spin_unlock_bh(&session->
lock);
2438 spin_unlock_bh(&session->
lock);
2442 spin_lock_bh(&session->
lock);
2443 memset(hdr, 0,
sizeof(*hdr));
2446 spin_unlock_bh(&session->
lock);
2448 iscsi_start_tx(conn);
2452 spin_unlock_bh(&session->
lock);
2455 rc ==
SUCCESS ?
"SUCCESS" :
"FAILED");
2488 int i, num_arrays = 1;
2490 memset(q, 0,
sizeof(*q));
2504 for (i = 0; i <
max; i++) {
2515 memcpy(*items, q->
pool, max *
sizeof(
void *));
2530 for (i = 0; i < q->
max; i++)
2553 shost->
transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
2554 return scsi_add_host(shost, pdev);
2568 int dd_data_size,
bool xmit_can_sleep)
2576 ihost = shost_priv(shost);
2578 if (xmit_can_sleep) {
2580 "iscsi_q_%d", shost->
host_no);
2612 struct iscsi_host *ihost = shost_priv(shost);
2613 unsigned long flags;
2617 spin_unlock_irqrestore(&ihost->
lock, flags);
2633 struct iscsi_host *ihost = shost_priv(shost);
2644 struct iscsi_host *ihost = shost_priv(shost);
2645 unsigned long flags;
2650 "of session teardown event because host already "
2659 spin_unlock_irqrestore(&ihost->
lock, flags);
2683 struct iscsi_host *ihost = shost_priv(shost);
2686 int cmd_i, scsi_cmds, total_cmds =
cmds_max;
2687 unsigned long flags;
2691 spin_unlock_irqrestore(&ihost->
lock, flags);
2695 spin_unlock_irqrestore(&ihost->
lock, flags);
2706 "must be a power of two that is at least %d.\n",
2708 goto dec_session_count;
2713 "must be a power of 2 less than or equal to %d.\n",
2720 "must be a power of 2.\n", total_cmds);
2733 goto dec_session_count;
2734 session = cls_session->
dd_data;
2748 session->
tt = iscsit;
2755 (
void***)&session->
cmds,
2757 goto cmdpool_alloc_fail;
2760 for (cmd_i = 0; cmd_i < session->
cmds_max; cmd_i++) {
2767 INIT_LIST_HEAD(&task->
running);
2770 if (!try_module_get(iscsit->
owner))
2771 goto module_get_fail;
2774 goto cls_session_fail;
2779 module_put(iscsit->
owner);
2785 iscsi_host_dec_session_cnt(shost);
2815 iscsi_host_dec_session_cnt(shost);
2840 memset(conn, 0,
sizeof(*conn) + dd_size);
2846 conn->
id = conn_idx;
2856 INIT_LIST_HEAD(&conn->
requeue);
2860 spin_lock_bh(&session->
lock);
2864 spin_unlock_bh(&session->
lock);
2865 goto login_task_alloc_fail;
2867 spin_unlock_bh(&session->
lock);
2872 goto login_task_data_alloc_fail;
2880 login_task_data_alloc_fail:
2883 login_task_alloc_fail:
2900 unsigned long flags;
2904 spin_lock_bh(&session->
lock);
2913 spin_unlock_bh(&session->
lock);
2921 if (!session->
host->host_busy) {
2922 spin_unlock_irqrestore(session->
host->host_lock, flags);
2925 spin_unlock_irqrestore(session->
host->host_lock, flags);
2928 "host_busy %d host_failed %d\n",
2929 session->
host->host_busy,
2930 session->
host->host_failed);
2940 spin_lock_bh(&session->
lock);
2948 spin_unlock_bh(&session->
lock);
2961 "can't start unbound connection\n");
2968 "first_burst %d max_burst %d\n",
2975 "zero. Using 5 seconds\n.");
2981 "zero. Using 5 seconds.\n");
2985 spin_lock_bh(&session->
lock);
3005 if (session->
age == 16)
3014 spin_unlock_bh(&session->
lock);
3028 for (i = 0; i < conn->
session->cmds_max; i++) {
3037 "failing mgmt itt 0x%x state %d\n",
3042 iscsi_complete_task(task, state);
3047 static void iscsi_start_session_recovery(
struct iscsi_session *session,
3053 spin_lock_bh(&session->
lock);
3055 spin_unlock_bh(&session->
lock);
3072 spin_unlock_bh(&session->
lock);
3077 spin_lock_bh(&session->
lock);
3079 spin_unlock_bh(&session->
lock);
3100 spin_lock_bh(&session->
lock);
3102 fail_mgmt_tasks(session, conn);
3104 spin_unlock_bh(&session->
lock);
3116 iscsi_start_session_recovery(session, conn, flag);
3120 "invalid stop flag %d\n", flag);
3131 spin_lock_bh(&session->
lock);
3134 spin_unlock_bh(&session->
lock);
3145 static int iscsi_switch_str_param(
char **
param,
char *new_val_buf)
3150 if (!
strcmp(*param, new_val_buf))
3228 return iscsi_switch_str_param(&session->
username, buf);
3230 return iscsi_switch_str_param(&session->
username_in, buf);
3232 return iscsi_switch_str_param(&session->
password, buf);
3234 return iscsi_switch_str_param(&session->
password_in, buf);
3236 return iscsi_switch_str_param(&session->
targetname, buf);
3238 return iscsi_switch_str_param(&session->
targetalias, buf);
3248 return iscsi_switch_str_param(&session->
ifacename, buf);
3250 return iscsi_switch_str_param(&session->
initiatorname, buf);
3344 switch (addr->ss_family) {
3429 struct iscsi_host *ihost = shost_priv(shost);
3453 struct iscsi_host *ihost = shost_priv(shost);
3457 return iscsi_switch_str_param(&ihost->
netdev, buf);
3459 return iscsi_switch_str_param(&ihost->
hwaddress, buf);