~ubuntu-branches/ubuntu/hardy/open-iscsi/hardy-updates

« back to all changes in this revision

Viewing changes to kernel/scsi_transport_iscsi.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Zobel-Helas
  • Date: 2006-12-03 16:54:21 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061203165421-xhttz5j4l9sowg8u
Tags: 2.0.730-0.2
upload to unstable, as no new bugs arised.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
22
 */
23
23
#include <linux/module.h>
24
 
#include <linux/mempool.h>
25
24
#include <linux/mutex.h>
26
25
#include <net/tcp.h>
27
26
#include <scsi/scsi.h>
31
30
#include "scsi_transport_iscsi.h"
32
31
#include "iscsi_if.h"
33
32
 
34
 
#define ISCSI_SESSION_ATTRS 8
35
 
#define ISCSI_CONN_ATTRS 6
 
33
#define ISCSI_SESSION_ATTRS 11
 
34
#define ISCSI_CONN_ATTRS 11
 
35
#define ISCSI_HOST_ATTRS 0
 
36
#define ISCSI_TRANSPORT_VERSION "2.0-727"
36
37
 
37
38
struct iscsi_internal {
 
39
        int daemon_pid;
38
40
        struct scsi_transport_template t;
39
41
        struct iscsi_transport *iscsi_transport;
40
42
        struct list_head list;
41
 
        /*
42
 
         * based on transport capabilities, at register time we set these
43
 
         * bits to tell the transport class it wants attributes displayed
44
 
         * in sysfs or that it can support different iSCSI Data-Path
45
 
         * capabilities
46
 
         */
47
 
        uint32_t param_mask;
48
 
 
49
43
        struct class_device cdev;
50
 
        /*
51
 
         * We do not have any private or other attrs.
52
 
         */
 
44
 
 
45
        struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
53
46
        struct transport_container conn_cont;
54
47
        struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
55
48
        struct transport_container session_cont;
56
49
        struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
57
50
};
58
51
 
 
52
static int iscsi_session_nr;    /* sysfs session id for next new session */
 
53
 
59
54
/*
60
55
 * list of registered transports and lock that must
61
56
 * be held while accessing list. The iscsi_transport_lock must
120
115
        .attrs = iscsi_transport_attrs,
121
116
};
122
117
 
 
118
static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
 
119
                            struct class_device *cdev)
 
120
{
 
121
        struct Scsi_Host *shost = dev_to_shost(dev);
 
122
        struct iscsi_host *ihost = shost->shost_data;
 
123
 
 
124
        memset(ihost, 0, sizeof(*ihost));
 
125
        INIT_LIST_HEAD(&ihost->sessions);
 
126
        mutex_init(&ihost->mutex);
 
127
        return 0;
 
128
}
 
129
 
 
130
static DECLARE_TRANSPORT_CLASS(iscsi_host_class,
 
131
                               "iscsi_host",
 
132
                               iscsi_setup_host,
 
133
                               NULL,
 
134
                               NULL);
 
135
 
123
136
static DECLARE_TRANSPORT_CLASS(iscsi_session_class,
124
137
                               "iscsi_session",
125
138
                               NULL,
133
146
                               NULL);
134
147
 
135
148
static struct sock *nls;
136
 
static int daemon_pid;
137
149
static DEFINE_MUTEX(rx_queue_mutex);
138
150
 
139
 
struct mempool_zone {
140
 
        mempool_t *pool;
141
 
        atomic_t allocated;
142
 
        int size;
143
 
        int hiwat;
144
 
        struct list_head freequeue;
145
 
        spinlock_t freelock;
146
 
};
147
 
 
148
 
static struct mempool_zone *z_reply;
149
 
 
150
 
/*
151
 
 * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time
152
 
 * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM
153
 
 *             so daemon will notice OOM on NETLINK tranposrt level and will
154
 
 *             be able to predict or change operational behavior
155
 
 */
156
 
#define Z_MAX_REPLY     8
157
 
#define Z_HIWAT_REPLY   6
158
 
#define Z_MAX_PDU       8
159
 
#define Z_HIWAT_PDU     6
160
 
#define Z_MAX_ERROR     16
161
 
#define Z_HIWAT_ERROR   12
162
 
 
163
151
static LIST_HEAD(sesslist);
164
152
static DEFINE_SPINLOCK(sesslock);
165
153
static LIST_HEAD(connlist);
166
154
static DEFINE_SPINLOCK(connlock);
167
155
 
168
 
static struct iscsi_cls_session *iscsi_session_lookup(uint64_t handle)
 
156
static uint32_t iscsi_conn_get_sid(struct iscsi_cls_conn *conn)
 
157
{
 
158
        struct iscsi_cls_session *sess = iscsi_dev_to_session(conn->dev.parent);
 
159
        return sess->sid;
 
160
}
 
161
 
 
162
/*
 
163
 * Returns the matching session to a given sid
 
164
 */
 
165
static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid)
169
166
{
170
167
        unsigned long flags;
171
168
        struct iscsi_cls_session *sess;
172
169
 
173
170
        spin_lock_irqsave(&sesslock, flags);
174
171
        list_for_each_entry(sess, &sesslist, sess_list) {
175
 
                if (sess == iscsi_ptr(handle)) {
 
172
                if (sess->sid == sid) {
176
173
                        spin_unlock_irqrestore(&sesslock, flags);
177
174
                        return sess;
178
175
                }
181
178
        return NULL;
182
179
}
183
180
 
184
 
static struct iscsi_cls_conn *iscsi_conn_lookup(uint64_t handle)
 
181
/*
 
182
 * Returns the matching connection to a given sid / cid tuple
 
183
 */
 
184
static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid)
185
185
{
186
186
        unsigned long flags;
187
187
        struct iscsi_cls_conn *conn;
188
188
 
189
189
        spin_lock_irqsave(&connlock, flags);
190
190
        list_for_each_entry(conn, &connlist, conn_list) {
191
 
                if (conn == iscsi_ptr(handle)) {
 
191
                if ((conn->cid == cid) && (iscsi_conn_get_sid(conn) == sid)) {
192
192
                        spin_unlock_irqrestore(&connlock, flags);
193
193
                        return conn;
194
194
                }
204
204
static void iscsi_session_release(struct device *dev)
205
205
{
206
206
        struct iscsi_cls_session *session = iscsi_dev_to_session(dev);
207
 
        struct iscsi_transport *transport = session->transport;
208
207
        struct Scsi_Host *shost;
209
208
 
210
209
        shost = iscsi_session_to_shost(session);
211
210
        scsi_host_put(shost);
212
211
        kfree(session);
213
 
        module_put(transport->owner);
214
212
}
215
213
 
216
214
static int iscsi_is_session_dev(const struct device *dev)
218
216
        return dev->release == iscsi_session_release;
219
217
}
220
218
 
221
 
/**
222
 
 * iscsi_create_session - create iscsi class session
223
 
 * @shost: scsi host
224
 
 * @transport: iscsi transport
225
 
 *
226
 
 * This can be called from a LLD or iscsi_transport
227
 
 **/
 
219
static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
 
220
                           uint id, uint lun)
 
221
{
 
222
        struct iscsi_host *ihost = shost->shost_data;
 
223
        struct iscsi_cls_session *session;
 
224
 
 
225
        mutex_lock(&ihost->mutex);
 
226
        list_for_each_entry(session, &ihost->sessions, host_list) {
 
227
                if ((channel == SCAN_WILD_CARD || channel == 0) &&
 
228
                    (id == SCAN_WILD_CARD || id == session->target_id))
 
229
                        scsi_scan_target(&session->dev, 0,
 
230
                                         session->target_id, lun, 1);
 
231
        }
 
232
        mutex_unlock(&ihost->mutex);
 
233
 
 
234
        return 0;
 
235
}
 
236
 
 
237
static void session_recovery_timedout(void *data)
 
238
{
 
239
        struct iscsi_cls_session *session = data;
 
240
 
 
241
        dev_printk(KERN_INFO, &session->dev, "iscsi: session recovery timed "
 
242
                  "out after %d secs\n", session->recovery_tmo);
 
243
 
 
244
        if (session->transport->session_recovery_timedout)
 
245
                session->transport->session_recovery_timedout(session);
 
246
 
 
247
        scsi_target_unblock(&session->dev);
 
248
}
 
249
 
 
250
void iscsi_unblock_session(struct iscsi_cls_session *session)
 
251
{
 
252
        if (!cancel_delayed_work(&session->recovery_work))
 
253
                flush_scheduled_work();
 
254
        scsi_target_unblock(&session->dev);
 
255
}
 
256
EXPORT_SYMBOL_GPL(iscsi_unblock_session);
 
257
 
 
258
void iscsi_block_session(struct iscsi_cls_session *session)
 
259
{
 
260
        scsi_target_block(&session->dev);
 
261
        schedule_delayed_work(&session->recovery_work,
 
262
                             session->recovery_tmo * HZ);
 
263
}
 
264
EXPORT_SYMBOL_GPL(iscsi_block_session);
 
265
 
228
266
struct iscsi_cls_session *
229
 
iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport)
 
267
iscsi_alloc_session(struct Scsi_Host *shost,
 
268
                    struct iscsi_transport *transport)
230
269
{
231
270
        struct iscsi_cls_session *session;
232
 
        int err;
233
271
 
234
 
        if (!try_module_get(transport->owner))
 
272
        session = kzalloc(sizeof(*session) + transport->sessiondata_size,
 
273
                          GFP_KERNEL);
 
274
        if (!session)
235
275
                return NULL;
236
276
 
237
 
        session = kzalloc(sizeof(*session), GFP_KERNEL);
238
 
        if (!session)
239
 
                goto module_put;
240
277
        session->transport = transport;
 
278
        session->recovery_tmo = 120;
 
279
        INIT_WORK(&session->recovery_work, session_recovery_timedout, session);
 
280
        INIT_LIST_HEAD(&session->host_list);
 
281
        INIT_LIST_HEAD(&session->sess_list);
241
282
 
242
283
        /* this is released in the dev's release function */
243
284
        scsi_host_get(shost);
244
 
        snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", shost->host_no);
245
285
        session->dev.parent = &shost->shost_gendev;
246
286
        session->dev.release = iscsi_session_release;
247
 
        err = device_register(&session->dev);
 
287
        device_initialize(&session->dev);
 
288
        if (transport->sessiondata_size)
 
289
                session->dd_data = &session[1];
 
290
        return session;
 
291
}
 
292
EXPORT_SYMBOL_GPL(iscsi_alloc_session);
 
293
 
 
294
int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
 
295
{
 
296
        struct Scsi_Host *shost = iscsi_session_to_shost(session);
 
297
        struct iscsi_host *ihost;
 
298
        int err;
 
299
 
 
300
        ihost = shost->shost_data;
 
301
        session->sid = iscsi_session_nr++;
 
302
        session->target_id = target_id;
 
303
 
 
304
        snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
 
305
                 session->sid);
 
306
        err = device_add(&session->dev);
248
307
        if (err) {
249
308
                dev_printk(KERN_ERR, &session->dev, "iscsi: could not "
250
309
                           "register session's dev\n");
251
 
                goto free_session;
 
310
                goto release_host;
252
311
        }
253
312
        transport_register_device(&session->dev);
254
313
 
 
314
        mutex_lock(&ihost->mutex);
 
315
        list_add(&session->host_list, &ihost->sessions);
 
316
        mutex_unlock(&ihost->mutex);
 
317
        return 0;
 
318
 
 
319
release_host:
 
320
        scsi_host_put(shost);
 
321
        return err;
 
322
}
 
323
EXPORT_SYMBOL_GPL(iscsi_add_session);
 
324
 
 
325
/**
 
326
 * iscsi_create_session - create iscsi class session
 
327
 * @shost: scsi host
 
328
 * @transport: iscsi transport
 
329
 *
 
330
 * This can be called from a LLD or iscsi_transport.
 
331
 **/
 
332
struct iscsi_cls_session *
 
333
iscsi_create_session(struct Scsi_Host *shost,
 
334
                     struct iscsi_transport *transport,
 
335
                     unsigned int target_id)
 
336
{
 
337
        struct iscsi_cls_session *session;
 
338
 
 
339
        session = iscsi_alloc_session(shost, transport);
 
340
        if (!session)
 
341
                return NULL;
 
342
 
 
343
        if (iscsi_add_session(session, target_id)) {
 
344
                iscsi_free_session(session);
 
345
                return NULL;
 
346
        }
255
347
        return session;
256
 
 
257
 
free_session:
258
 
        kfree(session);
259
 
module_put:
260
 
        module_put(transport->owner);
261
 
        return NULL;
262
348
}
263
 
 
264
349
EXPORT_SYMBOL_GPL(iscsi_create_session);
265
350
 
 
351
void iscsi_remove_session(struct iscsi_cls_session *session)
 
352
{
 
353
        struct Scsi_Host *shost = iscsi_session_to_shost(session);
 
354
        struct iscsi_host *ihost = shost->shost_data;
 
355
 
 
356
        if (!cancel_delayed_work(&session->recovery_work))
 
357
                flush_scheduled_work();
 
358
 
 
359
        mutex_lock(&ihost->mutex);
 
360
        list_del(&session->host_list);
 
361
        mutex_unlock(&ihost->mutex);
 
362
 
 
363
        scsi_remove_target(&session->dev);
 
364
 
 
365
        transport_unregister_device(&session->dev);
 
366
        device_del(&session->dev);
 
367
}
 
368
EXPORT_SYMBOL_GPL(iscsi_remove_session);
 
369
 
 
370
void iscsi_free_session(struct iscsi_cls_session *session)
 
371
{
 
372
        put_device(&session->dev);
 
373
}
 
374
 
 
375
EXPORT_SYMBOL_GPL(iscsi_free_session);
 
376
 
266
377
/**
267
378
 * iscsi_destroy_session - destroy iscsi session
268
379
 * @session: iscsi_session
272
383
 **/
273
384
int iscsi_destroy_session(struct iscsi_cls_session *session)
274
385
{
275
 
        transport_unregister_device(&session->dev);
276
 
        device_unregister(&session->dev);
 
386
        iscsi_remove_session(session);
 
387
        iscsi_free_session(session);
277
388
        return 0;
278
389
}
279
 
 
280
390
EXPORT_SYMBOL_GPL(iscsi_destroy_session);
281
391
 
282
392
static void iscsi_conn_release(struct device *dev)
301
411
 * This can be called from a LLD or iscsi_transport. The connection
302
412
 * is child of the session so cid must be unique for all connections
303
413
 * on the session.
 
414
 *
 
415
 * Since we do not support MCS, cid will normally be zero. In some cases
 
416
 * for software iscsi we could be trying to preallocate a connection struct
 
417
 * in which case there could be two connection structs and cid would be
 
418
 * non-zero.
304
419
 **/
305
420
struct iscsi_cls_conn *
306
421
iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid)
307
422
{
308
423
        struct iscsi_transport *transport = session->transport;
309
 
        struct Scsi_Host *shost = iscsi_session_to_shost(session);
310
424
        struct iscsi_cls_conn *conn;
311
425
        int err;
312
426
 
319
433
 
320
434
        INIT_LIST_HEAD(&conn->conn_list);
321
435
        conn->transport = transport;
 
436
        conn->cid = cid;
322
437
 
323
438
        /* this is released in the dev's release function */
324
439
        if (!get_device(&session->dev))
325
440
                goto free_conn;
 
441
 
326
442
        snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",
327
 
                 shost->host_no, cid);
 
443
                 session->sid, cid);
328
444
        conn->dev.parent = &session->dev;
329
445
        conn->dev.release = iscsi_conn_release;
330
446
        err = device_register(&conn->dev);
361
477
EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
362
478
 
363
479
/*
364
 
 * These functions are used only by software iscsi_transports
365
 
 * which do not allocate and more their scsi_hosts since this
366
 
 * is initiated from userspace.
367
 
 */
368
 
 
369
 
/*
370
 
 * iSCSI Session's hostdata organization:
371
 
 *
372
 
 *    *------------------* <== hostdata_session(host->hostdata)
373
 
 *    | ptr to class sess|
374
 
 *    |------------------| <== iscsi_hostdata(host->hostdata)
375
 
 *    | transport's data |
376
 
 *    *------------------*
377
 
 */
378
 
 
379
 
#define hostdata_privsize(_t)   (sizeof(unsigned long) + _t->hostdata_size + \
380
 
                                 _t->hostdata_size % sizeof(unsigned long))
381
 
 
382
 
#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
383
 
 
384
 
/**
385
 
 * iscsi_transport_create_session - create iscsi cls session and host
386
 
 * scsit: scsi transport template
387
 
 * transport: iscsi transport template
388
 
 *
389
 
 * This can be used by software iscsi_transports that allocate
390
 
 * a session per scsi host.
391
 
 **/
392
 
struct Scsi_Host *
393
 
iscsi_transport_create_session(struct scsi_transport_template *scsit,
394
 
                               struct iscsi_transport *transport)
395
 
{
396
 
        struct iscsi_cls_session *session;
397
 
        struct Scsi_Host *shost;
398
 
        unsigned long flags;
399
 
 
400
 
        shost = scsi_host_alloc(transport->host_template,
401
 
                                hostdata_privsize(transport));
402
 
        if (!shost) {
403
 
                printk(KERN_ERR "iscsi: can not allocate SCSI host for "
404
 
                        "session\n");
405
 
                return NULL;
406
 
        }
407
 
 
408
 
        shost->max_id = 1;
409
 
        shost->max_channel = 0;
410
 
        shost->max_lun = transport->max_lun;
411
 
        shost->max_cmd_len = transport->max_cmd_len;
412
 
        shost->transportt = scsit;
413
 
        shost->transportt->create_work_queue = 1;
414
 
 
415
 
        if (scsi_add_host(shost, NULL))
416
 
                goto free_host;
417
 
 
418
 
        session = iscsi_create_session(shost, transport);
419
 
        if (!session)
420
 
                goto remove_host;
421
 
 
422
 
        *(unsigned long*)shost->hostdata = (unsigned long)session;
423
 
        spin_lock_irqsave(&sesslock, flags);
424
 
        list_add(&session->sess_list, &sesslist);
425
 
        spin_unlock_irqrestore(&sesslock, flags);
426
 
        return shost;
427
 
 
428
 
remove_host:
429
 
        scsi_remove_host(shost);
430
 
free_host:
431
 
        scsi_host_put(shost);
432
 
        return NULL;
433
 
}
434
 
 
435
 
EXPORT_SYMBOL_GPL(iscsi_transport_create_session);
436
 
 
437
 
/**
438
 
 * iscsi_transport_destroy_session - destroy session and scsi host
439
 
 * shost: scsi host
440
 
 *
441
 
 * This can be used by software iscsi_transports that allocate
442
 
 * a session per scsi host.
443
 
 **/
444
 
int iscsi_transport_destroy_session(struct Scsi_Host *shost)
445
 
{
446
 
        struct iscsi_cls_session *session;
447
 
        unsigned long flags;
448
 
 
449
 
        scsi_remove_host(shost);
450
 
        session = hostdata_session(shost->hostdata);
451
 
        spin_lock_irqsave(&sesslock, flags);
452
 
        list_del(&session->sess_list);
453
 
        spin_unlock_irqrestore(&sesslock, flags);
454
 
        iscsi_destroy_session(session);
455
 
        /* ref from host alloc */
456
 
        scsi_host_put(shost);
457
 
        return 0;
458
 
}
459
 
 
460
 
EXPORT_SYMBOL_GPL(iscsi_transport_destroy_session);
461
 
 
462
 
/*
463
480
 * iscsi interface functions
464
481
 */
465
482
static struct iscsi_internal *
479
496
        return NULL;
480
497
}
481
498
 
482
 
static inline struct list_head *skb_to_lh(struct sk_buff *skb)
483
 
{
484
 
        return (struct list_head *)&skb->cb;
485
 
}
486
 
 
487
 
static void*
488
 
mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data)
489
 
{
490
 
        struct mempool_zone *zone = pool_data;
491
 
 
492
 
        return alloc_skb(zone->size, gfp_mask);
493
 
}
494
 
 
495
 
static void
496
 
mempool_zone_free_skb(void *element, void *pool_data)
497
 
{
498
 
        kfree_skb(element);
499
 
}
500
 
 
501
 
static void
502
 
mempool_zone_complete(struct mempool_zone *zone)
503
 
{
504
 
        unsigned long flags;
505
 
        struct list_head *lh, *n;
506
 
 
507
 
        spin_lock_irqsave(&zone->freelock, flags);
508
 
        list_for_each_safe(lh, n, &zone->freequeue) {
509
 
                struct sk_buff *skb = (struct sk_buff *)((char *)lh -
510
 
                                offsetof(struct sk_buff, cb));
511
 
                if (!skb_shared(skb)) {
512
 
                        list_del(skb_to_lh(skb));
513
 
                        mempool_free(skb, zone->pool);
514
 
                        atomic_dec(&zone->allocated);
515
 
                }
516
 
        }
517
 
        spin_unlock_irqrestore(&zone->freelock, flags);
518
 
}
519
 
 
520
 
static struct mempool_zone *
521
 
mempool_zone_init(unsigned max, unsigned size, unsigned hiwat)
522
 
{
523
 
        struct mempool_zone *zp;
524
 
 
525
 
        zp = kzalloc(sizeof(*zp), GFP_KERNEL);
526
 
        if (!zp)
527
 
                return NULL;
528
 
 
529
 
        zp->size = size;
530
 
        zp->hiwat = hiwat;
531
 
        INIT_LIST_HEAD(&zp->freequeue);
532
 
        spin_lock_init(&zp->freelock);
533
 
        atomic_set(&zp->allocated, 0);
534
 
 
535
 
        zp->pool = mempool_create(max, mempool_zone_alloc_skb,
536
 
                                  mempool_zone_free_skb, zp);
537
 
        if (!zp->pool) {
538
 
                kfree(zp);
539
 
                return NULL;
540
 
        }
541
 
 
542
 
        return zp;
543
 
}
544
 
 
545
 
static void mempool_zone_destroy(struct mempool_zone *zp)
546
 
{
547
 
        mempool_destroy(zp->pool);
548
 
        kfree(zp);
549
 
}
550
 
 
551
 
static struct sk_buff*
552
 
mempool_zone_get_skb(struct mempool_zone *zone)
553
 
{
554
 
        struct sk_buff *skb;
555
 
 
556
 
        skb = mempool_alloc(zone->pool, GFP_ATOMIC);
557
 
        if (skb)
558
 
                atomic_inc(&zone->allocated);
559
 
        return skb;
560
 
}
561
 
 
562
 
static int
563
 
iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb)
564
 
{
565
 
        unsigned long flags;
566
 
        int rc;
567
 
 
568
 
        skb_get(skb);
569
 
        rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT);
570
 
        if (rc < 0) {
571
 
                mempool_free(skb, zone->pool);
 
499
static int
 
500
iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp)
 
501
{
 
502
        int rc;
 
503
 
 
504
        rc = netlink_broadcast(nls, skb, 0, 1, gfp);
 
505
        if (rc < 0) {
 
506
                printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc);
 
507
                return rc;
 
508
        }
 
509
 
 
510
        return 0;
 
511
}
 
512
 
 
513
static int
 
514
iscsi_unicast_skb(struct sk_buff *skb, int pid)
 
515
{
 
516
        int rc;
 
517
 
 
518
        rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT);
 
519
        if (rc < 0) {
572
520
                printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
573
521
                return rc;
574
522
        }
575
523
 
576
 
        spin_lock_irqsave(&zone->freelock, flags);
577
 
        list_add(skb_to_lh(skb), &zone->freequeue);
578
 
        spin_unlock_irqrestore(&zone->freelock, flags);
579
 
 
580
524
        return 0;
581
525
}
582
526
 
587
531
        struct sk_buff *skb;
588
532
        struct iscsi_uevent *ev;
589
533
        char *pdu;
 
534
        struct iscsi_internal *priv;
590
535
        int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) +
591
536
                              data_size);
592
537
 
593
 
        mempool_zone_complete(conn->z_pdu);
 
538
        priv = iscsi_if_transport_lookup(conn->transport);
 
539
        if (!priv)
 
540
                return -EINVAL;
594
541
 
595
 
        skb = mempool_zone_get_skb(conn->z_pdu);
 
542
        skb = alloc_skb(len, GFP_ATOMIC);
596
543
        if (!skb) {
597
544
                iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED);
598
545
                dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver "
600
547
                return -ENOMEM;
601
548
        }
602
549
 
603
 
        nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
 
550
        nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
604
551
        ev = NLMSG_DATA(nlh);
605
552
        memset(ev, 0, sizeof(*ev));
606
553
        ev->transport_handle = iscsi_handle(conn->transport);
607
554
        ev->type = ISCSI_KEVENT_RECV_PDU;
608
 
        if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)
609
 
                ev->iferror = -ENOMEM;
610
 
        ev->r.recv_req.conn_handle = iscsi_handle(conn);
 
555
        ev->r.recv_req.cid = conn->cid;
 
556
        ev->r.recv_req.sid = iscsi_conn_get_sid(conn);
611
557
        pdu = (char*)ev + sizeof(*ev);
612
558
        memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
613
559
        memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
614
560
 
615
 
        return iscsi_unicast_skb(conn->z_pdu, skb);
 
561
        return iscsi_unicast_skb(skb, priv->daemon_pid);
616
562
}
617
563
EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
618
564
 
621
567
        struct nlmsghdr *nlh;
622
568
        struct sk_buff  *skb;
623
569
        struct iscsi_uevent *ev;
 
570
        struct iscsi_internal *priv;
624
571
        int len = NLMSG_SPACE(sizeof(*ev));
625
572
 
626
 
        mempool_zone_complete(conn->z_error);
 
573
        priv = iscsi_if_transport_lookup(conn->transport);
 
574
        if (!priv)
 
575
                return;
627
576
 
628
 
        skb = mempool_zone_get_skb(conn->z_error);
 
577
        skb = alloc_skb(len, GFP_ATOMIC);
629
578
        if (!skb) {
630
579
                dev_printk(KERN_ERR, &conn->dev, "iscsi: gracefully ignored "
631
580
                          "conn error (%d)\n", error);
632
581
                return;
633
582
        }
634
583
 
635
 
        nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
 
584
        nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
636
585
        ev = NLMSG_DATA(nlh);
637
586
        ev->transport_handle = iscsi_handle(conn->transport);
638
587
        ev->type = ISCSI_KEVENT_CONN_ERROR;
639
 
        if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat)
640
 
                ev->iferror = -ENOMEM;
641
588
        ev->r.connerror.error = error;
642
 
        ev->r.connerror.conn_handle = iscsi_handle(conn);
 
589
        ev->r.connerror.cid = conn->cid;
 
590
        ev->r.connerror.sid = iscsi_conn_get_sid(conn);
643
591
 
644
 
        iscsi_unicast_skb(conn->z_error, skb);
 
592
        iscsi_broadcast_skb(skb, GFP_ATOMIC);
645
593
 
646
594
        dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n",
647
595
                   error);
658
606
        int flags = multi ? NLM_F_MULTI : 0;
659
607
        int t = done ? NLMSG_DONE : type;
660
608
 
661
 
        mempool_zone_complete(z_reply);
662
 
 
663
 
        skb = mempool_zone_get_skb(z_reply);
 
609
        skb = alloc_skb(len, GFP_KERNEL);
664
610
        /*
665
611
         * FIXME:
666
612
         * user is supposed to react on iferror == -ENOMEM;
671
617
        nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);
672
618
        nlh->nlmsg_flags = flags;
673
619
        memcpy(NLMSG_DATA(nlh), payload, size);
674
 
        return iscsi_unicast_skb(z_reply, skb);
 
620
        return iscsi_unicast_skb(skb, pid);
675
621
}
676
622
 
677
623
static int
683
629
        struct iscsi_cls_conn *conn;
684
630
        struct nlmsghdr *nlhstat;
685
631
        struct iscsi_uevent *evstat;
 
632
        struct iscsi_internal *priv;
686
633
        int len = NLMSG_SPACE(sizeof(*ev) +
687
634
                              sizeof(struct iscsi_stats) +
688
635
                              sizeof(struct iscsi_stats_custom) *
689
636
                              ISCSI_STATS_CUSTOM_MAX);
690
637
        int err = 0;
691
638
 
692
 
        conn = iscsi_conn_lookup(ev->u.get_stats.conn_handle);
 
639
        priv = iscsi_if_transport_lookup(transport);
 
640
        if (!priv)
 
641
                return -EINVAL;
 
642
 
 
643
        conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid);
693
644
        if (!conn)
694
645
                return -EEXIST;
695
646
 
696
647
        do {
697
648
                int actual_size;
698
649
 
699
 
                mempool_zone_complete(conn->z_pdu);
700
 
 
701
 
                skbstat = mempool_zone_get_skb(conn->z_pdu);
 
650
                skbstat = alloc_skb(len, GFP_KERNEL);
702
651
                if (!skbstat) {
703
652
                        dev_printk(KERN_ERR, &conn->dev, "iscsi: can not "
704
653
                                   "deliver stats: OOM\n");
705
654
                        return -ENOMEM;
706
655
                }
707
656
 
708
 
                nlhstat = __nlmsg_put(skbstat, daemon_pid, 0, 0,
 
657
                nlhstat = __nlmsg_put(skbstat, priv->daemon_pid, 0, 0,
709
658
                                      (len - sizeof(*nlhstat)), 0);
710
659
                evstat = NLMSG_DATA(nlhstat);
711
660
                memset(evstat, 0, sizeof(*evstat));
712
661
                evstat->transport_handle = iscsi_handle(conn->transport);
713
662
                evstat->type = nlh->nlmsg_type;
714
 
                if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)
715
 
                        evstat->iferror = -ENOMEM;
716
 
                evstat->u.get_stats.conn_handle =
717
 
                        ev->u.get_stats.conn_handle;
 
663
                evstat->u.get_stats.cid =
 
664
                        ev->u.get_stats.cid;
 
665
                evstat->u.get_stats.sid =
 
666
                        ev->u.get_stats.sid;
718
667
                stats = (struct iscsi_stats *)
719
668
                        ((char*)evstat + sizeof(*evstat));
720
669
                memset(stats, 0, sizeof(*stats));
729
678
                skb_trim(skbstat, NLMSG_ALIGN(actual_size));
730
679
                nlhstat->nlmsg_len = actual_size;
731
680
 
732
 
                err = iscsi_unicast_skb(conn->z_pdu, skbstat);
 
681
                err = iscsi_unicast_skb(skbstat, priv->daemon_pid);
733
682
        } while (err < 0 && err != -ECONNREFUSED);
734
683
 
735
684
        return err;
736
685
}
737
686
 
 
687
/**
 
688
 * iscsi_if_destroy_session_done - send session destr. completion event
 
689
 * @conn: last connection for session
 
690
 *
 
691
 * This is called by HW iscsi LLDs to notify userpsace that its HW has
 
692
 * removed a session.
 
693
 **/
 
694
int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn)
 
695
{
 
696
        struct iscsi_internal *priv;
 
697
        struct iscsi_cls_session *session;
 
698
        struct Scsi_Host *shost;
 
699
        struct iscsi_uevent *ev;
 
700
        struct sk_buff  *skb;
 
701
        struct nlmsghdr *nlh;
 
702
        unsigned long flags;
 
703
        int rc, len = NLMSG_SPACE(sizeof(*ev));
 
704
 
 
705
        priv = iscsi_if_transport_lookup(conn->transport);
 
706
        if (!priv)
 
707
                return -EINVAL;
 
708
 
 
709
        session = iscsi_dev_to_session(conn->dev.parent);
 
710
        shost = iscsi_session_to_shost(session);
 
711
 
 
712
        skb = alloc_skb(len, GFP_KERNEL);
 
713
        if (!skb) {
 
714
                dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
 
715
                          "session creation event\n");
 
716
                return -ENOMEM;
 
717
        }
 
718
 
 
719
        nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
 
720
        ev = NLMSG_DATA(nlh);
 
721
        ev->transport_handle = iscsi_handle(conn->transport);
 
722
        ev->type = ISCSI_KEVENT_DESTROY_SESSION;
 
723
        ev->r.d_session.host_no = shost->host_no;
 
724
        ev->r.d_session.sid = session->sid;
 
725
 
 
726
        /*
 
727
         * this will occur if the daemon is not up, so we just warn
 
728
         * the user and when the daemon is restarted it will handle it
 
729
         */
 
730
        rc = iscsi_broadcast_skb(skb, GFP_KERNEL);
 
731
        if (rc < 0)
 
732
                dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
 
733
                          "session destruction event. Check iscsi daemon\n");
 
734
 
 
735
        spin_lock_irqsave(&sesslock, flags);
 
736
        list_del(&session->sess_list);
 
737
        spin_unlock_irqrestore(&sesslock, flags);
 
738
 
 
739
        spin_lock_irqsave(&connlock, flags);
 
740
        conn->active = 0;
 
741
        list_del(&conn->conn_list);
 
742
        spin_unlock_irqrestore(&connlock, flags);
 
743
 
 
744
        return rc;
 
745
}
 
746
EXPORT_SYMBOL_GPL(iscsi_if_destroy_session_done);
 
747
 
 
748
/**
 
749
 * iscsi_if_create_session_done - send session creation completion event
 
750
 * @conn: leading connection for session
 
751
 *
 
752
 * This is called by HW iscsi LLDs to notify userpsace that its HW has
 
753
 * created a session or a existing session is back in the logged in state.
 
754
 **/
 
755
int iscsi_if_create_session_done(struct iscsi_cls_conn *conn)
 
756
{
 
757
        struct iscsi_internal *priv;
 
758
        struct iscsi_cls_session *session;
 
759
        struct Scsi_Host *shost;
 
760
        struct iscsi_uevent *ev;
 
761
        struct sk_buff  *skb;
 
762
        struct nlmsghdr *nlh;
 
763
        unsigned long flags;
 
764
        int rc, len = NLMSG_SPACE(sizeof(*ev));
 
765
 
 
766
        priv = iscsi_if_transport_lookup(conn->transport);
 
767
        if (!priv)
 
768
                return -EINVAL;
 
769
 
 
770
        session = iscsi_dev_to_session(conn->dev.parent);
 
771
        shost = iscsi_session_to_shost(session);
 
772
 
 
773
        skb = alloc_skb(len, GFP_KERNEL);
 
774
        if (!skb) {
 
775
                dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
 
776
                          "session creation event\n");
 
777
                return -ENOMEM;
 
778
        }
 
779
 
 
780
        nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
 
781
        ev = NLMSG_DATA(nlh);
 
782
        ev->transport_handle = iscsi_handle(conn->transport);
 
783
        ev->type = ISCSI_UEVENT_CREATE_SESSION;
 
784
        ev->r.c_session_ret.host_no = shost->host_no;
 
785
        ev->r.c_session_ret.sid = session->sid;
 
786
 
 
787
        /*
 
788
         * this will occur if the daemon is not up, so we just warn
 
789
         * the user and when the daemon is restarted it will handle it
 
790
         */
 
791
        rc = iscsi_broadcast_skb(skb, GFP_KERNEL);
 
792
        if (rc < 0)
 
793
                dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
 
794
                          "session creation event. Check iscsi daemon\n");
 
795
 
 
796
        spin_lock_irqsave(&sesslock, flags);
 
797
        list_add(&session->sess_list, &sesslist);
 
798
        spin_unlock_irqrestore(&sesslock, flags);
 
799
 
 
800
        spin_lock_irqsave(&connlock, flags);
 
801
        list_add(&conn->conn_list, &connlist);
 
802
        conn->active = 1;
 
803
        spin_unlock_irqrestore(&connlock, flags);
 
804
        return rc;
 
805
}
 
806
EXPORT_SYMBOL_GPL(iscsi_if_create_session_done);
 
807
 
738
808
static int
739
809
iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
740
810
{
741
811
        struct iscsi_transport *transport = priv->iscsi_transport;
742
812
        struct iscsi_cls_session *session;
743
 
        uint32_t sid;
 
813
        unsigned long flags;
 
814
        uint32_t hostno;
744
815
 
745
 
        session = transport->create_session(&priv->t,
 
816
        session = transport->create_session(transport, &priv->t,
746
817
                                            ev->u.c_session.initial_cmdsn,
747
 
                                            &sid);
 
818
                                            &hostno);
748
819
        if (!session)
749
820
                return -ENOMEM;
750
821
 
751
 
        ev->r.c_session_ret.session_handle = iscsi_handle(session);
752
 
        ev->r.c_session_ret.sid = sid;
 
822
        spin_lock_irqsave(&sesslock, flags);
 
823
        list_add(&session->sess_list, &sesslist);
 
824
        spin_unlock_irqrestore(&sesslock, flags);
 
825
 
 
826
        ev->r.c_session_ret.host_no = hostno;
 
827
        ev->r.c_session_ret.sid = session->sid;
753
828
        return 0;
754
829
}
755
830
 
760
835
        struct iscsi_cls_session *session;
761
836
        unsigned long flags;
762
837
 
763
 
        session = iscsi_session_lookup(ev->u.c_conn.session_handle);
764
 
        if (!session)
 
838
        session = iscsi_session_lookup(ev->u.c_conn.sid);
 
839
        if (!session) {
 
840
                printk(KERN_ERR "iscsi: invalid session %d\n",
 
841
                       ev->u.c_conn.sid);
765
842
                return -EINVAL;
 
843
        }
766
844
 
767
845
        conn = transport->create_conn(session, ev->u.c_conn.cid);
768
 
        if (!conn)
 
846
        if (!conn) {
 
847
                printk(KERN_ERR "iscsi: couldn't create a new "
 
848
                           "connection for session %d\n",
 
849
                           session->sid);
769
850
                return -ENOMEM;
770
 
 
771
 
        conn->z_pdu = mempool_zone_init(Z_MAX_PDU,
772
 
                        NLMSG_SPACE(sizeof(struct iscsi_uevent) +
773
 
                                    sizeof(struct iscsi_hdr) +
774
 
                                    DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),
775
 
                        Z_HIWAT_PDU);
776
 
        if (!conn->z_pdu) {
777
 
                dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
778
 
                           "pdu zone for new conn\n");
779
 
                goto destroy_conn;
780
 
        }
781
 
 
782
 
        conn->z_error = mempool_zone_init(Z_MAX_ERROR,
783
 
                        NLMSG_SPACE(sizeof(struct iscsi_uevent)),
784
 
                        Z_HIWAT_ERROR);
785
 
        if (!conn->z_error) {
786
 
                dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
787
 
                           "error zone for new conn\n");
788
 
                goto free_pdu_pool;
789
 
        }
790
 
 
791
 
        ev->r.handle = iscsi_handle(conn);
 
851
        }
 
852
 
 
853
        ev->r.c_conn_ret.sid = session->sid;
 
854
        ev->r.c_conn_ret.cid = conn->cid;
792
855
 
793
856
        spin_lock_irqsave(&connlock, flags);
794
857
        list_add(&conn->conn_list, &connlist);
796
859
        spin_unlock_irqrestore(&connlock, flags);
797
860
 
798
861
        return 0;
799
 
 
800
 
free_pdu_pool:
801
 
        mempool_zone_destroy(conn->z_pdu);
802
 
destroy_conn:
803
 
        if (transport->destroy_conn)
804
 
                transport->destroy_conn(conn->dd_data);
805
 
        return -ENOMEM;
806
862
}
807
863
 
808
864
static int
810
866
{
811
867
        unsigned long flags;
812
868
        struct iscsi_cls_conn *conn;
813
 
        struct mempool_zone *z_error, *z_pdu;
814
869
 
815
 
        conn = iscsi_conn_lookup(ev->u.d_conn.conn_handle);
 
870
        conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid);
816
871
        if (!conn)
817
872
                return -EINVAL;
818
873
        spin_lock_irqsave(&connlock, flags);
820
875
        list_del(&conn->conn_list);
821
876
        spin_unlock_irqrestore(&connlock, flags);
822
877
 
823
 
        z_pdu = conn->z_pdu;
824
 
        z_error = conn->z_error;
825
 
 
826
878
        if (transport->destroy_conn)
827
879
                transport->destroy_conn(conn);
828
 
 
829
 
        mempool_zone_destroy(z_pdu);
830
 
        mempool_zone_destroy(z_error);
831
 
 
832
880
        return 0;
833
881
}
834
882
 
835
883
static int
 
884
iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
 
885
{
 
886
        char *data = (char*)ev + sizeof(*ev);
 
887
        struct iscsi_cls_conn *conn;
 
888
        struct iscsi_cls_session *session;
 
889
        int err = 0, value = 0;
 
890
 
 
891
        session = iscsi_session_lookup(ev->u.set_param.sid);
 
892
        conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid);
 
893
        if (!conn || !session)
 
894
                return -EINVAL;
 
895
 
 
896
        switch (ev->u.set_param.param) {
 
897
        case ISCSI_PARAM_SESS_RECOVERY_TMO:
 
898
                sscanf(data, "%d", &value);
 
899
                if (value != 0)
 
900
                        session->recovery_tmo = value;
 
901
                break;
 
902
        default:
 
903
                err = transport->set_param(conn, ev->u.set_param.param,
 
904
                                           data, ev->u.set_param.len);
 
905
        }
 
906
 
 
907
        return err;
 
908
}
 
909
 
 
910
static int
 
911
iscsi_if_transport_ep(struct iscsi_transport *transport,
 
912
                      struct iscsi_uevent *ev, int msg_type)
 
913
{
 
914
        struct sockaddr *dst_addr;
 
915
        int rc = 0;
 
916
 
 
917
        switch (msg_type) {
 
918
        case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
 
919
                if (!transport->ep_connect)
 
920
                        return -EINVAL;
 
921
 
 
922
                dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
 
923
                rc = transport->ep_connect(dst_addr,
 
924
                                           ev->u.ep_connect.non_blocking,
 
925
                                           &ev->r.ep_connect_ret.handle);
 
926
                break;
 
927
        case ISCSI_UEVENT_TRANSPORT_EP_POLL:
 
928
                if (!transport->ep_poll)
 
929
                        return -EINVAL;
 
930
 
 
931
                ev->r.retcode = transport->ep_poll(ev->u.ep_poll.ep_handle,
 
932
                                                   ev->u.ep_poll.timeout_ms);
 
933
                break;
 
934
        case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
 
935
                if (!transport->ep_disconnect)
 
936
                        return -EINVAL;
 
937
 
 
938
                transport->ep_disconnect(ev->u.ep_disconnect.ep_handle);
 
939
                break;
 
940
        }
 
941
        return rc;
 
942
}
 
943
 
 
944
static int
 
945
iscsi_tgt_dscvr(struct iscsi_transport *transport,
 
946
                struct iscsi_uevent *ev)
 
947
{
 
948
        struct sockaddr *dst_addr;
 
949
 
 
950
        if (!transport->tgt_dscvr)
 
951
                return -EINVAL;
 
952
 
 
953
        dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
 
954
        return transport->tgt_dscvr(ev->u.tgt_dscvr.type,
 
955
                                    ev->u.tgt_dscvr.host_no,
 
956
                                    ev->u.tgt_dscvr.enable, dst_addr);
 
957
}
 
958
 
 
959
static int
836
960
iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
837
961
{
838
962
        int err = 0;
841
965
        struct iscsi_internal *priv;
842
966
        struct iscsi_cls_session *session;
843
967
        struct iscsi_cls_conn *conn;
 
968
        unsigned long flags;
844
969
 
845
970
        priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
846
971
        if (!priv)
850
975
        if (!try_module_get(transport->owner))
851
976
                return -EINVAL;
852
977
 
 
978
        priv->daemon_pid = NETLINK_CREDS(skb)->pid;
 
979
 
853
980
        switch (nlh->nlmsg_type) {
854
981
        case ISCSI_UEVENT_CREATE_SESSION:
855
982
                err = iscsi_if_create_session(priv, ev);
856
983
                break;
857
984
        case ISCSI_UEVENT_DESTROY_SESSION:
858
 
                session = iscsi_session_lookup(ev->u.d_session.session_handle);
859
 
                if (session)
 
985
                session = iscsi_session_lookup(ev->u.d_session.sid);
 
986
                if (session) {
 
987
                        spin_lock_irqsave(&sesslock, flags);
 
988
                        list_del(&session->sess_list);
 
989
                        spin_unlock_irqrestore(&sesslock, flags);
 
990
 
860
991
                        transport->destroy_session(session);
861
 
                else
 
992
                } else
862
993
                        err = -EINVAL;
863
994
                break;
864
995
        case ISCSI_UEVENT_CREATE_CONN:
868
999
                err = iscsi_if_destroy_conn(transport, ev);
869
1000
                break;
870
1001
        case ISCSI_UEVENT_BIND_CONN:
871
 
                session = iscsi_session_lookup(ev->u.b_conn.session_handle);
872
 
                conn = iscsi_conn_lookup(ev->u.b_conn.conn_handle);
 
1002
                session = iscsi_session_lookup(ev->u.b_conn.sid);
 
1003
                conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid);
873
1004
 
874
1005
                if (session && conn)
875
1006
                        ev->r.retcode = transport->bind_conn(session, conn,
876
 
                                        ev->u.b_conn.transport_fd,
 
1007
                                        ev->u.b_conn.transport_eph,
877
1008
                                        ev->u.b_conn.is_leading);
878
1009
                else
879
1010
                        err = -EINVAL;
880
1011
                break;
881
1012
        case ISCSI_UEVENT_SET_PARAM:
882
 
                conn = iscsi_conn_lookup(ev->u.set_param.conn_handle);
883
 
                if (conn)
884
 
                        ev->r.retcode = transport->set_param(conn,
885
 
                                ev->u.set_param.param, ev->u.set_param.value);
886
 
                else
887
 
                        err = -EINVAL;
 
1013
                err = iscsi_set_param(transport, ev);
888
1014
                break;
889
1015
        case ISCSI_UEVENT_START_CONN:
890
 
                conn = iscsi_conn_lookup(ev->u.start_conn.conn_handle);
 
1016
                conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid);
891
1017
                if (conn)
892
1018
                        ev->r.retcode = transport->start_conn(conn);
893
1019
                else
894
1020
                        err = -EINVAL;
895
 
 
896
1021
                break;
897
1022
        case ISCSI_UEVENT_STOP_CONN:
898
 
                conn = iscsi_conn_lookup(ev->u.stop_conn.conn_handle);
 
1023
                conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid);
899
1024
                if (conn)
900
1025
                        transport->stop_conn(conn, ev->u.stop_conn.flag);
901
1026
                else
902
1027
                        err = -EINVAL;
903
1028
                break;
904
1029
        case ISCSI_UEVENT_SEND_PDU:
905
 
                conn = iscsi_conn_lookup(ev->u.send_pdu.conn_handle);
 
1030
                conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid);
906
1031
                if (conn)
907
1032
                        ev->r.retcode = transport->send_pdu(conn,
908
1033
                                (struct iscsi_hdr*)((char*)ev + sizeof(*ev)),
914
1039
        case ISCSI_UEVENT_GET_STATS:
915
1040
                err = iscsi_if_get_stats(transport, nlh);
916
1041
                break;
 
1042
        case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
 
1043
        case ISCSI_UEVENT_TRANSPORT_EP_POLL:
 
1044
        case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
 
1045
                err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type);
 
1046
                break;
 
1047
        case ISCSI_UEVENT_TGT_DSCVR:
 
1048
                err = iscsi_tgt_dscvr(transport, ev);
 
1049
                break;
917
1050
        default:
918
1051
                err = -EINVAL;
919
1052
                break;
923
1056
        return err;
924
1057
}
925
1058
 
926
 
/* Get message from skb (based on rtnetlink_rcv_skb).  Each message is
927
 
 * processed by iscsi_if_recv_msg.  Malformed skbs with wrong length are
928
 
 * or invalid creds discarded silently.  */
 
1059
/*
 
1060
 * Get message from skb (based on rtnetlink_rcv_skb).  Each message is
 
1061
 * processed by iscsi_if_recv_msg.  Malformed skbs with wrong lengths or
 
1062
 * invalid creds are discarded silently.
 
1063
 */
929
1064
static void
930
1065
iscsi_if_rx(struct sock *sk, int len)
931
1066
{
937
1072
                        skb_pull(skb, skb->len);
938
1073
                        goto free_skb;
939
1074
                }
940
 
                daemon_pid = NETLINK_CREDS(skb)->pid;
941
1075
 
942
1076
                while (skb->len >= NLMSG_SPACE(0)) {
943
1077
                        int err;
973
1107
                                err = iscsi_if_send_reply(
974
1108
                                        NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
975
1109
                                        nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
976
 
                                if (atomic_read(&z_reply->allocated) >=
977
 
                                                z_reply->hiwat)
978
 
                                        ev->iferror = -ENOMEM;
979
1110
                        } while (err < 0 && err != -ECONNREFUSED);
980
1111
                        skb_pull(skb, rlen);
981
1112
                }
988
1119
#define iscsi_cdev_to_conn(_cdev) \
989
1120
        iscsi_dev_to_conn(_cdev->dev)
990
1121
 
 
1122
#define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store)              \
 
1123
struct class_device_attribute class_device_attr_##_prefix##_##_name =   \
 
1124
        __ATTR(_name,_mode,_show,_store)
 
1125
 
991
1126
/*
992
1127
 * iSCSI connection attrs
993
1128
 */
994
 
#define iscsi_conn_int_attr_show(param, format)                         \
 
1129
#define iscsi_conn_attr_show(param)                                     \
995
1130
static ssize_t                                                          \
996
 
show_conn_int_param_##param(struct class_device *cdev, char *buf)       \
 
1131
show_conn_param_##param(struct class_device *cdev, char *buf)           \
997
1132
{                                                                       \
998
 
        uint32_t value = 0;                                             \
999
1133
        struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev);         \
1000
1134
        struct iscsi_transport *t = conn->transport;                    \
1001
 
                                                                        \
1002
 
        t->get_conn_param(conn, param, &value);                         \
1003
 
        return snprintf(buf, 20, format"\n", value);                    \
 
1135
        return t->get_conn_param(conn, param, buf);                     \
1004
1136
}
1005
1137
 
1006
 
#define iscsi_conn_int_attr(field, param, format)                       \
1007
 
        iscsi_conn_int_attr_show(param, format)                         \
1008
 
static CLASS_DEVICE_ATTR(field, S_IRUGO, show_conn_int_param_##param, NULL);
 
1138
#define iscsi_conn_attr(field, param)                                   \
 
1139
        iscsi_conn_attr_show(param)                                     \
 
1140
static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_param_##param,  \
 
1141
                        NULL);
1009
1142
 
1010
 
iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u");
1011
 
iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u");
1012
 
iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d");
1013
 
iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d");
1014
 
iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d");
1015
 
iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d");
 
1143
iscsi_conn_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH);
 
1144
iscsi_conn_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH);
 
1145
iscsi_conn_attr(header_digest, ISCSI_PARAM_HDRDGST_EN);
 
1146
iscsi_conn_attr(data_digest, ISCSI_PARAM_DATADGST_EN);
 
1147
iscsi_conn_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN);
 
1148
iscsi_conn_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN);
 
1149
iscsi_conn_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT);
 
1150
iscsi_conn_attr(port, ISCSI_PARAM_CONN_PORT);
 
1151
iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN);
 
1152
iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS);
 
1153
iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS);
1016
1154
 
1017
1155
#define iscsi_cdev_to_session(_cdev) \
1018
1156
        iscsi_dev_to_session(_cdev->dev)
1020
1158
/*
1021
1159
 * iSCSI session attrs
1022
1160
 */
1023
 
#define iscsi_session_int_attr_show(param, format)                      \
 
1161
#define iscsi_session_attr_show(param)                                  \
1024
1162
static ssize_t                                                          \
1025
 
show_session_int_param_##param(struct class_device *cdev, char *buf)    \
 
1163
show_session_param_##param(struct class_device *cdev, char *buf)        \
1026
1164
{                                                                       \
1027
 
        uint32_t value = 0;                                             \
1028
 
        struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);        \
 
1165
        struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
1029
1166
        struct iscsi_transport *t = session->transport;                 \
1030
 
                                                                        \
1031
 
        t->get_session_param(session, param, &value);                   \
1032
 
        return snprintf(buf, 20, format"\n", value);                    \
1033
 
}
1034
 
 
1035
 
#define iscsi_session_int_attr(field, param, format)                    \
1036
 
        iscsi_session_int_attr_show(param, format)                      \
1037
 
static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_int_param_##param, NULL);
1038
 
 
1039
 
iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d");
1040
 
iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu");
1041
 
iscsi_session_int_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, "%d");
1042
 
iscsi_session_int_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, "%u");
1043
 
iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u");
1044
 
iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d");
1045
 
iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d");
1046
 
iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d");
1047
 
 
1048
 
#define SETUP_SESSION_RD_ATTR(field, param)                             \
1049
 
        if (priv->param_mask & (1 << param)) {                          \
1050
 
                priv->session_attrs[count] = &class_device_attr_##field;\
1051
 
                count++;                                                \
1052
 
        }
1053
 
 
1054
 
#define SETUP_CONN_RD_ATTR(field, param)                                \
1055
 
        if (priv->param_mask & (1 << param)) {                          \
1056
 
                priv->conn_attrs[count] = &class_device_attr_##field;   \
1057
 
                count++;                                                \
1058
 
        }
 
1167
        return t->get_session_param(session, param, buf);               \
 
1168
}
 
1169
 
 
1170
#define iscsi_session_attr(field, param)                                \
 
1171
        iscsi_session_attr_show(param)                                  \
 
1172
static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_param_##param, \
 
1173
                        NULL);
 
1174
 
 
1175
iscsi_session_attr(targetname, ISCSI_PARAM_TARGET_NAME);
 
1176
iscsi_session_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN);
 
1177
iscsi_session_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T);
 
1178
iscsi_session_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN);
 
1179
iscsi_session_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST);
 
1180
iscsi_session_attr(max_burst_len, ISCSI_PARAM_MAX_BURST);
 
1181
iscsi_session_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN);
 
1182
iscsi_session_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN);
 
1183
iscsi_session_attr(erl, ISCSI_PARAM_ERL);
 
1184
iscsi_session_attr(tpgt, ISCSI_PARAM_TPGT);
 
1185
 
 
1186
#define iscsi_priv_session_attr_show(field, format)                     \
 
1187
static ssize_t                                                          \
 
1188
show_priv_session_##field(struct class_device *cdev, char *buf)         \
 
1189
{                                                                       \
 
1190
        struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);\
 
1191
        return sprintf(buf, format"\n", session->field);                \
 
1192
}
 
1193
 
 
1194
#define iscsi_priv_session_attr(field, format)                          \
 
1195
        iscsi_priv_session_attr_show(field, format)                     \
 
1196
static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \
 
1197
                        NULL)
 
1198
iscsi_priv_session_attr(recovery_tmo, "%d");
 
1199
 
 
1200
#define SETUP_PRIV_SESSION_RD_ATTR(field)                               \
 
1201
do {                                                                    \
 
1202
        priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \
 
1203
        count++;                                                        \
 
1204
} while (0)
 
1205
 
 
1206
 
 
1207
#define SETUP_SESSION_RD_ATTR(field, param_flag)                        \
 
1208
do {                                                                    \
 
1209
        if (tt->param_mask & param_flag) {                              \
 
1210
                priv->session_attrs[count] = &class_device_attr_sess_##field; \
 
1211
                count++;                                                \
 
1212
        }                                                               \
 
1213
} while (0)
 
1214
 
 
1215
#define SETUP_CONN_RD_ATTR(field, param_flag)                           \
 
1216
do {                                                                    \
 
1217
        if (tt->param_mask & param_flag) {                              \
 
1218
                priv->conn_attrs[count] = &class_device_attr_conn_##field; \
 
1219
                count++;                                                \
 
1220
        }                                                               \
 
1221
} while (0)
1059
1222
 
1060
1223
static int iscsi_session_match(struct attribute_container *cont,
1061
1224
                           struct device *dev)
1104
1267
        return &priv->conn_cont.ac == cont;
1105
1268
}
1106
1269
 
 
1270
static int iscsi_host_match(struct attribute_container *cont,
 
1271
                            struct device *dev)
 
1272
{
 
1273
        struct Scsi_Host *shost;
 
1274
        struct iscsi_internal *priv;
 
1275
 
 
1276
        if (!scsi_is_host_device(dev))
 
1277
                return 0;
 
1278
 
 
1279
        shost = dev_to_shost(dev);
 
1280
        if (!shost->transportt  ||
 
1281
            shost->transportt->host_attrs.ac.class != &iscsi_host_class.class)
 
1282
                return 0;
 
1283
 
 
1284
        priv = to_iscsi_internal(shost->transportt);
 
1285
        return &priv->t.host_attrs.ac == cont;
 
1286
}
 
1287
 
1107
1288
struct scsi_transport_template *
1108
1289
iscsi_register_transport(struct iscsi_transport *tt)
1109
1290
{
1121
1302
        if (!priv)
1122
1303
                return NULL;
1123
1304
        INIT_LIST_HEAD(&priv->list);
 
1305
        priv->daemon_pid = -1;
1124
1306
        priv->iscsi_transport = tt;
 
1307
        priv->t.user_scan = iscsi_user_scan;
1125
1308
 
1126
1309
        priv->cdev.class = &iscsi_transport_class;
1127
1310
        snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name);
1133
1316
        if (err)
1134
1317
                goto unregister_cdev;
1135
1318
 
1136
 
        /* setup parameters mask */
1137
 
        priv->param_mask = 0xFFFFFFFF;
1138
 
        if (!(tt->caps & CAP_MULTI_R2T))
1139
 
                priv->param_mask &= ~(1 << ISCSI_PARAM_MAX_R2T);
1140
 
        if (!(tt->caps & CAP_HDRDGST))
1141
 
                priv->param_mask &= ~(1 << ISCSI_PARAM_HDRDGST_EN);
1142
 
        if (!(tt->caps & CAP_DATADGST))
1143
 
                priv->param_mask &= ~(1 << ISCSI_PARAM_DATADGST_EN);
1144
 
        if (!(tt->caps & CAP_MARKERS)) {
1145
 
                priv->param_mask &= ~(1 << ISCSI_PARAM_IFMARKER_EN);
1146
 
                priv->param_mask &= ~(1 << ISCSI_PARAM_OFMARKER_EN);
1147
 
        }
 
1319
        /* host parameters */
 
1320
        priv->t.host_attrs.ac.attrs = &priv->host_attrs[0];
 
1321
        priv->t.host_attrs.ac.class = &iscsi_host_class.class;
 
1322
        priv->t.host_attrs.ac.match = iscsi_host_match;
 
1323
        priv->t.host_size = sizeof(struct iscsi_host);
 
1324
        priv->host_attrs[0] = NULL;
 
1325
        transport_container_register(&priv->t.host_attrs);
1148
1326
 
1149
1327
        /* connection parameters */
1150
1328
        priv->conn_cont.ac.attrs = &priv->conn_attrs[0];
1152
1330
        priv->conn_cont.ac.match = iscsi_conn_match;
1153
1331
        transport_container_register(&priv->conn_cont);
1154
1332
 
1155
 
        SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH);
1156
 
        SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH);
1157
 
        SETUP_CONN_RD_ATTR(header_digest, ISCSI_PARAM_HDRDGST_EN);
1158
 
        SETUP_CONN_RD_ATTR(data_digest, ISCSI_PARAM_DATADGST_EN);
1159
 
        SETUP_CONN_RD_ATTR(ifmarker, ISCSI_PARAM_IFMARKER_EN);
1160
 
        SETUP_CONN_RD_ATTR(ofmarker, ISCSI_PARAM_OFMARKER_EN);
 
1333
        SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_MAX_RECV_DLENGTH);
 
1334
        SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_MAX_XMIT_DLENGTH);
 
1335
        SETUP_CONN_RD_ATTR(header_digest, ISCSI_HDRDGST_EN);
 
1336
        SETUP_CONN_RD_ATTR(data_digest, ISCSI_DATADGST_EN);
 
1337
        SETUP_CONN_RD_ATTR(ifmarker, ISCSI_IFMARKER_EN);
 
1338
        SETUP_CONN_RD_ATTR(ofmarker, ISCSI_OFMARKER_EN);
 
1339
        SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS);
 
1340
        SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT);
 
1341
        SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN);
 
1342
        SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS);
 
1343
        SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT);
1161
1344
 
1162
1345
        BUG_ON(count > ISCSI_CONN_ATTRS);
1163
1346
        priv->conn_attrs[count] = NULL;
1169
1352
        priv->session_cont.ac.match = iscsi_session_match;
1170
1353
        transport_container_register(&priv->session_cont);
1171
1354
 
1172
 
        SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN);
1173
 
        SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T);
1174
 
        SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_PARAM_IMM_DATA_EN);
1175
 
        SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_PARAM_FIRST_BURST);
1176
 
        SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_PARAM_MAX_BURST);
1177
 
        SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN);
1178
 
        SETUP_SESSION_RD_ATTR(data_seq_in_order,ISCSI_PARAM_DATASEQ_INORDER_EN)
1179
 
        SETUP_SESSION_RD_ATTR(erl, ISCSI_PARAM_ERL);
 
1355
        SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_INITIAL_R2T_EN);
 
1356
        SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_MAX_R2T);
 
1357
        SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_IMM_DATA_EN);
 
1358
        SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_FIRST_BURST);
 
1359
        SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_MAX_BURST);
 
1360
        SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN);
 
1361
        SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN);
 
1362
        SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL);
 
1363
        SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME);
 
1364
        SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT);
 
1365
        SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo);
1180
1366
 
1181
1367
        BUG_ON(count > ISCSI_SESSION_ATTRS);
1182
1368
        priv->session_attrs[count] = NULL;
1214
1400
 
1215
1401
        transport_container_unregister(&priv->conn_cont);
1216
1402
        transport_container_unregister(&priv->session_cont);
 
1403
        transport_container_unregister(&priv->t.host_attrs);
1217
1404
 
1218
1405
        sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group);
1219
1406
        class_device_unregister(&priv->cdev);
1223
1410
}
1224
1411
EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
1225
1412
 
1226
 
static int
1227
 
iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr)
1228
 
{
1229
 
        struct netlink_notify *n = ptr;
1230
 
 
1231
 
        if (event == NETLINK_URELEASE &&
1232
 
            n->protocol == NETLINK_ISCSI && n->pid) {
1233
 
                struct iscsi_cls_conn *conn;
1234
 
                unsigned long flags;
1235
 
 
1236
 
                mempool_zone_complete(z_reply);
1237
 
                spin_lock_irqsave(&connlock, flags);
1238
 
                list_for_each_entry(conn, &connlist, conn_list) {
1239
 
                        mempool_zone_complete(conn->z_error);
1240
 
                        mempool_zone_complete(conn->z_pdu);
1241
 
                }
1242
 
                spin_unlock_irqrestore(&connlock, flags);
1243
 
        }
1244
 
 
1245
 
        return NOTIFY_DONE;
1246
 
}
1247
 
 
1248
 
static struct notifier_block iscsi_nl_notifier = {
1249
 
        .notifier_call  = iscsi_rcv_nl_event,
1250
 
};
1251
 
 
1252
1413
static __init int iscsi_transport_init(void)
1253
1414
{
1254
1415
        int err;
1255
1416
 
 
1417
        printk(KERN_INFO "Loading iSCSI transport class v%s.\n",
 
1418
                ISCSI_TRANSPORT_VERSION);
 
1419
 
1256
1420
        err = class_register(&iscsi_transport_class);
1257
1421
        if (err)
1258
1422
                return err;
1259
1423
 
 
1424
        err = transport_class_register(&iscsi_host_class);
 
1425
        if (err)
 
1426
                goto unregister_transport_class;
 
1427
 
1260
1428
        err = transport_class_register(&iscsi_connection_class);
1261
1429
        if (err)
1262
 
                goto unregister_transport_class;
 
1430
                goto unregister_host_class;
1263
1431
 
1264
1432
        err = transport_class_register(&iscsi_session_class);
1265
1433
        if (err)
1266
1434
                goto unregister_conn_class;
1267
1435
 
1268
 
        err = netlink_register_notifier(&iscsi_nl_notifier);
1269
 
        if (err)
1270
 
                goto unregister_session_class;
1271
 
 
1272
1436
        nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx,
1273
1437
                        THIS_MODULE);
1274
1438
        if (!nls) {
1275
1439
                err = -ENOBUFS;
1276
 
                goto unregister_notifier;
 
1440
                goto unregister_session_class;
1277
1441
        }
1278
1442
 
1279
 
        z_reply = mempool_zone_init(Z_MAX_REPLY,
1280
 
                NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY);
1281
 
        if (z_reply)
1282
 
                return 0;
 
1443
        return 0;
1283
1444
 
1284
 
        sock_release(nls->sk_socket);
1285
 
unregister_notifier:
1286
 
        netlink_unregister_notifier(&iscsi_nl_notifier);
1287
1445
unregister_session_class:
1288
1446
        transport_class_unregister(&iscsi_session_class);
1289
1447
unregister_conn_class:
1290
1448
        transport_class_unregister(&iscsi_connection_class);
 
1449
unregister_host_class:
 
1450
        transport_class_unregister(&iscsi_host_class);
1291
1451
unregister_transport_class:
1292
1452
        class_unregister(&iscsi_transport_class);
1293
1453
        return err;
1295
1455
 
1296
1456
static void __exit iscsi_transport_exit(void)
1297
1457
{
1298
 
        mempool_zone_destroy(z_reply);
1299
1458
        sock_release(nls->sk_socket);
1300
 
        netlink_unregister_notifier(&iscsi_nl_notifier);
1301
1459
        transport_class_unregister(&iscsi_connection_class);
1302
1460
        transport_class_unregister(&iscsi_session_class);
 
1461
        transport_class_unregister(&iscsi_host_class);
1303
1462
        class_unregister(&iscsi_transport_class);
1304
1463
}
1305
1464
 
1311
1470
              "Alex Aizman <itn780@yahoo.com>");
1312
1471
MODULE_DESCRIPTION("iSCSI Transport Interface");
1313
1472
MODULE_LICENSE("GPL");
 
1473
MODULE_VERSION(ISCSI_TRANSPORT_VERSION);