diff --git a/[refs] b/[refs] index 4140d75f723a..1937d3bd35c1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8eb88c80d444fd249edaa7d895666cde79e7b3b8 +refs/heads/master: 6388a388ffb720f40fc8046c261252ea2be9c12f diff --git a/trunk/arch/cris/Makefile b/trunk/arch/cris/Makefile index c6f5f5a2ffdf..838cd2ae03ae 100644 --- a/trunk/arch/cris/Makefile +++ b/trunk/arch/cris/Makefile @@ -10,8 +10,6 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. -KBUILD_DEFCONFIG := etrax-100lx_v2_defconfig - arch-y := v10 arch-$(CONFIG_ETRAX_ARCH_V10) := v10 arch-$(CONFIG_ETRAX_ARCH_V32) := v32 diff --git a/trunk/arch/cris/arch-v10/boot/compressed/Makefile b/trunk/arch/cris/arch-v10/boot/compressed/Makefile index 6fe0ffaf3be6..08d943ce4be7 100644 --- a/trunk/arch/cris/arch-v10/boot/compressed/Makefile +++ b/trunk/arch/cris/arch-v10/boot/compressed/Makefile @@ -4,7 +4,7 @@ asflags-y += $(LINUXINCLUDE) ccflags-y += -O2 $(LINUXINCLUDE) -ldflags-y += -T $(srctree)/$(src)/decompress.lds +ldflags-y += -T $(srctree)/$(obj)/decompress.ld OBJECTS = $(obj)/head.o $(obj)/misc.o OBJCOPYFLAGS = -O binary --remove-section=.bss diff --git a/trunk/arch/cris/arch-v10/boot/compressed/decompress.lds b/trunk/arch/cris/arch-v10/boot/compressed/decompress.ld similarity index 100% rename from trunk/arch/cris/arch-v10/boot/compressed/decompress.lds rename to trunk/arch/cris/arch-v10/boot/compressed/decompress.ld diff --git a/trunk/arch/cris/arch-v10/boot/rescue/Makefile b/trunk/arch/cris/arch-v10/boot/rescue/Makefile index 82ab59b968e5..07688da92708 100644 --- a/trunk/arch/cris/arch-v10/boot/rescue/Makefile +++ b/trunk/arch/cris/arch-v10/boot/rescue/Makefile @@ -4,7 +4,7 @@ ccflags-y += -O2 $(LINUXINCLUDE) asflags-y += $(LINUXINCLUDE) -ldflags-y += -T $(srctree)/$(src)/rescue.lds +ldflags-y += -T $(srctree)/$(obj)/rescue.ld OBJCOPYFLAGS = -O binary --remove-section=.bss obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o OBJECT := $(obj)/head.o diff --git a/trunk/arch/cris/arch-v10/boot/rescue/rescue.lds b/trunk/arch/cris/arch-v10/boot/rescue/rescue.ld similarity index 100% rename from trunk/arch/cris/arch-v10/boot/rescue/rescue.lds rename to trunk/arch/cris/arch-v10/boot/rescue/rescue.ld diff --git a/trunk/arch/cris/configs/etrax-100lx_defconfig b/trunk/arch/cris/arch-v10/defconfig similarity index 100% rename from trunk/arch/cris/configs/etrax-100lx_defconfig rename to trunk/arch/cris/arch-v10/defconfig diff --git a/trunk/arch/cris/arch-v32/boot/compressed/Makefile b/trunk/arch/cris/arch-v32/boot/compressed/Makefile index 5a1b31c99eaa..d6335f26083b 100644 --- a/trunk/arch/cris/arch-v32/boot/compressed/Makefile +++ b/trunk/arch/cris/arch-v32/boot/compressed/Makefile @@ -4,7 +4,7 @@ asflags-y += -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch -ldflags-y += -T $(srctree)/$(src)/decompress.lds +ldflags-y += -T $(srctree)/$(obj)/decompress.ld OBJECTS = $(obj)/head.o $(obj)/misc.o OBJCOPYFLAGS = -O binary --remove-section=.bss diff --git a/trunk/arch/cris/arch-v32/boot/compressed/decompress.lds b/trunk/arch/cris/arch-v32/boot/compressed/decompress.ld similarity index 100% rename from trunk/arch/cris/arch-v32/boot/compressed/decompress.lds rename to trunk/arch/cris/arch-v32/boot/compressed/decompress.ld diff --git a/trunk/arch/cris/arch-v32/boot/rescue/Makefile b/trunk/arch/cris/arch-v32/boot/rescue/Makefile index 566aac663a38..44ae0ad61f90 100644 --- a/trunk/arch/cris/arch-v32/boot/rescue/Makefile +++ b/trunk/arch/cris/arch-v32/boot/rescue/Makefile @@ -7,7 +7,7 @@ ccflags-y += -O2 -I $(srctree)/include/asm/arch/mach/ \ -I $(srctree)/include/asm/arch asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch LD = gcc-cris -mlinux -march=v32 -nostdlib -ldflags-y += -T $(srctree)/$(src)/rescue.lds +ldflags-y += -T $(srctree)/$(obj)/rescue.ld LDPOSTFLAGS = -lgcc OBJCOPYFLAGS = -O binary --remove-section=.bss obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o diff --git a/trunk/arch/cris/arch-v32/boot/rescue/rescue.lds b/trunk/arch/cris/arch-v32/boot/rescue/rescue.ld similarity index 100% rename from trunk/arch/cris/arch-v32/boot/rescue/rescue.lds rename to trunk/arch/cris/arch-v32/boot/rescue/rescue.ld diff --git a/trunk/arch/cris/configs/artpec_3_defconfig b/trunk/arch/cris/artpec_3_defconfig similarity index 100% rename from trunk/arch/cris/configs/artpec_3_defconfig rename to trunk/arch/cris/artpec_3_defconfig diff --git a/trunk/arch/cris/configs/etrax-100lx_v2_defconfig b/trunk/arch/cris/defconfig similarity index 100% rename from trunk/arch/cris/configs/etrax-100lx_v2_defconfig rename to trunk/arch/cris/defconfig diff --git a/trunk/arch/cris/configs/etraxfs_defconfig b/trunk/arch/cris/etraxfs_defconfig similarity index 100% rename from trunk/arch/cris/configs/etraxfs_defconfig rename to trunk/arch/cris/etraxfs_defconfig diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index c3df30cfb3fc..2d053b584410 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -257,6 +257,7 @@ void __generic_unplug_device(struct request_queue *q) q->request_fn(q); } +EXPORT_SYMBOL(__generic_unplug_device); /** * generic_unplug_device - fire a request queue @@ -324,9 +325,6 @@ EXPORT_SYMBOL(blk_unplug); static void blk_invoke_request_fn(struct request_queue *q) { - if (unlikely(blk_queue_stopped(q))) - return; - /* * one level of recursion is ok and is much faster than kicking * the unplug handling @@ -401,13 +399,8 @@ void blk_sync_queue(struct request_queue *q) EXPORT_SYMBOL(blk_sync_queue); /** - * __blk_run_queue - run a single device queue + * blk_run_queue - run a single device queue * @q: The queue to run - * - * Description: - * See @blk_run_queue. This variant must be called with the queue lock - * held and interrupts disabled. - * */ void __blk_run_queue(struct request_queue *q) { @@ -425,12 +418,6 @@ EXPORT_SYMBOL(__blk_run_queue); /** * blk_run_queue - run a single device queue * @q: The queue to run - * - * Description: - * Invoke request handling on this queue, if it has pending work to do. - * May be used to restart queueing when a request has completed. Also - * See @blk_start_queueing. - * */ void blk_run_queue(struct request_queue *q) { @@ -514,7 +501,6 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) init_timer(&q->unplug_timer); setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q); INIT_LIST_HEAD(&q->timeout_list); - INIT_WORK(&q->unplug_work, blk_unplug_work); kobject_init(&q->kobj, &blk_queue_ktype); @@ -898,8 +884,7 @@ EXPORT_SYMBOL(blk_get_request); * * This is basically a helper to remove the need to know whether a queue * is plugged or not if someone just wants to initiate dispatch of requests - * for this queue. Should be used to start queueing on a device outside - * of ->request_fn() context. Also see @blk_run_queue. + * for this queue. * * The queue lock must be held with interrupts disabled. */ @@ -1018,9 +1003,8 @@ static void part_round_stats_single(int cpu, struct hd_struct *part, } /** - * part_round_stats() - Round off the performance stats on a struct disk_stats. - * @cpu: cpu number for stats access - * @part: target partition + * part_round_stats() - Round off the performance stats on a struct + * disk_stats. * * The average IO queue length and utilisation statistics are maintained * by observing the current state of the queue length and the amount of @@ -1091,15 +1075,8 @@ void init_request_from_bio(struct request *req, struct bio *bio) /* * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST) */ - if (bio_rw_ahead(bio)) - req->cmd_flags |= (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | - REQ_FAILFAST_DRIVER); - if (bio_failfast_dev(bio)) - req->cmd_flags |= REQ_FAILFAST_DEV; - if (bio_failfast_transport(bio)) - req->cmd_flags |= REQ_FAILFAST_TRANSPORT; - if (bio_failfast_driver(bio)) - req->cmd_flags |= REQ_FAILFAST_DRIVER; + if (bio_rw_ahead(bio) || bio_failfast(bio)) + req->cmd_flags |= REQ_FAILFAST; /* * REQ_BARRIER implies no merging, but lets make it explicit diff --git a/trunk/block/blk-merge.c b/trunk/block/blk-merge.c index 8681cd6f9911..908d3e11ac52 100644 --- a/trunk/block/blk-merge.c +++ b/trunk/block/blk-merge.c @@ -77,20 +77,12 @@ void blk_recalc_rq_segments(struct request *rq) continue; } new_segment: - if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) - rq->bio->bi_seg_front_size = seg_size; - nr_phys_segs++; bvprv = bv; seg_size = bv->bv_len; highprv = high; } - if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) - rq->bio->bi_seg_front_size = seg_size; - if (seg_size > rq->biotail->bi_seg_back_size) - rq->biotail->bi_seg_back_size = seg_size; - rq->nr_phys_segments = nr_phys_segs; } @@ -114,8 +106,7 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) return 0; - if (bio->bi_seg_back_size + nxt->bi_seg_front_size > - q->max_segment_size) + if (bio->bi_size + nxt->bi_size > q->max_segment_size) return 0; if (!bio_has_data(bio)) @@ -318,8 +309,6 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, struct request *next) { int total_phys_segments; - unsigned int seg_size = - req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size; /* * First check if the either of the requests are re-queued @@ -335,13 +324,8 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, return 0; total_phys_segments = req->nr_phys_segments + next->nr_phys_segments; - if (blk_phys_contig_segment(q, req->biotail, next->bio)) { - if (req->nr_phys_segments == 1) - req->bio->bi_seg_front_size = seg_size; - if (next->nr_phys_segments == 1) - next->biotail->bi_seg_back_size = seg_size; + if (blk_phys_contig_segment(q, req->biotail, next->bio)) total_phys_segments--; - } if (total_phys_segments > q->max_phys_segments) return 0; diff --git a/trunk/block/blk-settings.c b/trunk/block/blk-settings.c index 41392fbe19ff..b21dcdb64151 100644 --- a/trunk/block/blk-settings.c +++ b/trunk/block/blk-settings.c @@ -141,6 +141,8 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) if (q->unplug_delay == 0) q->unplug_delay = 1; + INIT_WORK(&q->unplug_work, blk_unplug_work); + q->unplug_timer.function = blk_unplug_timeout; q->unplug_timer.data = (unsigned long)q; diff --git a/trunk/block/blk.h b/trunk/block/blk.h index d2e49af90db5..e5c579769963 100644 --- a/trunk/block/blk.h +++ b/trunk/block/blk.h @@ -20,7 +20,6 @@ void blk_unplug_timeout(unsigned long data); void blk_rq_timed_out_timer(unsigned long data); void blk_delete_timer(struct request *); void blk_add_timer(struct request *); -void __generic_unplug_device(struct request_queue *); /* * Internal atomic flags for request handling diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 59173a69ebdf..04518921db31 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -612,7 +612,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) * processing. */ blk_remove_plug(q); - blk_start_queueing(q); + q->request_fn(q); break; case ELEVATOR_INSERT_SORT: @@ -950,7 +950,7 @@ void elv_completed_request(struct request_queue *q, struct request *rq) blk_ordered_cur_seq(q) == QUEUE_ORDSEQ_DRAIN && blk_ordered_req_seq(first_rq) > QUEUE_ORDSEQ_DRAIN) { blk_ordered_complete_seq(q, QUEUE_ORDSEQ_DRAIN, 0); - blk_start_queueing(q); + q->request_fn(q); } } } @@ -1109,7 +1109,8 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e) elv_drain_elevator(q); while (q->rq.elvpriv) { - blk_start_queueing(q); + blk_remove_plug(q); + q->request_fn(q); spin_unlock_irq(q->queue_lock); msleep(10); spin_lock_irq(q->queue_lock); @@ -1165,10 +1166,15 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name, size_t count) { char elevator_name[ELV_NAME_MAX]; + size_t len; struct elevator_type *e; - strlcpy(elevator_name, name, sizeof(elevator_name)); - strstrip(elevator_name); + elevator_name[sizeof(elevator_name) - 1] = '\0'; + strncpy(elevator_name, name, sizeof(elevator_name) - 1); + len = strlen(elevator_name); + + if (len && elevator_name[len - 1] == '\n') + elevator_name[len - 1] = '\0'; e = elevator_get(elevator_name); if (!e) { diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index 646e1d2507c7..4cd3433c99ac 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -358,6 +358,7 @@ static int blk_mangle_minor(int minor) /** * blk_alloc_devt - allocate a dev_t for a partition * @part: partition to allocate dev_t for + * @gfp_mask: memory allocation flag * @devt: out parameter for resulting dev_t * * Allocate a dev_t for block device. @@ -534,7 +535,7 @@ void unlink_gendisk(struct gendisk *disk) /** * get_gendisk - get partitioning information for a given device * @devt: device to get partitioning information for - * @partno: returned partition index + * @part: returned partition index * * This function gets the structure containing partitioning * information for the given device @devt. diff --git a/trunk/drivers/hwmon/lm90.c b/trunk/drivers/hwmon/lm90.c index c24fe36ac787..73a1c622fb7a 100644 --- a/trunk/drivers/hwmon/lm90.c +++ b/trunk/drivers/hwmon/lm90.c @@ -1,7 +1,7 @@ /* * lm90.c - Part of lm_sensors, Linux kernel modules for hardware * monitoring - * Copyright (C) 2003-2006 Jean Delvare + * Copyright (C) 2003-2008 Jean Delvare * * Based on the lm83 driver. The LM90 is a sensor chip made by National * Semiconductor. It reports up to two temperatures (its own plus up to @@ -736,6 +736,38 @@ static int lm90_remove(struct i2c_client *client) return 0; } +static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value) +{ + int err; + u8 oldh, newh, l; + + /* + * There is a trick here. We have to read two registers to have the + * sensor temperature, but we have to beware a conversion could occur + * inbetween the readings. The datasheet says we should either use + * the one-shot conversion register, which we don't want to do + * (disables hardware monitoring) or monitor the busy bit, which is + * impossible (we can't read the values and monitor that bit at the + * exact same time). So the solution used here is to read the high + * byte once, then the low byte, then the high byte again. If the new + * high byte matches the old one, then we have a valid reading. Else + * we have to read the low byte again, and now we believe we have a + * correct reading. + */ + if ((err = lm90_read_reg(client, regh, &oldh)) + || (err = lm90_read_reg(client, regl, &l)) + || (err = lm90_read_reg(client, regh, &newh))) + return err; + if (oldh != newh) { + err = lm90_read_reg(client, regl, &l); + if (err) + return err; + } + *value = (newh << 8) | l; + + return 0; +} + static struct lm90_data *lm90_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -744,7 +776,7 @@ static struct lm90_data *lm90_update_device(struct device *dev) mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { - u8 oldh, newh, l; + u8 h, l; dev_dbg(&client->dev, "Updating lm90 data.\n"); lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &data->temp8[0]); @@ -754,39 +786,21 @@ static struct lm90_data *lm90_update_device(struct device *dev) lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[4]); lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); - /* - * There is a trick here. We have to read two registers to - * have the remote sensor temperature, but we have to beware - * a conversion could occur inbetween the readings. The - * datasheet says we should either use the one-shot - * conversion register, which we don't want to do (disables - * hardware monitoring) or monitor the busy bit, which is - * impossible (we can't read the values and monitor that bit - * at the exact same time). So the solution used here is to - * read the high byte once, then the low byte, then the high - * byte again. If the new high byte matches the old one, - * then we have a valid reading. Else we have to read the low - * byte again, and now we believe we have a correct reading. - */ - if (lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &oldh) == 0 - && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0 - && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &newh) == 0 - && (newh == oldh - || lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0)) - data->temp11[0] = (newh << 8) | l; - - if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &newh) == 0 + lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, + LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]); + + if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0 && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0) - data->temp11[1] = (newh << 8) | l; - if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0 + data->temp11[1] = (h << 8) | l; + if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0 && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) - data->temp11[2] = (newh << 8) | l; + data->temp11[2] = (h << 8) | l; if (data->kind != max6657) { if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, - &newh) == 0 + &h) == 0 && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, &l) == 0) - data->temp11[3] = (newh << 8) | l; + data->temp11[3] = (h << 8) | l; } lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index 7162d67562af..77c6eaeacefa 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -1493,8 +1493,8 @@ void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq) spin_lock_irqsave(&ide_lock, flags); hwgroup->rq = NULL; - __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); - blk_start_queueing(drive->queue); + __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 1); + __generic_unplug_device(drive->queue); spin_unlock_irqrestore(&ide_lock, flags); } diff --git a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c index 1e5b6446231d..5a1cf2580e16 100644 --- a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -378,7 +378,6 @@ static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session) { struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); - iscsi_session_teardown(cls_session); iscsi_host_remove(shost); iscsi_host_free(shost); } @@ -598,7 +597,7 @@ static struct scsi_host_template iscsi_iser_sht = { .cmd_per_lun = ISCSI_MAX_CMD_PER_LUN, .eh_abort_handler = iscsi_eh_abort, .eh_device_reset_handler= iscsi_eh_device_reset, - .eh_target_reset_handler= iscsi_eh_target_reset, + .eh_host_reset_handler = iscsi_eh_host_reset, .use_clustering = DISABLE_CLUSTERING, .proc_name = "iscsi_iser", .this_id = -1, diff --git a/trunk/drivers/md/dm-mpath.c b/trunk/drivers/md/dm-mpath.c index 9bf3460c5540..103304c1e3b0 100644 --- a/trunk/drivers/md/dm-mpath.c +++ b/trunk/drivers/md/dm-mpath.c @@ -849,7 +849,7 @@ static int multipath_map(struct dm_target *ti, struct bio *bio, dm_bio_record(&mpio->details, bio); map_context->ptr = mpio; - bio->bi_rw |= (1 << BIO_RW_FAILFAST_TRANSPORT); + bio->bi_rw |= (1 << BIO_RW_FAILFAST); r = map_io(m, bio, mpio, 0); if (r < 0 || r == DM_MAPIO_REQUEUE) mempool_free(mpio, m->mpio_pool); diff --git a/trunk/drivers/md/multipath.c b/trunk/drivers/md/multipath.c index d4ac47d11279..8744014b9d80 100644 --- a/trunk/drivers/md/multipath.c +++ b/trunk/drivers/md/multipath.c @@ -167,7 +167,7 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio) mp_bh->bio = *bio; mp_bh->bio.bi_sector += multipath->rdev->data_offset; mp_bh->bio.bi_bdev = multipath->rdev->bdev; - mp_bh->bio.bi_rw |= (1 << BIO_RW_FAILFAST_TRANSPORT); + mp_bh->bio.bi_rw |= (1 << BIO_RW_FAILFAST); mp_bh->bio.bi_end_io = multipath_end_request; mp_bh->bio.bi_private = mp_bh; generic_make_request(&mp_bh->bio); @@ -393,7 +393,7 @@ static void multipathd (mddev_t *mddev) *bio = *(mp_bh->master_bio); bio->bi_sector += conf->multipaths[mp_bh->path].rdev->data_offset; bio->bi_bdev = conf->multipaths[mp_bh->path].rdev->bdev; - bio->bi_rw |= (1 << BIO_RW_FAILFAST_TRANSPORT); + bio->bi_rw |= (1 << BIO_RW_FAILFAST); bio->bi_end_io = multipath_end_request; bio->bi_private = mp_bh; generic_make_request(bio); diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index ad301ace6085..1d8af3348331 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -2410,6 +2410,7 @@ config IXGBE tristate "Intel(R) 10GbE PCI Express adapters support" depends on PCI && INET select INET_LRO + select INTEL_IOATDMA ---help--- This driver supports Intel(R) 10GbE PCI Express family of adapters. For more information on how to identify your adapter, go @@ -2425,11 +2426,6 @@ config IXGBE To compile this driver as a module, choose M here. The module will be called ixgbe. -config IXGBE_DCA - bool - default y - depends on IXGBE && DCA && !(IXGBE=y && DCA=m) - config IXGB tristate "Intel(R) PRO/10GbE support" depends on PCI @@ -2466,6 +2462,7 @@ config MYRI10GE select FW_LOADER select CRC32 select INET_LRO + select INTEL_IOATDMA ---help--- This driver supports Myricom Myri-10G Dual Protocol interface in Ethernet mode. If the eeprom on your board is not recent enough, @@ -2477,11 +2474,6 @@ config MYRI10GE To compile this driver as a module, choose M here. The module will be called myri10ge. -config MYRI10GE_DCA - bool - default y - depends on MYRI10GE && DCA && !(MYRI10GE=y && DCA=m) - config NETXEN_NIC tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC" depends on PCI diff --git a/trunk/drivers/net/ixgbe/ixgbe.h b/trunk/drivers/net/ixgbe/ixgbe.h index e116d340dcc6..2198b77c53ed 100644 --- a/trunk/drivers/net/ixgbe/ixgbe.h +++ b/trunk/drivers/net/ixgbe/ixgbe.h @@ -36,7 +36,7 @@ #include "ixgbe_type.h" #include "ixgbe_common.h" -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) #include #endif @@ -136,7 +136,7 @@ struct ixgbe_ring { * offset associated with this ring, which is different * for DCE and RSS modes */ -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) /* cpu for tx queue */ int cpu; #endif diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index 7548fb7360d9..ca17af4349d0 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -80,7 +80,7 @@ static struct pci_device_id ixgbe_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl); -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) static int ixgbe_notify_dca(struct notifier_block *, unsigned long event, void *p); static struct notifier_block dca_notifier = { @@ -296,7 +296,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter, return (total_packets ? true : false); } -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, struct ixgbe_ring *rx_ring) { @@ -383,7 +383,7 @@ static int __ixgbe_notify_dca(struct device *dev, void *data) return 0; } -#endif /* CONFIG_IXGBE_DCA */ +#endif /* CONFIG_DCA or CONFIG_DCA_MODULE */ /** * ixgbe_receive_skb - Send a completed packet up the stack * @adapter: board private structure @@ -947,7 +947,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { tx_ring = &(adapter->tx_ring[r_idx]); -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) ixgbe_update_tx_dca(adapter, tx_ring); #endif @@ -1022,7 +1022,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); rx_ring = &(adapter->rx_ring[r_idx]); -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) ixgbe_update_rx_dca(adapter, rx_ring); #endif @@ -1066,7 +1066,7 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget) r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { rx_ring = &(adapter->rx_ring[r_idx]); -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) ixgbe_update_rx_dca(adapter, rx_ring); #endif @@ -2155,7 +2155,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) netif_carrier_off(netdev); -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED; dca_remove_requester(&adapter->pdev->dev); @@ -2167,7 +2167,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ixgbe_clean_all_tx_rings(adapter); ixgbe_clean_all_rx_rings(adapter); -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) /* since we reset the hardware DCA settings were cleared */ if (dca_add_requester(&adapter->pdev->dev) == 0) { adapter->flags |= IXGBE_FLAG_DCA_ENABLED; @@ -2193,7 +2193,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget) struct ixgbe_adapter *adapter = q_vector->adapter; int tx_cleaned, work_done = 0; -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { ixgbe_update_tx_dca(adapter, adapter->tx_ring); ixgbe_update_rx_dca(adapter, adapter->rx_ring); @@ -3922,7 +3922,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, if (err) goto err_register; -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (dca_add_requester(&pdev->dev) == 0) { adapter->flags |= IXGBE_FLAG_DCA_ENABLED; /* always use CB2 mode, difference is masked @@ -3972,7 +3972,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) flush_scheduled_work(); -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED; dca_remove_requester(&pdev->dev); @@ -4105,10 +4105,10 @@ static int __init ixgbe_init_module(void) printk(KERN_INFO "%s: %s\n", ixgbe_driver_name, ixgbe_copyright); -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) dca_register_notify(&dca_notifier); -#endif +#endif ret = pci_register_driver(&ixgbe_driver); return ret; } @@ -4123,13 +4123,13 @@ module_init(ixgbe_init_module); **/ static void __exit ixgbe_exit_module(void) { -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) dca_unregister_notify(&dca_notifier); #endif pci_unregister_driver(&ixgbe_driver); } -#ifdef CONFIG_IXGBE_DCA +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event, void *p) { @@ -4140,7 +4140,7 @@ static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event, return ret_val ? NOTIFY_BAD : NOTIFY_DONE; } -#endif /* CONFIG_IXGBE_DCA */ +#endif /* CONFIG_DCA or CONFIG_DCA_MODULE */ module_exit(ixgbe_exit_module); diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index a9aebad52652..6dce901c7f45 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -188,7 +188,7 @@ struct myri10ge_slice_state { dma_addr_t fw_stats_bus; int watchdog_tx_done; int watchdog_tx_req; -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) int cached_dca_tag; int cpu; __be32 __iomem *dca_tag; @@ -220,7 +220,7 @@ struct myri10ge_priv { int msi_enabled; int msix_enabled; struct msix_entry *msix_vectors; -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) int dca_enabled; #endif u32 link_state; @@ -902,7 +902,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) struct myri10ge_slice_state *ss; int i, status; size_t bytes; -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) unsigned long dca_tag_off; #endif @@ -1012,7 +1012,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) } put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_DCA_OFFSET, &cmd, 0); dca_tag_off = cmd.data0; for (i = 0; i < mgp->num_slices; i++) { @@ -1051,7 +1051,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) return status; } -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) static void myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag) { @@ -1505,7 +1505,7 @@ static int myri10ge_poll(struct napi_struct *napi, int budget) struct net_device *netdev = ss->mgp->dev; int work_done; -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) if (ss->mgp->dca_enabled) myri10ge_update_dca(ss); #endif @@ -1736,7 +1736,7 @@ static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = { "tx_boundary", "WC", "irq", "MSI", "MSIX", "read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs", "serial_number", "watchdog_resets", -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) "dca_capable_firmware", "dca_device_present", #endif "link_changes", "link_up", "dropped_link_overflow", @@ -1815,7 +1815,7 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, data[i++] = (unsigned int)mgp->read_write_dma; data[i++] = (unsigned int)mgp->serial_number; data[i++] = (unsigned int)mgp->watchdog_resets; -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) data[i++] = (unsigned int)(mgp->ss[0].dca_tag != NULL); data[i++] = (unsigned int)(mgp->dca_enabled); #endif @@ -3844,7 +3844,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(&pdev->dev, "failed reset\n"); goto abort_with_slices; } -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) myri10ge_setup_dca(mgp); #endif pci_set_drvdata(pdev, mgp); @@ -3948,7 +3948,7 @@ static void myri10ge_remove(struct pci_dev *pdev) netdev = mgp->dev; unregister_netdev(netdev); -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) myri10ge_teardown_dca(mgp); #endif myri10ge_dummy_rdma(mgp, 0); @@ -3993,7 +3993,7 @@ static struct pci_driver myri10ge_driver = { #endif }; -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) static int myri10ge_notify_dca(struct notifier_block *nb, unsigned long event, void *p) { @@ -4024,7 +4024,7 @@ static __init int myri10ge_init_module(void) myri10ge_driver.name, myri10ge_rss_hash); myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT; } -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) dca_register_notify(&myri10ge_dca_notifier); #endif if (myri10ge_max_slices > MYRI10GE_MAX_SLICES) @@ -4037,7 +4037,7 @@ module_init(myri10ge_init_module); static __exit void myri10ge_cleanup_module(void) { -#ifdef CONFIG_MYRI10GE_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) dca_unregister_notify(&myri10ge_dca_notifier); #endif pci_unregister_driver(&myri10ge_driver); diff --git a/trunk/drivers/net/pcmcia/Kconfig b/trunk/drivers/net/pcmcia/Kconfig index 9b8f793b1cc8..e8f55d8ed7a9 100644 --- a/trunk/drivers/net/pcmcia/Kconfig +++ b/trunk/drivers/net/pcmcia/Kconfig @@ -111,7 +111,7 @@ config ARCNET_COM20020_CS config PCMCIA_IBMTR tristate "IBM PCMCIA tokenring adapter support" - depends on IBMTR!=y && TR + depends on IBMTR!=y && TR && !64BIT help Say Y here if you intend to attach this type of Token Ring PCMCIA card to your computer. You then also need to say Y to "Token Ring diff --git a/trunk/drivers/net/wan/lmc/lmc_main.c b/trunk/drivers/net/wan/lmc/lmc_main.c index d7bb63e616b5..f80640f5a744 100644 --- a/trunk/drivers/net/wan/lmc/lmc_main.c +++ b/trunk/drivers/net/wan/lmc/lmc_main.c @@ -122,6 +122,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ * Most functions mess with the structure * Disable interrupts while we do the polling */ + spin_lock_irqsave(&sc->lmc_lock, flags); switch (cmd) { /* @@ -151,7 +152,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ break; } - spin_lock_irqsave(&sc->lmc_lock, flags); sc->lmc_media->set_status (sc, &ctl); if(ctl.crc_length != sc->ictl.crc_length) { @@ -161,7 +161,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ else sc->TxDescriptControlInit &= ~LMC_TDES_ADD_CRC_DISABLE; } - spin_unlock_irqrestore(&sc->lmc_lock, flags); ret = 0; break; @@ -188,18 +187,15 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ break; /* no change */ } - spin_lock_irqsave(&sc->lmc_lock, flags); lmc_proto_close(sc); sc->if_type = new_type; lmc_proto_attach(sc); ret = lmc_proto_open(sc); - spin_unlock_irqrestore(&sc->lmc_lock, flags); break; } case LMCIOCGETXINFO: /*fold01*/ - spin_lock_irqsave(&sc->lmc_lock, flags); sc->lmc_xinfo.Magic0 = 0xBEEFCAFE; sc->lmc_xinfo.PciCardType = sc->lmc_cardtype; @@ -212,7 +208,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ sc->lmc_xinfo.MaxFrameSize = LMC_PKT_BUF_SZ; sc->lmc_xinfo.link_status = sc->lmc_media->get_link_status (sc); sc->lmc_xinfo.mii_reg16 = lmc_mii_readreg (sc, 0, 16); - spin_unlock_irqrestore(&sc->lmc_lock, flags); sc->lmc_xinfo.Magic1 = 0xDEADBEEF; @@ -225,7 +220,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ break; case LMCIOCGETLMCSTATS: - spin_lock_irqsave(&sc->lmc_lock, flags); if (sc->lmc_cardtype == LMC_CARDTYPE_T1) { lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_LSB); sc->extra_stats.framingBitErrorCount += @@ -249,7 +243,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ sc->extra_stats.severelyErroredFrameCount += regVal & T1FRAMER_SEF_MASK; } - spin_unlock_irqrestore(&sc->lmc_lock, flags); if (copy_to_user(ifr->ifr_data, &sc->lmc_device->stats, sizeof(sc->lmc_device->stats)) || copy_to_user(ifr->ifr_data + sizeof(sc->lmc_device->stats), @@ -265,14 +258,12 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ break; } - spin_lock_irqsave(&sc->lmc_lock, flags); memset(&sc->lmc_device->stats, 0, sizeof(sc->lmc_device->stats)); memset(&sc->extra_stats, 0, sizeof(sc->extra_stats)); sc->extra_stats.check = STATCHECK; sc->extra_stats.version_size = (DRIVER_VERSION << 16) + sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats); sc->extra_stats.lmc_cardtype = sc->lmc_cardtype; - spin_unlock_irqrestore(&sc->lmc_lock, flags); ret = 0; break; @@ -291,10 +282,8 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ ret = -EFAULT; break; } - spin_lock_irqsave(&sc->lmc_lock, flags); sc->lmc_media->set_circuit_type(sc, ctl.circuit_type); sc->ictl.circuit_type = ctl.circuit_type; - spin_unlock_irqrestore(&sc->lmc_lock, flags); ret = 0; break; @@ -305,14 +294,12 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ break; } - spin_lock_irqsave(&sc->lmc_lock, flags); /* Reset driver and bring back to current state */ printk (" REG16 before reset +%04x\n", lmc_mii_readreg (sc, 0, 16)); lmc_running_reset (dev); printk (" REG16 after reset +%04x\n", lmc_mii_readreg (sc, 0, 16)); LMC_EVENT_LOG(LMC_EVENT_FORCEDRESET, LMC_CSR_READ (sc, csr_status), lmc_mii_readreg (sc, 0, 16)); - spin_unlock_irqrestore(&sc->lmc_lock, flags); ret = 0; break; @@ -351,15 +338,14 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ */ netif_stop_queue(dev); - if (copy_from_user(&xc, ifr->ifr_data, sizeof(struct lmc_xilinx_control))) { + if (copy_from_user(&xc, ifr->ifr_data, sizeof(struct lmc_xilinx_control))) { ret = -EFAULT; break; - } + } switch(xc.command){ case lmc_xilinx_reset: /*fold02*/ { u16 mii; - spin_lock_irqsave(&sc->lmc_lock, flags); mii = lmc_mii_readreg (sc, 0, 16); /* @@ -418,7 +404,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ lmc_led_off(sc, LMC_DS3_LED2); } } - spin_unlock_irqrestore(&sc->lmc_lock, flags); @@ -431,7 +416,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ { u16 mii; int timeout = 500000; - spin_lock_irqsave(&sc->lmc_lock, flags); mii = lmc_mii_readreg (sc, 0, 16); /* @@ -467,14 +451,13 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ */ while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 && (timeout-- > 0)) - cpu_relax(); + ; /* * stop driving Xilinx-related signals */ lmc_gpio_mkinput(sc, 0xff); - spin_unlock_irqrestore(&sc->lmc_lock, flags); ret = 0x0; @@ -510,7 +493,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ printk("%s: Starting load of data Len: %d at 0x%p == 0x%p\n", dev->name, xc.len, xc.data, data); - spin_lock_irqsave(&sc->lmc_lock, flags); lmc_gpio_mkinput(sc, 0xff); /* @@ -563,7 +545,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ */ while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 && (timeout-- > 0)) - cpu_relax(); + ; printk(KERN_DEBUG "%s: Waited %d for the Xilinx to clear it's memory\n", dev->name, 500000-timeout); @@ -606,7 +588,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET; lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16); - spin_unlock_irqrestore(&sc->lmc_lock, flags); kfree(data); @@ -630,6 +611,8 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ break; } + spin_unlock_irqrestore(&sc->lmc_lock, flags); /*fold01*/ + lmc_trace(dev, "lmc_ioctl out"); return ret; diff --git a/trunk/drivers/net/xen-netfront.c b/trunk/drivers/net/xen-netfront.c index c6948d8f53f6..5c7a87e38951 100644 --- a/trunk/drivers/net/xen-netfront.c +++ b/trunk/drivers/net/xen-netfront.c @@ -239,14 +239,11 @@ static void xennet_alloc_rx_buffers(struct net_device *dev) */ batch_target = np->rx_target - (req_prod - np->rx.rsp_cons); for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) { - skb = __netdev_alloc_skb(dev, RX_COPY_THRESHOLD + NET_IP_ALIGN, + skb = __netdev_alloc_skb(dev, RX_COPY_THRESHOLD, GFP_ATOMIC | __GFP_NOWARN); if (unlikely(!skb)) goto no_skb; - /* Align ip header to a 16 bytes boundary */ - skb_reserve(skb, NET_IP_ALIGN); - page = alloc_page(GFP_ATOMIC | __GFP_NOWARN); if (!page) { kfree_skb(skb); diff --git a/trunk/drivers/s390/block/dasd_diag.c b/trunk/drivers/s390/block/dasd_diag.c index 7844461a995b..85fcb4371054 100644 --- a/trunk/drivers/s390/block/dasd_diag.c +++ b/trunk/drivers/s390/block/dasd_diag.c @@ -544,7 +544,7 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev, } cqr->retries = DIAG_MAX_RETRIES; cqr->buildclk = get_clock(); - if (blk_noretry_request(req)) + if (req->cmd_flags & REQ_FAILFAST) set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); cqr->startdev = memdev; cqr->memdev = memdev; diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index 2e60d5f968c8..49f9d221e23d 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -1700,7 +1700,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, recid++; } } - if (blk_noretry_request(req)) + if (req->cmd_flags & REQ_FAILFAST) set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); cqr->startdev = startdev; cqr->memdev = startdev; diff --git a/trunk/drivers/s390/block/dasd_fba.c b/trunk/drivers/s390/block/dasd_fba.c index 7d442aeff3d1..93d9b6452a94 100644 --- a/trunk/drivers/s390/block/dasd_fba.c +++ b/trunk/drivers/s390/block/dasd_fba.c @@ -355,7 +355,7 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev, recid++; } } - if (blk_noretry_request(req)) + if (req->cmd_flags & REQ_FAILFAST) set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); cqr->startdev = memdev; cqr->memdev = memdev; diff --git a/trunk/drivers/s390/scsi/zfcp_def.h b/trunk/drivers/s390/scsi/zfcp_def.h index 9ce4c75bd190..8a13071c444c 100644 --- a/trunk/drivers/s390/scsi/zfcp_def.h +++ b/trunk/drivers/s390/scsi/zfcp_def.h @@ -583,8 +583,6 @@ struct zfcp_fsf_req { unsigned long long issued; /* request sent time (STCK) */ struct zfcp_unit *unit; void (*handler)(struct zfcp_fsf_req *); - u16 qdio_outb_usage;/* usage of outbound queue */ - u16 qdio_inb_usage; /* usage of inbound queue */ }; /* driver data */ diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.c b/trunk/drivers/s390/scsi/zfcp_fsf.c index 5ae1d497e5ed..739356a5c123 100644 --- a/trunk/drivers/s390/scsi/zfcp_fsf.c +++ b/trunk/drivers/s390/scsi/zfcp_fsf.c @@ -6,7 +6,6 @@ * Copyright IBM Corporation 2002, 2008 */ -#include #include "zfcp_ext.h" static void zfcp_fsf_request_timeout_handler(unsigned long data) @@ -778,7 +777,6 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) list_add_tail(&req->list, &adapter->req_list[idx]); spin_unlock(&adapter->req_list_lock); - req->qdio_outb_usage = atomic_read(&req_q->count); req->issued = get_clock(); if (zfcp_qdio_send(req)) { /* Queues are down..... */ @@ -2084,36 +2082,6 @@ static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req) spin_unlock_irqrestore(&unit->latencies.lock, flags); } -#ifdef CONFIG_BLK_DEV_IO_TRACE -static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) -{ - struct fsf_qual_latency_info *lat_inf; - struct scsi_cmnd *scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; - struct request *req = scsi_cmnd->request; - struct zfcp_blk_drv_data trace; - int ticks = fsf_req->adapter->timer_ticks; - - trace.flags = 0; - trace.magic = ZFCP_BLK_DRV_DATA_MAGIC; - if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) { - trace.flags |= ZFCP_BLK_LAT_VALID; - lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info; - trace.channel_lat = lat_inf->channel_lat * ticks; - trace.fabric_lat = lat_inf->fabric_lat * ticks; - } - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) - trace.flags |= ZFCP_BLK_REQ_ERROR; - trace.inb_usage = fsf_req->qdio_inb_usage; - trace.outb_usage = fsf_req->qdio_outb_usage; - - blk_add_driver_data(req->q, req, &trace, sizeof(trace)); -} -#else -static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) -{ -} -#endif - static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) { struct scsi_cmnd *scpnt = req->data; @@ -2146,8 +2114,6 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) zfcp_fsf_req_latency(req); - zfcp_fsf_trace_latency(req); - if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) { if (fcp_rsp_info[3] == RSP_CODE_GOOD) set_host_byte(scpnt, DID_OK); diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.h b/trunk/drivers/s390/scsi/zfcp_fsf.h index fa2a31780611..fd3a88777ac8 100644 --- a/trunk/drivers/s390/scsi/zfcp_fsf.h +++ b/trunk/drivers/s390/scsi/zfcp_fsf.h @@ -439,16 +439,4 @@ struct fsf_qtcb { u8 log[FSF_QTCB_LOG_SIZE]; } __attribute__ ((packed)); -struct zfcp_blk_drv_data { -#define ZFCP_BLK_DRV_DATA_MAGIC 0x1 - u32 magic; -#define ZFCP_BLK_LAT_VALID 0x1 -#define ZFCP_BLK_REQ_ERROR 0x2 - u16 flags; - u8 inb_usage; - u8 outb_usage; - u64 channel_lat; - u64 fabric_lat; -} __attribute__ ((packed)); - #endif /* FSF_H */ diff --git a/trunk/drivers/s390/scsi/zfcp_qdio.c b/trunk/drivers/s390/scsi/zfcp_qdio.c index 664752f90b20..3e05080e62d4 100644 --- a/trunk/drivers/s390/scsi/zfcp_qdio.c +++ b/trunk/drivers/s390/scsi/zfcp_qdio.c @@ -115,7 +115,6 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, spin_unlock_irqrestore(&adapter->req_list_lock, flags); fsf_req->sbal_response = sbal_idx; - fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count); zfcp_fsf_req_complete(fsf_req); } diff --git a/trunk/drivers/scsi/constants.c b/trunk/drivers/scsi/constants.c index 4003deefb7d8..9785d7384199 100644 --- a/trunk/drivers/scsi/constants.c +++ b/trunk/drivers/scsi/constants.c @@ -1364,8 +1364,7 @@ EXPORT_SYMBOL(scsi_print_sense); static const char * const hostbyte_table[]={ "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", -"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", "DID_REQUEUE", -"DID_TRANSPORT_DISRUPTED", "DID_TRANSPORT_FAILFAST" }; +"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", "DID_REQUEUE"}; #define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table) static const char * const driverbyte_table[]={ diff --git a/trunk/drivers/scsi/device_handler/scsi_dh_alua.c b/trunk/drivers/scsi/device_handler/scsi_dh_alua.c index e356b43753ff..708e475896b9 100644 --- a/trunk/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/trunk/drivers/scsi/device_handler/scsi_dh_alua.c @@ -109,8 +109,7 @@ static struct request *get_alua_req(struct scsi_device *sdev, } rq->cmd_type = REQ_TYPE_BLOCK_PC; - rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | - REQ_FAILFAST_DRIVER; + rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; rq->retries = ALUA_FAILOVER_RETRIES; rq->timeout = ALUA_FAILOVER_TIMEOUT; diff --git a/trunk/drivers/scsi/device_handler/scsi_dh_emc.c b/trunk/drivers/scsi/device_handler/scsi_dh_emc.c index 0e572d2c5b0a..8f45570a8a01 100644 --- a/trunk/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/trunk/drivers/scsi/device_handler/scsi_dh_emc.c @@ -303,8 +303,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd, rq->cmd[4] = len; rq->cmd_type = REQ_TYPE_BLOCK_PC; - rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | - REQ_FAILFAST_DRIVER; + rq->cmd_flags |= REQ_FAILFAST; rq->timeout = CLARIION_TIMEOUT; rq->retries = CLARIION_RETRIES; diff --git a/trunk/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/trunk/drivers/scsi/device_handler/scsi_dh_hp_sw.c index 9aec4ca64e56..5e93c88ad66b 100644 --- a/trunk/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/trunk/drivers/scsi/device_handler/scsi_dh_hp_sw.c @@ -112,8 +112,7 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h) return SCSI_DH_RES_TEMP_UNAVAIL; req->cmd_type = REQ_TYPE_BLOCK_PC; - req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | - REQ_FAILFAST_DRIVER; + req->cmd_flags |= REQ_FAILFAST; req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY); req->cmd[0] = TEST_UNIT_READY; req->timeout = HP_SW_TIMEOUT; @@ -205,8 +204,7 @@ static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h) return SCSI_DH_RES_TEMP_UNAVAIL; req->cmd_type = REQ_TYPE_BLOCK_PC; - req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | - REQ_FAILFAST_DRIVER; + req->cmd_flags |= REQ_FAILFAST; req->cmd_len = COMMAND_SIZE(START_STOP); req->cmd[0] = START_STOP; req->cmd[4] = 1; /* Start spin cycle */ diff --git a/trunk/drivers/scsi/device_handler/scsi_dh_rdac.c b/trunk/drivers/scsi/device_handler/scsi_dh_rdac.c index a43c3ed4df28..50bf95f3b5c4 100644 --- a/trunk/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/trunk/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -226,8 +226,7 @@ static struct request *get_rdac_req(struct scsi_device *sdev, } rq->cmd_type = REQ_TYPE_BLOCK_PC; - rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | - REQ_FAILFAST_DRIVER; + rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; rq->retries = RDAC_RETRIES; rq->timeout = RDAC_TIMEOUT; diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvfc.c b/trunk/drivers/scsi/ibmvscsi/ibmvfc.c index 7650707a40de..4e0b7c8eb32e 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvfc.c @@ -2031,6 +2031,8 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport) spin_unlock_irqrestore(shost->host_lock, flags); } else ibmvfc_issue_fc_host_lip(shost); + + scsi_target_unblock(&rport->dev); LEAVE; } diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c index ed6c54cae7b1..2a2f0094570f 100644 --- a/trunk/drivers/scsi/iscsi_tcp.c +++ b/trunk/drivers/scsi/iscsi_tcp.c @@ -523,20 +523,22 @@ iscsi_tcp_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task) } /** - * iscsi_data_in - SCSI Data-In Response processing + * iscsi_data_rsp - SCSI Data-In Response processing * @conn: iscsi connection * @task: scsi command task **/ static int -iscsi_data_in(struct iscsi_conn *conn, struct iscsi_task *task) +iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_task *task) { struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct iscsi_tcp_task *tcp_task = task->dd_data; struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr; + struct iscsi_session *session = conn->session; + struct scsi_cmnd *sc = task->sc; int datasn = be32_to_cpu(rhdr->datasn); - unsigned total_in_length = scsi_in(task->sc)->length; + unsigned total_in_length = scsi_in(sc)->length; - iscsi_update_cmdsn(conn->session, (struct iscsi_nopin*)rhdr); + iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr); if (tcp_conn->in.datalen == 0) return 0; @@ -556,6 +558,23 @@ iscsi_data_in(struct iscsi_conn *conn, struct iscsi_task *task) return ISCSI_ERR_DATA_OFFSET; } + if (rhdr->flags & ISCSI_FLAG_DATA_STATUS) { + sc->result = (DID_OK << 16) | rhdr->cmd_status; + conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; + if (rhdr->flags & (ISCSI_FLAG_DATA_UNDERFLOW | + ISCSI_FLAG_DATA_OVERFLOW)) { + int res_count = be32_to_cpu(rhdr->residual_count); + + if (res_count > 0 && + (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || + res_count <= total_in_length)) + scsi_in(sc)->resid = res_count; + else + sc->result = (DID_BAD_TARGET << 16) | + rhdr->cmd_status; + } + } + conn->datain_pdus_cnt++; return 0; } @@ -755,7 +774,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) if (!task) rc = ISCSI_ERR_BAD_ITT; else - rc = iscsi_data_in(conn, task); + rc = iscsi_data_rsp(conn, task); if (rc) { spin_unlock(&conn->session->lock); break; @@ -979,7 +998,7 @@ iscsi_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, error: debug_tcp("Error receiving PDU, errno=%d\n", rc); - iscsi_conn_failure(conn, rc); + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); return 0; } @@ -1098,10 +1117,8 @@ iscsi_xmit(struct iscsi_conn *conn) while (1) { rc = iscsi_tcp_xmit_segment(tcp_conn, segment); - if (rc < 0) { - rc = ISCSI_ERR_XMIT_FAILED; + if (rc < 0) goto error; - } if (rc == 0) break; @@ -1110,7 +1127,7 @@ iscsi_xmit(struct iscsi_conn *conn) if (segment->total_copied >= segment->total_size) { if (segment->done != NULL) { rc = segment->done(tcp_conn, segment); - if (rc != 0) + if (rc < 0) goto error; } } @@ -1125,8 +1142,8 @@ iscsi_xmit(struct iscsi_conn *conn) /* Transmit error. We could initiate error recovery * here. */ debug_tcp("Error sending PDU, errno=%d\n", rc); - iscsi_conn_failure(conn, rc); - return -EIO; + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + return rc; } /** @@ -1887,7 +1904,6 @@ static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session) struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); iscsi_r2tpool_free(cls_session->dd_data); - iscsi_session_teardown(cls_session); iscsi_host_remove(shost); iscsi_host_free(shost); @@ -1911,7 +1927,7 @@ static struct scsi_host_template iscsi_sht = { .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, .eh_abort_handler = iscsi_eh_abort, .eh_device_reset_handler= iscsi_eh_device_reset, - .eh_target_reset_handler= iscsi_eh_target_reset, + .eh_host_reset_handler = iscsi_eh_host_reset, .use_clustering = DISABLE_CLUSTERING, .slave_configure = iscsi_tcp_slave_configure, .proc_name = "iscsi_tcp", diff --git a/trunk/drivers/scsi/libiscsi.c b/trunk/drivers/scsi/libiscsi.c index 801c7cf54d2e..da7b67d30d9a 100644 --- a/trunk/drivers/scsi/libiscsi.c +++ b/trunk/drivers/scsi/libiscsi.c @@ -404,6 +404,11 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_task *task, conn->session->queued_cmdsn--; else conn->session->tt->cleanup_task(conn, task); + /* + * Check if cleanup_task dropped the lock and the command completed, + */ + if (!task->sc) + return; sc->result = err; if (!scsi_bidi_cmnd(sc)) @@ -628,40 +633,6 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, __iscsi_put_task(task); } -/** - * iscsi_data_in_rsp - SCSI Data-In Response processing - * @conn: iscsi connection - * @hdr: iscsi pdu - * @task: scsi command task - **/ -static void -iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, - struct iscsi_task *task) -{ - struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)hdr; - struct scsi_cmnd *sc = task->sc; - - if (!(rhdr->flags & ISCSI_FLAG_DATA_STATUS)) - return; - - sc->result = (DID_OK << 16) | rhdr->cmd_status; - conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; - if (rhdr->flags & (ISCSI_FLAG_DATA_UNDERFLOW | - ISCSI_FLAG_DATA_OVERFLOW)) { - int res_count = be32_to_cpu(rhdr->residual_count); - - if (res_count > 0 && - (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || - res_count <= scsi_in(sc)->length)) - scsi_in(sc)->resid = res_count; - else - sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; - } - - conn->scsirsp_pdus_cnt++; - __iscsi_put_task(task); -} - static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) { struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr; @@ -847,7 +818,12 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen); break; case ISCSI_OP_SCSI_DATA_IN: - iscsi_data_in_rsp(conn, hdr, task); + if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { + conn->scsirsp_pdus_cnt++; + iscsi_update_cmdsn(session, + (struct iscsi_nopin*) hdr); + __iscsi_put_task(task); + } break; case ISCSI_OP_LOGOUT_RSP: iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); @@ -978,38 +954,6 @@ struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt) } EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask); -void iscsi_session_failure(struct iscsi_cls_session *cls_session, - enum iscsi_err err) -{ - struct iscsi_session *session = cls_session->dd_data; - struct iscsi_conn *conn; - struct device *dev; - unsigned long flags; - - spin_lock_irqsave(&session->lock, flags); - conn = session->leadconn; - if (session->state == ISCSI_STATE_TERMINATE || !conn) { - spin_unlock_irqrestore(&session->lock, flags); - return; - } - - dev = get_device(&conn->cls_conn->dev); - spin_unlock_irqrestore(&session->lock, flags); - if (!dev) - return; - /* - * if the host is being removed bypass the connection - * recovery initialization because we are going to kill - * the session. - */ - if (err == ISCSI_ERR_INVALID_HOST) - iscsi_conn_error_event(conn->cls_conn, err); - else - iscsi_conn_failure(conn, err); - put_device(dev); -} -EXPORT_SYMBOL_GPL(iscsi_session_failure); - void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) { struct iscsi_session *session = conn->session; @@ -1024,10 +968,9 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) if (conn->stop_stage == 0) session->state = ISCSI_STATE_FAILED; spin_unlock_irqrestore(&session->lock, flags); - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); - iscsi_conn_error_event(conn->cls_conn, err); + iscsi_conn_error(conn->cls_conn, err); } EXPORT_SYMBOL_GPL(iscsi_conn_failure); @@ -1251,13 +1194,15 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) switch (session->state) { case ISCSI_STATE_IN_RECOVERY: reason = FAILURE_SESSION_IN_RECOVERY; - goto reject; + sc->result = DID_IMM_RETRY << 16; + break; case ISCSI_STATE_LOGGING_OUT: reason = FAILURE_SESSION_LOGGING_OUT; - goto reject; + sc->result = DID_IMM_RETRY << 16; + break; case ISCSI_STATE_RECOVERY_FAILED: reason = FAILURE_SESSION_RECOVERY_TIMEOUT; - sc->result = DID_TRANSPORT_FAILFAST << 16; + sc->result = DID_NO_CONNECT << 16; break; case ISCSI_STATE_TERMINATE: reason = FAILURE_SESSION_TERMINATE; @@ -1322,7 +1267,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) spin_unlock(&session->lock); debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); spin_lock(host->host_lock); - return SCSI_MLQUEUE_TARGET_BUSY; + return SCSI_MLQUEUE_HOST_BUSY; fault: spin_unlock(&session->lock); @@ -1362,7 +1307,7 @@ void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session) } EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout); -int iscsi_eh_target_reset(struct scsi_cmnd *sc) +int iscsi_eh_host_reset(struct scsi_cmnd *sc) { struct iscsi_cls_session *cls_session; struct iscsi_session *session; @@ -1376,7 +1321,7 @@ int iscsi_eh_target_reset(struct scsi_cmnd *sc) spin_lock_bh(&session->lock); if (session->state == ISCSI_STATE_TERMINATE) { failed: - debug_scsi("failing target reset: session terminated " + debug_scsi("failing host reset: session terminated " "[CID %d age %d]\n", conn->id, session->age); spin_unlock_bh(&session->lock); mutex_unlock(&session->eh_mutex); @@ -1391,7 +1336,7 @@ int iscsi_eh_target_reset(struct scsi_cmnd *sc) */ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - debug_scsi("iscsi_eh_target_reset wait for relogin\n"); + debug_scsi("iscsi_eh_host_reset wait for relogin\n"); wait_event_interruptible(conn->ehwait, session->state == ISCSI_STATE_TERMINATE || session->state == ISCSI_STATE_LOGGED_IN || @@ -1403,14 +1348,14 @@ int iscsi_eh_target_reset(struct scsi_cmnd *sc) spin_lock_bh(&session->lock); if (session->state == ISCSI_STATE_LOGGED_IN) iscsi_session_printk(KERN_INFO, session, - "target reset succeeded\n"); + "host reset succeeded\n"); else goto failed; spin_unlock_bh(&session->lock); mutex_unlock(&session->eh_mutex); return SUCCESS; } -EXPORT_SYMBOL_GPL(iscsi_eh_target_reset); +EXPORT_SYMBOL_GPL(iscsi_eh_host_reset); static void iscsi_tmf_timedout(unsigned long data) { @@ -1824,10 +1769,10 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) iscsi_suspend_tx(conn); - spin_lock_bh(&session->lock); + spin_lock(&session->lock); fail_all_commands(conn, sc->device->lun, DID_ERROR); conn->tmf_state = TMF_INITIAL; - spin_unlock_bh(&session->lock); + spin_unlock(&session->lock); iscsi_start_tx(conn); goto done; @@ -1933,7 +1878,6 @@ struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, int dd_data_size, uint16_t qdepth) { struct Scsi_Host *shost; - struct iscsi_host *ihost; shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size); if (!shost) @@ -1948,43 +1892,22 @@ struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, qdepth = ISCSI_DEF_CMD_PER_LUN; } shost->cmd_per_lun = qdepth; - - ihost = shost_priv(shost); - spin_lock_init(&ihost->lock); - ihost->state = ISCSI_HOST_SETUP; - ihost->num_sessions = 0; - init_waitqueue_head(&ihost->session_removal_wq); return shost; } EXPORT_SYMBOL_GPL(iscsi_host_alloc); -static void iscsi_notify_host_removed(struct iscsi_cls_session *cls_session) -{ - iscsi_session_failure(cls_session, ISCSI_ERR_INVALID_HOST); -} - /** * iscsi_host_remove - remove host and sessions * @shost: scsi host * - * If there are any sessions left, this will initiate the removal and wait - * for the completion. + * This will also remove any sessions attached to the host, but if userspace + * is managing the session at the same time this will break. TODO: add + * refcounting to the netlink iscsi interface so a rmmod or host hot unplug + * does not remove the memory from under us. */ void iscsi_host_remove(struct Scsi_Host *shost) { - struct iscsi_host *ihost = shost_priv(shost); - unsigned long flags; - - spin_lock_irqsave(&ihost->lock, flags); - ihost->state = ISCSI_HOST_REMOVED; - spin_unlock_irqrestore(&ihost->lock, flags); - - iscsi_host_for_each_session(shost, iscsi_notify_host_removed); - wait_event_interruptible(ihost->session_removal_wq, - ihost->num_sessions == 0); - if (signal_pending(current)) - flush_signals(current); - + iscsi_host_for_each_session(shost, iscsi_session_teardown); scsi_remove_host(shost); } EXPORT_SYMBOL_GPL(iscsi_host_remove); @@ -2000,27 +1923,6 @@ void iscsi_host_free(struct Scsi_Host *shost) } EXPORT_SYMBOL_GPL(iscsi_host_free); -static void iscsi_host_dec_session_cnt(struct Scsi_Host *shost) -{ - struct iscsi_host *ihost = shost_priv(shost); - unsigned long flags; - - shost = scsi_host_get(shost); - if (!shost) { - printk(KERN_ERR "Invalid state. Cannot notify host removal " - "of session teardown event because host already " - "removed.\n"); - return; - } - - spin_lock_irqsave(&ihost->lock, flags); - ihost->num_sessions--; - if (ihost->num_sessions == 0) - wake_up(&ihost->session_removal_wq); - spin_unlock_irqrestore(&ihost->lock, flags); - scsi_host_put(shost); -} - /** * iscsi_session_setup - create iscsi cls session and host and session * @iscsit: iscsi transport template @@ -2041,19 +1943,9 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, uint16_t cmds_max, int cmd_task_size, uint32_t initial_cmdsn, unsigned int id) { - struct iscsi_host *ihost = shost_priv(shost); struct iscsi_session *session; struct iscsi_cls_session *cls_session; int cmd_i, scsi_cmds, total_cmds = cmds_max; - unsigned long flags; - - spin_lock_irqsave(&ihost->lock, flags); - if (ihost->state == ISCSI_HOST_REMOVED) { - spin_unlock_irqrestore(&ihost->lock, flags); - return NULL; - } - ihost->num_sessions++; - spin_unlock_irqrestore(&ihost->lock, flags); if (!total_cmds) total_cmds = ISCSI_DEF_XMIT_CMDS_MAX; @@ -2066,7 +1958,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue " "must be a power of two that is at least %d.\n", total_cmds, ISCSI_TOTAL_CMDS_MIN); - goto dec_session_count; + return NULL; } if (total_cmds > ISCSI_TOTAL_CMDS_MAX) { @@ -2090,7 +1982,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, cls_session = iscsi_alloc_session(shost, iscsit, sizeof(struct iscsi_session)); if (!cls_session) - goto dec_session_count; + return NULL; session = cls_session->dd_data; session->cls_session = cls_session; session->host = shost; @@ -2129,7 +2021,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, if (iscsi_add_session(cls_session, id)) goto cls_session_fail; - return cls_session; cls_session_fail: @@ -2138,8 +2029,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, iscsi_pool_free(&session->cmdpool); cmdpool_alloc_fail: iscsi_free_session(cls_session); -dec_session_count: - iscsi_host_dec_session_cnt(shost); return NULL; } EXPORT_SYMBOL_GPL(iscsi_session_setup); @@ -2155,7 +2044,6 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) { struct iscsi_session *session = cls_session->dd_data; struct module *owner = cls_session->transport->owner; - struct Scsi_Host *shost = session->host; iscsi_pool_free(&session->cmdpool); @@ -2168,7 +2056,6 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) kfree(session->ifacename); iscsi_destroy_session(cls_session); - iscsi_host_dec_session_cnt(shost); module_put(owner); } EXPORT_SYMBOL_GPL(iscsi_session_teardown); @@ -2448,10 +2335,8 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, * flush queues. */ spin_lock_bh(&session->lock); - if (flag == STOP_CONN_RECOVER) - fail_all_commands(conn, -1, DID_TRANSPORT_DISRUPTED); - else - fail_all_commands(conn, -1, DID_ERROR); + fail_all_commands(conn, -1, + STOP_CONN_RECOVER ? DID_BUS_BUSY : DID_ERROR); flush_control_queues(session, conn); spin_unlock_bh(&session->lock); mutex_unlock(&session->eh_mutex); diff --git a/trunk/drivers/scsi/lpfc/lpfc.h b/trunk/drivers/scsi/lpfc/lpfc.h index 60a9e6e9384b..e0e018d12653 100644 --- a/trunk/drivers/scsi/lpfc/lpfc.h +++ b/trunk/drivers/scsi/lpfc/lpfc.h @@ -34,14 +34,7 @@ struct lpfc_sli2_slim; #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ #define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */ #define LPFC_VNAME_LEN 100 /* vport symbolic name length */ -#define LPFC_TGTQ_INTERVAL 40000 /* Min amount of time between tgt - queue depth change in millisecs */ -#define LPFC_TGTQ_RAMPUP_PCENT 5 /* Target queue rampup in percentage */ -#define LPFC_MIN_TGT_QDEPTH 100 -#define LPFC_MAX_TGT_QDEPTH 0xFFFF - -#define LPFC_MAX_BUCKET_COUNT 20 /* Maximum no. of buckets for stat data - collection. */ + /* * Following time intervals are used of adjusting SCSI device * queue depths when there are driver resource error or Firmware @@ -56,9 +49,6 @@ struct lpfc_sli2_slim; #define LPFC_HB_MBOX_INTERVAL 5 /* Heart beat interval in seconds. */ #define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */ -/* Error Attention event polling interval */ -#define LPFC_ERATT_POLL_INTERVAL 5 /* EATT poll interval in seconds */ - /* Define macros for 64 bit support */ #define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr))) #define putPaddrHigh(addr) ((uint32_t) (0xffffffff & (((u64)(addr))>>32))) @@ -70,9 +60,6 @@ struct lpfc_sli2_slim; #define MAX_HBAEVT 32 -/* Number of MSI-X vectors the driver uses */ -#define LPFC_MSIX_VECTORS 2 - /* lpfc wait event data ready flag */ #define LPFC_DATA_READY (1<<0) @@ -370,7 +357,6 @@ struct lpfc_vport { uint32_t cfg_log_verbose; uint32_t cfg_max_luns; uint32_t cfg_enable_da_id; - uint32_t cfg_max_scsicmpl_time; uint32_t dev_loss_tmo_changed; @@ -383,8 +369,6 @@ struct lpfc_vport { struct lpfc_debugfs_trc *disc_trc; atomic_t disc_trc_cnt; #endif - uint8_t stat_data_enabled; - uint8_t stat_data_blocked; }; struct hbq_s { @@ -423,11 +407,10 @@ struct lpfc_hba { struct lpfc_sli sli; uint32_t sli_rev; /* SLI2 or SLI3 */ uint32_t sli3_options; /* Mask of enabled SLI3 options */ -#define LPFC_SLI3_HBQ_ENABLED 0x01 -#define LPFC_SLI3_NPIV_ENABLED 0x02 -#define LPFC_SLI3_VPORT_TEARDOWN 0x04 -#define LPFC_SLI3_CRP_ENABLED 0x08 -#define LPFC_SLI3_INB_ENABLED 0x10 +#define LPFC_SLI3_ENABLED 0x01 +#define LPFC_SLI3_HBQ_ENABLED 0x02 +#define LPFC_SLI3_NPIV_ENABLED 0x04 +#define LPFC_SLI3_VPORT_TEARDOWN 0x08 uint32_t iocb_cmd_size; uint32_t iocb_rsp_size; @@ -439,21 +422,11 @@ struct lpfc_hba { #define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */ #define LS_IGNORE_ERATT 0x4 /* intr handler should ignore ERATT */ - uint32_t hba_flag; /* hba generic flags */ -#define HBA_ERATT_HANDLED 0x1 /* This flag is set when eratt handled */ - - struct lpfc_dmabuf slim2p; - - MAILBOX_t *mbox; - uint32_t *inb_ha_copy; - uint32_t *inb_counter; - uint32_t inb_last_counter; - uint32_t ha_copy; - struct _PCB *pcb; - struct _IOCB *IOCBs; - + struct lpfc_sli2_slim *slim2p; struct lpfc_dmabuf hbqslimp; + dma_addr_t slim2p_mapping; + uint16_t pci_cfg_value; uint8_t fc_linkspeed; /* Link speed after last READ_LA */ @@ -519,7 +492,7 @@ struct lpfc_hba { wait_queue_head_t work_waitq; struct task_struct *worker_thread; - unsigned long data_flags; + long data_flags; uint32_t hbq_in_use; /* HBQs in use flag */ struct list_head hbqbuf_in_list; /* in-fly hbq buffer list */ @@ -541,7 +514,6 @@ struct lpfc_hba { void __iomem *HCregaddr; /* virtual address for host ctl reg */ struct lpfc_hgp __iomem *host_gp; /* Host side get/put pointers */ - struct lpfc_pgp *port_gp; uint32_t __iomem *hbq_put; /* Address in SLIM to HBQ put ptrs */ uint32_t *hbq_get; /* Host mem address of HBQ get ptrs */ @@ -564,7 +536,6 @@ struct lpfc_hba { uint8_t soft_wwn_enable; struct timer_list fcp_poll_timer; - struct timer_list eratt_poll; /* * stat counters @@ -594,7 +565,7 @@ struct lpfc_hba { struct fc_host_statistics link_stats; enum intr_type_t intr_type; - struct msix_entry msix_entries[LPFC_MSIX_VECTORS]; + struct msix_entry msix_entries[1]; struct list_head port_list; struct lpfc_vport *pport; /* physical lpfc_vport pointer */ @@ -634,7 +605,6 @@ struct lpfc_hba { unsigned long last_completion_time; struct timer_list hb_tmofunc; uint8_t hb_outstanding; - enum hba_temp_state over_temp_state; /* ndlp reference management */ spinlock_t ndlp_lock; /* @@ -643,19 +613,7 @@ struct lpfc_hba { */ #define QUE_BUFTAG_BIT (1<<31) uint32_t buffer_tag_count; - int wait_4_mlo_maint_flg; - wait_queue_head_t wait_4_mlo_m_q; - /* data structure used for latency data collection */ -#define LPFC_NO_BUCKET 0 -#define LPFC_LINEAR_BUCKET 1 -#define LPFC_POWER2_BUCKET 2 - uint8_t bucket_type; - uint32_t bucket_base; - uint32_t bucket_step; - -/* Maximum number of events that can be outstanding at any time*/ -#define LPFC_MAX_EVT_COUNT 512 - atomic_t fast_event_count; + enum hba_temp_state over_temp_state; }; static inline struct Scsi_Host * @@ -692,25 +650,15 @@ lpfc_worker_wake_up(struct lpfc_hba *phba) return; } -static inline void -lpfc_sli_read_hs(struct lpfc_hba *phba) -{ - /* - * There was a link/board error. Read the status register to retrieve - * the error event and process it. - */ - phba->sli.slistat.err_attn_event++; - - /* Save status info */ - phba->work_hs = readl(phba->HSregaddr); - phba->work_status[0] = readl(phba->MBslimaddr + 0xa8); - phba->work_status[1] = readl(phba->MBslimaddr + 0xac); - - /* Clear chip Host Attention error bit */ - writel(HA_ERATT, phba->HAregaddr); - readl(phba->HAregaddr); /* flush */ - phba->pport->stopped = 1; - - return; -} +#define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */ +#define FC_REG_TEMPERATURE_EVENT 0x20 /* Register for temperature + event */ +struct temp_event { + uint32_t event_type; + uint32_t event_code; + uint32_t data; +}; +#define LPFC_CRIT_TEMP 0x1 +#define LPFC_THRESHOLD_TEMP 0x2 +#define LPFC_NORMAL_TEMP 0x3 diff --git a/trunk/drivers/scsi/lpfc/lpfc_attr.c b/trunk/drivers/scsi/lpfc/lpfc_attr.c index aa3d6277581d..37bfa0bd1dae 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_attr.c +++ b/trunk/drivers/scsi/lpfc/lpfc_attr.c @@ -32,7 +32,6 @@ #include "lpfc_hw.h" #include "lpfc_sli.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h" @@ -50,21 +49,6 @@ #define LPFC_LINK_SPEED_BITMAP 0x00000117 #define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8" -/** - * lpfc_jedec_to_ascii: Hex to ascii convertor according to JEDEC rules. - * @incr: integer to convert. - * @hdw: ascii string holding converted integer plus a string terminator. - * - * Description: - * JEDEC Joint Electron Device Engineering Council. - * Convert a 32 bit integer composed of 8 nibbles into an 8 byte ascii - * character string. The string is then terminated with a NULL in byte 9. - * Hex 0-9 becomes ascii '0' to '9'. - * Hex a-f becomes ascii '=' to 'B' capital B. - * - * Notes: - * Coded for 32 bit integers only. - **/ static void lpfc_jedec_to_ascii(int incr, char hdw[]) { @@ -81,14 +65,6 @@ lpfc_jedec_to_ascii(int incr, char hdw[]) return; } -/** - * lpfc_drvr_version_show: Return the Emulex driver string with version number. - * @dev: class unused variable. - * @attr: device attribute, not used. - * @buf: on return contains the module description text. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_drvr_version_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -96,14 +72,6 @@ lpfc_drvr_version_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n"); } -/** - * lpfc_info_show: Return some pci info about the host in ascii. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains the formatted text from lpfc_info(). - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_info_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -113,14 +81,6 @@ lpfc_info_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host)); } -/** - * lpfc_serialnum_show: Return the hba serial number in ascii. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains the formatted text serial number. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_serialnum_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -132,18 +92,6 @@ lpfc_serialnum_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber); } -/** - * lpfc_temp_sensor_show: Return the temperature sensor level. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains the formatted support level. - * - * Description: - * Returns a number indicating the temperature sensor level currently - * supported, zero or one in ascii. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_temp_sensor_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -154,14 +102,6 @@ lpfc_temp_sensor_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%d\n",phba->temp_sensor_support); } -/** - * lpfc_modeldesc_show: Return the model description of the hba. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains the scsi vpd model description. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_modeldesc_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -173,14 +113,6 @@ lpfc_modeldesc_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc); } -/** - * lpfc_modelname_show: Return the model name of the hba. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains the scsi vpd model name. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_modelname_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -192,14 +124,6 @@ lpfc_modelname_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName); } -/** - * lpfc_programtype_show: Return the program type of the hba. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains the scsi vpd program type. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_programtype_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -211,33 +135,6 @@ lpfc_programtype_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType); } -/** - * lpfc_mlomgmt_show: Return the Menlo Maintenance sli flag. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains the Menlo Maintenance sli flag. - * - * Returns: size of formatted string. - **/ -static ssize_t -lpfc_mlomgmt_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; - struct lpfc_hba *phba = vport->phba; - - return snprintf(buf, PAGE_SIZE, "%d\n", - (phba->sli.sli_flag & LPFC_MENLO_MAINT)); -} - -/** - * lpfc_vportnum_show: Return the port number in ascii of the hba. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains scsi vpd program type. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_vportnum_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -249,14 +146,6 @@ lpfc_vportnum_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port); } -/** - * lpfc_fwrev_show: Return the firmware rev running in the hba. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains the scsi vpd program type. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_fwrev_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -270,14 +159,6 @@ lpfc_fwrev_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s, sli-%d\n", fwrev, phba->sli_rev); } -/** - * lpfc_hdw_show: Return the jedec information about the hba. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains the scsi vpd program type. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_hdw_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -290,15 +171,6 @@ lpfc_hdw_show(struct device *dev, struct device_attribute *attr, char *buf) lpfc_jedec_to_ascii(vp->rev.biuRev, hdw); return snprintf(buf, PAGE_SIZE, "%s\n", hdw); } - -/** - * lpfc_option_rom_version_show: Return the adapter ROM FCode version. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains the ROM and FCode ascii strings. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -309,18 +181,6 @@ lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion); } - -/** - * lpfc_state_show: Return the link state of the port. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains text describing the state of the link. - * - * Notes: - * The switch statement has no default so zero will be returned. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_link_state_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -372,10 +232,8 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr, "Unknown\n"); break; } - if (phba->sli.sli_flag & LPFC_MENLO_MAINT) - len += snprintf(buf + len, PAGE_SIZE-len, - " Menlo Maint Mode\n"); - else if (phba->fc_topology == TOPOLOGY_LOOP) { + + if (phba->fc_topology == TOPOLOGY_LOOP) { if (vport->fc_flag & FC_PUBLIC_LOOP) len += snprintf(buf + len, PAGE_SIZE-len, " Public Loop\n"); @@ -395,18 +253,6 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr, return len; } -/** - * lpfc_num_discovered_ports_show: Return sum of mapped and unmapped vports. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the sum of fc mapped and unmapped. - * - * Description: - * Returns the ascii text number of the sum of the fc mapped and unmapped - * vport counts. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_num_discovered_ports_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -418,20 +264,7 @@ lpfc_num_discovered_ports_show(struct device *dev, vport->fc_map_cnt + vport->fc_unmap_cnt); } -/** - * lpfc_issue_lip: Misnomer, name carried over from long ago. - * @shost: Scsi_Host pointer. - * - * Description: - * Bring the link down gracefully then re-init the link. The firmware will - * re-init the fiber channel interface as required. Does not issue a LIP. - * - * Returns: - * -EPERM port offline or management commands are being blocked - * -ENOMEM cannot allocate memory for the mailbox command - * -EIO error sending the mailbox command - * zero for success - **/ + static int lpfc_issue_lip(struct Scsi_Host *shost) { @@ -473,21 +306,6 @@ lpfc_issue_lip(struct Scsi_Host *shost) return 0; } -/** - * lpfc_do_offline: Issues a mailbox command to bring the link down. - * @phba: lpfc_hba pointer. - * @type: LPFC_EVT_OFFLINE, LPFC_EVT_WARM_START, LPFC_EVT_KILL. - * - * Notes: - * Assumes any error from lpfc_do_offline() will be negative. - * Can wait up to 5 seconds for the port ring buffers count - * to reach zero, prints a warning if it is not zero and continues. - * lpfc_workq_post_event() returns a non-zero return coce if call fails. - * - * Returns: - * -EIO error posting the event - * zero for success - **/ static int lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) { @@ -535,22 +353,6 @@ lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) return 0; } -/** - * lpfc_selective_reset: Offline then onlines the port. - * @phba: lpfc_hba pointer. - * - * Description: - * If the port is configured to allow a reset then the hba is brought - * offline then online. - * - * Notes: - * Assumes any error from lpfc_do_offline() will be negative. - * - * Returns: - * lpfc_do_offline() return code if not zero - * -EIO reset not configured or error posting the event - * zero for success - **/ static int lpfc_selective_reset(struct lpfc_hba *phba) { @@ -576,27 +378,6 @@ lpfc_selective_reset(struct lpfc_hba *phba) return 0; } -/** - * lpfc_issue_reset: Selectively resets an adapter. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: containing the string "selective". - * @count: unused variable. - * - * Description: - * If the buf contains the string "selective" then lpfc_selective_reset() - * is called to perform the reset. - * - * Notes: - * Assumes any error from lpfc_selective_reset() will be negative. - * If lpfc_selective_reset() returns zero then the length of the buffer - * is returned which indicates succcess - * - * Returns: - * -EINVAL if the buffer does not contain the string "selective" - * length of buf if lpfc-selective_reset() if the call succeeds - * return value of lpfc_selective_reset() if the call fails -**/ static ssize_t lpfc_issue_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -616,14 +397,6 @@ lpfc_issue_reset(struct device *dev, struct device_attribute *attr, return status; } -/** - * lpfc_nport_evt_cnt_show: Return the number of nport events. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the ascii number of nport events. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -635,14 +408,6 @@ lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); } -/** - * lpfc_board_mode_show: Return the state of the board. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the state of the adapter. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_board_mode_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -664,19 +429,6 @@ lpfc_board_mode_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s\n", state); } -/** - * lpfc_board_mode_store: Puts the hba in online, offline, warm or error state. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: containing one of the strings "online", "offline", "warm" or "error". - * @count: unused variable. - * - * Returns: - * -EACCES if enable hba reset not enabled - * -EINVAL if the buffer does not contain a valid string (see above) - * -EIO if lpfc_workq_post_event() or lpfc_do_offline() fails - * buf length greater than zero indicates success - **/ static ssize_t lpfc_board_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -710,24 +462,6 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr, return -EIO; } -/** - * lpfc_get_hba_info: Return various bits of informaton about the adapter. - * @phba: pointer to the adapter structure. - * @mxri max xri count. - * @axri available xri count. - * @mrpi max rpi count. - * @arpi available rpi count. - * @mvpi max vpi count. - * @avpi available vpi count. - * - * Description: - * If an integer pointer for an count is not null then the value for the - * count is returned. - * - * Returns: - * zero on error - * one for success - **/ static int lpfc_get_hba_info(struct lpfc_hba *phba, uint32_t *mxri, uint32_t *axri, @@ -790,20 +524,6 @@ lpfc_get_hba_info(struct lpfc_hba *phba, return 1; } -/** - * lpfc_max_rpi_show: Return maximum rpi. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the maximum rpi count in decimal or "Unknown". - * - * Description: - * Calls lpfc_get_hba_info() asking for just the mrpi count. - * If lpfc_get_hba_info() returns zero (failure) the buffer text is set - * to "Unknown" and the buffer length is returned, therefore the caller - * must check for "Unknown" in the buffer to detect a failure. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -818,20 +538,6 @@ lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "Unknown\n"); } -/** - * lpfc_used_rpi_show: Return maximum rpi minus available rpi. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: containing the used rpi count in decimal or "Unknown". - * - * Description: - * Calls lpfc_get_hba_info() asking for just the mrpi and arpi counts. - * If lpfc_get_hba_info() returns zero (failure) the buffer text is set - * to "Unknown" and the buffer length is returned, therefore the caller - * must check for "Unknown" in the buffer to detect a failure. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -846,20 +552,6 @@ lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "Unknown\n"); } -/** - * lpfc_max_xri_show: Return maximum xri. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the maximum xri count in decimal or "Unknown". - * - * Description: - * Calls lpfc_get_hba_info() asking for just the mrpi count. - * If lpfc_get_hba_info() returns zero (failure) the buffer text is set - * to "Unknown" and the buffer length is returned, therefore the caller - * must check for "Unknown" in the buffer to detect a failure. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_max_xri_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -874,20 +566,6 @@ lpfc_max_xri_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "Unknown\n"); } -/** - * lpfc_used_xri_show: Return maximum xpi minus the available xpi. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the used xri count in decimal or "Unknown". - * - * Description: - * Calls lpfc_get_hba_info() asking for just the mxri and axri counts. - * If lpfc_get_hba_info() returns zero (failure) the buffer text is set - * to "Unknown" and the buffer length is returned, therefore the caller - * must check for "Unknown" in the buffer to detect a failure. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_used_xri_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -902,20 +580,6 @@ lpfc_used_xri_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "Unknown\n"); } -/** - * lpfc_max_vpi_show: Return maximum vpi. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the maximum vpi count in decimal or "Unknown". - * - * Description: - * Calls lpfc_get_hba_info() asking for just the mvpi count. - * If lpfc_get_hba_info() returns zero (failure) the buffer text is set - * to "Unknown" and the buffer length is returned, therefore the caller - * must check for "Unknown" in the buffer to detect a failure. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -930,20 +594,6 @@ lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "Unknown\n"); } -/** - * lpfc_used_vpi_show: Return maximum vpi minus the available vpi. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the used vpi count in decimal or "Unknown". - * - * Description: - * Calls lpfc_get_hba_info() asking for just the mvpi and avpi counts. - * If lpfc_get_hba_info() returns zero (failure) the buffer text is set - * to "Unknown" and the buffer length is returned, therefore the caller - * must check for "Unknown" in the buffer to detect a failure. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -958,19 +608,6 @@ lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "Unknown\n"); } -/** - * lpfc_npiv_info_show: Return text about NPIV support for the adapter. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: text that must be interpreted to determine if npiv is supported. - * - * Description: - * Buffer will contain text indicating npiv is not suppoerted on the port, - * the port is an NPIV physical port, or it is an npiv virtual port with - * the id of the vport. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -986,17 +623,6 @@ lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "NPIV Virtual (VPI %d)\n", vport->vpi); } -/** - * lpfc_poll_show: Return text about poll support for the adapter. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the cfg_poll in hex. - * - * Notes: - * cfg_poll should be a lpfc_polling_flags type. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_poll_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1008,20 +634,6 @@ lpfc_poll_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll); } -/** - * lpfc_poll_store: Set the value of cfg_poll for the adapter. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: one or more lpfc_polling_flags values. - * @count: not used. - * - * Notes: - * buf contents converted to integer and checked for a valid value. - * - * Returns: - * -EINVAL if the buffer connot be converted or is out of range - * length of the buf on success - **/ static ssize_t lpfc_poll_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1080,20 +692,6 @@ lpfc_poll_store(struct device *dev, struct device_attribute *attr, return strlen(buf); } -/** - * lpfc_param_show: Return a cfg attribute value in decimal. - * - * Description: - * Macro that given an attr e.g. hba_queue_depth expands - * into a function with the name lpfc_hba_queue_depth_show. - * - * lpfc_##attr##_show: Return the decimal value of an adapters cfg_xxx field. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the attribute value in decimal. - * - * Returns: size of formatted string. - **/ #define lpfc_param_show(attr) \ static ssize_t \ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ @@ -1108,20 +706,6 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ phba->cfg_##attr);\ } -/** - * lpfc_param_hex_show: Return a cfg attribute value in hex. - * - * Description: - * Macro that given an attr e.g. hba_queue_depth expands - * into a function with the name lpfc_hba_queue_depth_show - * - * lpfc_##attr##_show: Return the hex value of an adapters cfg_xxx field. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the attribute value in hexidecimal. - * - * Returns: size of formatted string. - **/ #define lpfc_param_hex_show(attr) \ static ssize_t \ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ @@ -1136,25 +720,6 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ phba->cfg_##attr);\ } -/** - * lpfc_param_init: Intializes a cfg attribute. - * - * Description: - * Macro that given an attr e.g. hba_queue_depth expands - * into a function with the name lpfc_hba_queue_depth_init. The macro also - * takes a default argument, a minimum and maximum argument. - * - * lpfc_##attr##_init: Initializes an attribute. - * @phba: pointer the the adapter structure. - * @val: integer attribute value. - * - * Validates the min and max values then sets the adapter config field - * accordingly, or uses the default if out of range and prints an error message. - * - * Returns: - * zero on success - * -EINVAL if default used - **/ #define lpfc_param_init(attr, default, minval, maxval) \ static int \ lpfc_##attr##_init(struct lpfc_hba *phba, int val) \ @@ -1170,26 +735,6 @@ lpfc_##attr##_init(struct lpfc_hba *phba, int val) \ return -EINVAL;\ } -/** - * lpfc_param_set: Set a cfg attribute value. - * - * Description: - * Macro that given an attr e.g. hba_queue_depth expands - * into a function with the name lpfc_hba_queue_depth_set - * - * lpfc_##attr##_set: Sets an attribute value. - * @phba: pointer the the adapter structure. - * @val: integer attribute value. - * - * Description: - * Validates the min and max values then sets the - * adapter config field if in the valid range. prints error message - * and does not set the parameter if invalid. - * - * Returns: - * zero on success - * -EINVAL if val is invalid - **/ #define lpfc_param_set(attr, default, minval, maxval) \ static int \ lpfc_##attr##_set(struct lpfc_hba *phba, int val) \ @@ -1204,27 +749,6 @@ lpfc_##attr##_set(struct lpfc_hba *phba, int val) \ return -EINVAL;\ } -/** - * lpfc_param_store: Set a vport attribute value. - * - * Description: - * Macro that given an attr e.g. hba_queue_depth expands - * into a function with the name lpfc_hba_queue_depth_store. - * - * lpfc_##attr##_store: Set an sttribute value. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: contains the attribute value in ascii. - * @count: not used. - * - * Description: - * Convert the ascii text number to an integer, then - * use the lpfc_##attr##_set function to set the value. - * - * Returns: - * -EINVAL if val is invalid or lpfc_##attr##_set() fails - * length of buffer upon success. - **/ #define lpfc_param_store(attr) \ static ssize_t \ lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \ @@ -1244,20 +768,6 @@ lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \ return -EINVAL;\ } -/** - * lpfc_vport_param_show: Return decimal formatted cfg attribute value. - * - * Description: - * Macro that given an attr e.g. hba_queue_depth expands - * into a function with the name lpfc_hba_queue_depth_show - * - * lpfc_##attr##_show: prints the attribute value in decimal. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the attribute value in decimal. - * - * Returns: length of formatted string. - **/ #define lpfc_vport_param_show(attr) \ static ssize_t \ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ @@ -1270,21 +780,6 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\ } -/** - * lpfc_vport_param_hex_show: Return hex formatted attribute value. - * - * Description: - * Macro that given an attr e.g. - * hba_queue_depth expands into a function with the name - * lpfc_hba_queue_depth_show - * - * lpfc_##attr##_show: prints the attribute value in hexidecimal. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the attribute value in hexidecimal. - * - * Returns: length of formatted string. - **/ #define lpfc_vport_param_hex_show(attr) \ static ssize_t \ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ @@ -1297,24 +792,6 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ return snprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\ } -/** - * lpfc_vport_param_init: Initialize a vport cfg attribute. - * - * Description: - * Macro that given an attr e.g. hba_queue_depth expands - * into a function with the name lpfc_hba_queue_depth_init. The macro also - * takes a default argument, a minimum and maximum argument. - * - * lpfc_##attr##_init: validates the min and max values then sets the - * adapter config field accordingly, or uses the default if out of range - * and prints an error message. - * @phba: pointer the the adapter structure. - * @val: integer attribute value. - * - * Returns: - * zero on success - * -EINVAL if default used - **/ #define lpfc_vport_param_init(attr, default, minval, maxval) \ static int \ lpfc_##attr##_init(struct lpfc_vport *vport, int val) \ @@ -1324,29 +801,12 @@ lpfc_##attr##_init(struct lpfc_vport *vport, int val) \ return 0;\ }\ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \ - "0423 lpfc_"#attr" attribute cannot be set to %d, "\ + "0449 lpfc_"#attr" attribute cannot be set to %d, "\ "allowed range is ["#minval", "#maxval"]\n", val); \ vport->cfg_##attr = default;\ return -EINVAL;\ } -/** - * lpfc_vport_param_set: Set a vport cfg attribute. - * - * Description: - * Macro that given an attr e.g. hba_queue_depth expands - * into a function with the name lpfc_hba_queue_depth_set - * - * lpfc_##attr##_set: validates the min and max values then sets the - * adapter config field if in the valid range. prints error message - * and does not set the parameter if invalid. - * @phba: pointer the the adapter structure. - * @val: integer attribute value. - * - * Returns: - * zero on success - * -EINVAL if val is invalid - **/ #define lpfc_vport_param_set(attr, default, minval, maxval) \ static int \ lpfc_##attr##_set(struct lpfc_vport *vport, int val) \ @@ -1356,28 +816,11 @@ lpfc_##attr##_set(struct lpfc_vport *vport, int val) \ return 0;\ }\ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \ - "0424 lpfc_"#attr" attribute cannot be set to %d, "\ + "0450 lpfc_"#attr" attribute cannot be set to %d, "\ "allowed range is ["#minval", "#maxval"]\n", val); \ return -EINVAL;\ } -/** - * lpfc_vport_param_store: Set a vport attribute. - * - * Description: - * Macro that given an attr e.g. hba_queue_depth - * expands into a function with the name lpfc_hba_queue_depth_store - * - * lpfc_##attr##_store: convert the ascii text number to an integer, then - * use the lpfc_##attr##_set function to set the value. - * @cdev: class device that is converted into a Scsi_host. - * @buf: contains the attribute value in decimal. - * @count: not used. - * - * Returns: - * -EINVAL if val is invalid or lpfc_##attr##_set() fails - * length of buffer upon success. - **/ #define lpfc_vport_param_store(attr) \ static ssize_t \ lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \ @@ -1498,7 +941,6 @@ static DEVICE_ATTR(option_rom_version, S_IRUGO, lpfc_option_rom_version_show, NULL); static DEVICE_ATTR(num_discovered_ports, S_IRUGO, lpfc_num_discovered_ports_show, NULL); -static DEVICE_ATTR(menlo_mgmt_mode, S_IRUGO, lpfc_mlomgmt_show, NULL); static DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL); static DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, NULL); static DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, @@ -1516,17 +958,6 @@ static DEVICE_ATTR(lpfc_temp_sensor, S_IRUGO, lpfc_temp_sensor_show, NULL); static char *lpfc_soft_wwn_key = "C99G71SL8032A"; -/** - * lpfc_soft_wwn_enable_store: Allows setting of the wwn if the key is valid. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: containing the string lpfc_soft_wwn_key. - * @count: must be size of lpfc_soft_wwn_key. - * - * Returns: - * -EINVAL if the buffer does not contain lpfc_soft_wwn_key - * length of buf indicates success - **/ static ssize_t lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1563,14 +994,6 @@ lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL, lpfc_soft_wwn_enable_store); -/** - * lpfc_soft_wwpn_show: Return the cfg soft ww port name of the adapter. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the wwpn in hexidecimal. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_soft_wwpn_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1583,19 +1006,7 @@ lpfc_soft_wwpn_show(struct device *dev, struct device_attribute *attr, (unsigned long long)phba->cfg_soft_wwpn); } -/** - * lpfc_soft_wwpn_store: Set the ww port name of the adapter. - * @dev class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: contains the wwpn in hexidecimal. - * @count: number of wwpn bytes in buf - * - * Returns: - * -EACCES hba reset not enabled, adapter over temp - * -EINVAL soft wwn not enabled, count is invalid, invalid wwpn byte invalid - * -EIO error taking adapter offline or online - * value of count on success - **/ + static ssize_t lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1669,14 +1080,6 @@ lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\ lpfc_soft_wwpn_show, lpfc_soft_wwpn_store); -/** - * lpfc_soft_wwnn_show: Return the cfg soft ww node name for the adapter. - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: on return contains the wwnn in hexidecimal. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_soft_wwnn_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1687,16 +1090,7 @@ lpfc_soft_wwnn_show(struct device *dev, struct device_attribute *attr, (unsigned long long)phba->cfg_soft_wwnn); } -/** - * lpfc_soft_wwnn_store: sets the ww node name of the adapter. - * @cdev: class device that is converted into a Scsi_host. - * @buf: contains the ww node name in hexidecimal. - * @count: number of wwnn bytes in buf. - * - * Returns: - * -EINVAL soft wwn not enabled, count is invalid, invalid wwnn byte invalid - * value of count on success - **/ + static ssize_t lpfc_soft_wwnn_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1784,15 +1178,6 @@ module_param(lpfc_nodev_tmo, int, 0); MODULE_PARM_DESC(lpfc_nodev_tmo, "Seconds driver will hold I/O waiting " "for a device to come back"); - -/** - * lpfc_nodev_tmo_show: Return the hba dev loss timeout value. - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains the dev loss timeout in decimal. - * - * Returns: size of formatted string. - **/ static ssize_t lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1804,21 +1189,6 @@ lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo); } -/** - * lpfc_nodev_tmo_init: Set the hba nodev timeout value. - * @vport: lpfc vport structure pointer. - * @val: contains the nodev timeout value. - * - * Description: - * If the devloss tmo is already set then nodev tmo is set to devloss tmo, - * a kernel error message is printed and zero is returned. - * Else if val is in range then nodev tmo and devloss tmo are set to val. - * Otherwise nodev tmo is set to the default value. - * - * Returns: - * zero if already set or if val is in range - * -EINVAL val out of range - **/ static int lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val) { @@ -1826,7 +1196,7 @@ lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val) vport->cfg_nodev_tmo = vport->cfg_devloss_tmo; if (val != LPFC_DEF_DEVLOSS_TMO) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0407 Ignoring nodev_tmo module " + "0402 Ignoring nodev_tmo module " "parameter because devloss_tmo is " "set.\n"); return 0; @@ -1845,13 +1215,6 @@ lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val) return -EINVAL; } -/** - * lpfc_update_rport_devloss_tmo: Update dev loss tmo value. - * @vport: lpfc vport structure pointer. - * - * Description: - * Update all the ndlp's dev loss tmo with the vport devloss tmo value. - **/ static void lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport) { @@ -1866,21 +1229,6 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport) spin_unlock_irq(shost->host_lock); } -/** - * lpfc_nodev_tmo_set: Set the vport nodev tmo and devloss tmo values. - * @vport: lpfc vport structure pointer. - * @val: contains the tmo value. - * - * Description: - * If the devloss tmo is already set or the vport dev loss tmo has changed - * then a kernel error message is printed and zero is returned. - * Else if val is in range then nodev tmo and devloss tmo are set to val. - * Otherwise nodev tmo is set to the default value. - * - * Returns: - * zero if already set or if val is in range - * -EINVAL val out of range - **/ static int lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val) { @@ -1921,21 +1269,6 @@ MODULE_PARM_DESC(lpfc_devloss_tmo, lpfc_vport_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO) lpfc_vport_param_show(devloss_tmo) - -/** - * lpfc_devloss_tmo_set: Sets vport nodev tmo, devloss tmo values, changed bit. - * @vport: lpfc vport structure pointer. - * @val: contains the tmo value. - * - * Description: - * If val is in a valid range then set the vport nodev tmo, - * devloss tmo, also set the vport dev loss tmo changed flag. - * Else a kernel error message is printed. - * - * Returns: - * zero if val is in range - * -EINVAL val out of range - **/ static int lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val) { @@ -2033,27 +1366,12 @@ MODULE_PARM_DESC(lpfc_restrict_login, "Restrict virtual ports login to remote initiators."); lpfc_vport_param_show(restrict_login); -/** - * lpfc_restrict_login_init: Set the vport restrict login flag. - * @vport: lpfc vport structure pointer. - * @val: contains the restrict login value. - * - * Description: - * If val is not in a valid range then log a kernel error message and set - * the vport restrict login to one. - * If the port type is physical clear the restrict login flag and return. - * Else set the restrict login flag to val. - * - * Returns: - * zero if val is in range - * -EINVAL val out of range - **/ static int lpfc_restrict_login_init(struct lpfc_vport *vport, int val) { if (val < 0 || val > 1) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0422 lpfc_restrict_login attribute cannot " + "0449 lpfc_restrict_login attribute cannot " "be set to %d, allowed range is [0, 1]\n", val); vport->cfg_restrict_login = 1; @@ -2067,28 +1385,12 @@ lpfc_restrict_login_init(struct lpfc_vport *vport, int val) return 0; } -/** - * lpfc_restrict_login_set: Set the vport restrict login flag. - * @vport: lpfc vport structure pointer. - * @val: contains the restrict login value. - * - * Description: - * If val is not in a valid range then log a kernel error message and set - * the vport restrict login to one. - * If the port type is physical and the val is not zero log a kernel - * error message, clear the restrict login flag and return zero. - * Else set the restrict login flag to val. - * - * Returns: - * zero if val is in range - * -EINVAL val out of range - **/ static int lpfc_restrict_login_set(struct lpfc_vport *vport, int val) { if (val < 0 || val > 1) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0425 lpfc_restrict_login attribute cannot " + "0450 lpfc_restrict_login attribute cannot " "be set to %d, allowed range is [0, 1]\n", val); vport->cfg_restrict_login = 1; @@ -2139,23 +1441,6 @@ LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1, # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6]. # Default value is 0. */ - -/** - * lpfc_topology_set: Set the adapters topology field. - * @phba: lpfc_hba pointer. - * @val: topology value. - * - * Description: - * If val is in a valid range then set the adapter's topology field and - * issue a lip; if the lip fails reset the topology to the old value. - * - * If the value is not in range log a kernel error message and return an error. - * - * Returns: - * zero if val is in range and lip okay - * non-zero return value from lpfc_issue_lip() - * -EINVAL val out of range - **/ static int lpfc_topology_set(struct lpfc_hba *phba, int val) { @@ -2184,335 +1469,6 @@ lpfc_param_store(topology) static DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR, lpfc_topology_show, lpfc_topology_store); - -/** - * lpfc_stat_data_ctrl_store: write call back for lpfc_stat_data_ctrl - * sysfs file. - * @dev: Pointer to class device. - * @buf: Data buffer. - * @count: Size of the data buffer. - * - * This function get called when an user write to the lpfc_stat_data_ctrl - * sysfs file. This function parse the command written to the sysfs file - * and take appropriate action. These commands are used for controlling - * driver statistical data collection. - * Following are the command this function handles. - * - * setbucket - * = Set the latency buckets. - * destroybucket = destroy all the buckets. - * start = start data collection - * stop = stop data collection - * reset = reset the collected data - **/ -static ssize_t -lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; - struct lpfc_hba *phba = vport->phba; -#define LPFC_MAX_DATA_CTRL_LEN 1024 - static char bucket_data[LPFC_MAX_DATA_CTRL_LEN]; - unsigned long i; - char *str_ptr, *token; - struct lpfc_vport **vports; - struct Scsi_Host *v_shost; - char *bucket_type_str, *base_str, *step_str; - unsigned long base, step, bucket_type; - - if (!strncmp(buf, "setbucket", strlen("setbucket"))) { - if (strlen(buf) > LPFC_MAX_DATA_CTRL_LEN) - return -EINVAL; - - strcpy(bucket_data, buf); - str_ptr = &bucket_data[0]; - /* Ignore this token - this is command token */ - token = strsep(&str_ptr, "\t "); - if (!token) - return -EINVAL; - - bucket_type_str = strsep(&str_ptr, "\t "); - if (!bucket_type_str) - return -EINVAL; - - if (!strncmp(bucket_type_str, "linear", strlen("linear"))) - bucket_type = LPFC_LINEAR_BUCKET; - else if (!strncmp(bucket_type_str, "power2", strlen("power2"))) - bucket_type = LPFC_POWER2_BUCKET; - else - return -EINVAL; - - base_str = strsep(&str_ptr, "\t "); - if (!base_str) - return -EINVAL; - base = simple_strtoul(base_str, NULL, 0); - - step_str = strsep(&str_ptr, "\t "); - if (!step_str) - return -EINVAL; - step = simple_strtoul(step_str, NULL, 0); - if (!step) - return -EINVAL; - - /* Block the data collection for every vport */ - vports = lpfc_create_vport_work_array(phba); - if (vports == NULL) - return -ENOMEM; - - for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { - v_shost = lpfc_shost_from_vport(vports[i]); - spin_lock_irq(v_shost->host_lock); - /* Block and reset data collection */ - vports[i]->stat_data_blocked = 1; - if (vports[i]->stat_data_enabled) - lpfc_vport_reset_stat_data(vports[i]); - spin_unlock_irq(v_shost->host_lock); - } - - /* Set the bucket attributes */ - phba->bucket_type = bucket_type; - phba->bucket_base = base; - phba->bucket_step = step; - - for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { - v_shost = lpfc_shost_from_vport(vports[i]); - - /* Unblock data collection */ - spin_lock_irq(v_shost->host_lock); - vports[i]->stat_data_blocked = 0; - spin_unlock_irq(v_shost->host_lock); - } - lpfc_destroy_vport_work_array(phba, vports); - return strlen(buf); - } - - if (!strncmp(buf, "destroybucket", strlen("destroybucket"))) { - vports = lpfc_create_vport_work_array(phba); - if (vports == NULL) - return -ENOMEM; - - for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { - v_shost = lpfc_shost_from_vport(vports[i]); - spin_lock_irq(shost->host_lock); - vports[i]->stat_data_blocked = 1; - lpfc_free_bucket(vport); - vport->stat_data_enabled = 0; - vports[i]->stat_data_blocked = 0; - spin_unlock_irq(shost->host_lock); - } - lpfc_destroy_vport_work_array(phba, vports); - phba->bucket_type = LPFC_NO_BUCKET; - phba->bucket_base = 0; - phba->bucket_step = 0; - return strlen(buf); - } - - if (!strncmp(buf, "start", strlen("start"))) { - /* If no buckets configured return error */ - if (phba->bucket_type == LPFC_NO_BUCKET) - return -EINVAL; - spin_lock_irq(shost->host_lock); - if (vport->stat_data_enabled) { - spin_unlock_irq(shost->host_lock); - return strlen(buf); - } - lpfc_alloc_bucket(vport); - vport->stat_data_enabled = 1; - spin_unlock_irq(shost->host_lock); - return strlen(buf); - } - - if (!strncmp(buf, "stop", strlen("stop"))) { - spin_lock_irq(shost->host_lock); - if (vport->stat_data_enabled == 0) { - spin_unlock_irq(shost->host_lock); - return strlen(buf); - } - lpfc_free_bucket(vport); - vport->stat_data_enabled = 0; - spin_unlock_irq(shost->host_lock); - return strlen(buf); - } - - if (!strncmp(buf, "reset", strlen("reset"))) { - if ((phba->bucket_type == LPFC_NO_BUCKET) - || !vport->stat_data_enabled) - return strlen(buf); - spin_lock_irq(shost->host_lock); - vport->stat_data_blocked = 1; - lpfc_vport_reset_stat_data(vport); - vport->stat_data_blocked = 0; - spin_unlock_irq(shost->host_lock); - return strlen(buf); - } - return -EINVAL; -} - - -/** - * lpfc_stat_data_ctrl_show: Read callback function for - * lpfc_stat_data_ctrl sysfs file. - * @dev: Pointer to class device object. - * @buf: Data buffer. - * - * This function is the read call back function for - * lpfc_stat_data_ctrl sysfs file. This function report the - * current statistical data collection state. - **/ -static ssize_t -lpfc_stat_data_ctrl_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; - struct lpfc_hba *phba = vport->phba; - int index = 0; - int i; - char *bucket_type; - unsigned long bucket_value; - - switch (phba->bucket_type) { - case LPFC_LINEAR_BUCKET: - bucket_type = "linear"; - break; - case LPFC_POWER2_BUCKET: - bucket_type = "power2"; - break; - default: - bucket_type = "No Bucket"; - break; - } - - sprintf(&buf[index], "Statistical Data enabled :%d, " - "blocked :%d, Bucket type :%s, Bucket base :%d," - " Bucket step :%d\nLatency Ranges :", - vport->stat_data_enabled, vport->stat_data_blocked, - bucket_type, phba->bucket_base, phba->bucket_step); - index = strlen(buf); - if (phba->bucket_type != LPFC_NO_BUCKET) { - for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) { - if (phba->bucket_type == LPFC_LINEAR_BUCKET) - bucket_value = phba->bucket_base + - phba->bucket_step * i; - else - bucket_value = phba->bucket_base + - (1 << i) * phba->bucket_step; - - if (index + 10 > PAGE_SIZE) - break; - sprintf(&buf[index], "%08ld ", bucket_value); - index = strlen(buf); - } - } - sprintf(&buf[index], "\n"); - return strlen(buf); -} - -/* - * Sysfs attribute to control the statistical data collection. - */ -static DEVICE_ATTR(lpfc_stat_data_ctrl, S_IRUGO | S_IWUSR, - lpfc_stat_data_ctrl_show, lpfc_stat_data_ctrl_store); - -/* - * lpfc_drvr_stat_data: sysfs attr to get driver statistical data. - */ - -/* - * Each Bucket takes 11 characters and 1 new line + 17 bytes WWN - * for each target. - */ -#define STAT_DATA_SIZE_PER_TARGET(NUM_BUCKETS) ((NUM_BUCKETS) * 11 + 18) -#define MAX_STAT_DATA_SIZE_PER_TARGET \ - STAT_DATA_SIZE_PER_TARGET(LPFC_MAX_BUCKET_COUNT) - - -/** - * sysfs_drvr_stat_data_read: Read callback function for lpfc_drvr_stat_data - * sysfs attribute. - * @kobj: Pointer to the kernel object - * @bin_attr: Attribute object - * @buff: Buffer pointer - * @off: File offset - * @count: Buffer size - * - * This function is the read call back function for lpfc_drvr_stat_data - * sysfs file. This function export the statistical data to user - * applications. - **/ -static ssize_t -sysfs_drvr_stat_data_read(struct kobject *kobj, struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) -{ - struct device *dev = container_of(kobj, struct device, - kobj); - struct Scsi_Host *shost = class_to_shost(dev); - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; - struct lpfc_hba *phba = vport->phba; - int i = 0, index = 0; - unsigned long nport_index; - struct lpfc_nodelist *ndlp = NULL; - nport_index = (unsigned long)off / - MAX_STAT_DATA_SIZE_PER_TARGET; - - if (!vport->stat_data_enabled || vport->stat_data_blocked - || (phba->bucket_type == LPFC_NO_BUCKET)) - return 0; - - spin_lock_irq(shost->host_lock); - list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { - if (!NLP_CHK_NODE_ACT(ndlp) || !ndlp->lat_data) - continue; - - if (nport_index > 0) { - nport_index--; - continue; - } - - if ((index + MAX_STAT_DATA_SIZE_PER_TARGET) - > count) - break; - - if (!ndlp->lat_data) - continue; - - /* Print the WWN */ - sprintf(&buf[index], "%02x%02x%02x%02x%02x%02x%02x%02x:", - ndlp->nlp_portname.u.wwn[0], - ndlp->nlp_portname.u.wwn[1], - ndlp->nlp_portname.u.wwn[2], - ndlp->nlp_portname.u.wwn[3], - ndlp->nlp_portname.u.wwn[4], - ndlp->nlp_portname.u.wwn[5], - ndlp->nlp_portname.u.wwn[6], - ndlp->nlp_portname.u.wwn[7]); - - index = strlen(buf); - - for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) { - sprintf(&buf[index], "%010u,", - ndlp->lat_data[i].cmd_count); - index = strlen(buf); - } - sprintf(&buf[index], "\n"); - index = strlen(buf); - } - spin_unlock_irq(shost->host_lock); - return index; -} - -static struct bin_attribute sysfs_drvr_stat_data_attr = { - .attr = { - .name = "lpfc_drvr_stat_data", - .mode = S_IRUSR, - .owner = THIS_MODULE, - }, - .size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET, - .read = sysfs_drvr_stat_data_read, - .write = NULL, -}; - /* # lpfc_link_speed: Link speed selection for initializing the Fibre Channel # connection. @@ -2523,24 +1479,6 @@ static struct bin_attribute sysfs_drvr_stat_data_attr = { # 8 = 8 Gigabaud # Value range is [0,8]. Default value is 0. */ - -/** - * lpfc_link_speed_set: Set the adapters link speed. - * @phba: lpfc_hba pointer. - * @val: link speed value. - * - * Description: - * If val is in a valid range then set the adapter's link speed field and - * issue a lip; if the lip fails reset the link speed to the old value. - * - * Notes: - * If the value is not in range log a kernel error message and return an error. - * - * Returns: - * zero if val is in range and lip okay. - * non-zero return value from lpfc_issue_lip() - * -EINVAL val out of range - **/ static int lpfc_link_speed_set(struct lpfc_hba *phba, int val) { @@ -2575,23 +1513,6 @@ static int lpfc_link_speed = 0; module_param(lpfc_link_speed, int, 0); MODULE_PARM_DESC(lpfc_link_speed, "Select link speed"); lpfc_param_show(link_speed) - -/** - * lpfc_link_speed_init: Set the adapters link speed. - * @phba: lpfc_hba pointer. - * @val: link speed value. - * - * Description: - * If val is in a valid range then set the adapter's link speed field. - * - * Notes: - * If the value is not in range log a kernel error message, clear the link - * speed and return an error. - * - * Returns: - * zero if val saved. - * -EINVAL val out of range - **/ static int lpfc_link_speed_init(struct lpfc_hba *phba, int val) { @@ -2601,7 +1522,7 @@ lpfc_link_speed_init(struct lpfc_hba *phba, int val) return 0; } lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0405 lpfc_link_speed attribute cannot " + "0454 lpfc_link_speed attribute cannot " "be set to %d, allowed values are " "["LPFC_LINK_SPEED_STRING"]\n", val); phba->cfg_link_speed = 0; @@ -2626,48 +1547,6 @@ LPFC_VPORT_ATTR_R(fcp_class, 3, 2, 3, LPFC_VPORT_ATTR_RW(use_adisc, 0, 0, 1, "Use ADISC on rediscovery to authenticate FCP devices"); -/* -# lpfc_max_scsicmpl_time: Use scsi command completion time to control I/O queue -# depth. Default value is 0. When the value of this parameter is zero the -# SCSI command completion time is not used for controlling I/O queue depth. When -# the parameter is set to a non-zero value, the I/O queue depth is controlled -# to limit the I/O completion time to the parameter value. -# The value is set in milliseconds. -*/ -static int lpfc_max_scsicmpl_time; -module_param(lpfc_max_scsicmpl_time, int, 0); -MODULE_PARM_DESC(lpfc_max_scsicmpl_time, - "Use command completion time to control queue depth"); -lpfc_vport_param_show(max_scsicmpl_time); -lpfc_vport_param_init(max_scsicmpl_time, 0, 0, 60000); -static int -lpfc_max_scsicmpl_time_set(struct lpfc_vport *vport, int val) -{ - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - struct lpfc_nodelist *ndlp, *next_ndlp; - - if (val == vport->cfg_max_scsicmpl_time) - return 0; - if ((val < 0) || (val > 60000)) - return -EINVAL; - vport->cfg_max_scsicmpl_time = val; - - spin_lock_irq(shost->host_lock); - list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { - if (!NLP_CHK_NODE_ACT(ndlp)) - continue; - if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) - continue; - ndlp->cmd_qdepth = LPFC_MAX_TGT_QDEPTH; - } - spin_unlock_irq(shost->host_lock); - return 0; -} -lpfc_vport_param_store(max_scsicmpl_time); -static DEVICE_ATTR(lpfc_max_scsicmpl_time, S_IRUGO | S_IWUSR, - lpfc_max_scsicmpl_time_show, - lpfc_max_scsicmpl_time_store); - /* # lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value # range is [0,1]. Default value is 0. @@ -2744,12 +1623,12 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255, /* # lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that # support this feature -# 0 = MSI disabled +# 0 = MSI disabled (default) # 1 = MSI enabled -# 2 = MSI-X enabled (default) -# Value range is [0,2]. Default value is 2. +# 2 = MSI-X enabled +# Value range is [0,2]. Default value is 0. */ -LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or " +LPFC_ATTR_R(use_msi, 0, 0, 2, "Use Message Signaled Interrupts (1) or " "MSI-X (2), if possible"); /* @@ -2789,7 +1668,6 @@ struct device_attribute *lpfc_hba_attrs[] = { &dev_attr_option_rom_version, &dev_attr_link_state, &dev_attr_num_discovered_ports, - &dev_attr_menlo_mgmt_mode, &dev_attr_lpfc_drvr_version, &dev_attr_lpfc_temp_sensor, &dev_attr_lpfc_log_verbose, @@ -2831,8 +1709,6 @@ struct device_attribute *lpfc_hba_attrs[] = { &dev_attr_lpfc_enable_hba_reset, &dev_attr_lpfc_enable_hba_heartbeat, &dev_attr_lpfc_sg_seg_cnt, - &dev_attr_lpfc_max_scsicmpl_time, - &dev_attr_lpfc_stat_data_ctrl, NULL, }; @@ -2855,29 +1731,9 @@ struct device_attribute *lpfc_vport_attrs[] = { &dev_attr_nport_evt_cnt, &dev_attr_npiv_info, &dev_attr_lpfc_enable_da_id, - &dev_attr_lpfc_max_scsicmpl_time, - &dev_attr_lpfc_stat_data_ctrl, NULL, }; -/** - * sysfs_ctlreg_write: Write method for writing to ctlreg. - * @kobj: kernel kobject that contains the kernel class device. - * @bin_attr: kernel attributes passed to us. - * @buf: contains the data to be written to the adapter IOREG space. - * @off: offset into buffer to beginning of data. - * @count: bytes to transfer. - * - * Description: - * Accessed via /sys/class/scsi_host/hostxxx/ctlreg. - * Uses the adapter io control registers to send buf contents to the adapter. - * - * Returns: - * -ERANGE off and count combo out of range - * -EINVAL off, count or buff address invalid - * -EPERM adapter is offline - * value of count, buf contents written - **/ static ssize_t sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) @@ -2910,23 +1766,6 @@ sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, return count; } -/** - * sysfs_ctlreg_read: Read method for reading from ctlreg. - * @kobj: kernel kobject that contains the kernel class device. - * @bin_attr: kernel attributes passed to us. - * @buf: if succesful contains the data from the adapter IOREG space. - * @off: offset into buffer to beginning of data. - * @count: bytes to transfer. - * - * Description: - * Accessed via /sys/class/scsi_host/hostxxx/ctlreg. - * Uses the adapter io control registers to read data into buf. - * - * Returns: - * -ERANGE off and count combo out of range - * -EINVAL off, count or buff address invalid - * value of count, buf contents read - **/ static ssize_t sysfs_ctlreg_read(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) @@ -2971,10 +1810,7 @@ static struct bin_attribute sysfs_ctlreg_attr = { .write = sysfs_ctlreg_write, }; -/** - * sysfs_mbox_idle: frees the sysfs mailbox. - * @phba: lpfc_hba pointer - **/ + static void sysfs_mbox_idle(struct lpfc_hba *phba) { @@ -2988,27 +1824,6 @@ sysfs_mbox_idle(struct lpfc_hba *phba) } } -/** - * sysfs_mbox_write: Write method for writing information via mbox. - * @kobj: kernel kobject that contains the kernel class device. - * @bin_attr: kernel attributes passed to us. - * @buf: contains the data to be written to sysfs mbox. - * @off: offset into buffer to beginning of data. - * @count: bytes to transfer. - * - * Description: - * Accessed via /sys/class/scsi_host/hostxxx/mbox. - * Uses the sysfs mbox to send buf contents to the adapter. - * - * Returns: - * -ERANGE off and count combo out of range - * -EINVAL off, count or buff address invalid - * zero if count is zero - * -EPERM adapter is offline - * -ENOMEM failed to allocate memory for the mail box - * -EAGAIN offset, state or mbox is NULL - * count number of bytes transferred - **/ static ssize_t sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) @@ -3063,29 +1878,6 @@ sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr, return count; } -/** - * sysfs_mbox_read: Read method for reading information via mbox. - * @kobj: kernel kobject that contains the kernel class device. - * @bin_attr: kernel attributes passed to us. - * @buf: contains the data to be read from sysfs mbox. - * @off: offset into buffer to beginning of data. - * @count: bytes to transfer. - * - * Description: - * Accessed via /sys/class/scsi_host/hostxxx/mbox. - * Uses the sysfs mbox to receive data from to the adapter. - * - * Returns: - * -ERANGE off greater than mailbox command size - * -EINVAL off, count or buff address invalid - * zero if off and count are zero - * -EACCES adapter over temp - * -EPERM garbage can value to catch a multitude of errors - * -EAGAIN management IO not permitted, state or off error - * -ETIME mailbox timeout - * -ENODEV mailbox error - * count number of bytes transferred - **/ static ssize_t sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) @@ -3162,8 +1954,6 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, case MBX_DEL_LD_ENTRY: case MBX_SET_VARIABLE: case MBX_WRITE_WWN: - case MBX_PORT_CAPABILITIES: - case MBX_PORT_IOV_CONTROL: break; case MBX_READ_SPARM64: case MBX_READ_LA: @@ -3188,15 +1978,17 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, /* If HBA encountered an error attention, allow only DUMP * or RESTART mailbox commands until the HBA is restarted. */ - if (phba->pport->stopped && - phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_DUMP_MEMORY && - phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_RESTART && - phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_WRITE_VPARMS && - phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_WRITE_WWN) - lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, - "1259 mbox: Issued mailbox cmd " - "0x%x while in stopped state.\n", - phba->sysfs_mbox.mbox->mb.mbxCommand); + if ((phba->pport->stopped) && + (phba->sysfs_mbox.mbox->mb.mbxCommand != + MBX_DUMP_MEMORY && + phba->sysfs_mbox.mbox->mb.mbxCommand != + MBX_RESTART && + phba->sysfs_mbox.mbox->mb.mbxCommand != + MBX_WRITE_VPARMS)) { + sysfs_mbox_idle(phba); + spin_unlock_irq(&phba->hbalock); + return -EPERM; + } phba->sysfs_mbox.mbox->vport = vport; @@ -3267,14 +2059,6 @@ static struct bin_attribute sysfs_mbox_attr = { .write = sysfs_mbox_write, }; -/** - * lpfc_alloc_sysfs_attr: Creates the ctlreg and mbox entries. - * @vport: address of lpfc vport structure. - * - * Return codes: - * zero on success - * error return code from sysfs_create_bin_file() - **/ int lpfc_alloc_sysfs_attr(struct lpfc_vport *vport) { @@ -3291,30 +2075,18 @@ lpfc_alloc_sysfs_attr(struct lpfc_vport *vport) if (error) goto out_remove_ctlreg_attr; - error = sysfs_create_bin_file(&shost->shost_dev.kobj, - &sysfs_drvr_stat_data_attr); - if (error) - goto out_remove_mbox_attr; - return 0; -out_remove_mbox_attr: - sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr); out_remove_ctlreg_attr: sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr); out: return error; } -/** - * lpfc_free_sysfs_attr: Removes the ctlreg and mbox entries. - * @vport: address of lpfc vport structure. - **/ void lpfc_free_sysfs_attr(struct lpfc_vport *vport) { struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - sysfs_remove_bin_file(&shost->shost_dev.kobj, - &sysfs_drvr_stat_data_attr); + sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr); sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr); } @@ -3324,10 +2096,6 @@ lpfc_free_sysfs_attr(struct lpfc_vport *vport) * Dynamic FC Host Attributes Support */ -/** - * lpfc_get_host_port_id: Copy the vport DID into the scsi host port id. - * @shost: kernel scsi host pointer. - **/ static void lpfc_get_host_port_id(struct Scsi_Host *shost) { @@ -3337,10 +2105,6 @@ lpfc_get_host_port_id(struct Scsi_Host *shost) fc_host_port_id(shost) = vport->fc_myDID; } -/** - * lpfc_get_host_port_type: Set the value of the scsi host port type. - * @shost: kernel scsi host pointer. - **/ static void lpfc_get_host_port_type(struct Scsi_Host *shost) { @@ -3369,10 +2133,6 @@ lpfc_get_host_port_type(struct Scsi_Host *shost) spin_unlock_irq(shost->host_lock); } -/** - * lpfc_get_host_port_state: Set the value of the scsi host port state. - * @shost: kernel scsi host pointer. - **/ static void lpfc_get_host_port_state(struct Scsi_Host *shost) { @@ -3407,10 +2167,6 @@ lpfc_get_host_port_state(struct Scsi_Host *shost) spin_unlock_irq(shost->host_lock); } -/** - * lpfc_get_host_speed: Set the value of the scsi host speed. - * @shost: kernel scsi host pointer. - **/ static void lpfc_get_host_speed(struct Scsi_Host *shost) { @@ -3443,10 +2199,6 @@ lpfc_get_host_speed(struct Scsi_Host *shost) spin_unlock_irq(shost->host_lock); } -/** - * lpfc_get_host_fabric_name: Set the value of the scsi host fabric name. - * @shost: kernel scsi host pointer. - **/ static void lpfc_get_host_fabric_name (struct Scsi_Host *shost) { @@ -3469,18 +2221,6 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost) fc_host_fabric_name(shost) = node_name; } -/** - * lpfc_get_stats: Return statistical information about the adapter. - * @shost: kernel scsi host pointer. - * - * Notes: - * NULL on error for link down, no mbox pool, sli2 active, - * management not allowed, memory allocation error, or mbox error. - * - * Returns: - * NULL for error - * address of the adapter host statistics - **/ static struct fc_host_statistics * lpfc_get_stats(struct Scsi_Host *shost) { @@ -3594,10 +2334,6 @@ lpfc_get_stats(struct Scsi_Host *shost) return hs; } -/** - * lpfc_reset_stats: Copy the adapter link stats information. - * @shost: kernel scsi host pointer. - **/ static void lpfc_reset_stats(struct Scsi_Host *shost) { @@ -3675,14 +2411,6 @@ lpfc_reset_stats(struct Scsi_Host *shost) * are no sysfs handlers for link_down_tmo. */ -/** - * lpfc_get_node_by_target: Return the nodelist for a target. - * @starget: kernel scsi target pointer. - * - * Returns: - * address of the node list if found - * NULL target not found - **/ static struct lpfc_nodelist * lpfc_get_node_by_target(struct scsi_target *starget) { @@ -3704,10 +2432,6 @@ lpfc_get_node_by_target(struct scsi_target *starget) return NULL; } -/** - * lpfc_get_starget_port_id: Set the target port id to the ndlp DID or -1. - * @starget: kernel scsi target pointer. - **/ static void lpfc_get_starget_port_id(struct scsi_target *starget) { @@ -3716,12 +2440,6 @@ lpfc_get_starget_port_id(struct scsi_target *starget) fc_starget_port_id(starget) = ndlp ? ndlp->nlp_DID : -1; } -/** - * lpfc_get_starget_node_name: Set the target node name. - * @starget: kernel scsi target pointer. - * - * Description: Set the target node name to the ndlp node name wwn or zero. - **/ static void lpfc_get_starget_node_name(struct scsi_target *starget) { @@ -3731,12 +2449,6 @@ lpfc_get_starget_node_name(struct scsi_target *starget) ndlp ? wwn_to_u64(ndlp->nlp_nodename.u.wwn) : 0; } -/** - * lpfc_get_starget_port_name: Set the target port name. - * @starget: kernel scsi target pointer. - * - * Description: set the target port name to the ndlp port name wwn or zero. - **/ static void lpfc_get_starget_port_name(struct scsi_target *starget) { @@ -3746,15 +2458,6 @@ lpfc_get_starget_port_name(struct scsi_target *starget) ndlp ? wwn_to_u64(ndlp->nlp_portname.u.wwn) : 0; } -/** - * lpfc_set_rport_loss_tmo: Set the rport dev loss tmo. - * @rport: fc rport address. - * @timeout: new value for dev loss tmo. - * - * Description: - * If timeout is non zero set the dev_loss_tmo to timeout, else set - * dev_loss_tmo to one. - **/ static void lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) { @@ -3764,18 +2467,7 @@ lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) rport->dev_loss_tmo = 1; } -/** - * lpfc_rport_show_function: Return rport target information. - * - * Description: - * Macro that uses field to generate a function with the name lpfc_show_rport_ - * - * lpfc_show_rport_##field: returns the bytes formatted in buf - * @cdev: class converted to an fc_rport. - * @buf: on return contains the target_field or zero. - * - * Returns: size of formatted string. - **/ + #define lpfc_rport_show_function(field, format_string, sz, cast) \ static ssize_t \ lpfc_show_rport_##field (struct device *dev, \ @@ -3910,10 +2602,6 @@ struct fc_function_template lpfc_vport_transport_functions = { .vport_disable = lpfc_vport_disable, }; -/** - * lpfc_get_cfgparam: Used during probe_one to init the adapter structure. - * @phba: lpfc_hba pointer. - **/ void lpfc_get_cfgparam(struct lpfc_hba *phba) { @@ -3949,10 +2637,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) return; } -/** - * lpfc_get_vport_cfgparam: Used during port create, init the vport structure. - * @vport: lpfc_vport pointer. - **/ void lpfc_get_vport_cfgparam(struct lpfc_vport *vport) { @@ -3964,7 +2648,6 @@ lpfc_get_vport_cfgparam(struct lpfc_vport *vport) lpfc_restrict_login_init(vport, lpfc_restrict_login); lpfc_fcp_class_init(vport, lpfc_fcp_class); lpfc_use_adisc_init(vport, lpfc_use_adisc); - lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time); lpfc_fdmi_on_init(vport, lpfc_fdmi_on); lpfc_discovery_threads_init(vport, lpfc_discovery_threads); lpfc_max_luns_init(vport, lpfc_max_luns); diff --git a/trunk/drivers/scsi/lpfc/lpfc_crtn.h b/trunk/drivers/scsi/lpfc/lpfc_crtn.h index 044ef4057d28..1b8245213b83 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_crtn.h +++ b/trunk/drivers/scsi/lpfc/lpfc_crtn.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -typedef int (*node_filter)(struct lpfc_nodelist *, void *); +typedef int (*node_filter)(struct lpfc_nodelist *ndlp, void *param); struct fc_rport; void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); @@ -26,11 +26,11 @@ void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *); -int lpfc_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *, struct lpfc_dmabuf *); +int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, + struct lpfc_dmabuf *mp); void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *); -void lpfc_issue_clear_la(struct lpfc_hba *, struct lpfc_vport *); +void lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport); void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); -int lpfc_config_msi(struct lpfc_hba *, LPFC_MBOXQ_t *); int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *, int); void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *); @@ -43,7 +43,7 @@ void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *); void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t); -void lpfc_cleanup_rpis(struct lpfc_vport *, int); +void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove); int lpfc_linkdown(struct lpfc_hba *); void lpfc_port_link_failure(struct lpfc_vport *); void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); @@ -135,7 +135,7 @@ void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t); int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int); void lpfc_fdmi_tmo(unsigned long); -void lpfc_fdmi_timeout_handler(struct lpfc_vport *); +void lpfc_fdmi_timeout_handler(struct lpfc_vport *vport); int lpfc_config_port_prep(struct lpfc_hba *); int lpfc_config_port_post(struct lpfc_hba *); @@ -155,8 +155,6 @@ int lpfc_sli_queue_setup(struct lpfc_hba *); void lpfc_handle_eratt(struct lpfc_hba *); void lpfc_handle_latt(struct lpfc_hba *); irqreturn_t lpfc_intr_handler(int, void *); -irqreturn_t lpfc_sp_intr_handler(int, void *); -irqreturn_t lpfc_fp_intr_handler(int, void *); void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *); @@ -177,12 +175,11 @@ void lpfc_mem_free(struct lpfc_hba *); void lpfc_stop_vport_timers(struct lpfc_vport *); void lpfc_poll_timeout(unsigned long ptr); -void lpfc_poll_start_timer(struct lpfc_hba *); -void lpfc_poll_eratt(unsigned long); -void lpfc_sli_poll_fcp_ring(struct lpfc_hba *); +void lpfc_poll_start_timer(struct lpfc_hba * phba); +void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba); struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); -void lpfc_sli_release_iocbq(struct lpfc_hba *, struct lpfc_iocbq *); -uint16_t lpfc_sli_next_iotag(struct lpfc_hba *, struct lpfc_iocbq *); +void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); +uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); void lpfc_reset_barrier(struct lpfc_hba * phba); int lpfc_sli_brdready(struct lpfc_hba *, uint32_t); @@ -190,13 +187,11 @@ int lpfc_sli_brdkill(struct lpfc_hba *); int lpfc_sli_brdreset(struct lpfc_hba *); int lpfc_sli_brdrestart(struct lpfc_hba *); int lpfc_sli_hba_setup(struct lpfc_hba *); -int lpfc_sli_config_port(struct lpfc_hba *, int); int lpfc_sli_host_down(struct lpfc_vport *); int lpfc_sli_hba_down(struct lpfc_hba *); int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); int lpfc_sli_handle_mb_event(struct lpfc_hba *); int lpfc_sli_flush_mbox_queue(struct lpfc_hba *); -int lpfc_sli_check_eratt(struct lpfc_hba *); int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *, struct lpfc_sli_ring *, uint32_t); void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); @@ -204,7 +199,6 @@ int lpfc_sli_issue_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *, uint32_t); void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t); void lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *); -void lpfc_sli_flush_fcp_rings(struct lpfc_hba *); int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_dmabuf *); struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *, @@ -232,13 +226,17 @@ struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t); struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *, struct lpfc_name *); -int lpfc_sli_issue_mbox_wait(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); +int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, + uint32_t timeout); -int lpfc_sli_issue_iocb_wait(struct lpfc_hba *, struct lpfc_sli_ring *, - struct lpfc_iocbq *, struct lpfc_iocbq *, - uint32_t); -void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *, struct lpfc_iocbq *, - struct lpfc_iocbq *); +int lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, + struct lpfc_sli_ring * pring, + struct lpfc_iocbq * piocb, + struct lpfc_iocbq * prspiocbq, + uint32_t timeout); +void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, + struct lpfc_iocbq * cmdiocb, + struct lpfc_iocbq * rspiocb); void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *); @@ -271,7 +269,7 @@ void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport); struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct device *); int lpfc_vport_disable(struct fc_vport *fc_vport, bool disable); -int lpfc_mbx_unreg_vpi(struct lpfc_vport *); +void lpfc_mbx_unreg_vpi(struct lpfc_vport *); void destroy_port(struct lpfc_vport *); int lpfc_get_instance(void); void lpfc_host_attrib_init(struct Scsi_Host *); @@ -292,13 +290,6 @@ void lpfc_unblock_fabric_iocbs(struct lpfc_hba *); void lpfc_adjust_queue_depth(struct lpfc_hba *); void lpfc_ramp_down_queue_handler(struct lpfc_hba *); void lpfc_ramp_up_queue_handler(struct lpfc_hba *); -void lpfc_scsi_dev_block(struct lpfc_hba *); - -void -lpfc_send_els_failure_event(struct lpfc_hba *, struct lpfc_iocbq *, - struct lpfc_iocbq *); -struct lpfc_fast_path_event *lpfc_alloc_fast_evt(struct lpfc_hba *); -void lpfc_free_fast_evt(struct lpfc_hba *, struct lpfc_fast_path_event *); #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) #define HBA_EVENT_RSCN 5 diff --git a/trunk/drivers/scsi/lpfc/lpfc_ct.c b/trunk/drivers/scsi/lpfc/lpfc_ct.c index 26dae8bae2d1..7fc74cf5823b 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_ct.c +++ b/trunk/drivers/scsi/lpfc/lpfc_ct.c @@ -34,7 +34,6 @@ #include "lpfc_hw.h" #include "lpfc_sli.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h" @@ -135,24 +134,25 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } list_del(&head); } else { - INIT_LIST_HEAD(&head); - list_add_tail(&head, &piocbq->list); - list_for_each_entry(iocbq, &head, list) { + struct lpfc_iocbq *next; + + list_for_each_entry_safe(iocbq, next, &piocbq->list, list) { icmd = &iocbq->iocb; if (icmd->ulpBdeCount == 0) - lpfc_ct_unsol_buffer(phba, iocbq, NULL, 0); + lpfc_ct_unsol_buffer(phba, piocbq, NULL, 0); for (i = 0; i < icmd->ulpBdeCount; i++) { paddr = getPaddr(icmd->un.cont64[i].addrHigh, icmd->un.cont64[i].addrLow); mp = lpfc_sli_ringpostbuf_get(phba, pring, paddr); size = icmd->un.cont64[i].tus.f.bdeSize; - lpfc_ct_unsol_buffer(phba, iocbq, mp, size); + lpfc_ct_unsol_buffer(phba, piocbq, mp, size); lpfc_in_buf_free(phba, mp); } + list_del(&iocbq->list); + lpfc_sli_release_iocbq(phba, iocbq); lpfc_post_buffer(phba, pring, i); } - list_del(&head); } } @@ -212,7 +212,7 @@ lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl, else list_add_tail(&mp->list, &mlist->list); - bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I; + bpl->tus.f.bdeFlags = BUFF_USE_RCV; /* build buffer ptr list for IOCB */ bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) ); bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) ); @@ -283,7 +283,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, icmd->un.genreq64.bdl.ulpIoTag32 = 0; icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys); icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys); - icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; + icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BDL; icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof (struct ulp_bde64)); if (usr_flg) @@ -861,7 +861,7 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, retry++; lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "0250 Retrying NS cmd %x\n", cmdcode); + "0216 Retrying NS cmd %x\n", cmdcode); rc = lpfc_ns_cmd(vport, cmdcode, retry, 0); if (rc == 0) goto out; diff --git a/trunk/drivers/scsi/lpfc/lpfc_debugfs.c b/trunk/drivers/scsi/lpfc/lpfc_debugfs.c index 771920bdde44..094b47e94b29 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/trunk/drivers/scsi/lpfc/lpfc_debugfs.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2007-2008 Emulex. All rights reserved. * + * Copyright (C) 2007 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -35,7 +35,6 @@ #include "lpfc_hw.h" #include "lpfc_sli.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h" @@ -47,14 +46,13 @@ #include "lpfc_debugfs.h" #ifdef CONFIG_LPFC_DEBUG_FS -/** - * debugfs interface +/* debugfs interface * * To access this interface the user should: * # mkdir /debug * # mount -t debugfs none /debug * - * The lpfc debugfs directory hierarchy is: + * The lpfc debugfs directory hierachy is: * lpfc/lpfcX/vportY * where X is the lpfc hba unique_id * where Y is the vport VPI on that hba @@ -63,21 +61,14 @@ * discovery_trace * This is an ACSII readable file that contains a trace of the last * lpfc_debugfs_max_disc_trc events that happened on a specific vport. - * See lpfc_debugfs.h for different categories of discovery events. - * To enable the discovery trace, the following module parameters must be set: + * See lpfc_debugfs.h for different categories of + * discovery events. To enable the discovery trace, the following + * module parameters must be set: * lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support * lpfc_debugfs_max_disc_trc=X Where X is the event trace depth for * EACH vport. X MUST also be a power of 2. * lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in * lpfc_debugfs.h . - * - * slow_ring_trace - * This is an ACSII readable file that contains a trace of the last - * lpfc_debugfs_max_slow_ring_trc events that happened on a specific HBA. - * To enable the slow ring trace, the following module parameters must be set: - * lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support - * lpfc_debugfs_max_slow_ring_trc=X Where X is the event trace depth for - * the HBA. X MUST also be a power of 2. */ static int lpfc_debugfs_enable = 1; module_param(lpfc_debugfs_enable, int, 0); @@ -126,25 +117,6 @@ struct lpfc_debug { static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0); static unsigned long lpfc_debugfs_start_time = 0L; -/** - * lpfc_debugfs_disc_trc_data - Dump discovery logging to a buffer. - * @vport: The vport to gather the log info from. - * @buf: The buffer to dump log into. - * @size: The maximum amount of data to process. - * - * Description: - * This routine gathers the lpfc discovery debugfs data from the @vport and - * dumps it to @buf up to @size number of bytes. It will start at the next entry - * in the log and process the log until the end of the buffer. Then it will - * gather from the beginning of the log and process until the current entry. - * - * Notes: - * Discovery logging will be disabled while while this routine dumps the log. - * - * Return Value: - * This routine returns the amount of bytes that were dumped into @buf and will - * not exceed @size. - **/ static int lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) { @@ -153,6 +125,7 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) struct lpfc_debugfs_trc *dtp; char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE]; + enable = lpfc_debugfs_enable; lpfc_debugfs_enable = 0; @@ -186,25 +159,6 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) return len; } -/** - * lpfc_debugfs_slow_ring_trc_data - Dump slow ring logging to a buffer. - * @phba: The HBA to gather the log info from. - * @buf: The buffer to dump log into. - * @size: The maximum amount of data to process. - * - * Description: - * This routine gathers the lpfc slow ring debugfs data from the @phba and - * dumps it to @buf up to @size number of bytes. It will start at the next entry - * in the log and process the log until the end of the buffer. Then it will - * gather from the beginning of the log and process until the current entry. - * - * Notes: - * Slow ring logging will be disabled while while this routine dumps the log. - * - * Return Value: - * This routine returns the amount of bytes that were dumped into @buf and will - * not exceed @size. - **/ static int lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size) { @@ -249,25 +203,6 @@ lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size) static int lpfc_debugfs_last_hbq = -1; -/** - * lpfc_debugfs_hbqinfo_data - Dump host buffer queue info to a buffer. - * @phba: The HBA to gather host buffer info from. - * @buf: The buffer to dump log into. - * @size: The maximum amount of data to process. - * - * Description: - * This routine dumps the host buffer queue info from the @phba to @buf up to - * @size number of bytes. A header that describes the current hbq state will be - * dumped to @buf first and then info on each hbq entry will be dumped to @buf - * until @size bytes have been dumped or all the hbq info has been dumped. - * - * Notes: - * This routine will rotate through each configured HBQ each time called. - * - * Return Value: - * This routine returns the amount of bytes that were dumped into @buf and will - * not exceed @size. - **/ static int lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) { @@ -368,24 +303,6 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) static int lpfc_debugfs_last_hba_slim_off; -/** - * lpfc_debugfs_dumpHBASlim_data - Dump HBA SLIM info to a buffer. - * @phba: The HBA to gather SLIM info from. - * @buf: The buffer to dump log into. - * @size: The maximum amount of data to process. - * - * Description: - * This routine dumps the current contents of HBA SLIM for the HBA associated - * with @phba to @buf up to @size bytes of data. This is the raw HBA SLIM data. - * - * Notes: - * This routine will only dump up to 1024 bytes of data each time called and - * should be called multiple times to dump the entire HBA SLIM. - * - * Return Value: - * This routine returns the amount of bytes that were dumped into @buf and will - * not exceed @size. - **/ static int lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size) { @@ -425,21 +342,6 @@ lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size) return len; } -/** - * lpfc_debugfs_dumpHostSlim_data - Dump host SLIM info to a buffer. - * @phba: The HBA to gather Host SLIM info from. - * @buf: The buffer to dump log into. - * @size: The maximum amount of data to process. - * - * Description: - * This routine dumps the current contents of host SLIM for the host associated - * with @phba to @buf up to @size bytes of data. The dump will contain the - * Mailbox, PCB, Rings, and Registers that are located in host memory. - * - * Return Value: - * This routine returns the amount of bytes that were dumped into @buf and will - * not exceed @size. - **/ static int lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) { @@ -455,7 +357,7 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) spin_lock_irq(&phba->hbalock); len += snprintf(buf+len, size-len, "SLIM Mailbox\n"); - ptr = (uint32_t *)phba->slim2p.virt; + ptr = (uint32_t *)phba->slim2p; i = sizeof(MAILBOX_t); while (i > 0) { len += snprintf(buf+len, size-len, @@ -468,7 +370,7 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) } len += snprintf(buf+len, size-len, "SLIM PCB\n"); - ptr = (uint32_t *)phba->pcb; + ptr = (uint32_t *)&phba->slim2p->pcb; i = sizeof(PCB_t); while (i > 0) { len += snprintf(buf+len, size-len, @@ -480,16 +382,44 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) off += (8 * sizeof(uint32_t)); } - for (i = 0; i < 4; i++) { - pgpp = &phba->port_gp[i]; - pring = &psli->ring[i]; - len += snprintf(buf+len, size-len, - "Ring %d: CMD GetInx:%d (Max:%d Next:%d " - "Local:%d flg:x%x) RSP PutInx:%d Max:%d\n", - i, pgpp->cmdGetInx, pring->numCiocb, - pring->next_cmdidx, pring->local_getidx, - pring->flag, pgpp->rspPutInx, pring->numRiocb); - } + pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port; + pring = &psli->ring[0]; + len += snprintf(buf+len, size-len, + "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " + "RSP PutInx:%d Max:%d\n", + pgpp->cmdGetInx, pring->numCiocb, + pring->next_cmdidx, pring->local_getidx, pring->flag, + pgpp->rspPutInx, pring->numRiocb); + pgpp++; + + pring = &psli->ring[1]; + len += snprintf(buf+len, size-len, + "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " + "RSP PutInx:%d Max:%d\n", + pgpp->cmdGetInx, pring->numCiocb, + pring->next_cmdidx, pring->local_getidx, pring->flag, + pgpp->rspPutInx, pring->numRiocb); + pgpp++; + + pring = &psli->ring[2]; + len += snprintf(buf+len, size-len, + "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " + "RSP PutInx:%d Max:%d\n", + pgpp->cmdGetInx, pring->numCiocb, + pring->next_cmdidx, pring->local_getidx, pring->flag, + pgpp->rspPutInx, pring->numRiocb); + pgpp++; + + pring = &psli->ring[3]; + len += snprintf(buf+len, size-len, + "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " + "RSP PutInx:%d Max:%d\n", + pgpp->cmdGetInx, pring->numCiocb, + pring->next_cmdidx, pring->local_getidx, pring->flag, + pgpp->rspPutInx, pring->numRiocb); + + + ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get; word0 = readl(phba->HAregaddr); word1 = readl(phba->CAregaddr); word2 = readl(phba->HSregaddr); @@ -500,21 +430,6 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) return len; } -/** - * lpfc_debugfs_nodelist_data - Dump target node list to a buffer. - * @vport: The vport to gather target node info from. - * @buf: The buffer to dump log into. - * @size: The maximum amount of data to process. - * - * Description: - * This routine dumps the current target node list associated with @vport to - * @buf up to @size bytes of data. Each node entry in the dump will contain a - * node state, DID, WWPN, WWNN, RPI, flags, type, and other useful fields. - * - * Return Value: - * This routine returns the amount of bytes that were dumped into @buf and will - * not exceed @size. - **/ static int lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) { @@ -598,22 +513,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) } #endif -/** - * lpfc_debugfs_disc_trc - Store discovery trace log. - * @vport: The vport to associate this trace string with for retrieval. - * @mask: Log entry classification. - * @fmt: Format string to be displayed when dumping the log. - * @data1: 1st data parameter to be applied to @fmt. - * @data2: 2nd data parameter to be applied to @fmt. - * @data3: 3rd data parameter to be applied to @fmt. - * - * Description: - * This routine is used by the driver code to add a debugfs log entry to the - * discovery trace buffer associated with @vport. Only entries with a @mask that - * match the current debugfs discovery mask will be saved. Entries that do not - * match will be thrown away. @fmt, @data1, @data2, and @data3 are used like - * printf when displaying the log. - **/ + inline void lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt, uint32_t data1, uint32_t data2, uint32_t data3) @@ -642,19 +542,6 @@ lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt, return; } -/** - * lpfc_debugfs_slow_ring_trc - Store slow ring trace log. - * @phba: The phba to associate this trace string with for retrieval. - * @fmt: Format string to be displayed when dumping the log. - * @data1: 1st data parameter to be applied to @fmt. - * @data2: 2nd data parameter to be applied to @fmt. - * @data3: 3rd data parameter to be applied to @fmt. - * - * Description: - * This routine is used by the driver code to add a debugfs log entry to the - * discovery trace buffer associated with @vport. @fmt, @data1, @data2, and - * @data3 are used like printf when displaying the log. - **/ inline void lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt, uint32_t data1, uint32_t data2, uint32_t data3) @@ -681,21 +568,6 @@ lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt, } #ifdef CONFIG_LPFC_DEBUG_FS -/** - * lpfc_debugfs_disc_trc_open - Open the discovery trace log. - * @inode: The inode pointer that contains a vport pointer. - * @file: The file pointer to attach the log output. - * - * Description: - * This routine is the entry point for the debugfs open file operation. It gets - * the vport from the i_private field in @inode, allocates the necessary buffer - * for the log, fills the buffer from the in-memory log for this vport, and then - * returns a pointer to that log in the private_data field in @file. - * - * Returns: - * This function returns zero if successful. On error it will return an negative - * error value. - **/ static int lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file) { @@ -713,7 +585,7 @@ lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file) if (!debug) goto out; - /* Round to page boundary */ + /* Round to page boundry */ size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); size = PAGE_ALIGN(size); @@ -731,21 +603,6 @@ lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file) return rc; } -/** - * lpfc_debugfs_slow_ring_trc_open - Open the Slow Ring trace log. - * @inode: The inode pointer that contains a vport pointer. - * @file: The file pointer to attach the log output. - * - * Description: - * This routine is the entry point for the debugfs open file operation. It gets - * the vport from the i_private field in @inode, allocates the necessary buffer - * for the log, fills the buffer from the in-memory log for this vport, and then - * returns a pointer to that log in the private_data field in @file. - * - * Returns: - * This function returns zero if successful. On error it will return an negative - * error value. - **/ static int lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file) { @@ -763,7 +620,7 @@ lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file) if (!debug) goto out; - /* Round to page boundary */ + /* Round to page boundry */ size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); size = PAGE_ALIGN(size); @@ -781,21 +638,6 @@ lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file) return rc; } -/** - * lpfc_debugfs_hbqinfo_open - Open the hbqinfo debugfs buffer. - * @inode: The inode pointer that contains a vport pointer. - * @file: The file pointer to attach the log output. - * - * Description: - * This routine is the entry point for the debugfs open file operation. It gets - * the vport from the i_private field in @inode, allocates the necessary buffer - * for the log, fills the buffer from the in-memory log for this vport, and then - * returns a pointer to that log in the private_data field in @file. - * - * Returns: - * This function returns zero if successful. On error it will return an negative - * error value. - **/ static int lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file) { @@ -807,7 +649,7 @@ lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file) if (!debug) goto out; - /* Round to page boundary */ + /* Round to page boundry */ debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL); if (!debug->buffer) { kfree(debug); @@ -823,21 +665,6 @@ lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file) return rc; } -/** - * lpfc_debugfs_dumpHBASlim_open - Open the Dump HBA SLIM debugfs buffer. - * @inode: The inode pointer that contains a vport pointer. - * @file: The file pointer to attach the log output. - * - * Description: - * This routine is the entry point for the debugfs open file operation. It gets - * the vport from the i_private field in @inode, allocates the necessary buffer - * for the log, fills the buffer from the in-memory log for this vport, and then - * returns a pointer to that log in the private_data field in @file. - * - * Returns: - * This function returns zero if successful. On error it will return an negative - * error value. - **/ static int lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file) { @@ -849,7 +676,7 @@ lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file) if (!debug) goto out; - /* Round to page boundary */ + /* Round to page boundry */ debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL); if (!debug->buffer) { kfree(debug); @@ -865,21 +692,6 @@ lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file) return rc; } -/** - * lpfc_debugfs_dumpHostSlim_open - Open the Dump Host SLIM debugfs buffer. - * @inode: The inode pointer that contains a vport pointer. - * @file: The file pointer to attach the log output. - * - * Description: - * This routine is the entry point for the debugfs open file operation. It gets - * the vport from the i_private field in @inode, allocates the necessary buffer - * for the log, fills the buffer from the in-memory log for this vport, and then - * returns a pointer to that log in the private_data field in @file. - * - * Returns: - * This function returns zero if successful. On error it will return an negative - * error value. - **/ static int lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file) { @@ -891,7 +703,7 @@ lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file) if (!debug) goto out; - /* Round to page boundary */ + /* Round to page boundry */ debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL); if (!debug->buffer) { kfree(debug); @@ -907,21 +719,6 @@ lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file) return rc; } -/** - * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file. - * @inode: The inode pointer that contains a vport pointer. - * @file: The file pointer to attach the log output. - * - * Description: - * This routine is the entry point for the debugfs open file operation. It gets - * the vport from the i_private field in @inode, allocates the necessary buffer - * for the log, fills the buffer from the in-memory log for this vport, and then - * returns a pointer to that log in the private_data field in @file. - * - * Returns: - * This function returns zero if successful. On error it will return an negative - * error value. - **/ static int lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file) { @@ -933,7 +730,7 @@ lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file) if (!debug) goto out; - /* Round to page boundary */ + /* Round to page boundry */ debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL); if (!debug->buffer) { kfree(debug); @@ -949,23 +746,6 @@ lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file) return rc; } -/** - * lpfc_debugfs_lseek - Seek through a debugfs file. - * @file: The file pointer to seek through. - * @off: The offset to seek to or the amount to seek by. - * @whence: Indicates how to seek. - * - * Description: - * This routine is the entry point for the debugfs lseek file operation. The - * @whence parameter indicates whether @off is the offset to directly seek to, - * or if it is a value to seek forward or reverse by. This function figures out - * what the new offset of the debugfs file will be and assigns that value to the - * f_pos field of @file. - * - * Returns: - * This function returns the new offset if successful and returns a negative - * error if unable to process the seek. - **/ static loff_t lpfc_debugfs_lseek(struct file *file, loff_t off, int whence) { @@ -987,22 +767,6 @@ lpfc_debugfs_lseek(struct file *file, loff_t off, int whence) return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos); } -/** - * lpfc_debugfs_read - Read a debugfs file. - * @file: The file pointer to read from. - * @buf: The buffer to copy the data to. - * @nbytes: The number of bytes to read. - * @ppos: The position in the file to start reading from. - * - * Description: - * This routine reads data from from the buffer indicated in the private_data - * field of @file. It will start reading at @ppos and copy up to @nbytes of - * data to @buf. - * - * Returns: - * This function returns the amount of data that was read (this could be less - * than @nbytes if the end of the file was reached) or a negative error value. - **/ static ssize_t lpfc_debugfs_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) @@ -1012,18 +776,6 @@ lpfc_debugfs_read(struct file *file, char __user *buf, debug->len); } -/** - * lpfc_debugfs_release - Release the buffer used to store debugfs file data. - * @inode: The inode pointer that contains a vport pointer. (unused) - * @file: The file pointer that contains the buffer to release. - * - * Description: - * This routine frees the buffer that was allocated when the debugfs file was - * opened. - * - * Returns: - * This function returns zero. - **/ static int lpfc_debugfs_release(struct inode *inode, struct file *file) { @@ -1093,16 +845,6 @@ static struct dentry *lpfc_debugfs_root = NULL; static atomic_t lpfc_debugfs_hba_count; #endif -/** - * lpfc_debugfs_initialize - Initialize debugfs for a vport. - * @vport: The vport pointer to initialize. - * - * Description: - * When Debugfs is configured this routine sets up the lpfc debugfs file system. - * If not already created, this routine will create the lpfc directory, and - * lpfcX directory (for this HBA), and vportX directory for this vport. It will - * also create each file used to access lpfc specific debugfs information. - **/ inline void lpfc_debugfs_initialize(struct lpfc_vport *vport) { @@ -1120,7 +862,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) atomic_set(&lpfc_debugfs_hba_count, 0); if (!lpfc_debugfs_root) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0408 Cannot create debugfs root\n"); + "0409 Cannot create debugfs root\n"); goto debug_failed; } } @@ -1134,7 +876,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) debugfs_create_dir(name, lpfc_debugfs_root); if (!phba->hba_debugfs_root) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0412 Cannot create debugfs hba\n"); + "0409 Cannot create debugfs hba\n"); goto debug_failed; } atomic_inc(&lpfc_debugfs_hba_count); @@ -1148,7 +890,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) phba, &lpfc_debugfs_op_hbqinfo); if (!phba->debug_hbqinfo) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0411 Cannot create debugfs hbqinfo\n"); + "0409 Cannot create debugfs hbqinfo\n"); goto debug_failed; } @@ -1160,7 +902,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) phba, &lpfc_debugfs_op_dumpHBASlim); if (!phba->debug_dumpHBASlim) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0413 Cannot create debugfs dumpHBASlim\n"); + "0409 Cannot create debugfs dumpHBASlim\n"); goto debug_failed; } @@ -1172,7 +914,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) phba, &lpfc_debugfs_op_dumpHostSlim); if (!phba->debug_dumpHostSlim) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0414 Cannot create debugfs dumpHostSlim\n"); + "0409 Cannot create debugfs dumpHostSlim\n"); goto debug_failed; } @@ -1202,7 +944,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) phba, &lpfc_debugfs_op_slow_ring_trc); if (!phba->debug_slow_ring_trc) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0415 Cannot create debugfs " + "0409 Cannot create debugfs " "slow_ring_trace\n"); goto debug_failed; } @@ -1213,7 +955,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) GFP_KERNEL); if (!phba->slow_ring_trc) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0416 Cannot create debugfs " + "0409 Cannot create debugfs " "slow_ring buffer\n"); goto debug_failed; } @@ -1230,7 +972,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) debugfs_create_dir(name, phba->hba_debugfs_root); if (!vport->vport_debugfs_root) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0417 Cant create debugfs"); + "0409 Cant create debugfs"); goto debug_failed; } atomic_inc(&phba->debugfs_vport_count); @@ -1259,7 +1001,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) if (!vport->disc_trc) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0418 Cannot create debugfs disc trace " + "0409 Cannot create debugfs disc trace " "buffer\n"); goto debug_failed; } @@ -1272,7 +1014,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) vport, &lpfc_debugfs_op_disc_trc); if (!vport->debug_disc_trc) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0419 Cannot create debugfs " + "0409 Cannot create debugfs " "discovery_trace\n"); goto debug_failed; } @@ -1291,17 +1033,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) #endif } -/** - * lpfc_debugfs_terminate - Tear down debugfs infrastructure for this vport. - * @vport: The vport pointer to remove from debugfs. - * - * Description: - * When Debugfs is configured this routine removes debugfs file system elements - * that are specific to this vport. It also checks to see if there are any - * users left for the debugfs directories associated with the HBA and driver. If - * this is the last user of the HBA directory or driver directory then it will - * remove those from the debugfs infrastructure as well. - **/ + inline void lpfc_debugfs_terminate(struct lpfc_vport *vport) { @@ -1364,3 +1096,5 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) #endif return; } + + diff --git a/trunk/drivers/scsi/lpfc/lpfc_disc.h b/trunk/drivers/scsi/lpfc/lpfc_disc.h index f29e548a90d1..2db0b74b6fad 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_disc.h +++ b/trunk/drivers/scsi/lpfc/lpfc_disc.h @@ -37,7 +37,6 @@ enum lpfc_work_type { LPFC_EVT_KILL, LPFC_EVT_ELS_RETRY, LPFC_EVT_DEV_LOSS, - LPFC_EVT_FASTPATH_MGMT_EVT, }; /* structure used to queue event to the discovery tasklet */ @@ -48,24 +47,6 @@ struct lpfc_work_evt { enum lpfc_work_type evt; }; -struct lpfc_scsi_check_condition_event; -struct lpfc_scsi_varqueuedepth_event; -struct lpfc_scsi_event_header; -struct lpfc_fabric_event_header; -struct lpfc_fcprdchkerr_event; - -/* structure used for sending events from fast path */ -struct lpfc_fast_path_event { - struct lpfc_work_evt work_evt; - struct lpfc_vport *vport; - union { - struct lpfc_scsi_check_condition_event check_cond_evt; - struct lpfc_scsi_varqueuedepth_event queue_depth_evt; - struct lpfc_scsi_event_header scsi_evt; - struct lpfc_fabric_event_header fabric_evt; - struct lpfc_fcprdchkerr_event read_check_error; - } un; -}; struct lpfc_nodelist { struct list_head nlp_listp; @@ -107,10 +88,6 @@ struct lpfc_nodelist { unsigned long last_ramp_up_time; /* jiffy of last ramp up */ unsigned long last_q_full_time; /* jiffy of last queue full */ struct kref kref; - atomic_t cmd_pending; - uint32_t cmd_qdepth; - unsigned long last_change_time; - struct lpfc_scsicmd_bkt *lat_data; /* Latency data */ }; /* Defines for nlp_flag (uint32) */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_els.c b/trunk/drivers/scsi/lpfc/lpfc_els.c index 630bd28fb997..f54e0f7eaee3 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_els.c +++ b/trunk/drivers/scsi/lpfc/lpfc_els.c @@ -30,7 +30,6 @@ #include "lpfc_hw.h" #include "lpfc_sli.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h" @@ -54,28 +53,6 @@ static void lpfc_register_new_vport(struct lpfc_hba *phba, static int lpfc_max_els_tries = 3; -/** - * lpfc_els_chk_latt: Check host link attention event for a vport. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine checks whether there is an outstanding host link - * attention event during the discovery process with the @vport. It is done - * by reading the HBA's Host Attention (HA) register. If there is any host - * link attention events during this @vport's discovery process, the @vport - * shall be marked as FC_ABORT_DISCOVERY, a host link attention clear shall - * be issued if the link state is not already in host link cleared state, - * and a return code shall indicate whether the host link attention event - * had happened. - * - * Note that, if either the host link is in state LPFC_LINK_DOWN or @vport - * state in LPFC_VPORT_READY, the request for checking host link attention - * event will be ignored and a return code shall indicate no host link - * attention event had happened. - * - * Return codes - * 0 - no host link attention event happened - * 1 - host link attention event happened - **/ int lpfc_els_chk_latt(struct lpfc_vport *vport) { @@ -115,34 +92,6 @@ lpfc_els_chk_latt(struct lpfc_vport *vport) return 1; } -/** - * lpfc_prep_els_iocb: Allocate and prepare a lpfc iocb data structure. - * @vport: pointer to a host virtual N_Port data structure. - * @expectRsp: flag indicating whether response is expected. - * @cmdSize: size of the ELS command. - * @retry: number of retries to the command IOCB when it fails. - * @ndlp: pointer to a node-list data structure. - * @did: destination identifier. - * @elscmd: the ELS command code. - * - * This routine is used for allocating a lpfc-IOCB data structure from - * the driver lpfc-IOCB free-list and prepare the IOCB with the parameters - * passed into the routine for discovery state machine to issue an Extended - * Link Service (ELS) commands. It is a generic lpfc-IOCB allocation - * and preparation routine that is used by all the discovery state machine - * routines and the ELS command-specific fields will be later set up by - * the individual discovery machine routines after calling this routine - * allocating and preparing a generic IOCB data structure. It fills in the - * Buffer Descriptor Entries (BDEs), allocates buffers for both command - * payload and response payload (if expected). The reference count on the - * ndlp is incremented by 1 and the reference to the ndlp is put into - * context1 of the IOCB data structure for this IOCB to hold the ndlp - * reference for the command's callback function to access later. - * - * Return code - * Pointer to the newly allocated/prepared els iocb data structure - * NULL - when els iocb data structure allocation/preparation failed - **/ static struct lpfc_iocbq * lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, uint16_t cmdSize, uint8_t retry, @@ -201,7 +150,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys); icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys); - icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; + icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL; icmd->un.elsreq64.remoteID = did; /* DID */ if (expectRsp) { icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64)); @@ -236,7 +185,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, bpl->addrLow = le32_to_cpu(putPaddrLow(prsp->phys)); bpl->addrHigh = le32_to_cpu(putPaddrHigh(prsp->phys)); bpl->tus.f.bdeSize = FCELSSIZE; - bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64; + bpl->tus.f.bdeFlags = BUFF_USE_RCV; bpl->tus.w = le32_to_cpu(bpl->tus.w); } @@ -284,22 +233,6 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, return NULL; } -/** - * lpfc_issue_fabric_reglogin: Issue fabric registration login for a vport. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine issues a fabric registration login for a @vport. An - * active ndlp node with Fabric_DID must already exist for this @vport. - * The routine invokes two mailbox commands to carry out fabric registration - * login through the HBA firmware: the first mailbox command requests the - * HBA to perform link configuration for the @vport; and the second mailbox - * command requests the HBA to perform the actual fabric registration login - * with the @vport. - * - * Return code - * 0 - successfully issued fabric registration login for @vport - * -ENXIO -- failed to issue fabric registration login for @vport - **/ static int lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) { @@ -380,26 +313,6 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) return -ENXIO; } -/** - * lpfc_cmpl_els_flogi_fabric: Completion function for flogi to a fabric port. - * @vport: pointer to a host virtual N_Port data structure. - * @ndlp: pointer to a node-list data structure. - * @sp: pointer to service parameter data structure. - * @irsp: pointer to the IOCB within the lpfc response IOCB. - * - * This routine is invoked by the lpfc_cmpl_els_flogi() completion callback - * function to handle the completion of a Fabric Login (FLOGI) into a fabric - * port in a fabric topology. It properly sets up the parameters to the @ndlp - * from the IOCB response. It also check the newly assigned N_Port ID to the - * @vport against the previously assigned N_Port ID. If it is different from - * the previously assigned Destination ID (DID), the lpfc_unreg_rpi() routine - * is invoked on all the remaining nodes with the @vport to unregister the - * Remote Port Indicators (RPIs). Finally, the lpfc_issue_fabric_reglogin() - * is invoked to register login to the fabric. - * - * Return code - * 0 - Success (currently, always return 0) - **/ static int lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct serv_parm *sp, IOCB_t *irsp) @@ -474,7 +387,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, */ list_for_each_entry_safe(np, next_np, &vport->fc_nodes, nlp_listp) { - if (!NLP_CHK_NODE_ACT(np)) + if (!NLP_CHK_NODE_ACT(ndlp)) continue; if ((np->nlp_state != NLP_STE_NPR_NODE) || !(np->nlp_flag & NLP_NPR_ADISC)) @@ -503,26 +416,9 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 0; } -/** - * lpfc_cmpl_els_flogi_nport: Completion function for flogi to an N_Port. - * @vport: pointer to a host virtual N_Port data structure. - * @ndlp: pointer to a node-list data structure. - * @sp: pointer to service parameter data structure. - * - * This routine is invoked by the lpfc_cmpl_els_flogi() completion callback - * function to handle the completion of a Fabric Login (FLOGI) into an N_Port - * in a point-to-point topology. First, the @vport's N_Port Name is compared - * with the received N_Port Name: if the @vport's N_Port Name is greater than - * the received N_Port Name lexicographically, this node shall assign local - * N_Port ID (PT2PT_LocalID: 1) and remote N_Port ID (PT2PT_RemoteID: 2) and - * will send out Port Login (PLOGI) with the N_Port IDs assigned. Otherwise, - * this node shall just wait for the remote node to issue PLOGI and assign - * N_Port IDs. - * - * Return code - * 0 - Success - * -ENXIO - Fail - **/ +/* + * We FLOGIed into an NPort, initiate pt2pt protocol + */ static int lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct serv_parm *sp) @@ -620,29 +516,6 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return -ENXIO; } -/** - * lpfc_cmpl_els_flogi: Completion callback function for flogi. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine is the top-level completion callback function for issuing - * a Fabric Login (FLOGI) command. If the response IOCB reported error, - * the lpfc_els_retry() routine shall be invoked to retry the FLOGI. If - * retry has been made (either immediately or delayed with lpfc_els_retry() - * returning 1), the command IOCB will be released and function returned. - * If the retry attempt has been given up (possibly reach the maximum - * number of retries), one additional decrement of ndlp reference shall be - * invoked before going out after releasing the command IOCB. This will - * actually release the remote node (Note, lpfc_els_free_iocb() will also - * invoke one decrement of ndlp reference count). If no error reported in - * the IOCB status, the command Port ID field is used to determine whether - * this is a point-to-point topology or a fabric topology: if the Port ID - * field is assigned, it is a fabric topology; otherwise, it is a - * point-to-point topology. The routine lpfc_cmpl_els_flogi_fabric() or - * lpfc_cmpl_els_flogi_nport() shall be invoked accordingly to handle the - * specific topology completion conditions. - **/ static void lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -745,28 +618,6 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_els_free_iocb(phba, cmdiocb); } -/** - * lpfc_issue_els_flogi: Issue an flogi iocb command for a vport. - * @vport: pointer to a host virtual N_Port data structure. - * @ndlp: pointer to a node-list data structure. - * @retry: number of retries to the command IOCB. - * - * This routine issues a Fabric Login (FLOGI) Request ELS command - * for a @vport. The initiator service parameters are put into the payload - * of the FLOGI Request IOCB and the top-level callback function pointer - * to lpfc_cmpl_els_flogi() routine is put to the IOCB completion callback - * function field. The lpfc_issue_fabric_iocb routine is invoked to send - * out FLOGI ELS command with one outstanding fabric IOCB at a time. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the FLOGI ELS command. - * - * Return code - * 0 - successfully issued flogi iocb for @vport - * 1 - failed to issue flogi iocb for @vport - **/ static int lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, uint8_t retry) @@ -843,20 +694,6 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 0; } -/** - * lpfc_els_abort_flogi: Abort all outstanding flogi iocbs. - * @phba: pointer to lpfc hba data structure. - * - * This routine aborts all the outstanding Fabric Login (FLOGI) IOCBs - * with a @phba. This routine walks all the outstanding IOCBs on the txcmplq - * list and issues an abort IOCB commond on each outstanding IOCB that - * contains a active Fabric_DID ndlp. Note that this function is to issue - * the abort IOCB command on all the outstanding IOCBs, thus when this - * function returns, it does not guarantee all the IOCBs are actually aborted. - * - * Return code - * 0 - Sucessfully issued abort iocb on all outstanding flogis (Always 0) - **/ int lpfc_els_abort_flogi(struct lpfc_hba *phba) { @@ -892,22 +729,6 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba) return 0; } -/** - * lpfc_initial_flogi: Issue an initial fabric login for a vport. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine issues an initial Fabric Login (FLOGI) for the @vport - * specified. It first searches the ndlp with the Fabric_DID (0xfffffe) from - * the @vport's ndlp list. If no such ndlp found, it will create an ndlp and - * put it into the @vport's ndlp list. If an inactive ndlp found on the list, - * it will just be enabled and made active. The lpfc_issue_els_flogi() routine - * is then invoked with the @vport and the ndlp to perform the FLOGI for the - * @vport. - * - * Return code - * 0 - failed to issue initial flogi for @vport - * 1 - successfully issued initial flogi for @vport - **/ int lpfc_initial_flogi(struct lpfc_vport *vport) { @@ -943,22 +764,6 @@ lpfc_initial_flogi(struct lpfc_vport *vport) return 1; } -/** - * lpfc_initial_fdisc: Issue an initial fabric discovery for a vport. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine issues an initial Fabric Discover (FDISC) for the @vport - * specified. It first searches the ndlp with the Fabric_DID (0xfffffe) from - * the @vport's ndlp list. If no such ndlp found, it will create an ndlp and - * put it into the @vport's ndlp list. If an inactive ndlp found on the list, - * it will just be enabled and made active. The lpfc_issue_els_fdisc() routine - * is then invoked with the @vport and the ndlp to perform the FDISC for the - * @vport. - * - * Return code - * 0 - failed to issue initial fdisc for @vport - * 1 - successfully issued initial fdisc for @vport - **/ int lpfc_initial_fdisc(struct lpfc_vport *vport) { @@ -992,17 +797,6 @@ lpfc_initial_fdisc(struct lpfc_vport *vport) return 1; } -/** - * lpfc_more_plogi: Check and issue remaining plogis for a vport. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine checks whether there are more remaining Port Logins - * (PLOGI) to be issued for the @vport. If so, it will invoke the routine - * lpfc_els_disc_plogi() to go through the Node Port Recovery (NPR) nodes - * to issue ELS PLOGIs up to the configured discover threads with the - * @vport (@vport->cfg_discovery_threads). The function also decrement - * the @vport's num_disc_node by 1 if it is not already 0. - **/ void lpfc_more_plogi(struct lpfc_vport *vport) { @@ -1025,37 +819,6 @@ lpfc_more_plogi(struct lpfc_vport *vport) return; } -/** - * lpfc_plogi_confirm_nport: Confirm pologi wwpn matches stored ndlp. - * @phba: pointer to lpfc hba data structure. - * @prsp: pointer to response IOCB payload. - * @ndlp: pointer to a node-list data structure. - * - * This routine checks and indicates whether the WWPN of an N_Port, retrieved - * from a PLOGI, matches the WWPN that is stored in the @ndlp for that N_POrt. - * The following cases are considered N_Port confirmed: - * 1) The N_Port is a Fabric ndlp; 2) The @ndlp is on vport list and matches - * the WWPN of the N_Port logged into; 3) The @ndlp is not on vport list but - * it does not have WWPN assigned either. If the WWPN is confirmed, the - * pointer to the @ndlp will be returned. If the WWPN is not confirmed: - * 1) if there is a node on vport list other than the @ndlp with the same - * WWPN of the N_Port PLOGI logged into, the lpfc_unreg_rpi() will be invoked - * on that node to release the RPI associated with the node; 2) if there is - * no node found on vport list with the same WWPN of the N_Port PLOGI logged - * into, a new node shall be allocated (or activated). In either case, the - * parameters of the @ndlp shall be copied to the new_ndlp, the @ndlp shall - * be released and the new_ndlp shall be put on to the vport node list and - * its pointer returned as the confirmed node. - * - * Note that before the @ndlp got "released", the keepDID from not-matching - * or inactive "new_ndlp" on the vport node list is assigned to the nlp_DID - * of the @ndlp. This is because the release of @ndlp is actually to put it - * into an inactive state on the vport node list and the vport node list - * management algorithm does not allow two node with a same DID. - * - * Return code - * pointer to the PLOGI N_Port @ndlp - **/ static struct lpfc_nodelist * lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, struct lpfc_nodelist *ndlp) @@ -1159,17 +922,6 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, return new_ndlp; } -/** - * lpfc_end_rscn: Check and handle more rscn for a vport. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine checks whether more Registration State Change - * Notifications (RSCNs) came in while the discovery state machine was in - * the FC_RSCN_MODE. If so, the lpfc_els_handle_rscn() routine will be - * invoked to handle the additional RSCNs for the @vport. Otherwise, the - * FC_RSCN_MODE bit will be cleared with the @vport to mark as the end of - * handling the RSCNs. - **/ void lpfc_end_rscn(struct lpfc_vport *vport) { @@ -1191,26 +943,6 @@ lpfc_end_rscn(struct lpfc_vport *vport) } } -/** - * lpfc_cmpl_els_plogi: Completion callback function for plogi. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine is the completion callback function for issuing the Port - * Login (PLOGI) command. For PLOGI completion, there must be an active - * ndlp on the vport node list that matches the remote node ID from the - * PLOGI reponse IOCB. If such ndlp does not exist, the PLOGI is simply - * ignored and command IOCB released. The PLOGI response IOCB status is - * checked for error conditons. If there is error status reported, PLOGI - * retry shall be attempted by invoking the lpfc_els_retry() routine. - * Otherwise, the lpfc_plogi_confirm_nport() routine shall be invoked on - * the ndlp and the NLP_EVT_CMPL_PLOGI state to the Discover State Machine - * (DSM) is set for this PLOGI completion. Finally, it checks whether - * there are additional N_Port nodes with the vport that need to perform - * PLOGI. If so, the lpfc_more_plogi() routine is invoked to issue addition - * PLOGIs. - **/ static void lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -1316,27 +1048,6 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; } -/** - * lpfc_issue_els_plogi: Issue an plogi iocb command for a vport. - * @vport: pointer to a host virtual N_Port data structure. - * @did: destination port identifier. - * @retry: number of retries to the command IOCB. - * - * This routine issues a Port Login (PLOGI) command to a remote N_Port - * (with the @did) for a @vport. Before issuing a PLOGI to a remote N_Port, - * the ndlp with the remote N_Port DID must exist on the @vport's ndlp list. - * This routine constructs the proper feilds of the PLOGI IOCB and invokes - * the lpfc_sli_issue_iocb() routine to send out PLOGI ELS command. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the PLOGI ELS command. - * - * Return code - * 0 - Successfully issued a plogi for @vport - * 1 - failed to issue a plogi for @vport - **/ int lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) { @@ -1395,19 +1106,6 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) return 0; } -/** - * lpfc_cmpl_els_prli: Completion callback function for prli. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine is the completion callback function for a Process Login - * (PRLI) ELS command. The PRLI response IOCB status is checked for error - * status. If there is error status reported, PRLI retry shall be attempted - * by invoking the lpfc_els_retry() routine. Otherwise, the state - * NLP_EVT_CMPL_PRLI is sent to the Discover State Machine (DSM) for this - * ndlp to mark the PRLI completion. - **/ static void lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -1466,27 +1164,6 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; } -/** - * lpfc_issue_els_prli: Issue a prli iocb command for a vport. - * @vport: pointer to a host virtual N_Port data structure. - * @ndlp: pointer to a node-list data structure. - * @retry: number of retries to the command IOCB. - * - * This routine issues a Process Login (PRLI) ELS command for the - * @vport. The PRLI service parameters are set up in the payload of the - * PRLI Request command and the pointer to lpfc_cmpl_els_prli() routine - * is put to the IOCB completion callback func field before invoking the - * routine lpfc_sli_issue_iocb() to send out PRLI command. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the PRLI ELS command. - * - * Return code - * 0 - successfully issued prli iocb command for @vport - * 1 - failed to issue prli iocb command for @vport - **/ int lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, uint8_t retry) @@ -1556,92 +1233,6 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 0; } -/** - * lpfc_rscn_disc: Perform rscn discovery for a vport. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine performs Registration State Change Notification (RSCN) - * discovery for a @vport. If the @vport's node port recovery count is not - * zero, it will invoke the lpfc_els_disc_plogi() to perform PLOGI for all - * the nodes that need recovery. If none of the PLOGI were needed through - * the lpfc_els_disc_plogi() routine, the lpfc_end_rscn() routine shall be - * invoked to check and handle possible more RSCN came in during the period - * of processing the current ones. - **/ -static void -lpfc_rscn_disc(struct lpfc_vport *vport) -{ - lpfc_can_disctmo(vport); - - /* RSCN discovery */ - /* go thru NPR nodes and issue ELS PLOGIs */ - if (vport->fc_npr_cnt) - if (lpfc_els_disc_plogi(vport)) - return; - - lpfc_end_rscn(vport); -} - -/** - * lpfc_adisc_done: Complete the adisc phase of discovery. - * @vport: pointer to lpfc_vport hba data structure that finished all ADISCs. - * - * This function is called when the final ADISC is completed during discovery. - * This function handles clearing link attention or issuing reg_vpi depending - * on whether npiv is enabled. This function also kicks off the PLOGI phase of - * discovery. - * This function is called with no locks held. - **/ -static void -lpfc_adisc_done(struct lpfc_vport *vport) -{ - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - struct lpfc_hba *phba = vport->phba; - - /* - * For NPIV, cmpl_reg_vpi will set port_state to READY, - * and continue discovery. - */ - if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && - !(vport->fc_flag & FC_RSCN_MODE)) { - lpfc_issue_reg_vpi(phba, vport); - return; - } - /* - * For SLI2, we need to set port_state to READY - * and continue discovery. - */ - if (vport->port_state < LPFC_VPORT_READY) { - /* If we get here, there is nothing to ADISC */ - if (vport->port_type == LPFC_PHYSICAL_PORT) - lpfc_issue_clear_la(phba, vport); - if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) { - vport->num_disc_nodes = 0; - /* go thru NPR list, issue ELS PLOGIs */ - if (vport->fc_npr_cnt) - lpfc_els_disc_plogi(vport); - if (!vport->num_disc_nodes) { - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_NDISC_ACTIVE; - spin_unlock_irq(shost->host_lock); - lpfc_can_disctmo(vport); - lpfc_end_rscn(vport); - } - } - vport->port_state = LPFC_VPORT_READY; - } else - lpfc_rscn_disc(vport); -} - -/** - * lpfc_more_adisc: Issue more adisc as needed. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine determines whether there are more ndlps on a @vport - * node list need to have Address Discover (ADISC) issued. If so, it will - * invoke the lpfc_els_disc_adisc() routine to issue ADISC on the @vport's - * remaining nodes which need to have ADISC sent. - **/ void lpfc_more_adisc(struct lpfc_vport *vport) { @@ -1661,27 +1252,23 @@ lpfc_more_adisc(struct lpfc_vport *vport) /* go thru NPR nodes and issue any remaining ELS ADISCs */ sentadisc = lpfc_els_disc_adisc(vport); } - if (!vport->num_disc_nodes) - lpfc_adisc_done(vport); return; } -/** - * lpfc_cmpl_els_adisc: Completion callback function for adisc. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine is the completion function for issuing the Address Discover - * (ADISC) command. It first checks to see whether link went down during - * the discovery process. If so, the node will be marked as node port - * recovery for issuing discover IOCB by the link attention handler and - * exit. Otherwise, the response status is checked. If error was reported - * in the response status, the ADISC command shall be retried by invoking - * the lpfc_els_retry() routine. Otherwise, if no error was reported in - * the response status, the state machine is invoked to set transition - * with respect to NLP_EVT_CMPL_ADISC event. - **/ +static void +lpfc_rscn_disc(struct lpfc_vport *vport) +{ + lpfc_can_disctmo(vport); + + /* RSCN discovery */ + /* go thru NPR nodes and issue ELS PLOGIs */ + if (vport->fc_npr_cnt) + if (lpfc_els_disc_plogi(vport)) + return; + + lpfc_end_rscn(vport); +} + static void lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -1746,34 +1333,57 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_ADISC); - /* Check to see if there are more ADISCs to be sent */ - if (disc && vport->num_disc_nodes) + if (disc && vport->num_disc_nodes) { + /* Check to see if there are more ADISCs to be sent */ lpfc_more_adisc(vport); + + /* Check to see if we are done with ADISC authentication */ + if (vport->num_disc_nodes == 0) { + /* If we get here, there is nothing left to ADISC */ + /* + * For NPIV, cmpl_reg_vpi will set port_state to READY, + * and continue discovery. + */ + if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && + !(vport->fc_flag & FC_RSCN_MODE)) { + lpfc_issue_reg_vpi(phba, vport); + goto out; + } + /* + * For SLI2, we need to set port_state to READY + * and continue discovery. + */ + if (vport->port_state < LPFC_VPORT_READY) { + /* If we get here, there is nothing to ADISC */ + if (vport->port_type == LPFC_PHYSICAL_PORT) + lpfc_issue_clear_la(phba, vport); + + if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) { + vport->num_disc_nodes = 0; + /* go thru NPR list, issue ELS PLOGIs */ + if (vport->fc_npr_cnt) + lpfc_els_disc_plogi(vport); + + if (!vport->num_disc_nodes) { + spin_lock_irq(shost->host_lock); + vport->fc_flag &= + ~FC_NDISC_ACTIVE; + spin_unlock_irq( + shost->host_lock); + lpfc_can_disctmo(vport); + } + } + vport->port_state = LPFC_VPORT_READY; + } else { + lpfc_rscn_disc(vport); + } + } + } out: lpfc_els_free_iocb(phba, cmdiocb); return; } -/** - * lpfc_issue_els_adisc: Issue an address discover iocb to an node on a vport. - * @vport: pointer to a virtual N_Port data structure. - * @ndlp: pointer to a node-list data structure. - * @retry: number of retries to the command IOCB. - * - * This routine issues an Address Discover (ADISC) for an @ndlp on a - * @vport. It prepares the payload of the ADISC ELS command, updates the - * and states of the ndlp, and invokes the lpfc_sli_issue_iocb() routine - * to issue the ADISC ELS command. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the ADISC ELS command. - * - * Return code - * 0 - successfully issued adisc - * 1 - failed to issue adisc - **/ int lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, uint8_t retry) @@ -1827,18 +1437,6 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 0; } -/** - * lpfc_cmpl_els_logo: Completion callback function for logo. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine is the completion function for issuing the ELS Logout (LOGO) - * command. If no error status was reported from the LOGO response, the - * state machine of the associated ndlp shall be invoked for transition with - * respect to NLP_EVT_CMPL_LOGO event. Otherwise, if error status was reported, - * the lpfc_els_retry() routine will be invoked to retry the LOGO command. - **/ static void lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -1904,26 +1502,6 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; } -/** - * lpfc_issue_els_logo: Issue a logo to an node on a vport. - * @vport: pointer to a virtual N_Port data structure. - * @ndlp: pointer to a node-list data structure. - * @retry: number of retries to the command IOCB. - * - * This routine constructs and issues an ELS Logout (LOGO) iocb command - * to a remote node, referred by an @ndlp on a @vport. It constructs the - * payload of the IOCB, properly sets up the @ndlp state, and invokes the - * lpfc_sli_issue_iocb() routine to send out the LOGO ELS command. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the LOGO ELS command. - * - * Return code - * 0 - successfully issued logo - * 1 - failed to issue logo - **/ int lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, uint8_t retry) @@ -1985,22 +1563,6 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 0; } -/** - * lpfc_cmpl_els_cmd: Completion callback function for generic els command. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine is a generic completion callback function for ELS commands. - * Specifically, it is the callback function which does not need to perform - * any command specific operations. It is currently used by the ELS command - * issuing routines for the ELS State Change Request (SCR), - * lpfc_issue_els_scr(), and the ELS Fibre Channel Address Resolution - * Protocol Response (FARPR) routine, lpfc_issue_els_farpr(). Other than - * certain debug loggings, this callback function simply invokes the - * lpfc_els_chk_latt() routine to check whether link went down during the - * discovery process. - **/ static void lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -2025,28 +1587,6 @@ lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; } -/** - * lpfc_issue_els_scr: Issue a scr to an node on a vport. - * @vport: pointer to a host virtual N_Port data structure. - * @nportid: N_Port identifier to the remote node. - * @retry: number of retries to the command IOCB. - * - * This routine issues a State Change Request (SCR) to a fabric node - * on a @vport. The remote node @nportid is passed into the function. It - * first search the @vport node list to find the matching ndlp. If no such - * ndlp is found, a new ndlp shall be created for this (SCR) purpose. An - * IOCB is allocated, payload prepared, and the lpfc_sli_issue_iocb() - * routine is invoked to send the SCR IOCB. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the SCR ELS command. - * - * Return code - * 0 - Successfully issued scr command - * 1 - Failed to issue scr command - **/ int lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) { @@ -2119,28 +1659,6 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) return 0; } -/** - * lpfc_issue_els_farpr: Issue a farp to an node on a vport. - * @vport: pointer to a host virtual N_Port data structure. - * @nportid: N_Port identifier to the remote node. - * @retry: number of retries to the command IOCB. - * - * This routine issues a Fibre Channel Address Resolution Response - * (FARPR) to a node on a vport. The remote node N_Port identifier (@nportid) - * is passed into the function. It first search the @vport node list to find - * the matching ndlp. If no such ndlp is found, a new ndlp shall be created - * for this (FARPR) purpose. An IOCB is allocated, payload prepared, and the - * lpfc_sli_issue_iocb() routine is invoked to send the FARPR ELS command. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the PARPR ELS command. - * - * Return code - * 0 - Successfully issued farpr command - * 1 - Failed to issue farpr command - **/ static int lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) { @@ -2230,18 +1748,6 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) return 0; } -/** - * lpfc_cancel_retry_delay_tmo: Cancel the timer with delayed iocb-cmd retry. - * @vport: pointer to a host virtual N_Port data structure. - * @nlp: pointer to a node-list data structure. - * - * This routine cancels the timer with a delayed IOCB-command retry for - * a @vport's @ndlp. It stops the timer for the delayed function retrial and - * removes the ELS retry event if it presents. In addition, if the - * NLP_NPR_2B_DISC bit is set in the @nlp's nlp_flag bitmap, ADISC IOCB - * commands are sent for the @vport's nodes that require issuing discovery - * ADISC. - **/ void lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) { @@ -2269,36 +1775,25 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) if (vport->port_state < LPFC_VPORT_READY) { /* Check if there are more ADISCs to be sent */ lpfc_more_adisc(vport); + if ((vport->num_disc_nodes == 0) && + (vport->fc_npr_cnt)) + lpfc_els_disc_plogi(vport); } else { /* Check if there are more PLOGIs to be sent */ lpfc_more_plogi(vport); - if (vport->num_disc_nodes == 0) { - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_NDISC_ACTIVE; - spin_unlock_irq(shost->host_lock); - lpfc_can_disctmo(vport); - lpfc_end_rscn(vport); - } + } + if (vport->num_disc_nodes == 0) { + spin_lock_irq(shost->host_lock); + vport->fc_flag &= ~FC_NDISC_ACTIVE; + spin_unlock_irq(shost->host_lock); + lpfc_can_disctmo(vport); + lpfc_end_rscn(vport); } } } return; } -/** - * lpfc_els_retry_delay: Timer function with a ndlp delayed function timer. - * @ptr: holder for the pointer to the timer function associated data (ndlp). - * - * This routine is invoked by the ndlp delayed-function timer to check - * whether there is any pending ELS retry event(s) with the node. If not, it - * simply returns. Otherwise, if there is at least one ELS delayed event, it - * adds the delayed events to the HBA work list and invokes the - * lpfc_worker_wake_up() routine to wake up worker thread to process the - * event. Note that lpfc_nlp_get() is called before posting the event to - * the work list to hold reference count of ndlp so that it guarantees the - * reference to ndlp will still be available when the worker thread gets - * to the event associated with the ndlp. - **/ void lpfc_els_retry_delay(unsigned long ptr) { @@ -2327,15 +1822,6 @@ lpfc_els_retry_delay(unsigned long ptr) return; } -/** - * lpfc_els_retry_delay_handler: Work thread handler for ndlp delayed function. - * @ndlp: pointer to a node-list data structure. - * - * This routine is the worker-thread handler for processing the @ndlp delayed - * event(s), posted by the lpfc_els_retry_delay() routine. It simply retrieves - * the last ELS command from the associated ndlp and invokes the proper ELS - * function according to the delayed ELS command to retry the command. - **/ void lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) { @@ -2398,27 +1884,6 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) return; } -/** - * lpfc_els_retry: Make retry decision on an els command iocb. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine makes a retry decision on an ELS command IOCB, which has - * failed. The following ELS IOCBs use this function for retrying the command - * when previously issued command responsed with error status: FLOGI, PLOGI, - * PRLI, ADISC, LOGO, and FDISC. Based on the ELS command type and the - * returned error status, it makes the decision whether a retry shall be - * issued for the command, and whether a retry shall be made immediately or - * delayed. In the former case, the corresponding ELS command issuing-function - * is called to retry the command. In the later case, the ELS command shall - * be posted to the ndlp delayed event and delayed function timer set to the - * ndlp for the delayed command issusing. - * - * Return code - * 0 - No retry of els command is made - * 1 - Immediate or delayed retry of els command is made - **/ static int lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -2586,7 +2051,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, (stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_NPORT_ID)) ) { lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, - "0122 FDISC Failed (x%x). " + "0123 FDISC Failed (x%x). " "Fabric Detected Bad WWN\n", stat.un.lsRjtError); lpfc_vport_set_state(vport, @@ -2717,26 +2182,12 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return 0; } -/** - * lpfc_els_free_data: Free lpfc dma buffer and data structure with an iocb. - * @phba: pointer to lpfc hba data structure. - * @buf_ptr1: pointer to the lpfc DMA buffer data structure. - * - * This routine releases the lpfc DMA (Direct Memory Access) buffer(s) - * associated with a command IOCB back to the lpfc DMA buffer pool. It first - * checks to see whether there is a lpfc DMA buffer associated with the - * response of the command IOCB. If so, it will be released before releasing - * the lpfc DMA buffer associated with the IOCB itself. - * - * Return code - * 0 - Successfully released lpfc DMA buffer (currently, always return 0) - **/ static int lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1) { struct lpfc_dmabuf *buf_ptr; - /* Free the response before processing the command. */ + /* Free the response before processing the command. */ if (!list_empty(&buf_ptr1->list)) { list_remove_head(&buf_ptr1->list, buf_ptr, struct lpfc_dmabuf, @@ -2749,18 +2200,6 @@ lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1) return 0; } -/** - * lpfc_els_free_bpl: Free lpfc dma buffer and data structure with bpl. - * @phba: pointer to lpfc hba data structure. - * @buf_ptr: pointer to the lpfc dma buffer data structure. - * - * This routine releases the lpfc Direct Memory Access (DMA) buffer - * associated with a Buffer Pointer List (BPL) back to the lpfc DMA buffer - * pool. - * - * Return code - * 0 - Successfully released lpfc DMA buffer (currently, always return 0) - **/ static int lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr) { @@ -2769,33 +2208,6 @@ lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr) return 0; } -/** - * lpfc_els_free_iocb: Free a command iocb and its associated resources. - * @phba: pointer to lpfc hba data structure. - * @elsiocb: pointer to lpfc els command iocb data structure. - * - * This routine frees a command IOCB and its associated resources. The - * command IOCB data structure contains the reference to various associated - * resources, these fields must be set to NULL if the associated reference - * not present: - * context1 - reference to ndlp - * context2 - reference to cmd - * context2->next - reference to rsp - * context3 - reference to bpl - * - * It first properly decrements the reference count held on ndlp for the - * IOCB completion callback function. If LPFC_DELAY_MEM_FREE flag is not - * set, it invokes the lpfc_els_free_data() routine to release the Direct - * Memory Access (DMA) buffers associated with the IOCB. Otherwise, it - * adds the DMA buffer the @phba data structure for the delayed release. - * If reference to the Buffer Pointer List (BPL) is present, the - * lpfc_els_free_bpl() routine is invoked to release the DMA memory - * associated with BPL. Finally, the lpfc_sli_release_iocbq() routine is - * invoked to release the IOCB data structure back to @phba IOCBQ list. - * - * Return code - * 0 - Success (currently, always return 0) - **/ int lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) { @@ -2862,23 +2274,6 @@ lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) return 0; } -/** - * lpfc_cmpl_els_logo_acc: Completion callback function to logo acc response. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine is the completion callback function to the Logout (LOGO) - * Accept (ACC) Response ELS command. This routine is invoked to indicate - * the completion of the LOGO process. It invokes the lpfc_nlp_not_used() to - * release the ndlp if it has the last reference remaining (reference count - * is 1). If succeeded (meaning ndlp released), it sets the IOCB context1 - * field to NULL to inform the following lpfc_els_free_iocb() routine no - * ndlp reference count needs to be decremented. Otherwise, the ndlp - * reference use-count shall be decremented by the lpfc_els_free_iocb() - * routine. Finally, the lpfc_els_free_iocb() is invoked to release the - * IOCB data structure. - **/ static void lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -2916,19 +2311,6 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; } -/** - * lpfc_mbx_cmpl_dflt_rpi: Completion callbk func for unreg dflt rpi mbox cmd. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * This routine is the completion callback function for unregister default - * RPI (Remote Port Index) mailbox command to the @phba. It simply releases - * the associated lpfc Direct Memory Access (DMA) buffer back to the pool and - * decrements the ndlp reference count held for this completion callback - * function. After that, it invokes the lpfc_nlp_not_used() to check - * whether there is only one reference left on the ndlp. If so, it will - * perform one more decrement and trigger the release of the ndlp. - **/ void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) { @@ -2950,22 +2332,6 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) return; } -/** - * lpfc_cmpl_els_rsp: Completion callback function for els response iocb cmd. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine is the completion callback function for ELS Response IOCB - * command. In normal case, this callback function just properly sets the - * nlp_flag bitmap in the ndlp data structure, if the mbox command reference - * field in the command IOCB is not NULL, the referred mailbox command will - * be send out, and then invokes the lpfc_els_free_iocb() routine to release - * the IOCB. Under error conditions, such as when a LS_RJT is returned or a - * link down event occurred during the discovery, the lpfc_nlp_not_used() - * routine shall be invoked trying to release the ndlp if no other threads - * are currently referring it. - **/ static void lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -3121,31 +2487,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; } -/** - * lpfc_els_rsp_acc: Prepare and issue an acc response iocb command. - * @vport: pointer to a host virtual N_Port data structure. - * @flag: the els command code to be accepted. - * @oldiocb: pointer to the original lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * @mbox: pointer to the driver internal queue element for mailbox command. - * - * This routine prepares and issues an Accept (ACC) response IOCB - * command. It uses the @flag to properly set up the IOCB field for the - * specific ACC response command to be issued and invokes the - * lpfc_sli_issue_iocb() routine to send out ACC response IOCB. If a - * @mbox pointer is passed in, it will be put into the context_un.mbox - * field of the IOCB for the completion callback function to issue the - * mailbox command to the HBA later when callback is invoked. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the corresponding response ELS IOCB command. - * - * Return code - * 0 - Successfully issued acc response - * 1 - Failed to issue acc response - **/ int lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp, @@ -3260,28 +2601,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, return 0; } -/** - * lpfc_els_rsp_reject: Propare and issue a rjt response iocb command. - * @vport: pointer to a virtual N_Port data structure. - * @rejectError: - * @oldiocb: pointer to the original lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * @mbox: pointer to the driver internal queue element for mailbox command. - * - * This routine prepares and issue an Reject (RJT) response IOCB - * command. If a @mbox pointer is passed in, it will be put into the - * context_un.mbox field of the IOCB for the completion callback function - * to issue to the HBA later. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the reject response ELS IOCB command. - * - * Return code - * 0 - Successfully issued reject response - * 1 - Failed to issue reject response - **/ int lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp, @@ -3341,25 +2660,6 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, return 0; } -/** - * lpfc_els_rsp_adisc_acc: Prepare and issue acc response to adisc iocb cmd. - * @vport: pointer to a virtual N_Port data structure. - * @oldiocb: pointer to the original lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine prepares and issues an Accept (ACC) response to Address - * Discover (ADISC) ELS command. It simply prepares the payload of the IOCB - * and invokes the lpfc_sli_issue_iocb() routine to send out the command. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the ADISC Accept response ELS IOCB command. - * - * Return code - * 0 - Successfully issued acc adisc response - * 1 - Failed to issue adisc acc response - **/ int lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) @@ -3416,25 +2716,6 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, return 0; } -/** - * lpfc_els_rsp_prli_acc: Prepare and issue acc response to prli iocb cmd. - * @vport: pointer to a virtual N_Port data structure. - * @oldiocb: pointer to the original lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine prepares and issues an Accept (ACC) response to Process - * Login (PRLI) ELS command. It simply prepares the payload of the IOCB - * and invokes the lpfc_sli_issue_iocb() routine to send out the command. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the PRLI Accept response ELS IOCB command. - * - * Return code - * 0 - Successfully issued acc prli response - * 1 - Failed to issue acc prli response - **/ int lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) @@ -3514,32 +2795,6 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, return 0; } -/** - * lpfc_els_rsp_rnid_acc: Issue rnid acc response iocb command. - * @vport: pointer to a virtual N_Port data structure. - * @format: rnid command format. - * @oldiocb: pointer to the original lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine issues a Request Node Identification Data (RNID) Accept - * (ACC) response. It constructs the RNID ACC response command according to - * the proper @format and then calls the lpfc_sli_issue_iocb() routine to - * issue the response. Note that this command does not need to hold the ndlp - * reference count for the callback. So, the ndlp reference count taken by - * the lpfc_prep_els_iocb() routine is put back and the context1 field of - * IOCB is set to NULL to indicate to the lpfc_els_free_iocb() routine that - * there is no ndlp reference available. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function. However, for the RNID Accept Response ELS command, - * this is undone later by this routine after the IOCB is allocated. - * - * Return code - * 0 - Successfully issued acc rnid response - * 1 - Failed to issue acc rnid response - **/ static int lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) @@ -3620,25 +2875,6 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, return 0; } -/** - * lpfc_els_disc_adisc: Issue remaining adisc iocbs to npr nodes of a vport. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine issues Address Discover (ADISC) ELS commands to those - * N_Ports which are in node port recovery state and ADISC has not been issued - * for the @vport. Each time an ELS ADISC IOCB is issued by invoking the - * lpfc_issue_els_adisc() routine, the per @vport number of discover count - * (num_disc_nodes) shall be incremented. If the num_disc_nodes reaches a - * pre-configured threshold (cfg_discovery_threads), the @vport fc_flag will - * be marked with FC_NLP_MORE bit and the process of issuing remaining ADISC - * IOCBs quit for later pick up. On the other hand, after walking through - * all the ndlps with the @vport and there is none ADISC IOCB issued, the - * @vport fc_flag shall be cleared with FC_NLP_MORE bit indicating there is - * no more ADISC need to be sent. - * - * Return code - * The number of N_Ports with adisc issued. - **/ int lpfc_els_disc_adisc(struct lpfc_vport *vport) { @@ -3678,25 +2914,6 @@ lpfc_els_disc_adisc(struct lpfc_vport *vport) return sentadisc; } -/** - * lpfc_els_disc_plogi: Issue plogi for all npr nodes of a vport before adisc. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine issues Port Login (PLOGI) ELS commands to all the N_Ports - * which are in node port recovery state, with a @vport. Each time an ELS - * ADISC PLOGI IOCB is issued by invoking the lpfc_issue_els_plogi() routine, - * the per @vport number of discover count (num_disc_nodes) shall be - * incremented. If the num_disc_nodes reaches a pre-configured threshold - * (cfg_discovery_threads), the @vport fc_flag will be marked with FC_NLP_MORE - * bit set and quit the process of issuing remaining ADISC PLOGIN IOCBs for - * later pick up. On the other hand, after walking through all the ndlps with - * the @vport and there is none ADISC PLOGI IOCB issued, the @vport fc_flag - * shall be cleared with the FC_NLP_MORE bit indicating there is no more ADISC - * PLOGI need to be sent. - * - * Return code - * The number of N_Ports with plogi issued. - **/ int lpfc_els_disc_plogi(struct lpfc_vport *vport) { @@ -3737,15 +2954,6 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport) return sentplogi; } -/** - * lpfc_els_flush_rscn: Clean up any rscn activities with a vport. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine cleans up any Registration State Change Notification - * (RSCN) activity with a @vport. Note that the fc_rscn_flush flag of the - * @vport together with the host_lock is used to prevent multiple thread - * trying to access the RSCN array on a same @vport at the same time. - **/ void lpfc_els_flush_rscn(struct lpfc_vport *vport) { @@ -3776,18 +2984,6 @@ lpfc_els_flush_rscn(struct lpfc_vport *vport) vport->fc_rscn_flush = 0; } -/** - * lpfc_rscn_payload_check: Check whether there is a pending rscn to a did. - * @vport: pointer to a host virtual N_Port data structure. - * @did: remote destination port identifier. - * - * This routine checks whether there is any pending Registration State - * Configuration Notification (RSCN) to a @did on @vport. - * - * Return code - * None zero - The @did matched with a pending rscn - * 0 - not able to match @did with a pending rscn - **/ int lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) { @@ -3857,17 +3053,6 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) return did; } -/** - * lpfc_rscn_recovery_check: Send recovery event to vport nodes matching rscn - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine sends recovery (NLP_EVT_DEVICE_RECOVERY) event to the - * state machine for a @vport's nodes that are with pending RSCN (Registration - * State Change Notification). - * - * Return code - * 0 - Successful (currently alway return 0) - **/ static int lpfc_rscn_recovery_check(struct lpfc_vport *vport) { @@ -3886,28 +3071,6 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport) return 0; } -/** - * lpfc_els_rcv_rscn: Process an unsolicited rscn iocb. - * @vport: pointer to a host virtual N_Port data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine processes an unsolicited RSCN (Registration State Change - * Notification) IOCB. First, the payload of the unsolicited RSCN is walked - * to invoke fc_host_post_event() routine to the FC transport layer. If the - * discover state machine is about to begin discovery, it just accepts the - * RSCN and the discovery process will satisfy the RSCN. If this RSCN only - * contains N_Port IDs for other vports on this HBA, it just accepts the - * RSCN and ignore processing it. If the state machine is in the recovery - * state, the fc_rscn_id_list of this @vport is walked and the - * lpfc_rscn_recovery_check() routine is invoked to send recovery event for - * all nodes that match RSCN payload. Otherwise, the lpfc_els_handle_rscn() - * routine is invoked to handle the RSCN event. - * - * Return code - * 0 - Just sent the acc response - * 1 - Sent the acc response and waited for name server completion - **/ static int lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp) @@ -3967,7 +3130,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, if (rscn_id == hba_id) { /* ALL NPortIDs in RSCN are on HBA */ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "0219 Ignore RSCN " + "0214 Ignore RSCN " "Data: x%x x%x x%x x%x\n", vport->fc_flag, payload_len, *lp, vport->fc_rscn_id_cnt); @@ -4078,22 +3241,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return lpfc_els_handle_rscn(vport); } -/** - * lpfc_els_handle_rscn: Handle rscn for a vport. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine handles the Registration State Configuration Notification - * (RSCN) for a @vport. If login to NameServer does not exist, a new ndlp shall - * be created and a Port Login (PLOGI) to the NameServer is issued. Otherwise, - * if the ndlp to NameServer exists, a Common Transport (CT) command to the - * NameServer shall be issued. If CT command to the NameServer fails to be - * issued, the lpfc_els_flush_rscn() routine shall be invoked to clean up any - * RSCN activities with the @vport. - * - * Return code - * 0 - Cleaned up rscn on the @vport - * 1 - Wait for plogi to name server before proceed - **/ int lpfc_els_handle_rscn(struct lpfc_vport *vport) { @@ -4166,31 +3313,6 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport) return 0; } -/** - * lpfc_els_rcv_flogi: Process an unsolicited flogi iocb. - * @vport: pointer to a host virtual N_Port data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine processes Fabric Login (FLOGI) IOCB received as an ELS - * unsolicited event. An unsolicited FLOGI can be received in a point-to- - * point topology. As an unsolicited FLOGI should not be received in a loop - * mode, any unsolicited FLOGI received in loop mode shall be ignored. The - * lpfc_check_sparm() routine is invoked to check the parameters in the - * unsolicited FLOGI. If parameters validation failed, the routine - * lpfc_els_rsp_reject() shall be called with reject reason code set to - * LSEXP_SPARM_OPTIONS to reject the FLOGI. Otherwise, the Port WWN in the - * FLOGI shall be compared with the Port WWN of the @vport to determine who - * will initiate PLOGI. The higher lexicographical value party shall has - * higher priority (as the winning port) and will initiate PLOGI and - * communicate Port_IDs (Addresses) for both nodes in PLOGI. The result - * of this will be marked in the @vport fc_flag field with FC_PT2PT_PLOGI - * and then the lpfc_els_rsp_acc() routine is invoked to accept the FLOGI. - * - * Return code - * 0 - Successfully processed the unsolicited flogi - * 1 - Failed to process the unsolicited flogi - **/ static int lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp) @@ -4280,22 +3402,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 0; } -/** - * lpfc_els_rcv_rnid: Process an unsolicited rnid iocb. - * @vport: pointer to a host virtual N_Port data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine processes Request Node Identification Data (RNID) IOCB - * received as an ELS unsolicited event. Only when the RNID specified format - * 0x0 or 0xDF (Topology Discovery Specific Node Identification Data) - * present, this routine will invoke the lpfc_els_rsp_rnid_acc() routine to - * Accept (ACC) the RNID ELS command. All the other RNID formats are - * rejected by invoking the lpfc_els_rsp_reject() routine. - * - * Return code - * 0 - Successfully processed rnid iocb (currently always return 0) - **/ static int lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp) @@ -4335,19 +3441,6 @@ lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 0; } -/** - * lpfc_els_rcv_lirr: Process an unsolicited lirr iocb. - * @vport: pointer to a host virtual N_Port data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine processes a Link Incident Report Registration(LIRR) IOCB - * received as an ELS unsolicited event. Currently, this function just invokes - * the lpfc_els_rsp_reject() routine to reject the LIRR IOCB unconditionally. - * - * Return code - * 0 - Successfully processed lirr iocb (currently always return 0) - **/ static int lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp) @@ -4363,25 +3456,6 @@ lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 0; } -/** - * lpfc_els_rsp_rps_acc: Completion callbk func for MBX_READ_LNK_STAT mbox cmd. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * This routine is the completion callback function for the MBX_READ_LNK_STAT - * mailbox command. This callback function is to actually send the Accept - * (ACC) response to a Read Port Status (RPS) unsolicited IOCB event. It - * collects the link statistics from the completion of the MBX_READ_LNK_STAT - * mailbox command, constructs the RPS response with the link statistics - * collected, and then invokes the lpfc_sli_issue_iocb() routine to send ACC - * response to the RPS. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the RPS Accept Response ELS IOCB command. - * - **/ static void lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) { @@ -4457,24 +3531,6 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) return; } -/** - * lpfc_els_rcv_rps: Process an unsolicited rps iocb. - * @vport: pointer to a host virtual N_Port data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine processes Read Port Status (RPS) IOCB received as an - * ELS unsolicited event. It first checks the remote port state. If the - * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE - * state, it invokes the lpfc_els_rsp_reject() routine to send the reject - * response. Otherwise, it issue the MBX_READ_LNK_STAT mailbox command - * for reading the HBA link statistics. It is for the callback function, - * lpfc_els_rsp_rps_acc(), set to the MBX_READ_LNK_STAT mailbox command - * to actually sending out RPS Accept (ACC) response. - * - * Return codes - * 0 - Successfully processed rps iocb (currently always return 0) - **/ static int lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp) @@ -4488,9 +3544,14 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct ls_rjt stat; if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && - (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) - /* reject the unsolicited RPS request and done with it */ - goto reject_out; + (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; + stat.un.b.vendorUnique = 0; + lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, + NULL); + } pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; lp = (uint32_t *) pcmd->virt; @@ -4523,9 +3584,6 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, mempool_free(mbox, phba->mbox_mem_pool); } } - -reject_out: - /* issue rejection response */ stat.un.b.lsRjtRsvd0 = 0; stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; @@ -4534,25 +3592,6 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 0; } -/** - * lpfc_els_rsp_rpl_acc: Issue an accept rpl els command. - * @vport: pointer to a host virtual N_Port data structure. - * @cmdsize: size of the ELS command. - * @oldiocb: pointer to the original lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine issuees an Accept (ACC) Read Port List (RPL) ELS command. - * It is to be called by the lpfc_els_rcv_rpl() routine to accept the RPL. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the RPL Accept Response ELS command. - * - * Return code - * 0 - Successfully issued ACC RPL ELS command - * 1 - Failed to issue ACC RPL ELS command - **/ static int lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) @@ -4606,22 +3645,6 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, return 0; } -/** - * lpfc_els_rcv_rpl: Process an unsolicited rpl iocb. - * @vport: pointer to a host virtual N_Port data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine processes Read Port List (RPL) IOCB received as an ELS - * unsolicited event. It first checks the remote port state. If the remote - * port is not in NLP_STE_UNMAPPED_NODE and NLP_STE_MAPPED_NODE states, it - * invokes the lpfc_els_rsp_reject() routine to send reject response. - * Otherwise, this routine then invokes the lpfc_els_rsp_rpl_acc() routine - * to accept the RPL. - * - * Return code - * 0 - Successfully processed rpl iocb (currently always return 0) - **/ static int lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp) @@ -4635,15 +3658,12 @@ lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { - /* issue rejection response */ stat.un.b.lsRjtRsvd0 = 0; stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; stat.un.b.vendorUnique = 0; lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); - /* rejected the unsolicited RPL request and done with it */ - return 0; } pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; @@ -4665,30 +3685,6 @@ lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 0; } -/** - * lpfc_els_rcv_farp: Process an unsolicited farp request els command. - * @vport: pointer to a virtual N_Port data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine processes Fibre Channel Address Resolution Protocol - * (FARP) Request IOCB received as an ELS unsolicited event. Currently, - * the lpfc driver only supports matching on WWPN or WWNN for FARP. As such, - * FARP_MATCH_PORT flag and FARP_MATCH_NODE flag are checked against the - * Match Flag in the FARP request IOCB: if FARP_MATCH_PORT flag is set, the - * remote PortName is compared against the FC PortName stored in the @vport - * data structure; if FARP_MATCH_NODE flag is set, the remote NodeName is - * compared against the FC NodeName stored in the @vport data structure. - * If any of these matches and the FARP_REQUEST_FARPR flag is set in the - * FARP request IOCB Response Flag, the lpfc_issue_els_farpr() routine is - * invoked to send out FARP Response to the remote node. Before sending the - * FARP Response, however, the FARP_REQUEST_PLOGI flag is check in the FARP - * request IOCB Response Flag and, if it is set, the lpfc_issue_els_plogi() - * routine is invoked to log into the remote port first. - * - * Return code - * 0 - Either the FARP Match Mode not supported or successfully processed - **/ static int lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp) @@ -4748,20 +3744,6 @@ lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 0; } -/** - * lpfc_els_rcv_farpr: Process an unsolicited farp response iocb. - * @vport: pointer to a host virtual N_Port data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine processes Fibre Channel Address Resolution Protocol - * Response (FARPR) IOCB received as an ELS unsolicited event. It simply - * invokes the lpfc_els_rsp_acc() routine to the remote node to accept - * the FARP response request. - * - * Return code - * 0 - Successfully processed FARPR IOCB (currently always return 0) - **/ static int lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp) @@ -4786,25 +3768,6 @@ lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 0; } -/** - * lpfc_els_rcv_fan: Process an unsolicited fan iocb command. - * @vport: pointer to a host virtual N_Port data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @fan_ndlp: pointer to a node-list data structure. - * - * This routine processes a Fabric Address Notification (FAN) IOCB - * command received as an ELS unsolicited event. The FAN ELS command will - * only be processed on a physical port (i.e., the @vport represents the - * physical port). The fabric NodeName and PortName from the FAN IOCB are - * compared against those in the phba data structure. If any of those is - * different, the lpfc_initial_flogi() routine is invoked to initialize - * Fabric Login (FLOGI) to the fabric to start the discover over. Otherwise, - * if both of those are identical, the lpfc_issue_fabric_reglogin() routine - * is invoked to register login to the fabric. - * - * Return code - * 0 - Successfully processed fan iocb (currently always return 0). - **/ static int lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *fan_ndlp) @@ -4834,16 +3797,6 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 0; } -/** - * lpfc_els_timeout: Handler funciton to the els timer. - * @ptr: holder for the timer function associated data. - * - * This routine is invoked by the ELS timer after timeout. It posts the ELS - * timer timeout event by setting the WORKER_ELS_TMO bit to the work port - * event bitmap and then invokes the lpfc_worker_wake_up() routine to wake - * up the worker thread. It is for the worker thread to invoke the routine - * lpfc_els_timeout_handler() to work on the posted event WORKER_ELS_TMO. - **/ void lpfc_els_timeout(unsigned long ptr) { @@ -4863,15 +3816,6 @@ lpfc_els_timeout(unsigned long ptr) return; } -/** - * lpfc_els_timeout_handler: Process an els timeout event. - * @vport: pointer to a virtual N_Port data structure. - * - * This routine is the actual handler function that processes an ELS timeout - * event. It walks the ELS ring to get and abort all the IOCBs (except the - * ABORT/CLOSE/FARP/FARPR/FDISC), which are associated with the @vport by - * invoking the lpfc_sli_issue_abort_iotag() routine. - **/ void lpfc_els_timeout_handler(struct lpfc_vport *vport) { @@ -4942,26 +3886,6 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); } -/** - * lpfc_els_flush_cmd: Clean up the outstanding els commands to a vport. - * @vport: pointer to a host virtual N_Port data structure. - * - * This routine is used to clean up all the outstanding ELS commands on a - * @vport. It first aborts the @vport by invoking lpfc_fabric_abort_vport() - * routine. After that, it walks the ELS transmit queue to remove all the - * IOCBs with the @vport other than the QUE_RING and ABORT/CLOSE IOCBs. For - * the IOCBs with a non-NULL completion callback function, the callback - * function will be invoked with the status set to IOSTAT_LOCAL_REJECT and - * un.ulpWord[4] set to IOERR_SLI_ABORTED. For IOCBs with a NULL completion - * callback function, the IOCB will simply be released. Finally, it walks - * the ELS transmit completion queue to issue an abort IOCB to any transmit - * completion queue IOCB that is associated with the @vport and is not - * an IOCB from libdfc (i.e., the management plane IOCBs that are not - * part of the discovery state machine) out to HBA by invoking the - * lpfc_sli_issue_abort_iotag() routine. Note that this function issues the - * abort IOCB to any transmit completion queueed IOCB, it does not guarantee - * the IOCBs are aborted when this function returns. - **/ void lpfc_els_flush_cmd(struct lpfc_vport *vport) { @@ -5024,23 +3948,6 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport) return; } -/** - * lpfc_els_flush_all_cmd: Clean up all the outstanding els commands to a HBA. - * @phba: pointer to lpfc hba data structure. - * - * This routine is used to clean up all the outstanding ELS commands on a - * @phba. It first aborts the @phba by invoking the lpfc_fabric_abort_hba() - * routine. After that, it walks the ELS transmit queue to remove all the - * IOCBs to the @phba other than the QUE_RING and ABORT/CLOSE IOCBs. For - * the IOCBs with the completion callback function associated, the callback - * function will be invoked with the status set to IOSTAT_LOCAL_REJECT and - * un.ulpWord[4] set to IOERR_SLI_ABORTED. For IOCBs without the completion - * callback function associated, the IOCB will simply be released. Finally, - * it walks the ELS transmit completion queue to issue an abort IOCB to any - * transmit completion queue IOCB that is not an IOCB from libdfc (i.e., the - * management plane IOCBs that are not part of the discovery state machine) - * out to HBA by invoking the lpfc_sli_issue_abort_iotag() routine. - **/ void lpfc_els_flush_all_cmd(struct lpfc_hba *phba) { @@ -5085,130 +3992,6 @@ lpfc_els_flush_all_cmd(struct lpfc_hba *phba) return; } -/** - * lpfc_send_els_failure_event: Posts an ELS command failure event. - * @phba: Pointer to hba context object. - * @cmdiocbp: Pointer to command iocb which reported error. - * @rspiocbp: Pointer to response iocb which reported error. - * - * This function sends an event when there is an ELS command - * failure. - **/ -void -lpfc_send_els_failure_event(struct lpfc_hba *phba, - struct lpfc_iocbq *cmdiocbp, - struct lpfc_iocbq *rspiocbp) -{ - struct lpfc_vport *vport = cmdiocbp->vport; - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - struct lpfc_lsrjt_event lsrjt_event; - struct lpfc_fabric_event_header fabric_event; - struct ls_rjt stat; - struct lpfc_nodelist *ndlp; - uint32_t *pcmd; - - ndlp = cmdiocbp->context1; - if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) - return; - - if (rspiocbp->iocb.ulpStatus == IOSTAT_LS_RJT) { - lsrjt_event.header.event_type = FC_REG_ELS_EVENT; - lsrjt_event.header.subcategory = LPFC_EVENT_LSRJT_RCV; - memcpy(lsrjt_event.header.wwpn, &ndlp->nlp_portname, - sizeof(struct lpfc_name)); - memcpy(lsrjt_event.header.wwnn, &ndlp->nlp_nodename, - sizeof(struct lpfc_name)); - pcmd = (uint32_t *) (((struct lpfc_dmabuf *) - cmdiocbp->context2)->virt); - lsrjt_event.command = *pcmd; - stat.un.lsRjtError = be32_to_cpu(rspiocbp->iocb.un.ulpWord[4]); - lsrjt_event.reason_code = stat.un.b.lsRjtRsnCode; - lsrjt_event.explanation = stat.un.b.lsRjtRsnCodeExp; - fc_host_post_vendor_event(shost, - fc_get_event_number(), - sizeof(lsrjt_event), - (char *)&lsrjt_event, - SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); - return; - } - if ((rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) || - (rspiocbp->iocb.ulpStatus == IOSTAT_FABRIC_BSY)) { - fabric_event.event_type = FC_REG_FABRIC_EVENT; - if (rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) - fabric_event.subcategory = LPFC_EVENT_PORT_BUSY; - else - fabric_event.subcategory = LPFC_EVENT_FABRIC_BUSY; - memcpy(fabric_event.wwpn, &ndlp->nlp_portname, - sizeof(struct lpfc_name)); - memcpy(fabric_event.wwnn, &ndlp->nlp_nodename, - sizeof(struct lpfc_name)); - fc_host_post_vendor_event(shost, - fc_get_event_number(), - sizeof(fabric_event), - (char *)&fabric_event, - SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); - return; - } - -} - -/** - * lpfc_send_els_event: Posts unsolicited els event. - * @vport: Pointer to vport object. - * @ndlp: Pointer FC node object. - * @cmd: ELS command code. - * - * This function posts an event when there is an incoming - * unsolicited ELS command. - **/ -static void -lpfc_send_els_event(struct lpfc_vport *vport, - struct lpfc_nodelist *ndlp, - uint32_t cmd) -{ - struct lpfc_els_event_header els_data; - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - - els_data.event_type = FC_REG_ELS_EVENT; - switch (cmd) { - case ELS_CMD_PLOGI: - els_data.subcategory = LPFC_EVENT_PLOGI_RCV; - break; - case ELS_CMD_PRLO: - els_data.subcategory = LPFC_EVENT_PRLO_RCV; - break; - case ELS_CMD_ADISC: - els_data.subcategory = LPFC_EVENT_ADISC_RCV; - break; - default: - return; - } - memcpy(els_data.wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name)); - memcpy(els_data.wwnn, &ndlp->nlp_nodename, sizeof(struct lpfc_name)); - fc_host_post_vendor_event(shost, - fc_get_event_number(), - sizeof(els_data), - (char *)&els_data, - SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); - - return; -} - - -/** - * lpfc_els_unsol_buffer: Process an unsolicited event data buffer. - * @phba: pointer to lpfc hba data structure. - * @pring: pointer to a SLI ring. - * @vport: pointer to a host virtual N_Port data structure. - * @elsiocb: pointer to lpfc els command iocb data structure. - * - * This routine is used for processing the IOCB associated with a unsolicited - * event. It first determines whether there is an existing ndlp that matches - * the DID from the unsolicited IOCB. If not, it will create a new one with - * the DID from the unsolicited IOCB. The ELS command from the unsolicited - * IOCB is then used to invoke the proper routine and to set up proper state - * of the discovery state machine. - **/ static void lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb) @@ -5276,6 +4059,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } phba->fc_stat.elsRcvFrame++; + if (elsiocb->context1) + lpfc_nlp_put(elsiocb->context1); elsiocb->context1 = lpfc_nlp_get(ndlp); elsiocb->vport = vport; @@ -5296,7 +4081,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, phba->fc_stat.elsRcvPLOGI++; ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); - lpfc_send_els_event(vport, ndlp, cmd); if (vport->port_state < LPFC_DISC_AUTH) { if (!(phba->pport->fc_flag & FC_PT2PT) || (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { @@ -5346,7 +4130,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, did, vport->port_state, ndlp->nlp_flag); phba->fc_stat.elsRcvPRLO++; - lpfc_send_els_event(vport, ndlp, cmd); if (vport->port_state < LPFC_DISC_AUTH) { rjt_err = LSRJT_UNABLE_TPC; break; @@ -5364,7 +4147,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, "RCV ADISC: did:x%x/ste:x%x flg:x%x", did, vport->port_state, ndlp->nlp_flag); - lpfc_send_els_event(vport, ndlp, cmd); phba->fc_stat.elsRcvADISC++; if (vport->port_state < LPFC_DISC_AUTH) { rjt_err = LSRJT_UNABLE_TPC; @@ -5488,8 +4270,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, NULL); } - lpfc_nlp_put(elsiocb->context1); - elsiocb->context1 = NULL; return; dropit: @@ -5502,19 +4282,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, phba->fc_stat.elsRcvDrop++; } -/** - * lpfc_find_vport_by_vpid: Find a vport on a HBA through vport identifier. - * @phba: pointer to lpfc hba data structure. - * @vpi: host virtual N_Port identifier. - * - * This routine finds a vport on a HBA (referred by @phba) through a - * @vpi. The function walks the HBA's vport list and returns the address - * of the vport with the matching @vpi. - * - * Return code - * NULL - No vport with the matching @vpi found - * Otherwise - Address to the vport with the matching @vpi. - **/ static struct lpfc_vport * lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) { @@ -5532,18 +4299,6 @@ lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) return NULL; } -/** - * lpfc_els_unsol_event: Process an unsolicited event from an els sli ring. - * @phba: pointer to lpfc hba data structure. - * @pring: pointer to a SLI ring. - * @elsiocb: pointer to lpfc els iocb data structure. - * - * This routine is used to process an unsolicited event received from a SLI - * (Service Level Interface) ring. The actual processing of the data buffer - * associated with the unsolicited event is done by invoking the routine - * lpfc_els_unsol_buffer() after properly set up the iocb buffer from the - * SLI ring on which the unsolicited event was received. - **/ void lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *elsiocb) @@ -5554,7 +4309,6 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_dmabuf *bdeBuf1 = elsiocb->context2; struct lpfc_dmabuf *bdeBuf2 = elsiocb->context3; - elsiocb->context1 = NULL; elsiocb->context2 = NULL; elsiocb->context3 = NULL; @@ -5602,6 +4356,8 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, * The different unsolicited event handlers would tell us * if they are done with "mp" by setting context2 to NULL. */ + lpfc_nlp_put(elsiocb->context1); + elsiocb->context1 = NULL; if (elsiocb->context2) { lpfc_in_buf_free(phba, (struct lpfc_dmabuf *)elsiocb->context2); elsiocb->context2 = NULL; @@ -5620,19 +4376,6 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } } -/** - * lpfc_do_scr_ns_plogi: Issue a plogi to the name server for scr. - * @phba: pointer to lpfc hba data structure. - * @vport: pointer to a virtual N_Port data structure. - * - * This routine issues a Port Login (PLOGI) to the Name Server with - * State Change Request (SCR) for a @vport. This routine will create an - * ndlp for the Name Server associated to the @vport if such node does - * not already exist. The PLOGI to Name Server is issued by invoking the - * lpfc_issue_els_plogi() routine. If Fabric-Device Management Interface - * (FDMI) is configured to the @vport, a FDMI node will be created and - * the PLOGI to FDMI is issued by invoking lpfc_issue_els_plogi() routine. - **/ void lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) { @@ -5691,18 +4434,6 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) return; } -/** - * lpfc_cmpl_reg_new_vport: Completion callback function to register new vport. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * This routine is the completion callback function to register new vport - * mailbox command. If the new vport mailbox command completes successfully, - * the fabric registration login shall be performed on physical port (the - * new vport created is actually a physical port, with VPI 0) or the port - * login to Name Server for State Change Request (SCR) will be performed - * on virtual port (real virtual port, with VPI greater than 0). - **/ static void lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) { @@ -5760,15 +4491,6 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) return; } -/** - * lpfc_register_new_vport: Register a new vport with a HBA. - * @phba: pointer to lpfc hba data structure. - * @vport: pointer to a host virtual N_Port data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine registers the @vport as a new virtual port with a HBA. - * It is done through a registering vpi mailbox command. - **/ static void lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) @@ -5809,26 +4531,6 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, return; } -/** - * lpfc_cmpl_els_fdisc: Completion function for fdisc iocb command. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine is the completion callback function to a Fabric Discover - * (FDISC) ELS command. Since all the FDISC ELS commands are issued - * single threaded, each FDISC completion callback function will reset - * the discovery timer for all vports such that the timers will not get - * unnecessary timeout. The function checks the FDISC IOCB status. If error - * detected, the vport will be set to FC_VPORT_FAILED state. Otherwise,the - * vport will set to FC_VPORT_ACTIVE state. It then checks whether the DID - * assigned to the vport has been changed with the completion of the FDISC - * command. If so, both RPI (Remote Port Index) and VPI (Virtual Port Index) - * are unregistered from the HBA, and then the lpfc_register_new_vport() - * routine is invoked to register new vport with the HBA. Otherwise, the - * lpfc_do_scr_ns_plogi() routine is invoked to issue a PLOGI to the Name - * Server for State Change Request (SCR). - **/ static void lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -5863,80 +4565,58 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, goto out; /* FDISC failed */ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, - "0126 FDISC failed. (%d/%d)\n", + "0124 FDISC failed. (%d/%d)\n", irsp->ulpStatus, irsp->un.ulpWord[4]); - goto fdisc_failed; - } if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING) lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_nlp_put(ndlp); /* giving up on FDISC. Cancel discovery timer */ lpfc_can_disctmo(vport); - spin_lock_irq(shost->host_lock); - vport->fc_flag |= FC_FABRIC; - if (vport->phba->fc_topology == TOPOLOGY_LOOP) - vport->fc_flag |= FC_PUBLIC_LOOP; - spin_unlock_irq(shost->host_lock); + } else { + spin_lock_irq(shost->host_lock); + vport->fc_flag |= FC_FABRIC; + if (vport->phba->fc_topology == TOPOLOGY_LOOP) + vport->fc_flag |= FC_PUBLIC_LOOP; + spin_unlock_irq(shost->host_lock); - vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID; - lpfc_vport_set_state(vport, FC_VPORT_ACTIVE); - if ((vport->fc_prevDID != vport->fc_myDID) && - !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) { - /* If our NportID changed, we need to ensure all - * remaining NPORTs get unreg_login'ed so we can - * issue unreg_vpi. - */ - list_for_each_entry_safe(np, next_np, - &vport->fc_nodes, nlp_listp) { - if (!NLP_CHK_NODE_ACT(ndlp) || - (np->nlp_state != NLP_STE_NPR_NODE) || - !(np->nlp_flag & NLP_NPR_ADISC)) - continue; + vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID; + lpfc_vport_set_state(vport, FC_VPORT_ACTIVE); + if ((vport->fc_prevDID != vport->fc_myDID) && + !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) { + /* If our NportID changed, we need to ensure all + * remaining NPORTs get unreg_login'ed so we can + * issue unreg_vpi. + */ + list_for_each_entry_safe(np, next_np, + &vport->fc_nodes, nlp_listp) { + if (!NLP_CHK_NODE_ACT(ndlp) || + (np->nlp_state != NLP_STE_NPR_NODE) || + !(np->nlp_flag & NLP_NPR_ADISC)) + continue; + spin_lock_irq(shost->host_lock); + np->nlp_flag &= ~NLP_NPR_ADISC; + spin_unlock_irq(shost->host_lock); + lpfc_unreg_rpi(vport, np); + } + lpfc_mbx_unreg_vpi(vport); spin_lock_irq(shost->host_lock); - np->nlp_flag &= ~NLP_NPR_ADISC; + vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; spin_unlock_irq(shost->host_lock); - lpfc_unreg_rpi(vport, np); } - lpfc_mbx_unreg_vpi(vport); - spin_lock_irq(shost->host_lock); - vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; - spin_unlock_irq(shost->host_lock); + + if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) + lpfc_register_new_vport(phba, vport, ndlp); + else + lpfc_do_scr_ns_plogi(phba, vport); + + /* Unconditionaly kick off releasing fabric node for vports */ + lpfc_nlp_put(ndlp); } - if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) - lpfc_register_new_vport(phba, vport, ndlp); - else - lpfc_do_scr_ns_plogi(phba, vport); - goto out; -fdisc_failed: - lpfc_vport_set_state(vport, FC_VPORT_FAILED); - /* Cancel discovery timer */ - lpfc_can_disctmo(vport); - lpfc_nlp_put(ndlp); out: lpfc_els_free_iocb(phba, cmdiocb); } -/** - * lpfc_issue_els_fdisc: Issue a fdisc iocb command. - * @vport: pointer to a virtual N_Port data structure. - * @ndlp: pointer to a node-list data structure. - * @retry: number of retries to the command IOCB. - * - * This routine prepares and issues a Fabric Discover (FDISC) IOCB to - * a remote node (@ndlp) off a @vport. It uses the lpfc_issue_fabric_iocb() - * routine to issue the IOCB, which makes sure only one outstanding fabric - * IOCB will be sent off HBA at any given time. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the FDISC ELS command. - * - * Return code - * 0 - Successfully issued fdisc iocb command - * 1 - Failed to issue fdisc iocb command - **/ static int lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, uint8_t retry) @@ -6011,20 +4691,6 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 0; } -/** - * lpfc_cmpl_els_npiv_logo: Completion function with vport logo. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine is the completion callback function to the issuing of a LOGO - * ELS command off a vport. It frees the command IOCB and then decrement the - * reference count held on ndlp for this completion function, indicating that - * the reference to the ndlp is no long needed. Note that the - * lpfc_els_free_iocb() routine decrements the ndlp reference held for this - * callback function and an additional explicit ndlp reference decrementation - * will trigger the actual release of the ndlp. - **/ static void lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -6046,22 +4712,6 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_nlp_put(ndlp); } -/** - * lpfc_issue_els_npiv_logo: Issue a logo off a vport. - * @vport: pointer to a virtual N_Port data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine issues a LOGO ELS command to an @ndlp off a @vport. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the LOGO ELS command. - * - * Return codes - * 0 - Successfully issued logo off the @vport - * 1 - Failed to issue logo off the @vport - **/ int lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { @@ -6107,17 +4757,6 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) return 0; } -/** - * lpfc_fabric_block_timeout: Handler function to the fabric block timer. - * @ptr: holder for the timer function associated data. - * - * This routine is invoked by the fabric iocb block timer after - * timeout. It posts the fabric iocb block timeout event by setting the - * WORKER_FABRIC_BLOCK_TMO bit to work port event bitmap and then invokes - * lpfc_worker_wake_up() routine to wake up the worker thread. It is for - * the worker thread to invoke the lpfc_unblock_fabric_iocbs() on the - * posted event WORKER_FABRIC_BLOCK_TMO. - **/ void lpfc_fabric_block_timeout(unsigned long ptr) { @@ -6136,16 +4775,6 @@ lpfc_fabric_block_timeout(unsigned long ptr) return; } -/** - * lpfc_resume_fabric_iocbs: Issue a fabric iocb from driver internal list. - * @phba: pointer to lpfc hba data structure. - * - * This routine issues one fabric iocb from the driver internal list to - * the HBA. It first checks whether it's ready to issue one fabric iocb to - * the HBA (whether there is no outstanding fabric iocb). If so, it shall - * remove one pending fabric iocb from the driver internal list and invokes - * lpfc_sli_issue_iocb() routine to send the fabric iocb to the HBA. - **/ static void lpfc_resume_fabric_iocbs(struct lpfc_hba *phba) { @@ -6195,15 +4824,6 @@ lpfc_resume_fabric_iocbs(struct lpfc_hba *phba) return; } -/** - * lpfc_unblock_fabric_iocbs: Unblock issuing fabric iocb command. - * @phba: pointer to lpfc hba data structure. - * - * This routine unblocks the issuing fabric iocb command. The function - * will clear the fabric iocb block bit and then invoke the routine - * lpfc_resume_fabric_iocbs() to issue one of the pending fabric iocb - * from the driver internal fabric iocb list. - **/ void lpfc_unblock_fabric_iocbs(struct lpfc_hba *phba) { @@ -6213,15 +4833,6 @@ lpfc_unblock_fabric_iocbs(struct lpfc_hba *phba) return; } -/** - * lpfc_block_fabric_iocbs: Block issuing fabric iocb command. - * @phba: pointer to lpfc hba data structure. - * - * This routine blocks the issuing fabric iocb for a specified amount of - * time (currently 100 ms). This is done by set the fabric iocb block bit - * and set up a timeout timer for 100ms. When the block bit is set, no more - * fabric iocb will be issued out of the HBA. - **/ static void lpfc_block_fabric_iocbs(struct lpfc_hba *phba) { @@ -6235,19 +4846,6 @@ lpfc_block_fabric_iocbs(struct lpfc_hba *phba) return; } -/** - * lpfc_cmpl_fabric_iocb: Completion callback function for fabric iocb. - * @phba: pointer to lpfc hba data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @rspiocb: pointer to lpfc response iocb data structure. - * - * This routine is the callback function that is put to the fabric iocb's - * callback function pointer (iocb->iocb_cmpl). The original iocb's callback - * function pointer has been stored in iocb->fabric_iocb_cmpl. This callback - * function first restores and invokes the original iocb's callback function - * and then invokes the lpfc_resume_fabric_iocbs() routine to issue the next - * fabric bound iocb from the driver internal fabric iocb list onto the wire. - **/ static void lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -6294,30 +4892,6 @@ lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } } -/** - * lpfc_issue_fabric_iocb: Issue a fabric iocb command. - * @phba: pointer to lpfc hba data structure. - * @iocb: pointer to lpfc command iocb data structure. - * - * This routine is used as the top-level API for issuing a fabric iocb command - * such as FLOGI and FDISC. To accommodate certain switch fabric, this driver - * function makes sure that only one fabric bound iocb will be outstanding at - * any given time. As such, this function will first check to see whether there - * is already an outstanding fabric iocb on the wire. If so, it will put the - * newly issued iocb onto the driver internal fabric iocb list, waiting to be - * issued later. Otherwise, it will issue the iocb on the wire and update the - * fabric iocb count it indicate that there is one fabric iocb on the wire. - * - * Note, this implementation has a potential sending out fabric IOCBs out of - * order. The problem is caused by the construction of the "ready" boolen does - * not include the condition that the internal fabric IOCB list is empty. As - * such, it is possible a fabric IOCB issued by this routine might be "jump" - * ahead of the fabric IOCBs in the internal list. - * - * Return code - * IOCB_SUCCESS - either fabric iocb put on the list or issued successfully - * IOCB_ERROR - failed to issue fabric iocb - **/ static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) { @@ -6363,17 +4937,7 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) return ret; } -/** - * lpfc_fabric_abort_vport: Abort a vport's iocbs from driver fabric iocb list. - * @vport: pointer to a virtual N_Port data structure. - * - * This routine aborts all the IOCBs associated with a @vport from the - * driver internal fabric IOCB list. The list contains fabric IOCBs to be - * issued to the ELS IOCB ring. This abort function walks the fabric IOCB - * list, removes each IOCB associated with the @vport off the list, set the - * status feild to IOSTAT_LOCAL_REJECT, and invokes the callback function - * associated with the IOCB. - **/ + static void lpfc_fabric_abort_vport(struct lpfc_vport *vport) { LIST_HEAD(completions); @@ -6403,17 +4967,6 @@ static void lpfc_fabric_abort_vport(struct lpfc_vport *vport) } } -/** - * lpfc_fabric_abort_nport: Abort a ndlp's iocbs from driver fabric iocb list. - * @ndlp: pointer to a node-list data structure. - * - * This routine aborts all the IOCBs associated with an @ndlp from the - * driver internal fabric IOCB list. The list contains fabric IOCBs to be - * issued to the ELS IOCB ring. This abort function walks the fabric IOCB - * list, removes each IOCB associated with the @ndlp off the list, set the - * status feild to IOSTAT_LOCAL_REJECT, and invokes the callback function - * associated with the IOCB. - **/ void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp) { LIST_HEAD(completions); @@ -6443,17 +4996,6 @@ void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp) } } -/** - * lpfc_fabric_abort_hba: Abort all iocbs on driver fabric iocb list. - * @phba: pointer to lpfc hba data structure. - * - * This routine aborts all the IOCBs currently on the driver internal - * fabric IOCB list. The list contains fabric IOCBs to be issued to the ELS - * IOCB ring. This function takes the entire IOCB list off the fabric IOCB - * list, removes IOCBs off the list, set the status feild to - * IOSTAT_LOCAL_REJECT, and invokes the callback function associated with - * the IOCB. - **/ void lpfc_fabric_abort_hba(struct lpfc_hba *phba) { LIST_HEAD(completions); diff --git a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c index a1a70d9ffc2a..a98d11bf3576 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -30,7 +30,6 @@ #include #include "lpfc_hw.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_sli.h" #include "lpfc_scsi.h" @@ -89,6 +88,14 @@ lpfc_terminate_rport_io(struct fc_rport *rport) &phba->sli.ring[phba->sli.fcp_ring], ndlp->nlp_sid, 0, LPFC_CTX_TGT); } + + /* + * A device is normally blocked for rediscovery and unblocked when + * devloss timeout happens. In case a vport is removed or driver + * unloaded before devloss timeout happens, we need to unblock here. + */ + scsi_target_unblock(&rport->dev); + return; } /* @@ -208,16 +215,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) return; } - if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) { - lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "0284 Devloss timeout Ignored on " - "WWPN %x:%x:%x:%x:%x:%x:%x:%x " - "NPort x%x\n", - *name, *(name+1), *(name+2), *(name+3), - *(name+4), *(name+5), *(name+6), *(name+7), - ndlp->nlp_DID); + if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) return; - } if (ndlp->nlp_type & NLP_FABRIC) { /* We will clean up these Nodes in linkup */ @@ -238,6 +237,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], ndlp->nlp_sid, 0, LPFC_CTX_TGT); } + if (vport->load_flag & FC_UNLOADING) + warn_on = 0; if (warn_on) { lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, @@ -275,124 +276,6 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); } -/** - * lpfc_alloc_fast_evt: Allocates data structure for posting event. - * @phba: Pointer to hba context object. - * - * This function is called from the functions which need to post - * events from interrupt context. This function allocates data - * structure required for posting event. It also keeps track of - * number of events pending and prevent event storm when there are - * too many events. - **/ -struct lpfc_fast_path_event * -lpfc_alloc_fast_evt(struct lpfc_hba *phba) { - struct lpfc_fast_path_event *ret; - - /* If there are lot of fast event do not exhaust memory due to this */ - if (atomic_read(&phba->fast_event_count) > LPFC_MAX_EVT_COUNT) - return NULL; - - ret = kzalloc(sizeof(struct lpfc_fast_path_event), - GFP_ATOMIC); - if (ret) - atomic_inc(&phba->fast_event_count); - INIT_LIST_HEAD(&ret->work_evt.evt_listp); - ret->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT; - return ret; -} - -/** - * lpfc_free_fast_evt: Frees event data structure. - * @phba: Pointer to hba context object. - * @evt: Event object which need to be freed. - * - * This function frees the data structure required for posting - * events. - **/ -void -lpfc_free_fast_evt(struct lpfc_hba *phba, - struct lpfc_fast_path_event *evt) { - - atomic_dec(&phba->fast_event_count); - kfree(evt); -} - -/** - * lpfc_send_fastpath_evt: Posts events generated from fast path. - * @phba: Pointer to hba context object. - * @evtp: Event data structure. - * - * This function is called from worker thread, when the interrupt - * context need to post an event. This function posts the event - * to fc transport netlink interface. - **/ -static void -lpfc_send_fastpath_evt(struct lpfc_hba *phba, - struct lpfc_work_evt *evtp) -{ - unsigned long evt_category, evt_sub_category; - struct lpfc_fast_path_event *fast_evt_data; - char *evt_data; - uint32_t evt_data_size; - struct Scsi_Host *shost; - - fast_evt_data = container_of(evtp, struct lpfc_fast_path_event, - work_evt); - - evt_category = (unsigned long) fast_evt_data->un.fabric_evt.event_type; - evt_sub_category = (unsigned long) fast_evt_data->un. - fabric_evt.subcategory; - shost = lpfc_shost_from_vport(fast_evt_data->vport); - if (evt_category == FC_REG_FABRIC_EVENT) { - if (evt_sub_category == LPFC_EVENT_FCPRDCHKERR) { - evt_data = (char *) &fast_evt_data->un.read_check_error; - evt_data_size = sizeof(fast_evt_data->un. - read_check_error); - } else if ((evt_sub_category == LPFC_EVENT_FABRIC_BUSY) || - (evt_sub_category == IOSTAT_NPORT_BSY)) { - evt_data = (char *) &fast_evt_data->un.fabric_evt; - evt_data_size = sizeof(fast_evt_data->un.fabric_evt); - } else { - lpfc_free_fast_evt(phba, fast_evt_data); - return; - } - } else if (evt_category == FC_REG_SCSI_EVENT) { - switch (evt_sub_category) { - case LPFC_EVENT_QFULL: - case LPFC_EVENT_DEVBSY: - evt_data = (char *) &fast_evt_data->un.scsi_evt; - evt_data_size = sizeof(fast_evt_data->un.scsi_evt); - break; - case LPFC_EVENT_CHECK_COND: - evt_data = (char *) &fast_evt_data->un.check_cond_evt; - evt_data_size = sizeof(fast_evt_data->un. - check_cond_evt); - break; - case LPFC_EVENT_VARQUEDEPTH: - evt_data = (char *) &fast_evt_data->un.queue_depth_evt; - evt_data_size = sizeof(fast_evt_data->un. - queue_depth_evt); - break; - default: - lpfc_free_fast_evt(phba, fast_evt_data); - return; - } - } else { - lpfc_free_fast_evt(phba, fast_evt_data); - return; - } - - fc_host_post_vendor_event(shost, - fc_get_event_number(), - evt_data_size, - evt_data, - SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); - - lpfc_free_fast_evt(phba, fast_evt_data); - return; -} - static void lpfc_work_list_done(struct lpfc_hba *phba) { @@ -464,10 +347,6 @@ lpfc_work_list_done(struct lpfc_hba *phba) lpfc_unblock_mgmt_io(phba); complete((struct completion *)(evtp->evt_arg2)); break; - case LPFC_EVT_FASTPATH_MGMT_EVT: - lpfc_send_fastpath_evt(phba, evtp); - free_evt = 0; - break; } if (free_evt) kfree(evtp); @@ -492,7 +371,6 @@ lpfc_work_done(struct lpfc_hba *phba) spin_unlock_irq(&phba->hbalock); if (ha_copy & HA_ERATT) - /* Handle the error attention event */ lpfc_handle_eratt(phba); if (ha_copy & HA_MBATT) @@ -500,7 +378,6 @@ lpfc_work_done(struct lpfc_hba *phba) if (ha_copy & HA_LATT) lpfc_handle_latt(phba); - vports = lpfc_create_vport_work_array(phba); if (vports != NULL) for(i = 0; i <= phba->max_vpi; i++) { @@ -1136,10 +1013,14 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) } static void -lpfc_enable_la(struct lpfc_hba *phba) +lpfc_mbx_issue_link_down(struct lpfc_hba *phba) { uint32_t control; struct lpfc_sli *psli = &phba->sli; + + lpfc_linkdown(phba); + + /* turn on Link Attention interrupts - no CLEAR_LA needed */ spin_lock_irq(&phba->hbalock); psli->sli_flag |= LPFC_PROCESS_LA; control = readl(phba->HCregaddr); @@ -1149,15 +1030,6 @@ lpfc_enable_la(struct lpfc_hba *phba) spin_unlock_irq(&phba->hbalock); } -static void -lpfc_mbx_issue_link_down(struct lpfc_hba *phba) -{ - lpfc_linkdown(phba); - lpfc_enable_la(phba); - /* turn on Link Attention interrupts - no CLEAR_LA needed */ -} - - /* * This routine handles processing a READ_LA mailbox * command upon completion. It is setup in the LPFC_MBOXQ @@ -1205,12 +1077,8 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) } phba->fc_eventTag = la->eventTag; - if (la->mm) - phba->sli.sli_flag |= LPFC_MENLO_MAINT; - else - phba->sli.sli_flag &= ~LPFC_MENLO_MAINT; - if (la->attType == AT_LINK_UP && (!la->mm)) { + if (la->attType == AT_LINK_UP) { phba->fc_stat.LinkUp++; if (phba->link_flag & LS_LOOPBACK_MODE) { lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, @@ -1222,15 +1090,13 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) } else { lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, "1303 Link Up Event x%x received " - "Data: x%x x%x x%x x%x x%x x%x %d\n", + "Data: x%x x%x x%x x%x\n", la->eventTag, phba->fc_eventTag, la->granted_AL_PA, la->UlnkSpeed, - phba->alpa_map[0], - la->mm, la->fa, - phba->wait_4_mlo_maint_flg); + phba->alpa_map[0]); } lpfc_mbx_process_link_up(phba, la); - } else if (la->attType == AT_LINK_DOWN) { + } else { phba->fc_stat.LinkDown++; if (phba->link_flag & LS_LOOPBACK_MODE) { lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, @@ -1243,46 +1109,11 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) else { lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, "1305 Link Down Event x%x received " - "Data: x%x x%x x%x x%x x%x\n", - la->eventTag, phba->fc_eventTag, - phba->pport->port_state, vport->fc_flag, - la->mm, la->fa); - } - lpfc_mbx_issue_link_down(phba); - } - if (la->mm && la->attType == AT_LINK_UP) { - if (phba->link_state != LPFC_LINK_DOWN) { - phba->fc_stat.LinkDown++; - lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, - "1312 Link Down Event x%x received " - "Data: x%x x%x x%x\n", - la->eventTag, phba->fc_eventTag, - phba->pport->port_state, vport->fc_flag); - lpfc_mbx_issue_link_down(phba); - } else - lpfc_enable_la(phba); - - lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, - "1310 Menlo Maint Mode Link up Event x%x rcvd " "Data: x%x x%x x%x\n", la->eventTag, phba->fc_eventTag, phba->pport->port_state, vport->fc_flag); - /* - * The cmnd that triggered this will be waiting for this - * signal. - */ - /* WAKEUP for MENLO_SET_MODE or MENLO_RESET command. */ - if (phba->wait_4_mlo_maint_flg) { - phba->wait_4_mlo_maint_flg = 0; - wake_up_interruptible(&phba->wait_4_mlo_m_q); } - } - - if (la->fa) { - if (la->mm) - lpfc_issue_clear_la(phba, vport); - lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, - "1311 fa %d\n", la->fa); + lpfc_mbx_issue_link_down(phba); } lpfc_mbx_cmpl_read_la_free_mbuf: @@ -1346,7 +1177,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) scsi_host_put(shost); } -int +void lpfc_mbx_unreg_vpi(struct lpfc_vport *vport) { struct lpfc_hba *phba = vport->phba; @@ -1355,7 +1186,7 @@ lpfc_mbx_unreg_vpi(struct lpfc_vport *vport) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) - return 1; + return; lpfc_unreg_vpi(phba, vport->vpi, mbox); mbox->vport = vport; @@ -1366,9 +1197,7 @@ lpfc_mbx_unreg_vpi(struct lpfc_vport *vport) "1800 Could not issue unreg_vpi\n"); mempool_free(mbox, phba->mbox_mem_pool); vport->unreg_vpi_cmpl = VPORT_ERROR; - return rc; } - return 0; } static void @@ -1724,22 +1553,6 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, */ lpfc_register_remote_port(vport, ndlp); } - if ((new_state == NLP_STE_MAPPED_NODE) && - (vport->stat_data_enabled)) { - /* - * A new target is discovered, if there is no buffer for - * statistical data collection allocate buffer. - */ - ndlp->lat_data = kcalloc(LPFC_MAX_BUCKET_COUNT, - sizeof(struct lpfc_scsicmd_bkt), - GFP_KERNEL); - - if (!ndlp->lat_data) - lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE, - "0286 lpfc_nlp_state_cleanup failed to " - "allocate statistical data buffer DID " - "0x%x\n", ndlp->nlp_DID); - } /* * if we added to Mapped list, but the remote port * registration failed or assigned a target id outside @@ -2973,7 +2786,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) default: lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, - "0273 Unexpected discovery timeout, " + "0229 Unexpected discovery timeout, " "vport State x%x\n", vport->port_state); break; } @@ -3127,8 +2940,6 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, INIT_LIST_HEAD(&ndlp->nlp_listp); kref_init(&ndlp->kref); NLP_INT_NODE_ACT(ndlp); - atomic_set(&ndlp->cmd_pending, 0); - ndlp->cmd_qdepth = LPFC_MAX_TGT_QDEPTH; lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE, "node init: did:x%x", @@ -3168,10 +2979,8 @@ lpfc_nlp_release(struct kref *kref) spin_unlock_irqrestore(&phba->ndlp_lock, flags); /* free ndlp memory for final ndlp release */ - if (NLP_CHK_FREE_REQ(ndlp)) { - kfree(ndlp->lat_data); + if (NLP_CHK_FREE_REQ(ndlp)) mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool); - } } /* This routine bumps the reference count for a ndlp structure to ensure diff --git a/trunk/drivers/scsi/lpfc/lpfc_hw.h b/trunk/drivers/scsi/lpfc/lpfc_hw.h index 5de5dabbbee6..7773b949aa7c 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hw.h +++ b/trunk/drivers/scsi/lpfc/lpfc_hw.h @@ -1107,8 +1107,6 @@ typedef struct { /* Start FireFly Register definitions */ #define PCI_VENDOR_ID_EMULEX 0x10df #define PCI_DEVICE_ID_FIREFLY 0x1ae5 -#define PCI_DEVICE_ID_PROTEUS_VF 0xe100 -#define PCI_DEVICE_ID_PROTEUS_PF 0xe180 #define PCI_DEVICE_ID_SAT_SMB 0xf011 #define PCI_DEVICE_ID_SAT_MID 0xf015 #define PCI_DEVICE_ID_RFLY 0xf095 @@ -1135,12 +1133,10 @@ typedef struct { #define PCI_DEVICE_ID_LP11000S 0xfc10 #define PCI_DEVICE_ID_LPE11000S 0xfc20 #define PCI_DEVICE_ID_SAT_S 0xfc40 -#define PCI_DEVICE_ID_PROTEUS_S 0xfc50 #define PCI_DEVICE_ID_HELIOS 0xfd00 #define PCI_DEVICE_ID_HELIOS_SCSP 0xfd11 #define PCI_DEVICE_ID_HELIOS_DCSP 0xfd12 #define PCI_DEVICE_ID_ZEPHYR 0xfe00 -#define PCI_DEVICE_ID_HORNET 0xfe05 #define PCI_DEVICE_ID_ZEPHYR_SCSP 0xfe11 #define PCI_DEVICE_ID_ZEPHYR_DCSP 0xfe12 @@ -1158,7 +1154,6 @@ typedef struct { #define ZEPHYR_JEDEC_ID 0x0577 #define VIPER_JEDEC_ID 0x4838 #define SATURN_JEDEC_ID 0x1004 -#define HORNET_JDEC_ID 0x2057706D #define JEDEC_ID_MASK 0x0FFFF000 #define JEDEC_ID_SHIFT 12 @@ -1203,18 +1198,6 @@ typedef struct { /* FireFly BIU registers */ #define HA_RXATT 0x00000008 /* Bit 3 */ #define HA_RXMASK 0x0000000f -#define HA_R0_CLR_MSK (HA_R0RE_REQ | HA_R0CE_RSP | HA_R0ATT) -#define HA_R1_CLR_MSK (HA_R1RE_REQ | HA_R1CE_RSP | HA_R1ATT) -#define HA_R2_CLR_MSK (HA_R2RE_REQ | HA_R2CE_RSP | HA_R2ATT) -#define HA_R3_CLR_MSK (HA_R3RE_REQ | HA_R3CE_RSP | HA_R3ATT) - -#define HA_R0_POS 3 -#define HA_R1_POS 7 -#define HA_R2_POS 11 -#define HA_R3_POS 15 -#define HA_LE_POS 29 -#define HA_MB_POS 30 -#define HA_ER_POS 31 /* Chip Attention Register */ #define CA_REG_OFFSET 4 /* Byte offset from register base address */ @@ -1252,7 +1235,7 @@ typedef struct { /* FireFly BIU registers */ /* Host Control Register */ -#define HC_REG_OFFSET 12 /* Byte offset from register base address */ +#define HC_REG_OFFSET 12 /* Word offset from register base address */ #define HC_MBINT_ENA 0x00000001 /* Bit 0 */ #define HC_R0INT_ENA 0x00000002 /* Bit 1 */ @@ -1265,19 +1248,6 @@ typedef struct { /* FireFly BIU registers */ #define HC_LAINT_ENA 0x20000000 /* Bit 29 */ #define HC_ERINT_ENA 0x80000000 /* Bit 31 */ -/* Message Signaled Interrupt eXtension (MSI-X) message identifiers */ -#define MSIX_DFLT_ID 0 -#define MSIX_RNG0_ID 0 -#define MSIX_RNG1_ID 1 -#define MSIX_RNG2_ID 2 -#define MSIX_RNG3_ID 3 - -#define MSIX_LINK_ID 4 -#define MSIX_MBOX_ID 5 - -#define MSIX_SPARE0_ID 6 -#define MSIX_SPARE1_ID 7 - /* Mailbox Commands */ #define MBX_SHUTDOWN 0x00 /* terminate testing */ #define MBX_LOAD_SM 0x01 @@ -1315,14 +1285,10 @@ typedef struct { /* FireFly BIU registers */ #define MBX_KILL_BOARD 0x24 #define MBX_CONFIG_FARP 0x25 #define MBX_BEACON 0x2A -#define MBX_CONFIG_MSI 0x30 #define MBX_HEARTBEAT 0x31 #define MBX_WRITE_VPARMS 0x32 #define MBX_ASYNCEVT_ENABLE 0x33 -#define MBX_PORT_CAPABILITIES 0x3B -#define MBX_PORT_IOV_CONTROL 0x3C - #define MBX_CONFIG_HBQ 0x7C #define MBX_LOAD_AREA 0x81 #define MBX_RUN_BIU_DIAG64 0x84 @@ -1508,18 +1474,24 @@ struct ulp_bde64 { /* SLI-2 */ uint32_t bdeFlags:8; /* BDE Flags 0 IS A SUPPORTED VALUE !! */ #endif -#define BUFF_TYPE_BDE_64 0x00 /* BDE (Host_resident) */ -#define BUFF_TYPE_BDE_IMMED 0x01 /* Immediate Data BDE */ -#define BUFF_TYPE_BDE_64P 0x02 /* BDE (Port-resident) */ -#define BUFF_TYPE_BDE_64I 0x08 /* Input BDE (Host-resident) */ -#define BUFF_TYPE_BDE_64IP 0x0A /* Input BDE (Port-resident) */ -#define BUFF_TYPE_BLP_64 0x40 /* BLP (Host-resident) */ -#define BUFF_TYPE_BLP_64P 0x42 /* BLP (Port-resident) */ + +#define BUFF_USE_RSVD 0x01 /* bdeFlags */ +#define BUFF_USE_INTRPT 0x02 /* Not Implemented with LP6000 */ +#define BUFF_USE_CMND 0x04 /* Optional, 1=cmd/rsp 0=data buffer */ +#define BUFF_USE_RCV 0x08 /* "" "", 1=rcv buffer, 0=xmit + buffer */ +#define BUFF_TYPE_32BIT 0x10 /* "" "", 1=32 bit addr 0=64 bit + addr */ +#define BUFF_TYPE_SPECIAL 0x20 /* Not Implemented with LP6000 */ +#define BUFF_TYPE_BDL 0x40 /* Optional, may be set in BDL */ +#define BUFF_TYPE_INVALID 0x80 /* "" "" */ } f; } tus; uint32_t addrLow; uint32_t addrHigh; }; +#define BDE64_SIZE_WORD 0 +#define BPL64_SIZE_WORD 0x40 typedef struct ULP_BDL { /* SLI-2 */ #ifdef __BIG_ENDIAN_BITFIELD @@ -2229,10 +2201,7 @@ typedef struct { typedef struct { uint32_t eventTag; /* Event tag */ #ifdef __BIG_ENDIAN_BITFIELD - uint32_t rsvd1:19; - uint32_t fa:1; - uint32_t mm:1; /* Menlo Maintenance mode enabled */ - uint32_t rx:1; + uint32_t rsvd1:22; uint32_t pb:1; uint32_t il:1; uint32_t attType:8; @@ -2240,10 +2209,7 @@ typedef struct { uint32_t attType:8; uint32_t il:1; uint32_t pb:1; - uint32_t rx:1; - uint32_t mm:1; - uint32_t fa:1; - uint32_t rsvd1:19; + uint32_t rsvd1:22; #endif #define AT_RESERVED 0x00 /* Reserved - attType */ @@ -2264,7 +2230,6 @@ typedef struct { #define TOPOLOGY_PT_PT 0x01 /* Topology is pt-pt / pt-fabric */ #define TOPOLOGY_LOOP 0x02 /* Topology is FC-AL */ -#define TOPOLOGY_LNK_MENLO_MAINTENANCE 0x05 /* maint mode zephtr to menlo */ union { struct ulp_bde lilpBde; /* This BDE points to a 128 byte buffer @@ -2359,36 +2324,6 @@ typedef struct { #define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */ #define DMP_RSP_SIZE 0x6C /* maximum of 27 words of rsp data */ -/* Structure for MB Command UPDATE_CFG (0x1B) */ - -struct update_cfg_var { -#ifdef __BIG_ENDIAN_BITFIELD - uint32_t rsvd2:16; - uint32_t type:8; - uint32_t rsvd:1; - uint32_t ra:1; - uint32_t co:1; - uint32_t cv:1; - uint32_t req:4; - uint32_t entry_length:16; - uint32_t region_id:16; -#else /* __LITTLE_ENDIAN_BITFIELD */ - uint32_t req:4; - uint32_t cv:1; - uint32_t co:1; - uint32_t ra:1; - uint32_t rsvd:1; - uint32_t type:8; - uint32_t rsvd2:16; - uint32_t region_id:16; - uint32_t entry_length:16; -#endif - - uint32_t resp_info; - uint32_t byte_cnt; - uint32_t data_offset; -}; - struct hbq_mask { #ifdef __BIG_ENDIAN_BITFIELD uint8_t tmatch; @@ -2625,40 +2560,6 @@ typedef struct { } CONFIG_PORT_VAR; -/* Structure for MB Command CONFIG_MSI (0x30) */ -struct config_msi_var { -#ifdef __BIG_ENDIAN_BITFIELD - uint32_t dfltMsgNum:8; /* Default message number */ - uint32_t rsvd1:11; /* Reserved */ - uint32_t NID:5; /* Number of secondary attention IDs */ - uint32_t rsvd2:5; /* Reserved */ - uint32_t dfltPresent:1; /* Default message number present */ - uint32_t addFlag:1; /* Add association flag */ - uint32_t reportFlag:1; /* Report association flag */ -#else /* __LITTLE_ENDIAN_BITFIELD */ - uint32_t reportFlag:1; /* Report association flag */ - uint32_t addFlag:1; /* Add association flag */ - uint32_t dfltPresent:1; /* Default message number present */ - uint32_t rsvd2:5; /* Reserved */ - uint32_t NID:5; /* Number of secondary attention IDs */ - uint32_t rsvd1:11; /* Reserved */ - uint32_t dfltMsgNum:8; /* Default message number */ -#endif - uint32_t attentionConditions[2]; - uint8_t attentionId[16]; - uint8_t messageNumberByHA[64]; - uint8_t messageNumberByID[16]; - uint32_t autoClearHA[2]; -#ifdef __BIG_ENDIAN_BITFIELD - uint32_t rsvd3:16; - uint32_t autoClearID:16; -#else /* __LITTLE_ENDIAN_BITFIELD */ - uint32_t autoClearID:16; - uint32_t rsvd3:16; -#endif - uint32_t rsvd4; -}; - /* SLI-2 Port Control Block */ /* SLIM POINTER */ @@ -2777,12 +2678,10 @@ typedef union { * NEW_FEATURE */ struct config_hbq_var varCfgHbq;/* cmd = 0x7c (CONFIG_HBQ) */ - struct update_cfg_var varUpdateCfg; /* cmd = 0x1B (UPDATE_CFG)*/ CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */ REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */ UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */ ASYNCEVT_ENABLE_VAR varCfgAsyncEvent; /*cmd = x33 (CONFIG_ASYNC) */ - struct config_msi_var varCfgMSI;/* cmd = x30 (CONFIG_MSI) */ } MAILVARIANTS; /* @@ -2816,19 +2715,11 @@ struct sli3_pgp { uint32_t hbq_get[16]; }; -struct sli3_inb_pgp { - uint32_t ha_copy; - uint32_t counter; - struct lpfc_pgp port[MAX_RINGS]; - uint32_t hbq_get[16]; -}; - -union sli_var { - struct sli2_desc s2; - struct sli3_desc s3; - struct sli3_pgp s3_pgp; - struct sli3_inb_pgp s3_inb_pgp; -}; +typedef union { + struct sli2_desc s2; + struct sli3_desc s3; + struct sli3_pgp s3_pgp; +} SLI_VAR; typedef struct { #ifdef __BIG_ENDIAN_BITFIELD @@ -2846,7 +2737,7 @@ typedef struct { #endif MAILVARIANTS un; - union sli_var us; + SLI_VAR us; } MAILBOX_t; /* @@ -3214,27 +3105,6 @@ struct que_xri64cx_ext_fields { struct lpfc_hbq_entry buff[5]; }; -#define LPFC_EXT_DATA_BDE_COUNT 3 -struct fcp_irw_ext { - uint32_t io_tag64_low; - uint32_t io_tag64_high; -#ifdef __BIG_ENDIAN_BITFIELD - uint8_t reserved1; - uint8_t reserved2; - uint8_t reserved3; - uint8_t ebde_count; -#else /* __LITTLE_ENDIAN */ - uint8_t ebde_count; - uint8_t reserved3; - uint8_t reserved2; - uint8_t reserved1; -#endif - uint32_t reserved4; - struct ulp_bde64 rbde; /* response bde */ - struct ulp_bde64 dbde[LPFC_EXT_DATA_BDE_COUNT]; /* data BDE or BPL */ - uint8_t icd[32]; /* immediate command data (32 bytes) */ -}; - typedef struct _IOCB { /* IOCB structure */ union { GENERIC_RSP grsp; /* Generic response */ @@ -3320,7 +3190,7 @@ typedef struct _IOCB { /* IOCB structure */ /* words 8-31 used for que_xri_cx iocb */ struct que_xri64cx_ext_fields que_xri64cx_ext_words; - struct fcp_irw_ext fcp_ext; + uint32_t sli3Words[24]; /* 96 extra bytes for SLI-3 */ } unsli3; @@ -3422,10 +3292,3 @@ lpfc_error_lost_link(IOCB_t *iocbp) iocbp->un.ulpWord[4] == IOERR_LINK_DOWN || iocbp->un.ulpWord[4] == IOERR_SLI_DOWN)); } - -#define MENLO_TRANSPORT_TYPE 0xfe -#define MENLO_CONTEXT 0 -#define MENLO_PU 3 -#define MENLO_TIMEOUT 30 -#define SETVAR_MLOMNT 0x103107 -#define SETVAR_MLORST 0x103007 diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index 909be3301bba..d51a2a4b43eb 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -36,7 +36,6 @@ #include "lpfc_hw.h" #include "lpfc_sli.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h" @@ -53,20 +52,17 @@ static struct scsi_transport_template *lpfc_transport_template = NULL; static struct scsi_transport_template *lpfc_vport_transport_template = NULL; static DEFINE_IDR(lpfc_hba_index); -/** - * lpfc_config_port_prep: Perform lpfc initialization prior to config port. - * @phba: pointer to lpfc hba data structure. - * - * This routine will do LPFC initialization prior to issuing the CONFIG_PORT - * mailbox command. It retrieves the revision information from the HBA and - * collects the Vital Product Data (VPD) about the HBA for preparing the - * configuration of the HBA. - * - * Return codes: - * 0 - success. - * -ERESTART - requests the SLI layer to reset the HBA and try again. - * Any other value - indicates an error. - **/ +/************************************************************************/ +/* */ +/* lpfc_config_port_prep */ +/* This routine will do LPFC initialization prior to the */ +/* CONFIG_PORT mailbox command. This will be initialized */ +/* as a SLI layer callback routine. */ +/* This routine returns 0 on success or -ERESTART if it wants */ +/* the SLI layer to reset the HBA and try again. Any */ +/* other return value indicates an error. */ +/* */ +/************************************************************************/ int lpfc_config_port_prep(struct lpfc_hba *phba) { @@ -184,9 +180,12 @@ lpfc_config_port_prep(struct lpfc_hba *phba) sizeof (phba->RandomData)); /* Get adapter VPD information */ + pmb->context2 = kmalloc(DMP_RSP_SIZE, GFP_KERNEL); + if (!pmb->context2) + goto out_free_mbox; lpfc_vpd_data = kmalloc(DMP_VPD_SIZE, GFP_KERNEL); if (!lpfc_vpd_data) - goto out_free_mbox; + goto out_free_context2; do { lpfc_dump_mem(phba, pmb, offset); @@ -201,29 +200,21 @@ lpfc_config_port_prep(struct lpfc_hba *phba) } if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset) mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset; - lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET, - lpfc_vpd_data + offset, + lpfc_sli_pcimem_bcopy(pmb->context2, lpfc_vpd_data + offset, mb->un.varDmp.word_cnt); offset += mb->un.varDmp.word_cnt; } while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE); lpfc_parse_vpd(phba, lpfc_vpd_data, offset); kfree(lpfc_vpd_data); +out_free_context2: + kfree(pmb->context2); out_free_mbox: mempool_free(pmb, phba->mbox_mem_pool); return 0; } -/** - * lpfc_config_async_cmpl: Completion handler for config async event mbox cmd. - * @phba: pointer to lpfc hba data structure. - * @pmboxq: pointer to the driver internal queue element for mailbox command. - * - * This is the completion handler for driver's configuring asynchronous event - * mailbox command to the device. If the mailbox command returns successfully, - * it will set internal async event support flag to 1; otherwise, it will - * set internal async event support flag to 0. - **/ +/* Completion handler for config async event mailbox command. */ static void lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) { @@ -235,19 +226,16 @@ lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) return; } -/** - * lpfc_config_port_post: Perform lpfc initialization after config port. - * @phba: pointer to lpfc hba data structure. - * - * This routine will do LPFC initialization after the CONFIG_PORT mailbox - * command call. It performs all internal resource and state setups on the - * port: post IOCB buffers, enable appropriate host interrupt attentions, - * ELS ring timers, etc. - * - * Return codes - * 0 - success. - * Any other value - error. - **/ +/************************************************************************/ +/* */ +/* lpfc_config_port_post */ +/* This routine will do LPFC initialization after the */ +/* CONFIG_PORT mailbox command. This will be initialized */ +/* as a SLI layer callback routine. */ +/* This routine returns 0 on success. Any other return value */ +/* indicates an error. */ +/* */ +/************************************************************************/ int lpfc_config_port_post(struct lpfc_hba *phba) { @@ -390,29 +378,6 @@ lpfc_config_port_post(struct lpfc_hba *phba) if (phba->sli_rev != 3) lpfc_post_rcv_buf(phba); - /* - * Configure HBA MSI-X attention conditions to messages if MSI-X mode - */ - if (phba->intr_type == MSIX) { - rc = lpfc_config_msi(phba, pmb); - if (rc) { - mempool_free(pmb, phba->mbox_mem_pool); - return -EIO; - } - rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); - if (rc != MBX_SUCCESS) { - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "0352 Config MSI mailbox command " - "failed, mbxCmd x%x, mbxStatus x%x\n", - pmb->mb.mbxCommand, pmb->mb.mbxStatus); - mempool_free(pmb, phba->mbox_mem_pool); - return -EIO; - } - } - - /* Initialize ERATT handling flag */ - phba->hba_flag &= ~HBA_ERATT_HANDLED; - /* Enable appropriate host interrupts */ spin_lock_irq(&phba->hbalock); status = readl(phba->HCregaddr); @@ -428,26 +393,26 @@ lpfc_config_port_post(struct lpfc_hba *phba) if ((phba->cfg_poll & ENABLE_FCP_RING_POLLING) && (phba->cfg_poll & DISABLE_FCP_RING_INT)) - status &= ~(HC_R0INT_ENA); + status &= ~(HC_R0INT_ENA << LPFC_FCP_RING); writel(status, phba->HCregaddr); readl(phba->HCregaddr); /* flush */ spin_unlock_irq(&phba->hbalock); - /* Set up ring-0 (ELS) timer */ - timeout = phba->fc_ratov * 2; + /* + * Setup the ring 0 (els) timeout handler + */ + timeout = phba->fc_ratov << 1; mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); - /* Set up heart beat (HB) timer */ mod_timer(&phba->hb_tmofunc, jiffies + HZ * LPFC_HB_MBOX_INTERVAL); phba->hb_outstanding = 0; phba->last_completion_time = jiffies; - /* Set up error attention (ERATT) polling timer */ - mod_timer(&phba->eratt_poll, jiffies + HZ * LPFC_ERATT_POLL_INTERVAL); lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - lpfc_set_loopback_flag(phba); + pmb->vport = vport; rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); + lpfc_set_loopback_flag(phba); if (rc != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0454 Adapter failed to init, mbxCmd x%x " @@ -482,20 +447,19 @@ lpfc_config_port_post(struct lpfc_hba *phba) rc); mempool_free(pmb, phba->mbox_mem_pool); } - return 0; + return (0); } -/** - * lpfc_hba_down_prep: Perform lpfc uninitialization prior to HBA reset. - * @phba: pointer to lpfc HBA data structure. - * - * This routine will do LPFC uninitialization before the HBA is reset when - * bringing down the SLI Layer. - * - * Return codes - * 0 - success. - * Any other value - error. - **/ +/************************************************************************/ +/* */ +/* lpfc_hba_down_prep */ +/* This routine will do LPFC uninitialization before the */ +/* HBA is reset when bringing down the SLI Layer. This will be */ +/* initialized as a SLI layer callback routine. */ +/* This routine returns 0 on success. Any other return value */ +/* indicates an error. */ +/* */ +/************************************************************************/ int lpfc_hba_down_prep(struct lpfc_hba *phba) { @@ -517,17 +481,15 @@ lpfc_hba_down_prep(struct lpfc_hba *phba) return 0; } -/** - * lpfc_hba_down_post: Perform lpfc uninitialization after HBA reset. - * @phba: pointer to lpfc HBA data structure. - * - * This routine will do uninitialization after the HBA is reset when bring - * down the SLI Layer. - * - * Return codes - * 0 - sucess. - * Any other value - error. - **/ +/************************************************************************/ +/* */ +/* lpfc_hba_down_post */ +/* This routine will do uninitialization after the HBA is reset */ +/* when bringing down the SLI Layer. */ +/* This routine returns 0 on success. Any other return value */ +/* indicates an error. */ +/* */ +/************************************************************************/ int lpfc_hba_down_post(struct lpfc_hba *phba) { @@ -586,18 +548,7 @@ lpfc_hba_down_post(struct lpfc_hba *phba) return 0; } -/** - * lpfc_hb_timeout: The HBA-timer timeout handler. - * @ptr: unsigned long holds the pointer to lpfc hba data structure. - * - * This is the HBA-timer timeout handler registered to the lpfc driver. When - * this timer fires, a HBA timeout event shall be posted to the lpfc driver - * work-port-events bitmap and the worker thread is notified. This timeout - * event will be used by the worker thread to invoke the actual timeout - * handler routine, lpfc_hb_timeout_handler. Any periodical operations will - * be performed in the timeout handler and the HBA timeout event bit shall - * be cleared by the worker thread after it has taken the event bitmap out. - **/ +/* HBA heart beat timeout handler */ static void lpfc_hb_timeout(unsigned long ptr) { @@ -606,36 +557,17 @@ lpfc_hb_timeout(unsigned long ptr) unsigned long iflag; phba = (struct lpfc_hba *)ptr; - - /* Check for heart beat timeout conditions */ spin_lock_irqsave(&phba->pport->work_port_lock, iflag); tmo_posted = phba->pport->work_port_events & WORKER_HB_TMO; if (!tmo_posted) phba->pport->work_port_events |= WORKER_HB_TMO; spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); - /* Tell the worker thread there is work to do */ if (!tmo_posted) lpfc_worker_wake_up(phba); return; } -/** - * lpfc_hb_mbox_cmpl: The lpfc heart-beat mailbox command callback function. - * @phba: pointer to lpfc hba data structure. - * @pmboxq: pointer to the driver internal queue element for mailbox command. - * - * This is the callback function to the lpfc heart-beat mailbox command. - * If configured, the lpfc driver issues the heart-beat mailbox command to - * the HBA every LPFC_HB_MBOX_INTERVAL (current 5) seconds. At the time the - * heart-beat mailbox command is issued, the driver shall set up heart-beat - * timeout timer to LPFC_HB_MBOX_TIMEOUT (current 30) seconds and marks - * heart-beat outstanding state. Once the mailbox command comes back and - * no error conditions detected, the heart-beat mailbox command timer is - * reset to LPFC_HB_MBOX_INTERVAL seconds and the heart-beat outstanding - * state is cleared for the next heart-beat. If the timer expired with the - * heart-beat outstanding state set, the driver will put the HBA offline. - **/ static void lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) { @@ -645,7 +577,6 @@ lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) phba->hb_outstanding = 0; spin_unlock_irqrestore(&phba->hbalock, drvr_flag); - /* Check and reset heart-beat timer is necessary */ mempool_free(pmboxq, phba->mbox_mem_pool); if (!(phba->pport->fc_flag & FC_OFFLINE_MODE) && !(phba->link_state == LPFC_HBA_ERROR) && @@ -655,22 +586,6 @@ lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) return; } -/** - * lpfc_hb_timeout_handler: The HBA-timer timeout handler. - * @phba: pointer to lpfc hba data structure. - * - * This is the actual HBA-timer timeout handler to be invoked by the worker - * thread whenever the HBA timer fired and HBA-timeout event posted. This - * handler performs any periodic operations needed for the device. If such - * periodic event has already been attended to either in the interrupt handler - * or by processing slow-ring or fast-ring events within the HBA-timer - * timeout window (LPFC_HB_MBOX_INTERVAL), this handler just simply resets - * the timer for the next timeout period. If lpfc heart-beat mailbox command - * is configured and there is no heart-beat mailbox command outstanding, a - * heart-beat mailbox is issued and timer set properly. Otherwise, if there - * has been a heart-beat mailbox command outstanding, the HBA shall be put - * to offline. - **/ void lpfc_hb_timeout_handler(struct lpfc_hba *phba) { @@ -769,13 +684,6 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) } } -/** - * lpfc_offline_eratt: Bring lpfc offline on hardware error attention. - * @phba: pointer to lpfc hba data structure. - * - * This routine is called to bring the HBA offline when HBA hardware error - * other than Port Error 6 has been detected. - **/ static void lpfc_offline_eratt(struct lpfc_hba *phba) { @@ -796,16 +704,14 @@ lpfc_offline_eratt(struct lpfc_hba *phba) return; } -/** - * lpfc_handle_eratt: The HBA hardware error handler. - * @phba: pointer to lpfc hba data structure. - * - * This routine is invoked to handle the following HBA hardware error - * conditions: - * 1 - HBA error attention interrupt - * 2 - DMA ring index out of range - * 3 - Mailbox command came back as unknown - **/ +/************************************************************************/ +/* */ +/* lpfc_handle_eratt */ +/* This routine will handle processing a Host Attention */ +/* Error Status event. This will be initialized */ +/* as a SLI layer callback routine. */ +/* */ +/************************************************************************/ void lpfc_handle_eratt(struct lpfc_hba *phba) { @@ -816,7 +722,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba) unsigned long temperature; struct temp_event temp_event_data; struct Scsi_Host *shost; - struct lpfc_board_event_header board_event; /* If the pci channel is offline, ignore possible errors, * since we cannot communicate with the pci card anyway. */ @@ -826,16 +731,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba) if (!phba->cfg_enable_hba_reset) return; - /* Send an internal error event to mgmt application */ - board_event.event_type = FC_REG_BOARD_EVENT; - board_event.subcategory = LPFC_EVENT_PORTINTERR; - shost = lpfc_shost_from_vport(phba->pport); - fc_host_post_vendor_event(shost, fc_get_event_number(), - sizeof(board_event), - (char *) &board_event, - SCSI_NL_VID_TYPE_PCI - | PCI_VENDOR_ID_EMULEX); - if (phba->work_hs & HS_FFER6) { /* Re-establishing Link */ lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, @@ -876,7 +771,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba) temp_event_data.data = (uint32_t)temperature; lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0406 Adapter maximum temperature exceeded " + "0459 Adapter maximum temperature exceeded " "(%ld), taking this port offline " "Data: x%x x%x x%x\n", temperature, phba->work_hs, @@ -896,8 +791,8 @@ lpfc_handle_eratt(struct lpfc_hba *phba) } else { /* The if clause above forces this code path when the status - * failure is a value other than FFER6. Do not call the offline - * twice. This is the adapter hardware error path. + * failure is a value other than FFER6. Do not call the offline + * twice. This is the adapter hardware error path. */ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0457 Adapter Hardware Error " @@ -913,16 +808,16 @@ lpfc_handle_eratt(struct lpfc_hba *phba) lpfc_offline_eratt(phba); } - return; } -/** - * lpfc_handle_latt: The HBA link event handler. - * @phba: pointer to lpfc hba data structure. - * - * This routine is invoked from the worker thread to handle a HBA host - * attention link event. - **/ +/************************************************************************/ +/* */ +/* lpfc_handle_latt */ +/* This routine will handle processing a Host Attention */ +/* Link Status event. This will be initialized */ +/* as a SLI layer callback routine. */ +/* */ +/************************************************************************/ void lpfc_handle_latt(struct lpfc_hba *phba) { @@ -1003,20 +898,12 @@ lpfc_handle_latt(struct lpfc_hba *phba) return; } -/** - * lpfc_parse_vpd: Parse VPD (Vital Product Data). - * @phba: pointer to lpfc hba data structure. - * @vpd: pointer to the vital product data. - * @len: length of the vital product data in bytes. - * - * This routine parses the Vital Product Data (VPD). The VPD is treated as - * an array of characters. In this routine, the ModelName, ProgramType, and - * ModelDesc, etc. fields of the phba data structure will be populated. - * - * Return codes - * 0 - pointer to the VPD passed in is NULL - * 1 - success - **/ +/************************************************************************/ +/* */ +/* lpfc_parse_vpd */ +/* This routine will parse the VPD data */ +/* */ +/************************************************************************/ static int lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len) { @@ -1153,25 +1040,12 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len) return(1); } -/** - * lpfc_get_hba_model_desc: Retrieve HBA device model name and description. - * @phba: pointer to lpfc hba data structure. - * @mdp: pointer to the data structure to hold the derived model name. - * @descp: pointer to the data structure to hold the derived description. - * - * This routine retrieves HBA's description based on its registered PCI device - * ID. The @descp passed into this function points to an array of 256 chars. It - * shall be returned with the model name, maximum speed, and the host bus type. - * The @mdp passed into this function points to an array of 80 chars. When the - * function returns, the @mdp will be filled with the model name. - **/ static void lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) { lpfc_vpd_t *vp; uint16_t dev_id = phba->pcidev->device; int max_speed; - int GE = 0; struct { char * name; int max_speed; @@ -1303,19 +1177,6 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) case PCI_DEVICE_ID_SAT_S: m = (typeof(m)){"LPe12000-S", max_speed, "PCIe"}; break; - case PCI_DEVICE_ID_HORNET: - m = (typeof(m)){"LP21000", max_speed, "PCIe"}; - GE = 1; - break; - case PCI_DEVICE_ID_PROTEUS_VF: - m = (typeof(m)) {"LPev12000", max_speed, "PCIe IOV"}; - break; - case PCI_DEVICE_ID_PROTEUS_PF: - m = (typeof(m)) {"LPev12000", max_speed, "PCIe IOV"}; - break; - case PCI_DEVICE_ID_PROTEUS_S: - m = (typeof(m)) {"LPemv12002-S", max_speed, "PCIe IOV"}; - break; default: m = (typeof(m)){ NULL }; break; @@ -1325,25 +1186,18 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) snprintf(mdp, 79,"%s", m.name); if (descp && descp[0] == '\0') snprintf(descp, 255, - "Emulex %s %d%s %s %s", - m.name, m.max_speed, - (GE) ? "GE" : "Gb", - m.bus, - (GE) ? "FCoE Adapter" : "Fibre Channel Adapter"); + "Emulex %s %dGb %s Fibre Channel Adapter", + m.name, m.max_speed, m.bus); } -/** - * lpfc_post_buffer: Post IOCB(s) with DMA buffer descriptor(s) to a IOCB ring. - * @phba: pointer to lpfc hba data structure. - * @pring: pointer to a IOCB ring. - * @cnt: the number of IOCBs to be posted to the IOCB ring. - * - * This routine posts a given number of IOCBs with the associated DMA buffer - * descriptors specified by the cnt argument to the given IOCB ring. - * - * Return codes - * The number of IOCBs NOT able to be posted to the IOCB ring. - **/ +/**************************************************/ +/* lpfc_post_buffer */ +/* */ +/* This routine will post count buffers to the */ +/* ring with the QUE_RING_BUF_CN command. This */ +/* allows 3 buffers / command to be posted. */ +/* Returns the number of buffers NOT posted. */ +/**************************************************/ int lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt) { @@ -1433,17 +1287,12 @@ lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt) return 0; } -/** - * lpfc_post_rcv_buf: Post the initial receive IOCB buffers to ELS ring. - * @phba: pointer to lpfc hba data structure. - * - * This routine posts initial receive IOCB buffers to the ELS ring. The - * current number of initial IOCB buffers specified by LPFC_BUF_RING0 is - * set to 64 IOCBs. - * - * Return codes - * 0 - success (currently always success) - **/ +/************************************************************************/ +/* */ +/* lpfc_post_rcv_buf */ +/* This routine post initial rcv buffers to the configured rings */ +/* */ +/************************************************************************/ static int lpfc_post_rcv_buf(struct lpfc_hba *phba) { @@ -1458,13 +1307,11 @@ lpfc_post_rcv_buf(struct lpfc_hba *phba) #define S(N,V) (((V)<<(N))|((V)>>(32-(N)))) -/** - * lpfc_sha_init: Set up initial array of hash table entries. - * @HashResultPointer: pointer to an array as hash table. - * - * This routine sets up the initial values to the array of hash table entries - * for the LC HBAs. - **/ +/************************************************************************/ +/* */ +/* lpfc_sha_init */ +/* */ +/************************************************************************/ static void lpfc_sha_init(uint32_t * HashResultPointer) { @@ -1475,16 +1322,11 @@ lpfc_sha_init(uint32_t * HashResultPointer) HashResultPointer[4] = 0xC3D2E1F0; } -/** - * lpfc_sha_iterate: Iterate initial hash table with the working hash table. - * @HashResultPointer: pointer to an initial/result hash table. - * @HashWorkingPointer: pointer to an working hash table. - * - * This routine iterates an initial hash table pointed by @HashResultPointer - * with the values from the working hash table pointeed by @HashWorkingPointer. - * The results are putting back to the initial hash table, returned through - * the @HashResultPointer as the result hash table. - **/ +/************************************************************************/ +/* */ +/* lpfc_sha_iterate */ +/* */ +/************************************************************************/ static void lpfc_sha_iterate(uint32_t * HashResultPointer, uint32_t * HashWorkingPointer) { @@ -1532,29 +1374,22 @@ lpfc_sha_iterate(uint32_t * HashResultPointer, uint32_t * HashWorkingPointer) } -/** - * lpfc_challenge_key: Create challenge key based on WWPN of the HBA. - * @RandomChallenge: pointer to the entry of host challenge random number array. - * @HashWorking: pointer to the entry of the working hash array. - * - * This routine calculates the working hash array referred by @HashWorking - * from the challenge random numbers associated with the host, referred by - * @RandomChallenge. The result is put into the entry of the working hash - * array and returned by reference through @HashWorking. - **/ +/************************************************************************/ +/* */ +/* lpfc_challenge_key */ +/* */ +/************************************************************************/ static void lpfc_challenge_key(uint32_t * RandomChallenge, uint32_t * HashWorking) { *HashWorking = (*RandomChallenge ^ *HashWorking); } -/** - * lpfc_hba_init: Perform special handling for LC HBA initialization. - * @phba: pointer to lpfc hba data structure. - * @hbainit: pointer to an array of unsigned 32-bit integers. - * - * This routine performs the special handling for LC HBA initialization. - **/ +/************************************************************************/ +/* */ +/* lpfc_hba_init */ +/* */ +/************************************************************************/ void lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) { @@ -1577,15 +1412,6 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) kfree(HashWorking); } -/** - * lpfc_cleanup: Performs vport cleanups before deleting a vport. - * @vport: pointer to a virtual N_Port data structure. - * - * This routine performs the necessary cleanups before deleting the @vport. - * It invokes the discovery state machine to perform necessary state - * transitions and to release the ndlps associated with the @vport. Note, - * the physical port is treated as @vport 0. - **/ void lpfc_cleanup(struct lpfc_vport *vport) { @@ -1633,6 +1459,14 @@ lpfc_cleanup(struct lpfc_vport *vport) lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); + /* nlp_type zero is not defined, nlp_flag zero also not defined, + * nlp_state is unused, this happens when + * an initiator has logged + * into us so cleanup this ndlp. + */ + if ((ndlp->nlp_type == 0) && (ndlp->nlp_flag == 0) && + (ndlp->nlp_state == 0)) + lpfc_nlp_put(ndlp); } /* At this point, ALL ndlp's should be gone @@ -1648,7 +1482,7 @@ lpfc_cleanup(struct lpfc_vport *vport) &vport->fc_nodes, nlp_listp) { lpfc_printf_vlog(ndlp->vport, KERN_ERR, LOG_NODE, - "0282 did:x%x ndlp:x%p " + "0282: did:x%x ndlp:x%p " "usgmap:x%x refcnt:%d\n", ndlp->nlp_DID, (void *)ndlp, ndlp->nlp_usg_map, @@ -1664,14 +1498,6 @@ lpfc_cleanup(struct lpfc_vport *vport) return; } -/** - * lpfc_stop_vport_timers: Stop all the timers associated with a vport. - * @vport: pointer to a virtual N_Port data structure. - * - * This routine stops all the timers associated with a @vport. This function - * is invoked before disabling or deleting a @vport. Note that the physical - * port is treated as @vport 0. - **/ void lpfc_stop_vport_timers(struct lpfc_vport *vport) { @@ -1681,13 +1507,6 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport) return; } -/** - * lpfc_stop_phba_timers: Stop all the timers associated with an HBA. - * @phba: pointer to lpfc hba data structure. - * - * This routine stops all the timers associated with a HBA. This function is - * invoked before either putting a HBA offline or unloading the driver. - **/ static void lpfc_stop_phba_timers(struct lpfc_hba *phba) { @@ -1697,20 +1516,9 @@ lpfc_stop_phba_timers(struct lpfc_hba *phba) del_timer_sync(&phba->fabric_block_timer); phba->hb_outstanding = 0; del_timer_sync(&phba->hb_tmofunc); - del_timer_sync(&phba->eratt_poll); return; } -/** - * lpfc_block_mgmt_io: Mark a HBA's management interface as blocked. - * @phba: pointer to lpfc hba data structure. - * - * This routine marks a HBA's management interface as blocked. Once the HBA's - * management interface is marked as blocked, all the user space access to - * the HBA, whether they are from sysfs interface or libdfc interface will - * all be blocked. The HBA is set to block the management interface when the - * driver prepares the HBA interface for online or offline. - **/ static void lpfc_block_mgmt_io(struct lpfc_hba * phba) { @@ -1721,18 +1529,6 @@ lpfc_block_mgmt_io(struct lpfc_hba * phba) spin_unlock_irqrestore(&phba->hbalock, iflag); } -/** - * lpfc_online: Initialize and bring a HBA online. - * @phba: pointer to lpfc hba data structure. - * - * This routine initializes the HBA and brings a HBA online. During this - * process, the management interface is blocked to prevent user space access - * to the HBA interfering with the driver initialization. - * - * Return codes - * 0 - successful - * 1 - failed - **/ int lpfc_online(struct lpfc_hba *phba) { @@ -1778,17 +1574,6 @@ lpfc_online(struct lpfc_hba *phba) return 0; } -/** - * lpfc_unblock_mgmt_io: Mark a HBA's management interface to be not blocked. - * @phba: pointer to lpfc hba data structure. - * - * This routine marks a HBA's management interface as not blocked. Once the - * HBA's management interface is marked as not blocked, all the user space - * access to the HBA, whether they are from sysfs interface or libdfc - * interface will be allowed. The HBA is set to block the management interface - * when the driver prepares the HBA interface for online or offline and then - * set to unblock the management interface afterwards. - **/ void lpfc_unblock_mgmt_io(struct lpfc_hba * phba) { @@ -1799,14 +1584,6 @@ lpfc_unblock_mgmt_io(struct lpfc_hba * phba) spin_unlock_irqrestore(&phba->hbalock, iflag); } -/** - * lpfc_offline_prep: Prepare a HBA to be brought offline. - * @phba: pointer to lpfc hba data structure. - * - * This routine is invoked to prepare a HBA to be brought offline. It performs - * unregistration login to all the nodes on all vports and flushes the mailbox - * queue to make it ready to be brought offline. - **/ void lpfc_offline_prep(struct lpfc_hba * phba) { @@ -1856,14 +1633,6 @@ lpfc_offline_prep(struct lpfc_hba * phba) lpfc_sli_flush_mbox_queue(phba); } -/** - * lpfc_offline: Bring a HBA offline. - * @phba: pointer to lpfc hba data structure. - * - * This routine actually brings a HBA offline. It stops all the timers - * associated with the HBA, brings down the SLI layer, and eventually - * marks the HBA as in offline state for the upper layer protocol. - **/ void lpfc_offline(struct lpfc_hba *phba) { @@ -1901,17 +1670,12 @@ lpfc_offline(struct lpfc_hba *phba) lpfc_destroy_vport_work_array(phba, vports); } -/** - * lpfc_scsi_free: Free all the SCSI buffers and IOCBs from driver lists. - * @phba: pointer to lpfc hba data structure. - * - * This routine is to free all the SCSI buffers and IOCBs from the driver - * list back to kernel. It is called from lpfc_pci_remove_one to free - * the internal resources before the device is removed from the system. - * - * Return codes - * 0 - successful (for now, it always returns 0) - **/ +/****************************************************************************** +* Function name: lpfc_scsi_free +* +* Description: Called from lpfc_pci_remove_one free internal driver resources +* +******************************************************************************/ static int lpfc_scsi_free(struct lpfc_hba *phba) { @@ -1940,22 +1704,6 @@ lpfc_scsi_free(struct lpfc_hba *phba) return 0; } -/** - * lpfc_create_port: Create an FC port. - * @phba: pointer to lpfc hba data structure. - * @instance: a unique integer ID to this FC port. - * @dev: pointer to the device data structure. - * - * This routine creates a FC port for the upper layer protocol. The FC port - * can be created on top of either a physical port or a virtual port provided - * by the HBA. This routine also allocates a SCSI host data structure (shost) - * and associates the FC port created before adding the shost into the SCSI - * layer. - * - * Return codes - * @vport - pointer to the virtual N_Port data structure. - * NULL - port create failed. - **/ struct lpfc_vport * lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) { @@ -2029,13 +1777,6 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) return NULL; } -/** - * destroy_port: Destroy an FC port. - * @vport: pointer to an lpfc virtual N_Port data structure. - * - * This routine destroys a FC port from the upper layer protocol. All the - * resources associated with the port are released. - **/ void destroy_port(struct lpfc_vport *vport) { @@ -2056,16 +1797,6 @@ destroy_port(struct lpfc_vport *vport) return; } -/** - * lpfc_get_instance: Get a unique integer ID. - * - * This routine allocates a unique integer ID from lpfc_hba_index pool. It - * uses the kernel idr facility to perform the task. - * - * Return codes: - * instance - a unique integer ID allocated as the new instance. - * -1 - lpfc get instance failed. - **/ int lpfc_get_instance(void) { @@ -2079,21 +1810,11 @@ lpfc_get_instance(void) return instance; } -/** - * lpfc_scan_finished: method for SCSI layer to detect whether scan is done. - * @shost: pointer to SCSI host data structure. - * @time: elapsed time of the scan in jiffies. - * - * This routine is called by the SCSI layer with a SCSI host to determine - * whether the scan host is finished. - * - * Note: there is no scan_start function as adapter initialization will have - * asynchronously kicked off the link initialization. - * - * Return codes - * 0 - SCSI host scan is not over yet. - * 1 - SCSI host scan is over. - **/ +/* + * Note: there is no scan_start function as adapter initialization + * will have asynchronously kicked off the link initialization. + */ + int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) { struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; @@ -2137,13 +1858,6 @@ int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) return stat; } -/** - * lpfc_host_attrib_init: Initialize SCSI host attributes on a FC port. - * @shost: pointer to SCSI host data structure. - * - * This routine initializes a given SCSI host attributes on a FC port. The - * SCSI host can be either on top of a physical port or a virtual port. - **/ void lpfc_host_attrib_init(struct Scsi_Host *shost) { struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; @@ -2192,157 +1906,42 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost) spin_unlock_irq(shost->host_lock); } -/** - * lpfc_enable_msix: Enable MSI-X interrupt mode. - * @phba: pointer to lpfc hba data structure. - * - * This routine is invoked to enable the MSI-X interrupt vectors. The kernel - * function pci_enable_msix() is called to enable the MSI-X vectors. Note that - * pci_enable_msix(), once invoked, enables either all or nothing, depending - * on the current availability of PCI vector resources. The device driver is - * responsible for calling the individual request_irq() to register each MSI-X - * vector with a interrupt handler, which is done in this function. Note that - * later when device is unloading, the driver should always call free_irq() - * on all MSI-X vectors it has done request_irq() on before calling - * pci_disable_msix(). Failure to do so results in a BUG_ON() and a device - * will be left with MSI-X enabled and leaks its vectors. - * - * Return codes - * 0 - sucessful - * other values - error - **/ static int lpfc_enable_msix(struct lpfc_hba *phba) { - int rc, i; - LPFC_MBOXQ_t *pmb; + int error; - /* Set up MSI-X multi-message vectors */ - for (i = 0; i < LPFC_MSIX_VECTORS; i++) - phba->msix_entries[i].entry = i; + phba->msix_entries[0].entry = 0; + phba->msix_entries[0].vector = 0; - /* Configure MSI-X capability structure */ - rc = pci_enable_msix(phba->pcidev, phba->msix_entries, + error = pci_enable_msix(phba->pcidev, phba->msix_entries, ARRAY_SIZE(phba->msix_entries)); - if (rc) { + if (error) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0420 Enable MSI-X failed (%d), continuing " - "with MSI\n", rc); - goto msi_fail_out; - } else - for (i = 0; i < LPFC_MSIX_VECTORS; i++) - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0477 MSI-X entry[%d]: vector=x%x " - "message=%d\n", i, - phba->msix_entries[i].vector, - phba->msix_entries[i].entry); - /* - * Assign MSI-X vectors to interrupt handlers - */ - - /* vector-0 is associated to slow-path handler */ - rc = request_irq(phba->msix_entries[0].vector, &lpfc_sp_intr_handler, - IRQF_SHARED, LPFC_SP_DRIVER_HANDLER_NAME, phba); - if (rc) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0421 MSI-X slow-path request_irq failed " - "(%d), continuing with MSI\n", rc); - goto msi_fail_out; - } - - /* vector-1 is associated to fast-path handler */ - rc = request_irq(phba->msix_entries[1].vector, &lpfc_fp_intr_handler, - IRQF_SHARED, LPFC_FP_DRIVER_HANDLER_NAME, phba); - - if (rc) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0429 MSI-X fast-path request_irq failed " - "(%d), continuing with MSI\n", rc); - goto irq_fail_out; + "with MSI\n", error); + pci_disable_msix(phba->pcidev); + return error; } - /* - * Configure HBA MSI-X attention conditions to messages - */ - pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - - if (!pmb) { - rc = -ENOMEM; + error = request_irq(phba->msix_entries[0].vector, lpfc_intr_handler, 0, + LPFC_DRIVER_NAME, phba); + if (error) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0474 Unable to allocate memory for issuing " - "MBOX_CONFIG_MSI command\n"); - goto mem_fail_out; - } - rc = lpfc_config_msi(phba, pmb); - if (rc) - goto mbx_fail_out; - rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); - if (rc != MBX_SUCCESS) { - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, - "0351 Config MSI mailbox command failed, " - "mbxCmd x%x, mbxStatus x%x\n", - pmb->mb.mbxCommand, pmb->mb.mbxStatus); - goto mbx_fail_out; + "0421 MSI-X request_irq failed (%d), " + "continuing with MSI\n", error); + pci_disable_msix(phba->pcidev); } - - /* Free memory allocated for mailbox command */ - mempool_free(pmb, phba->mbox_mem_pool); - return rc; - -mbx_fail_out: - /* Free memory allocated for mailbox command */ - mempool_free(pmb, phba->mbox_mem_pool); - -mem_fail_out: - /* free the irq already requested */ - free_irq(phba->msix_entries[1].vector, phba); - -irq_fail_out: - /* free the irq already requested */ - free_irq(phba->msix_entries[0].vector, phba); - -msi_fail_out: - /* Unconfigure MSI-X capability structure */ - pci_disable_msix(phba->pcidev); - return rc; + return error; } -/** - * lpfc_disable_msix: Disable MSI-X interrupt mode. - * @phba: pointer to lpfc hba data structure. - * - * This routine is invoked to release the MSI-X vectors and then disable the - * MSI-X interrupt mode. - **/ static void lpfc_disable_msix(struct lpfc_hba *phba) { - int i; - - /* Free up MSI-X multi-message vectors */ - for (i = 0; i < LPFC_MSIX_VECTORS; i++) - free_irq(phba->msix_entries[i].vector, phba); - /* Disable MSI-X */ + free_irq(phba->msix_entries[0].vector, phba); pci_disable_msix(phba->pcidev); } -/** - * lpfc_pci_probe_one: lpfc PCI probe func to register device to PCI subsystem. - * @pdev: pointer to PCI device - * @pid: pointer to PCI device identifier - * - * This routine is to be registered to the kernel's PCI subsystem. When an - * Emulex HBA is presented in PCI bus, the kernel PCI subsystem looks at - * PCI device-specific information of the device and driver to see if the - * driver state that it can support this kind of device. If the match is - * successful, the driver core invokes this routine. If this routine - * determines it can claim the HBA, it does all the initialization that it - * needs to do to handle the HBA properly. - * - * Return code - * 0 - driver can claim the device - * negative value - driver can not claim the device - **/ static int __devinit lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) { @@ -2357,7 +1956,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) int i, hbq_count; uint16_t iotag; int bars = pci_select_bars(pdev, IORESOURCE_MEM); - struct lpfc_adapter_event_header adapter_event; if (pci_enable_device_mem(pdev)) goto out; @@ -2368,7 +1966,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) if (!phba) goto out_release_regions; - atomic_set(&phba->fast_event_count, 0); spin_lock_init(&phba->hbalock); /* Initialize ndlp management spinlock */ @@ -2381,7 +1978,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) goto out_free_phba; INIT_LIST_HEAD(&phba->port_list); - init_waitqueue_head(&phba->wait_4_mlo_m_q); /* * Get all the module params for configuring this host and then * establish the host. @@ -2404,9 +2000,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) init_timer(&phba->fabric_block_timer); phba->fabric_block_timer.function = lpfc_fabric_block_timeout; phba->fabric_block_timer.data = (unsigned long) phba; - init_timer(&phba->eratt_poll); - phba->eratt_poll.function = lpfc_poll_eratt; - phba->eratt_poll.data = (unsigned long) phba; pci_set_master(pdev); pci_try_set_mwi(pdev); @@ -2426,7 +2019,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) bar2map_len = pci_resource_len(phba->pcidev, 2); /* Map HBA SLIM to a kernel virtual address. */ - phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len); + phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len); if (!phba->slim_memmap_p) { error = -ENODEV; dev_printk(KERN_ERR, &pdev->dev, @@ -2444,18 +2037,12 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) } /* Allocate memory for SLI-2 structures */ - phba->slim2p.virt = dma_alloc_coherent(&phba->pcidev->dev, - SLI2_SLIM_SIZE, - &phba->slim2p.phys, - GFP_KERNEL); - if (!phba->slim2p.virt) + phba->slim2p = dma_alloc_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE, + &phba->slim2p_mapping, GFP_KERNEL); + if (!phba->slim2p) goto out_iounmap; - memset(phba->slim2p.virt, 0, SLI2_SLIM_SIZE); - phba->mbox = phba->slim2p.virt + offsetof(struct lpfc_sli2_slim, mbx); - phba->pcb = (phba->slim2p.virt + offsetof(struct lpfc_sli2_slim, pcb)); - phba->IOCBs = (phba->slim2p.virt + - offsetof(struct lpfc_sli2_slim, IOCBs)); + memset(phba->slim2p, 0, SLI2_SLIM_SIZE); phba->hbqslimp.virt = dma_alloc_coherent(&phba->pcidev->dev, lpfc_sli_hbq_size(), @@ -2524,7 +2111,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) phba->fc_arbtov = FF_DEF_ARBTOV; INIT_LIST_HEAD(&phba->work_list); - phba->work_ha_mask = (HA_ERATT | HA_MBATT | HA_LATT); + phba->work_ha_mask = (HA_ERATT|HA_MBATT|HA_LATT); phba->work_ha_mask |= (HA_RXMASK << (LPFC_ELS_RING * 4)); /* Initialize the wait queue head for the kernel thread */ @@ -2559,42 +2146,21 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) pci_set_drvdata(pdev, shost); phba->intr_type = NONE; - phba->MBslimaddr = phba->slim_memmap_p; - phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET; - phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET; - phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; - phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; - - /* Configure and enable interrupt */ if (phba->cfg_use_msi == 2) { - /* Need to issue conf_port mbox cmd before conf_msi mbox cmd */ - error = lpfc_sli_config_port(phba, 3); - if (error) - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0427 Firmware not capable of SLI 3 mode.\n"); - else { - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0426 Firmware capable of SLI 3 mode.\n"); - /* Now, try to enable MSI-X interrupt mode */ - error = lpfc_enable_msix(phba); - if (!error) { - phba->intr_type = MSIX; - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0430 enable MSI-X mode.\n"); - } - } + error = lpfc_enable_msix(phba); + if (!error) + phba->intr_type = MSIX; } /* Fallback to MSI if MSI-X initialization failed */ if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { retval = pci_enable_msi(phba->pcidev); - if (!retval) { + if (!retval) phba->intr_type = MSI; + else lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0473 enable MSI mode.\n"); - } else - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0452 enable IRQ mode.\n"); + "0452 Enable MSI failed, continuing " + "with IRQ\n"); } /* MSI-X is the only case the doesn't need to call request_irq */ @@ -2610,16 +2176,18 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) phba->intr_type = INTx; } + phba->MBslimaddr = phba->slim_memmap_p; + phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET; + phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET; + phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; + phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; + if (lpfc_alloc_sysfs_attr(vport)) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "1476 Failed to allocate sysfs attr\n"); error = -ENOMEM; goto out_free_irq; } if (lpfc_sli_hba_setup(phba)) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "1477 Failed to set up hba\n"); error = -ENODEV; goto out_remove_device; } @@ -2638,16 +2206,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) spin_unlock_irq(shost->host_lock); } - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0428 Perform SCSI scan\n"); - /* Send board arrival event to upper layer */ - adapter_event.event_type = FC_REG_ADAPTER_EVENT; - adapter_event.subcategory = LPFC_EVENT_ARRIVAL; - fc_host_post_vendor_event(shost, fc_get_event_number(), - sizeof(adapter_event), - (char *) &adapter_event, - SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); - scsi_scan_host(shost); return 0; @@ -2680,11 +2238,11 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) } lpfc_mem_free(phba); out_free_hbqslimp: - dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(), - phba->hbqslimp.virt, phba->hbqslimp.phys); + dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(), phba->hbqslimp.virt, + phba->hbqslimp.phys); out_free_slim: - dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE, - phba->slim2p.virt, phba->slim2p.phys); + dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE, phba->slim2p, + phba->slim2p_mapping); out_iounmap: iounmap(phba->ctrl_regs_memmap_p); out_iounmap_slim: @@ -2704,14 +2262,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) return error; } -/** - * lpfc_pci_remove_one: lpfc PCI func to unregister device from PCI subsystem. - * @pdev: pointer to PCI device - * - * This routine is to be registered to the kernel's PCI subsystem. When an - * Emulex HBA is removed from PCI bus. It perform all the necessary cleanup - * for the HBA device to be removed from the PCI subsystem properly. - **/ static void __devexit lpfc_pci_remove_one(struct pci_dev *pdev) { @@ -2766,12 +2316,12 @@ lpfc_pci_remove_one(struct pci_dev *pdev) lpfc_scsi_free(phba); lpfc_mem_free(phba); - dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(), - phba->hbqslimp.virt, phba->hbqslimp.phys); + dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(), phba->hbqslimp.virt, + phba->hbqslimp.phys); /* Free resources associated with SLI2 interface */ dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE, - phba->slim2p.virt, phba->slim2p.phys); + phba->slim2p, phba->slim2p_mapping); /* unmap adapter SLIM and Control Registers */ iounmap(phba->ctrl_regs_memmap_p); @@ -2786,21 +2336,13 @@ lpfc_pci_remove_one(struct pci_dev *pdev) } /** - * lpfc_io_error_detected: Driver method for handling PCI I/O error detected. - * @pdev: pointer to PCI device. - * @state: the current PCI connection state. - * - * This routine is registered to the PCI subsystem for error handling. This - * function is called by the PCI subsystem after a PCI bus error affecting - * this device has been detected. When this function is invoked, it will - * need to stop all the I/Os and interrupt(s) to the device. Once that is - * done, it will return PCI_ERS_RESULT_NEED_RESET for the PCI subsystem to - * perform proper recovery as desired. + * lpfc_io_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device + * @state: The current pci conneection state * - * Return codes - * PCI_ERS_RESULT_NEED_RESET - need to reset before recovery - * PCI_ERS_RESULT_DISCONNECT - device could not be recovered - **/ + * This function is called after a PCI bus error affecting + * this device has been detected. + */ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { @@ -2809,15 +2351,8 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev, struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; - if (state == pci_channel_io_perm_failure) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0472 PCI channel I/O permanent failure\n"); - /* Block all SCSI devices' I/Os on the host */ - lpfc_scsi_dev_block(phba); - /* Clean up all driver's outstanding SCSI I/Os */ - lpfc_sli_flush_fcp_rings(phba); + if (state == pci_channel_io_perm_failure) return PCI_ERS_RESULT_DISCONNECT; - } pci_disable_device(pdev); /* @@ -2841,21 +2376,10 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev, } /** - * lpfc_io_slot_reset: Restart a PCI device from scratch. - * @pdev: pointer to PCI device. - * - * This routine is registered to the PCI subsystem for error handling. This is - * called after PCI bus has been reset to restart the PCI card from scratch, - * as if from a cold-boot. During the PCI subsystem error recovery, after the - * driver returns PCI_ERS_RESULT_NEED_RESET, the PCI subsystem will perform - * proper error recovery and then call this routine before calling the .resume - * method to recover the device. This function will initialize the HBA device, - * enable the interrupt, but it will just put the HBA to offline state without - * passing any I/O traffic. + * lpfc_io_slot_reset - called after the pci bus has been reset. + * @pdev: Pointer to PCI device * - * Return codes - * PCI_ERS_RESULT_RECOVERED - the device has been recovered - * PCI_ERS_RESULT_DISCONNECT - device could not be recovered + * Restart the card from scratch, as if from a cold-boot. */ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) { @@ -2880,34 +2404,20 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) /* Enable configured interrupt method */ phba->intr_type = NONE; if (phba->cfg_use_msi == 2) { - /* Need to issue conf_port mbox cmd before conf_msi mbox cmd */ - error = lpfc_sli_config_port(phba, 3); - if (error) - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0478 Firmware not capable of SLI 3 mode.\n"); - else { - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0479 Firmware capable of SLI 3 mode.\n"); - /* Now, try to enable MSI-X interrupt mode */ - error = lpfc_enable_msix(phba); - if (!error) { - phba->intr_type = MSIX; - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0480 enable MSI-X mode.\n"); - } - } + error = lpfc_enable_msix(phba); + if (!error) + phba->intr_type = MSIX; } /* Fallback to MSI if MSI-X initialization failed */ if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { retval = pci_enable_msi(phba->pcidev); - if (!retval) { + if (!retval) phba->intr_type = MSI; + else lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0481 enable MSI mode.\n"); - } else - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0470 enable IRQ mode.\n"); + "0470 Enable MSI failed, continuing " + "with IRQ\n"); } /* MSI-X is the only case the doesn't need to call request_irq */ @@ -2930,13 +2440,11 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) } /** - * lpfc_io_resume: Resume PCI I/O operation. - * @pdev: pointer to PCI device + * lpfc_io_resume - called when traffic can start flowing again. + * @pdev: Pointer to PCI device * - * This routine is registered to the PCI subsystem for error handling. It is - * called when kernel error recovery tells the lpfc driver that it is ok to - * resume normal PCI operation after PCI bus error recovery. After this call, - * traffic can start to flow from this device again. + * This callback is called when the error recovery driver tells us that + * its OK to resume normal operation. */ static void lpfc_io_resume(struct pci_dev *pdev) { @@ -2983,8 +2491,6 @@ static struct pci_device_id lpfc_id_table[] = { PCI_ANY_ID, PCI_ANY_ID, }, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR, PCI_ANY_ID, PCI_ANY_ID, }, - {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HORNET, - PCI_ANY_ID, PCI_ANY_ID, }, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_SCSP, PCI_ANY_ID, PCI_ANY_ID, }, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_DCSP, @@ -3015,12 +2521,6 @@ static struct pci_device_id lpfc_id_table[] = { PCI_ANY_ID, PCI_ANY_ID, }, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_S, PCI_ANY_ID, PCI_ANY_ID, }, - {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PROTEUS_VF, - PCI_ANY_ID, PCI_ANY_ID, }, - {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PROTEUS_PF, - PCI_ANY_ID, PCI_ANY_ID, }, - {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PROTEUS_S, - PCI_ANY_ID, PCI_ANY_ID, }, { 0 } }; @@ -3040,18 +2540,6 @@ static struct pci_driver lpfc_driver = { .err_handler = &lpfc_err_handler, }; -/** - * lpfc_init: lpfc module initialization routine. - * - * This routine is to be invoked when the lpfc module is loaded into the - * kernel. The special kernel macro module_init() is used to indicate the - * role of this routine to the kernel as lpfc module entry point. - * - * Return codes - * 0 - successful - * -ENOMEM - FC attach transport failed - * all others - failed - */ static int __init lpfc_init(void) { @@ -3079,20 +2567,12 @@ lpfc_init(void) error = pci_register_driver(&lpfc_driver); if (error) { fc_release_transport(lpfc_transport_template); - if (lpfc_enable_npiv) - fc_release_transport(lpfc_vport_transport_template); + fc_release_transport(lpfc_vport_transport_template); } return error; } -/** - * lpfc_exit: lpfc module removal routine. - * - * This routine is invoked when the lpfc module is removed from the kernel. - * The special kernel macro module_exit() is used to indicate the role of - * this routine to the kernel as lpfc module exit point. - */ static void __exit lpfc_exit(void) { diff --git a/trunk/drivers/scsi/lpfc/lpfc_mbox.c b/trunk/drivers/scsi/lpfc/lpfc_mbox.c index 7465fe746fe9..7a9be4c5b7cb 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_mbox.c +++ b/trunk/drivers/scsi/lpfc/lpfc_mbox.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2008 Emulex. All rights reserved. * + * Copyright (C) 2004-2007 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -30,7 +30,6 @@ #include "lpfc_hw.h" #include "lpfc_sli.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h" @@ -38,20 +37,10 @@ #include "lpfc_crtn.h" #include "lpfc_compat.h" -/** - * lpfc_dump_mem: Prepare a mailbox command for retrieving HBA's VPD memory. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * @offset: offset for dumping VPD memory mailbox command. - * - * The dump mailbox command provides a method for the device driver to obtain - * various types of information from the HBA device. - * - * This routine prepares the mailbox command for dumping HBA Vital Product - * Data (VPD) memory. This mailbox command is to be used for retrieving a - * portion (DMP_RSP_SIZE bytes) of a HBA's VPD from the HBA at an address - * offset specified by the offset parameter. - **/ +/**********************************************/ + +/* mailbox command */ +/**********************************************/ void lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset) { @@ -76,17 +65,10 @@ lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset) return; } -/** - * lpfc_read_nv: Prepare a mailbox command for reading HBA's NVRAM param. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The read NVRAM mailbox command returns the HBA's non-volatile parameters - * that are used as defaults when the Fibre Channel link is brought on-line. - * - * This routine prepares the mailbox command for reading information stored - * in the HBA's NVRAM. Specifically, the HBA's WWNN and WWPN. - **/ +/**********************************************/ +/* lpfc_read_nv Issue a READ NVPARAM */ +/* mailbox command */ +/**********************************************/ void lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { @@ -99,19 +81,10 @@ lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) return; } -/** - * lpfc_config_async: Prepare a mailbox command for enabling HBA async event. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * @ring: ring number for the asynchronous event to be configured. - * - * The asynchronous event enable mailbox command is used to enable the - * asynchronous event posting via the ASYNC_STATUS_CN IOCB response and - * specifies the default ring to which events are posted. - * - * This routine prepares the mailbox command for enabling HBA asynchronous - * event support on a IOCB ring. - **/ +/**********************************************/ +/* lpfc_config_async Issue a */ +/* MBX_ASYNC_EVT_ENABLE mailbox command */ +/**********************************************/ void lpfc_config_async(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint32_t ring) @@ -126,19 +99,10 @@ lpfc_config_async(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, return; } -/** - * lpfc_heart_beat: Prepare a mailbox command for heart beat. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The heart beat mailbox command is used to detect an unresponsive HBA, which - * is defined as any device where no error attention is sent and both mailbox - * and rings are not processed. - * - * This routine prepares the mailbox command for issuing a heart beat in the - * form of mailbox command to the HBA. The timely completion of the heart - * beat mailbox command indicates the health of the HBA. - **/ +/**********************************************/ +/* lpfc_heart_beat Issue a HEART_BEAT */ +/* mailbox command */ +/**********************************************/ void lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { @@ -151,26 +115,10 @@ lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) return; } -/** - * lpfc_read_la: Prepare a mailbox command for reading HBA link attention. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * @mp: DMA buffer memory for reading the link attention information into. - * - * The read link attention mailbox command is issued to read the Link Event - * Attention information indicated by the HBA port when the Link Event bit - * of the Host Attention (HSTATT) register is set to 1. A Link Event - * Attention occurs based on an exception detected at the Fibre Channel link - * interface. - * - * This routine prepares the mailbox command for reading HBA link attention - * information. A DMA memory has been set aside and address passed to the - * HBA through @mp for the HBA to DMA link attention information into the - * memory as part of the execution of the mailbox command. - * - * Return codes - * 0 - Success (currently always return 0) - **/ +/**********************************************/ +/* lpfc_read_la Issue a READ LA */ +/* mailbox command */ +/**********************************************/ int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp) { @@ -195,21 +143,10 @@ lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp) return (0); } -/** - * lpfc_clear_la: Prepare a mailbox command for clearing HBA link attention. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The clear link attention mailbox command is issued to clear the link event - * attention condition indicated by the Link Event bit of the Host Attention - * (HSTATT) register. The link event attention condition is cleared only if - * the event tag specified matches that of the current link event counter. - * The current event tag is read using the read link attention event mailbox - * command. - * - * This routine prepares the mailbox command for clearing HBA link attention - * information. - **/ +/**********************************************/ +/* lpfc_clear_la Issue a CLEAR LA */ +/* mailbox command */ +/**********************************************/ void lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { @@ -224,20 +161,10 @@ lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) return; } -/** - * lpfc_config_link: Prepare a mailbox command for configuring link on a HBA. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The configure link mailbox command is used before the initialize link - * mailbox command to override default value and to configure link-oriented - * parameters such as DID address and various timers. Typically, this - * command would be used after an F_Port login to set the returned DID address - * and the fabric timeout values. This command is not valid before a configure - * port command has configured the HBA port. - * - * This routine prepares the mailbox command for configuring link on a HBA. - **/ +/**************************************************/ +/* lpfc_config_link Issue a CONFIG LINK */ +/* mailbox command */ +/**************************************************/ void lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { @@ -272,98 +199,10 @@ lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) return; } -/** - * lpfc_config_msi: Prepare a mailbox command for configuring msi-x. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The configure MSI-X mailbox command is used to configure the HBA's SLI-3 - * MSI-X multi-message interrupt vector association to interrupt attention - * conditions. - * - * Return codes - * 0 - Success - * -EINVAL - Failure - **/ -int -lpfc_config_msi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) -{ - MAILBOX_t *mb = &pmb->mb; - uint32_t attentionConditions[2]; - - /* Sanity check */ - if (phba->cfg_use_msi != 2) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0475 Not configured for supporting MSI-X " - "cfg_use_msi: 0x%x\n", phba->cfg_use_msi); - return -EINVAL; - } - - if (phba->sli_rev < 3) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0476 HBA not supporting SLI-3 or later " - "SLI Revision: 0x%x\n", phba->sli_rev); - return -EINVAL; - } - - /* Clear mailbox command fields */ - memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); - - /* - * SLI-3, Message Signaled Interrupt Fearure. - */ - - /* Multi-message attention configuration */ - attentionConditions[0] = (HA_R0ATT | HA_R1ATT | HA_R2ATT | HA_ERATT | - HA_LATT | HA_MBATT); - attentionConditions[1] = 0; - - mb->un.varCfgMSI.attentionConditions[0] = attentionConditions[0]; - mb->un.varCfgMSI.attentionConditions[1] = attentionConditions[1]; - - /* - * Set up message number to HA bit association - */ -#ifdef __BIG_ENDIAN_BITFIELD - /* RA0 (FCP Ring) */ - mb->un.varCfgMSI.messageNumberByHA[HA_R0_POS] = 1; - /* RA1 (Other Protocol Extra Ring) */ - mb->un.varCfgMSI.messageNumberByHA[HA_R1_POS] = 1; -#else /* __LITTLE_ENDIAN_BITFIELD */ - /* RA0 (FCP Ring) */ - mb->un.varCfgMSI.messageNumberByHA[HA_R0_POS^3] = 1; - /* RA1 (Other Protocol Extra Ring) */ - mb->un.varCfgMSI.messageNumberByHA[HA_R1_POS^3] = 1; -#endif - /* Multi-message interrupt autoclear configuration*/ - mb->un.varCfgMSI.autoClearHA[0] = attentionConditions[0]; - mb->un.varCfgMSI.autoClearHA[1] = attentionConditions[1]; - - /* For now, HBA autoclear does not work reliably, disable it */ - mb->un.varCfgMSI.autoClearHA[0] = 0; - mb->un.varCfgMSI.autoClearHA[1] = 0; - - /* Set command and owner bit */ - mb->mbxCommand = MBX_CONFIG_MSI; - mb->mbxOwner = OWN_HOST; - - return 0; -} - -/** - * lpfc_init_link: Prepare a mailbox command for initialize link on a HBA. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * @topology: the link topology for the link to be initialized to. - * @linkspeed: the link speed for the link to be initialized to. - * - * The initialize link mailbox command is used to initialize the Fibre - * Channel link. This command must follow a configure port command that - * establishes the mode of operation. - * - * This routine prepares the mailbox command for initializing link on a HBA - * with the specified link topology and speed. - **/ +/**********************************************/ +/* lpfc_init_link Issue an INIT LINK */ +/* mailbox command */ +/**********************************************/ void lpfc_init_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint32_t topology, uint32_t linkspeed) @@ -430,27 +269,10 @@ lpfc_init_link(struct lpfc_hba * phba, return; } -/** - * lpfc_read_sparam: Prepare a mailbox command for reading HBA parameters. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * @vpi: virtual N_Port identifier. - * - * The read service parameter mailbox command is used to read the HBA port - * service parameters. The service parameters are read into the buffer - * specified directly by a BDE in the mailbox command. These service - * parameters may then be used to build the payload of an N_Port/F_POrt - * login request and reply (LOGI/ACC). - * - * This routine prepares the mailbox command for reading HBA port service - * parameters. The DMA memory is allocated in this function and the addresses - * are populated into the mailbox command for the HBA to DMA the service - * parameters into. - * - * Return codes - * 0 - Success - * 1 - DMA memory allocation failed - **/ +/**********************************************/ +/* lpfc_read_sparam Issue a READ SPARAM */ +/* mailbox command */ +/**********************************************/ int lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi) { @@ -490,21 +312,10 @@ lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi) return (0); } -/** - * lpfc_unreg_did: Prepare a mailbox command for unregistering DID. - * @phba: pointer to lpfc hba data structure. - * @vpi: virtual N_Port identifier. - * @did: remote port identifier. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The unregister DID mailbox command is used to unregister an N_Port/F_Port - * login for an unknown RPI by specifying the DID of a remote port. This - * command frees an RPI context in the HBA port. This has the effect of - * performing an implicit N_Port/F_Port logout. - * - * This routine prepares the mailbox command for unregistering a remote - * N_Port/F_Port (DID) login. - **/ +/********************************************/ +/* lpfc_unreg_did Issue a UNREG_DID */ +/* mailbox command */ +/********************************************/ void lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did, LPFC_MBOXQ_t * pmb) @@ -522,19 +333,10 @@ lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did, return; } -/** - * lpfc_read_config: Prepare a mailbox command for reading HBA configuration. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The read configuration mailbox command is used to read the HBA port - * configuration parameters. This mailbox command provides a method for - * seeing any parameters that may have changed via various configuration - * mailbox commands. - * - * This routine prepares the mailbox command for reading out HBA configuration - * parameters. - **/ +/**********************************************/ +/* lpfc_read_nv Issue a READ CONFIG */ +/* mailbox command */ +/**********************************************/ void lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { @@ -548,18 +350,10 @@ lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) return; } -/** - * lpfc_read_lnk_stat: Prepare a mailbox command for reading HBA link stats. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The read link status mailbox command is used to read the link status from - * the HBA. Link status includes all link-related error counters. These - * counters are maintained by the HBA and originated in the link hardware - * unit. Note that all of these counters wrap. - * - * This routine prepares the mailbox command for reading out HBA link status. - **/ +/*************************************************/ +/* lpfc_read_lnk_stat Issue a READ LINK STATUS */ +/* mailbox command */ +/*************************************************/ void lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { @@ -573,30 +367,10 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) return; } -/** - * lpfc_reg_login: Prepare a mailbox command for registering remote login. - * @phba: pointer to lpfc hba data structure. - * @vpi: virtual N_Port identifier. - * @did: remote port identifier. - * @param: pointer to memory holding the server parameters. - * @pmb: pointer to the driver internal queue element for mailbox command. - * @flag: action flag to be passed back for the complete function. - * - * The registration login mailbox command is used to register an N_Port or - * F_Port login. This registration allows the HBA to cache the remote N_Port - * service parameters internally and thereby make the appropriate FC-2 - * decisions. The remote port service parameters are handed off by the driver - * to the HBA using a descriptor entry that directly identifies a buffer in - * host memory. In exchange, the HBA returns an RPI identifier. - * - * This routine prepares the mailbox command for registering remote port login. - * The function allocates DMA buffer for passing the service parameters to the - * HBA with the mailbox command. - * - * Return codes - * 0 - Success - * 1 - DMA memory allocation failed - **/ +/********************************************/ +/* lpfc_reg_login Issue a REG_LOGIN */ +/* mailbox command */ +/********************************************/ int lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag) @@ -644,20 +418,10 @@ lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, return (0); } -/** - * lpfc_unreg_login: Prepare a mailbox command for unregistering remote login. - * @phba: pointer to lpfc hba data structure. - * @vpi: virtual N_Port identifier. - * @rpi: remote port identifier - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The unregistration login mailbox command is used to unregister an N_Port - * or F_Port login. This command frees an RPI context in the HBA. It has the - * effect of performing an implicit N_Port/F_Port logout. - * - * This routine prepares the mailbox command for unregistering remote port - * login. - **/ +/**********************************************/ +/* lpfc_unreg_login Issue a UNREG_LOGIN */ +/* mailbox command */ +/**********************************************/ void lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi, LPFC_MBOXQ_t * pmb) @@ -676,21 +440,10 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi, return; } -/** - * lpfc_reg_vpi: Prepare a mailbox command for registering vport identifier. - * @phba: pointer to lpfc hba data structure. - * @vpi: virtual N_Port identifier. - * @sid: Fibre Channel S_ID (N_Port_ID assigned to a virtual N_Port). - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The registration vport identifier mailbox command is used to activate a - * virtual N_Port after it has acquired an N_Port_ID. The HBA validates the - * N_Port_ID against the information in the selected virtual N_Port context - * block and marks it active to allow normal processing of IOCB commands and - * received unsolicited exchanges. - * - * This routine prepares the mailbox command for registering a virtual N_Port. - **/ +/**************************************************/ +/* lpfc_reg_vpi Issue a REG_VPI */ +/* mailbox command */ +/**************************************************/ void lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid, LPFC_MBOXQ_t *pmb) @@ -708,22 +461,10 @@ lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid, } -/** - * lpfc_unreg_vpi: Prepare a mailbox command for unregistering vport id. - * @phba: pointer to lpfc hba data structure. - * @vpi: virtual N_Port identifier. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The unregistration vport identifier mailbox command is used to inactivate - * a virtual N_Port. The driver must have logged out and unregistered all - * remote N_Ports to abort any activity on the virtual N_Port. The HBA will - * unregisters any default RPIs associated with the specified vpi, aborting - * any active exchanges. The HBA will post the mailbox response after making - * the virtual N_Port inactive. - * - * This routine prepares the mailbox command for unregistering a virtual - * N_Port. - **/ +/**************************************************/ +/* lpfc_unreg_vpi Issue a UNREG_VNPI */ +/* mailbox command */ +/**************************************************/ void lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb) { @@ -738,19 +479,12 @@ lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb) } -/** - * lpfc_config_pcb_setup: Set up IOCB rings in the Port Control Block (PCB) - * @phba: pointer to lpfc hba data structure. - * - * This routine sets up and initializes the IOCB rings in the Port Control - * Block (PCB). - **/ static void lpfc_config_pcb_setup(struct lpfc_hba * phba) { struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; - PCB_t *pcbp = phba->pcb; + PCB_t *pcbp = &phba->slim2p->pcb; dma_addr_t pdma_addr; uint32_t offset; uint32_t iocbCnt = 0; @@ -779,43 +513,29 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba) continue; } /* Command ring setup for ring */ - pring->cmdringaddr = (void *)&phba->IOCBs[iocbCnt]; + pring->cmdringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt]; pcbp->rdsc[i].cmdEntries = pring->numCiocb; - offset = (uint8_t *) &phba->IOCBs[iocbCnt] - - (uint8_t *) phba->slim2p.virt; - pdma_addr = phba->slim2p.phys + offset; + offset = (uint8_t *) &phba->slim2p->IOCBs[iocbCnt] - + (uint8_t *) phba->slim2p; + pdma_addr = phba->slim2p_mapping + offset; pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr); pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr); iocbCnt += pring->numCiocb; /* Response ring setup for ring */ - pring->rspringaddr = (void *) &phba->IOCBs[iocbCnt]; + pring->rspringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt]; pcbp->rdsc[i].rspEntries = pring->numRiocb; - offset = (uint8_t *)&phba->IOCBs[iocbCnt] - - (uint8_t *)phba->slim2p.virt; - pdma_addr = phba->slim2p.phys + offset; + offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] - + (uint8_t *)phba->slim2p; + pdma_addr = phba->slim2p_mapping + offset; pcbp->rdsc[i].rspAddrHigh = putPaddrHigh(pdma_addr); pcbp->rdsc[i].rspAddrLow = putPaddrLow(pdma_addr); iocbCnt += pring->numRiocb; } } -/** - * lpfc_read_rev: Prepare a mailbox command for reading HBA revision. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The read revision mailbox command is used to read the revision levels of - * the HBA components. These components include hardware units, resident - * firmware, and available firmware. HBAs that supports SLI-3 mode of - * operation provide different response information depending on the version - * requested by the driver. - * - * This routine prepares the mailbox command for reading HBA revision - * information. - **/ void lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { @@ -828,16 +548,6 @@ lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) return; } -/** - * lpfc_build_hbq_profile2: Set up the HBQ Selection Profile 2. - * @hbqmb: pointer to the HBQ configuration data structure in mailbox command. - * @hbq_desc: pointer to the HBQ selection profile descriptor. - * - * The Host Buffer Queue (HBQ) Selection Profile 2 specifies that the HBA - * tests the incoming frames' R_CTL/TYPE fields with works 10:15 and performs - * the Sequence Length Test using the fields in the Selection Profile 2 - * extension in words 20:31. - **/ static void lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb, struct lpfc_hbq_init *hbq_desc) @@ -847,16 +557,6 @@ lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb, hbqmb->profiles.profile2.seqlenoff = hbq_desc->seqlenoff; } -/** - * lpfc_build_hbq_profile3: Set up the HBQ Selection Profile 3. - * @hbqmb: pointer to the HBQ configuration data structure in mailbox command. - * @hbq_desc: pointer to the HBQ selection profile descriptor. - * - * The Host Buffer Queue (HBQ) Selection Profile 3 specifies that the HBA - * tests the incoming frame's R_CTL/TYPE fields with words 10:15 and performs - * the Sequence Length Test and Byte Field Test using the fields in the - * Selection Profile 3 extension in words 20:31. - **/ static void lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb, struct lpfc_hbq_init *hbq_desc) @@ -869,17 +569,6 @@ lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb, sizeof(hbqmb->profiles.profile3.cmdmatch)); } -/** - * lpfc_build_hbq_profile5: Set up the HBQ Selection Profile 5. - * @hbqmb: pointer to the HBQ configuration data structure in mailbox command. - * @hbq_desc: pointer to the HBQ selection profile descriptor. - * - * The Host Buffer Queue (HBQ) Selection Profile 5 specifies a header HBQ. The - * HBA tests the initial frame of an incoming sequence using the frame's - * R_CTL/TYPE fields with words 10:15 and performs the Sequence Length Test - * and Byte Field Test using the fields in the Selection Profile 5 extension - * words 20:31. - **/ static void lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb, struct lpfc_hbq_init *hbq_desc) @@ -892,20 +581,6 @@ lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb, sizeof(hbqmb->profiles.profile5.cmdmatch)); } -/** - * lpfc_config_hbq: Prepare a mailbox command for configuring an HBQ. - * @phba: pointer to lpfc hba data structure. - * @id: HBQ identifier. - * @hbq_desc: pointer to the HBA descriptor data structure. - * @hbq_entry_index: index of the HBQ entry data structures. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The configure HBQ (Host Buffer Queue) mailbox command is used to configure - * an HBQ. The configuration binds events that require buffers to a particular - * ring and HBQ based on a selection profile. - * - * This routine prepares the mailbox command for configuring an HBQ. - **/ void lpfc_config_hbq(struct lpfc_hba *phba, uint32_t id, struct lpfc_hbq_init *hbq_desc, @@ -966,23 +641,8 @@ lpfc_config_hbq(struct lpfc_hba *phba, uint32_t id, return; } -/** - * lpfc_config_ring: Prepare a mailbox command for configuring an IOCB ring. - * @phba: pointer to lpfc hba data structure. - * @ring: - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The configure ring mailbox command is used to configure an IOCB ring. This - * configuration binds from one to six of HBA RC_CTL/TYPE mask entries to the - * ring. This is used to map incoming sequences to a particular ring whose - * RC_CTL/TYPE mask entry matches that of the sequence. The driver should not - * attempt to configure a ring whose number is greater than the number - * specified in the Port Control Block (PCB). It is an error to issue the - * configure ring command more than once with the same ring number. The HBA - * returns an error if the driver attempts this. - * - * This routine prepares the mailbox command for configuring IOCB ring. - **/ + + void lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) { @@ -1024,20 +684,6 @@ lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) return; } -/** - * lpfc_config_port: Prepare a mailbox command for configuring port. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The configure port mailbox command is used to identify the Port Control - * Block (PCB) in the driver memory. After this command is issued, the - * driver must not access the mailbox in the HBA without first resetting - * the HBA. The HBA may copy the PCB information to internal storage for - * subsequent use; the driver can not change the PCB information unless it - * resets the HBA. - * - * This routine prepares the mailbox command for configuring port. - **/ void lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) { @@ -1056,8 +702,8 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) mb->un.varCfgPort.pcbLen = sizeof(PCB_t); - offset = (uint8_t *)phba->pcb - (uint8_t *)phba->slim2p.virt; - pdma_addr = phba->slim2p.phys + offset; + offset = (uint8_t *)&phba->slim2p->pcb - (uint8_t *)phba->slim2p; + pdma_addr = phba->slim2p_mapping + offset; mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr); mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr); @@ -1065,13 +711,12 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) { mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ - mb->un.varCfgPort.ccrp = 1; /* Command Ring Polling */ - mb->un.varCfgPort.cinb = 1; /* Interrupt Notification Block */ mb->un.varCfgPort.max_hbq = lpfc_sli_hbq_count(); if (phba->max_vpi && phba->cfg_enable_npiv && phba->vpd.sli3Feat.cmv) { mb->un.varCfgPort.max_vpi = phba->max_vpi; mb->un.varCfgPort.cmv = 1; + phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED; } else mb->un.varCfgPort.max_vpi = phba->max_vpi = 0; } else @@ -1079,15 +724,16 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) mb->un.varCfgPort.sli_mode = phba->sli_rev; /* Now setup pcb */ - phba->pcb->type = TYPE_NATIVE_SLI2; - phba->pcb->feature = FEATURE_INITIAL_SLI2; + phba->slim2p->pcb.type = TYPE_NATIVE_SLI2; + phba->slim2p->pcb.feature = FEATURE_INITIAL_SLI2; /* Setup Mailbox pointers */ - phba->pcb->mailBoxSize = sizeof(MAILBOX_t); - offset = (uint8_t *)phba->mbox - (uint8_t *)phba->slim2p.virt; - pdma_addr = phba->slim2p.phys + offset; - phba->pcb->mbAddrHigh = putPaddrHigh(pdma_addr); - phba->pcb->mbAddrLow = putPaddrLow(pdma_addr); + phba->slim2p->pcb.mailBoxSize = offsetof(MAILBOX_t, us) + + sizeof(struct sli2_desc); + offset = (uint8_t *)&phba->slim2p->mbx - (uint8_t *)phba->slim2p; + pdma_addr = phba->slim2p_mapping + offset; + phba->slim2p->pcb.mbAddrHigh = putPaddrHigh(pdma_addr); + phba->slim2p->pcb.mbAddrLow = putPaddrLow(pdma_addr); /* * Setup Host Group ring pointer. @@ -1148,13 +794,13 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) } /* mask off BAR0's flag bits 0 - 3 */ - phba->pcb->hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) + - (void __iomem *)phba->host_gp - + phba->slim2p->pcb.hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) + + (void __iomem *) phba->host_gp - (void __iomem *)phba->MBslimaddr; if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64) - phba->pcb->hgpAddrHigh = bar_high; + phba->slim2p->pcb.hgpAddrHigh = bar_high; else - phba->pcb->hgpAddrHigh = 0; + phba->slim2p->pcb.hgpAddrHigh = 0; /* write HGP data to SLIM at the required longword offset */ memset(&hgp, 0, sizeof(struct lpfc_hgp)); @@ -1164,19 +810,17 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) } /* Setup Port Group ring pointer */ - if (phba->sli3_options & LPFC_SLI3_INB_ENABLED) { - pgp_offset = offsetof(struct lpfc_sli2_slim, - mbx.us.s3_inb_pgp.port); - phba->hbq_get = phba->mbox->us.s3_inb_pgp.hbq_get; - } else if (phba->sli_rev == 3) { - pgp_offset = offsetof(struct lpfc_sli2_slim, - mbx.us.s3_pgp.port); - phba->hbq_get = phba->mbox->us.s3_pgp.hbq_get; - } else - pgp_offset = offsetof(struct lpfc_sli2_slim, mbx.us.s2.port); - pdma_addr = phba->slim2p.phys + pgp_offset; - phba->pcb->pgpAddrHigh = putPaddrHigh(pdma_addr); - phba->pcb->pgpAddrLow = putPaddrLow(pdma_addr); + if (phba->sli_rev == 3) + pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s3_pgp.port - + (uint8_t *)phba->slim2p; + else + pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port - + (uint8_t *)phba->slim2p; + + pdma_addr = phba->slim2p_mapping + pgp_offset; + phba->slim2p->pcb.pgpAddrHigh = putPaddrHigh(pdma_addr); + phba->slim2p->pcb.pgpAddrLow = putPaddrLow(pdma_addr); + phba->hbq_get = &phba->slim2p->mbx.us.s3_pgp.hbq_get[0]; /* Use callback routine to setp rings in the pcb */ lpfc_config_pcb_setup(phba); @@ -1191,24 +835,10 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) } /* Swap PCB if needed */ - lpfc_sli_pcimem_bcopy(phba->pcb, phba->pcb, sizeof(PCB_t)); + lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb, + sizeof(PCB_t)); } -/** - * lpfc_kill_board: Prepare a mailbox command for killing board. - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * The kill board mailbox command is used to tell firmware to perform a - * graceful shutdown of a channel on a specified board to prepare for reset. - * When the kill board mailbox command is received, the ER3 bit is set to 1 - * in the Host Status register and the ER Attention bit is set to 1 in the - * Host Attention register of the HBA function that received the kill board - * command. - * - * This routine prepares the mailbox command for killing the board in - * preparation for a graceful shutdown. - **/ void lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { @@ -1220,16 +850,6 @@ lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) return; } -/** - * lpfc_mbox_put: Put a mailbox cmd into the tail of driver's mailbox queue. - * @phba: pointer to lpfc hba data structure. - * @mbq: pointer to the driver internal queue element for mailbox command. - * - * Driver maintains a internal mailbox command queue implemented as a linked - * list. When a mailbox command is issued, it shall be put into the mailbox - * command queue such that they shall be processed orderly as HBA can process - * one mailbox command at a time. - **/ void lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) { @@ -1244,20 +864,6 @@ lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) return; } -/** - * lpfc_mbox_get: Remove a mailbox cmd from the head of driver's mailbox queue. - * @phba: pointer to lpfc hba data structure. - * - * Driver maintains a internal mailbox command queue implemented as a linked - * list. When a mailbox command is issued, it shall be put into the mailbox - * command queue such that they shall be processed orderly as HBA can process - * one mailbox command at a time. After HBA finished processing a mailbox - * command, the driver will remove a pending mailbox command from the head of - * the mailbox command queue and send to the HBA for processing. - * - * Return codes - * pointer to the driver internal queue element for mailbox command. - **/ LPFC_MBOXQ_t * lpfc_mbox_get(struct lpfc_hba * phba) { @@ -1271,17 +877,6 @@ lpfc_mbox_get(struct lpfc_hba * phba) return mbq; } -/** - * lpfc_mbox_cmpl_put: Put mailbox command into mailbox command complete list. - * @phba: pointer to lpfc hba data structure. - * @mbq: pointer to the driver internal queue element for mailbox command. - * - * This routine put the completed mailbox command into the mailbox command - * complete list. This routine is called from driver interrupt handler - * context.The mailbox complete list is used by the driver worker thread - * to process mailbox complete callback functions outside the driver interrupt - * handler. - **/ void lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) { @@ -1292,17 +887,6 @@ lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) return; } -/** - * lpfc_mbox_tmo_val: Retrieve mailbox command timeout value. - * @phba: pointer to lpfc hba data structure. - * @cmd: mailbox command code. - * - * This routine retrieves the proper timeout value according to the mailbox - * command code. - * - * Return codes - * Timeout value to be used for the given mailbox command - **/ int lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd) { diff --git a/trunk/drivers/scsi/lpfc/lpfc_mem.c b/trunk/drivers/scsi/lpfc/lpfc_mem.c index a4bba2069248..3c0cebc71800 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_mem.c +++ b/trunk/drivers/scsi/lpfc/lpfc_mem.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2008 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -30,7 +30,6 @@ #include "lpfc_hw.h" #include "lpfc_sli.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h" @@ -40,21 +39,7 @@ #define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */ -/** - * lpfc_mem_alloc: create and allocate all PCI and memory pools - * @phba: HBA to allocate pools for - * - * Description: Creates and allocates PCI pools lpfc_scsi_dma_buf_pool, - * lpfc_mbuf_pool, lpfc_hbq_pool. Creates and allocates kmalloc-backed mempools - * for LPFC_MBOXQ_t and lpfc_nodelist. Also allocates the VPI bitmask. - * - * Notes: Not interrupt-safe. Must be called with no locks held. If any - * allocation fails, frees all successfully allocated memory before returning. - * - * Returns: - * 0 on success - * -ENOMEM on failure (if any memory allocations fail) - **/ + int lpfc_mem_alloc(struct lpfc_hba * phba) { @@ -135,16 +120,6 @@ lpfc_mem_alloc(struct lpfc_hba * phba) return -ENOMEM; } -/** - * lpfc_mem_free: Frees all PCI and memory allocated by lpfc_mem_alloc - * @phba: HBA to free memory for - * - * Description: Frees PCI pools lpfc_scsi_dma_buf_pool, lpfc_mbuf_pool, - * lpfc_hbq_pool. Frees kmalloc-backed mempools for LPFC_MBOXQ_t and - * lpfc_nodelist. Also frees the VPI bitmask. - * - * Returns: None - **/ void lpfc_mem_free(struct lpfc_hba * phba) { @@ -206,29 +181,12 @@ lpfc_mem_free(struct lpfc_hba * phba) phba->lpfc_scsi_dma_buf_pool = NULL; phba->lpfc_mbuf_pool = NULL; - /* Free the iocb lookup array */ + /* Free the iocb lookup array */ kfree(psli->iocbq_lookup); psli->iocbq_lookup = NULL; + } -/** - * lpfc_mbuf_alloc: Allocate an mbuf from the lpfc_mbuf_pool PCI pool - * @phba: HBA which owns the pool to allocate from - * @mem_flags: indicates if this is a priority (MEM_PRI) allocation - * @handle: used to return the DMA-mapped address of the mbuf - * - * Description: Allocates a DMA-mapped buffer from the lpfc_mbuf_pool PCI pool. - * Allocates from generic pci_pool_alloc function first and if that fails and - * mem_flags has MEM_PRI set (the only defined flag), returns an mbuf from the - * HBA's pool. - * - * Notes: Not interrupt-safe. Must be called with no locks held. Takes - * phba->hbalock. - * - * Returns: - * pointer to the allocated mbuf on success - * NULL on failure - **/ void * lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) { @@ -248,20 +206,6 @@ lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) return ret; } -/** - * __lpfc_mem_free: Free an mbuf from the lpfc_mbuf_pool PCI pool (locked) - * @phba: HBA which owns the pool to return to - * @virt: mbuf to free - * @dma: the DMA-mapped address of the lpfc_mbuf_pool to be freed - * - * Description: Returns an mbuf lpfc_mbuf_pool to the lpfc_mbuf_safety_pool if - * it is below its max_count, frees the mbuf otherwise. - * - * Notes: Must be called with phba->hbalock held to synchronize access to - * lpfc_mbuf_safety_pool. - * - * Returns: None - **/ void __lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) { @@ -277,21 +221,7 @@ __lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) return; } -/** - * lpfc_mem_free: Free an mbuf from the lpfc_mbuf_pool PCI pool (unlocked) - * @phba: HBA which owns the pool to return to - * @virt: mbuf to free - * @dma: the DMA-mapped address of the lpfc_mbuf_pool to be freed - * - * Description: Returns an mbuf lpfc_mbuf_pool to the lpfc_mbuf_safety_pool if - * it is below its max_count, frees the mbuf otherwise. - * - * Notes: Takes phba->hbalock. Can be called with or without other locks held. - * - * Returns: None - **/ void - lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) { unsigned long iflags; @@ -302,19 +232,6 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) return; } -/** - * lpfc_els_hbq_alloc: Allocate an HBQ buffer - * @phba: HBA to allocate HBQ buffer for - * - * Description: Allocates a DMA-mapped HBQ buffer from the lpfc_hbq_pool PCI - * pool along a non-DMA-mapped container for it. - * - * Notes: Not interrupt-safe. Must be called with no locks held. - * - * Returns: - * pointer to HBQ on success - * NULL on failure - **/ struct hbq_dmabuf * lpfc_els_hbq_alloc(struct lpfc_hba *phba) { @@ -334,18 +251,6 @@ lpfc_els_hbq_alloc(struct lpfc_hba *phba) return hbqbp; } -/** - * lpfc_mem_hbq_free: Frees an HBQ buffer allocated with lpfc_els_hbq_alloc - * @phba: HBA buffer was allocated for - * @hbqbp: HBQ container returned by lpfc_els_hbq_alloc - * - * Description: Frees both the container and the DMA-mapped buffer returned by - * lpfc_els_hbq_alloc. - * - * Notes: Can be called with or without locks held. - * - * Returns: None - **/ void lpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp) { @@ -354,18 +259,7 @@ lpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp) return; } -/** - * lpfc_in_buf_free: Free a DMA buffer - * @phba: HBA buffer is associated with - * @mp: Buffer to free - * - * Description: Frees the given DMA buffer in the appropriate way given if the - * HBA is running in SLI3 mode with HBQs enabled. - * - * Notes: Takes phba->hbalock. Can be called with or without other locks held. - * - * Returns: None - **/ +/* This is ONLY called for the LPFC_ELS_HBQ */ void lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp) { diff --git a/trunk/drivers/scsi/lpfc/lpfc_nl.h b/trunk/drivers/scsi/lpfc/lpfc_nl.h deleted file mode 100644 index 1accb5a9f4e6..000000000000 --- a/trunk/drivers/scsi/lpfc/lpfc_nl.h +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************* - * This file is part of the Emulex Linux Device Driver for * - * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2008 Emulex. All rights reserved. * - * EMULEX and SLI are trademarks of Emulex. * - * www.emulex.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of version 2 of the GNU General * - * Public License as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful. * - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * - * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * - * TO BE LEGALLY INVALID. See the GNU General Public License for * - * more details, a copy of which can be found in the file COPYING * - * included with this package. * - *******************************************************************/ - -/* Event definitions for RegisterForEvent */ -#define FC_REG_LINK_EVENT 0x0001 /* link up / down events */ -#define FC_REG_RSCN_EVENT 0x0002 /* RSCN events */ -#define FC_REG_CT_EVENT 0x0004 /* CT request events */ -#define FC_REG_DUMP_EVENT 0x0008 /* Dump events */ -#define FC_REG_TEMPERATURE_EVENT 0x0010 /* temperature events */ -#define FC_REG_ELS_EVENT 0x0020 /* lpfc els events */ -#define FC_REG_FABRIC_EVENT 0x0040 /* lpfc fabric events */ -#define FC_REG_SCSI_EVENT 0x0080 /* lpfc scsi events */ -#define FC_REG_BOARD_EVENT 0x0100 /* lpfc board events */ -#define FC_REG_ADAPTER_EVENT 0x0200 /* lpfc adapter events */ -#define FC_REG_EVENT_MASK (FC_REG_LINK_EVENT | \ - FC_REG_RSCN_EVENT | \ - FC_REG_CT_EVENT | \ - FC_REG_DUMP_EVENT | \ - FC_REG_TEMPERATURE_EVENT | \ - FC_REG_ELS_EVENT | \ - FC_REG_FABRIC_EVENT | \ - FC_REG_SCSI_EVENT | \ - FC_REG_BOARD_EVENT | \ - FC_REG_ADAPTER_EVENT) -/* Temperature events */ -#define LPFC_CRIT_TEMP 0x1 -#define LPFC_THRESHOLD_TEMP 0x2 -#define LPFC_NORMAL_TEMP 0x3 -/* - * All net link event payloads will begin with and event type - * and subcategory. The event type must come first. - * The subcategory further defines the data that follows in the rest - * of the payload. Each category will have its own unique header plus - * any addtional data unique to the subcategory. - * The payload sent via the fc transport is one-way driver->application. - */ - -/* els event header */ -struct lpfc_els_event_header { - uint32_t event_type; - uint32_t subcategory; - uint8_t wwpn[8]; - uint8_t wwnn[8]; -}; - -/* subcategory codes for FC_REG_ELS_EVENT */ -#define LPFC_EVENT_PLOGI_RCV 0x01 -#define LPFC_EVENT_PRLO_RCV 0x02 -#define LPFC_EVENT_ADISC_RCV 0x04 -#define LPFC_EVENT_LSRJT_RCV 0x08 - -/* special els lsrjt event */ -struct lpfc_lsrjt_event { - struct lpfc_els_event_header header; - uint32_t command; - uint32_t reason_code; - uint32_t explanation; -}; - - -/* fabric event header */ -struct lpfc_fabric_event_header { - uint32_t event_type; - uint32_t subcategory; - uint8_t wwpn[8]; - uint8_t wwnn[8]; -}; - -/* subcategory codes for FC_REG_FABRIC_EVENT */ -#define LPFC_EVENT_FABRIC_BUSY 0x01 -#define LPFC_EVENT_PORT_BUSY 0x02 -#define LPFC_EVENT_FCPRDCHKERR 0x04 - -/* special case fabric fcprdchkerr event */ -struct lpfc_fcprdchkerr_event { - struct lpfc_fabric_event_header header; - uint32_t lun; - uint32_t opcode; - uint32_t fcpiparam; -}; - - -/* scsi event header */ -struct lpfc_scsi_event_header { - uint32_t event_type; - uint32_t subcategory; - uint32_t lun; - uint8_t wwpn[8]; - uint8_t wwnn[8]; -}; - -/* subcategory codes for FC_REG_SCSI_EVENT */ -#define LPFC_EVENT_QFULL 0x0001 -#define LPFC_EVENT_DEVBSY 0x0002 -#define LPFC_EVENT_CHECK_COND 0x0004 -#define LPFC_EVENT_LUNRESET 0x0008 -#define LPFC_EVENT_TGTRESET 0x0010 -#define LPFC_EVENT_BUSRESET 0x0020 -#define LPFC_EVENT_VARQUEDEPTH 0x0040 - -/* special case scsi varqueuedepth event */ -struct lpfc_scsi_varqueuedepth_event { - struct lpfc_scsi_event_header scsi_event; - uint32_t oldval; - uint32_t newval; -}; - -/* special case scsi check condition event */ -struct lpfc_scsi_check_condition_event { - struct lpfc_scsi_event_header scsi_event; - uint8_t sense_key; - uint8_t asc; - uint8_t ascq; -}; - -/* event codes for FC_REG_BOARD_EVENT */ -#define LPFC_EVENT_PORTINTERR 0x01 - -/* board event header */ -struct lpfc_board_event_header { - uint32_t event_type; - uint32_t subcategory; -}; - - -/* event codes for FC_REG_ADAPTER_EVENT */ -#define LPFC_EVENT_ARRIVAL 0x01 - -/* adapter event header */ -struct lpfc_adapter_event_header { - uint32_t event_type; - uint32_t subcategory; -}; - - -/* event codes for temp_event */ -#define LPFC_CRIT_TEMP 0x1 -#define LPFC_THRESHOLD_TEMP 0x2 -#define LPFC_NORMAL_TEMP 0x3 - -struct temp_event { - uint32_t event_type; - uint32_t event_code; - uint32_t data; -}; - diff --git a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c index 0c25d97acb42..6688a8689b56 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -30,7 +30,6 @@ #include "lpfc_hw.h" #include "lpfc_sli.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h" @@ -1004,8 +1003,20 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, spin_lock_irq(shost->host_lock); ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(shost->host_lock); - if (vport->num_disc_nodes) + + if (vport->num_disc_nodes) { lpfc_more_adisc(vport); + if ((vport->num_disc_nodes == 0) && + (vport->fc_npr_cnt)) + lpfc_els_disc_plogi(vport); + if (vport->num_disc_nodes == 0) { + spin_lock_irq(shost->host_lock); + vport->fc_flag &= ~FC_NDISC_ACTIVE; + spin_unlock_irq(shost->host_lock); + lpfc_can_disctmo(vport); + lpfc_end_rscn(vport); + } + } } return ndlp->nlp_state; } @@ -1854,13 +1865,8 @@ static uint32_t lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) { - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - if (ndlp->nlp_DID == Fabric_DID) { - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); - spin_unlock_irq(shost->host_lock); - } lpfc_unreg_rpi(vport, ndlp); + /* This routine does nothing, just return the current state */ return ndlp->nlp_state; } @@ -2149,7 +2155,7 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_nlp_put(ndlp); } else { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "0213 DSM out state %d on NPort free\n", rc); + "0212 DSM out state %d on NPort free\n", rc); lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM, "DSM out: ste:%d did:x%x flg:x%x", diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.c b/trunk/drivers/scsi/lpfc/lpfc_scsi.c index bd1867411821..1bcebbd3dfac 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.c +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.c @@ -32,7 +32,6 @@ #include "lpfc_version.h" #include "lpfc_hw.h" #include "lpfc_sli.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h" @@ -43,111 +42,6 @@ #define LPFC_RESET_WAIT 2 #define LPFC_ABORT_WAIT 2 -/** - * lpfc_update_stats: Update statistical data for the command completion. - * @phba: Pointer to HBA object. - * @lpfc_cmd: lpfc scsi command object pointer. - * - * This function is called when there is a command completion and this - * function updates the statistical data for the command completion. - **/ -static void -lpfc_update_stats(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) -{ - struct lpfc_rport_data *rdata = lpfc_cmd->rdata; - struct lpfc_nodelist *pnode = rdata->pnode; - struct scsi_cmnd *cmd = lpfc_cmd->pCmd; - unsigned long flags; - struct Scsi_Host *shost = cmd->device->host; - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; - unsigned long latency; - int i; - - if (cmd->result) - return; - - spin_lock_irqsave(shost->host_lock, flags); - if (!vport->stat_data_enabled || - vport->stat_data_blocked || - !pnode->lat_data || - (phba->bucket_type == LPFC_NO_BUCKET)) { - spin_unlock_irqrestore(shost->host_lock, flags); - return; - } - latency = jiffies_to_msecs(jiffies - lpfc_cmd->start_time); - - if (phba->bucket_type == LPFC_LINEAR_BUCKET) { - i = (latency + phba->bucket_step - 1 - phba->bucket_base)/ - phba->bucket_step; - if (i >= LPFC_MAX_BUCKET_COUNT) - i = LPFC_MAX_BUCKET_COUNT; - } else { - for (i = 0; i < LPFC_MAX_BUCKET_COUNT-1; i++) - if (latency <= (phba->bucket_base + - ((1<bucket_step))) - break; - } - - pnode->lat_data[i].cmd_count++; - spin_unlock_irqrestore(shost->host_lock, flags); -} - - -/** - * lpfc_send_sdev_queuedepth_change_event: Posts a queuedepth change - * event. - * @phba: Pointer to HBA context object. - * @vport: Pointer to vport object. - * @ndlp: Pointer to FC node associated with the target. - * @lun: Lun number of the scsi device. - * @old_val: Old value of the queue depth. - * @new_val: New value of the queue depth. - * - * This function sends an event to the mgmt application indicating - * there is a change in the scsi device queue depth. - **/ -static void -lpfc_send_sdev_queuedepth_change_event(struct lpfc_hba *phba, - struct lpfc_vport *vport, - struct lpfc_nodelist *ndlp, - uint32_t lun, - uint32_t old_val, - uint32_t new_val) -{ - struct lpfc_fast_path_event *fast_path_evt; - unsigned long flags; - - fast_path_evt = lpfc_alloc_fast_evt(phba); - if (!fast_path_evt) - return; - - fast_path_evt->un.queue_depth_evt.scsi_event.event_type = - FC_REG_SCSI_EVENT; - fast_path_evt->un.queue_depth_evt.scsi_event.subcategory = - LPFC_EVENT_VARQUEDEPTH; - - /* Report all luns with change in queue depth */ - fast_path_evt->un.queue_depth_evt.scsi_event.lun = lun; - if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { - memcpy(&fast_path_evt->un.queue_depth_evt.scsi_event.wwpn, - &ndlp->nlp_portname, sizeof(struct lpfc_name)); - memcpy(&fast_path_evt->un.queue_depth_evt.scsi_event.wwnn, - &ndlp->nlp_nodename, sizeof(struct lpfc_name)); - } - - fast_path_evt->un.queue_depth_evt.oldval = old_val; - fast_path_evt->un.queue_depth_evt.newval = new_val; - fast_path_evt->vport = vport; - - fast_path_evt->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT; - spin_lock_irqsave(&phba->hbalock, flags); - list_add_tail(&fast_path_evt->work_evt.evt_listp, &phba->work_list); - spin_unlock_irqrestore(&phba->hbalock, flags); - lpfc_worker_wake_up(phba); - - return; -} - /* * This function is called with no lock held when there is a resource * error in driver or in firmware. @@ -223,10 +117,9 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) struct lpfc_vport **vports; struct Scsi_Host *shost; struct scsi_device *sdev; - unsigned long new_queue_depth, old_queue_depth; + unsigned long new_queue_depth; unsigned long num_rsrc_err, num_cmd_success; int i; - struct lpfc_rport_data *rdata; num_rsrc_err = atomic_read(&phba->num_rsrc_err); num_cmd_success = atomic_read(&phba->num_cmd_success); @@ -244,7 +137,6 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) else new_queue_depth = sdev->queue_depth - new_queue_depth; - old_queue_depth = sdev->queue_depth; if (sdev->ordered_tags) scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, @@ -253,13 +145,6 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, new_queue_depth); - rdata = sdev->hostdata; - if (rdata) - lpfc_send_sdev_queuedepth_change_event( - phba, vports[i], - rdata->pnode, - sdev->lun, old_queue_depth, - new_queue_depth); } } lpfc_destroy_vport_work_array(phba, vports); @@ -274,7 +159,6 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) struct Scsi_Host *shost; struct scsi_device *sdev; int i; - struct lpfc_rport_data *rdata; vports = lpfc_create_vport_work_array(phba); if (vports != NULL) @@ -292,14 +176,6 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, sdev->queue_depth+1); - rdata = sdev->hostdata; - if (rdata) - lpfc_send_sdev_queuedepth_change_event( - phba, vports[i], - rdata->pnode, - sdev->lun, - sdev->queue_depth - 1, - sdev->queue_depth); } } lpfc_destroy_vport_work_array(phba, vports); @@ -307,35 +183,6 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) atomic_set(&phba->num_cmd_success, 0); } -/** - * lpfc_scsi_dev_block: set all scsi hosts to block state. - * @phba: Pointer to HBA context object. - * - * This function walks vport list and set each SCSI host to block state - * by invoking fc_remote_port_delete() routine. This function is invoked - * with EEH when device's PCI slot has been permanently disabled. - **/ -void -lpfc_scsi_dev_block(struct lpfc_hba *phba) -{ - struct lpfc_vport **vports; - struct Scsi_Host *shost; - struct scsi_device *sdev; - struct fc_rport *rport; - int i; - - vports = lpfc_create_vport_work_array(phba); - if (vports != NULL) - for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { - shost = lpfc_shost_from_vport(vports[i]); - shost_for_each_device(sdev, shost) { - rport = starget_to_rport(scsi_target(sdev)); - fc_remote_port_delete(rport); - } - } - lpfc_destroy_vport_work_array(phba, vports); -} - /* * This routine allocates a scsi buffer, which contains all the necessary * information needed to initiate a SCSI I/O. The non-DMAable buffer region @@ -351,9 +198,7 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport) struct lpfc_scsi_buf *psb; struct ulp_bde64 *bpl; IOCB_t *iocb; - dma_addr_t pdma_phys_fcp_cmd; - dma_addr_t pdma_phys_fcp_rsp; - dma_addr_t pdma_phys_bpl; + dma_addr_t pdma_phys; uint16_t iotag; psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); @@ -393,60 +238,40 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport) /* Initialize local short-hand pointers. */ bpl = psb->fcp_bpl; - pdma_phys_fcp_cmd = psb->dma_handle; - pdma_phys_fcp_rsp = psb->dma_handle + sizeof(struct fcp_cmnd); - pdma_phys_bpl = psb->dma_handle + sizeof(struct fcp_cmnd) + - sizeof(struct fcp_rsp); + pdma_phys = psb->dma_handle; /* * The first two bdes are the FCP_CMD and FCP_RSP. The balance are sg * list bdes. Initialize the first two and leave the rest for * queuecommand. */ - bpl[0].addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys_fcp_cmd)); - bpl[0].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_cmd)); - bpl[0].tus.f.bdeSize = sizeof(struct fcp_cmnd); - bpl[0].tus.f.bdeFlags = BUFF_TYPE_BDE_64; - bpl[0].tus.w = le32_to_cpu(bpl->tus.w); + bpl->addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys)); + bpl->addrLow = le32_to_cpu(putPaddrLow(pdma_phys)); + bpl->tus.f.bdeSize = sizeof (struct fcp_cmnd); + bpl->tus.f.bdeFlags = BUFF_USE_CMND; + bpl->tus.w = le32_to_cpu(bpl->tus.w); + bpl++; /* Setup the physical region for the FCP RSP */ - bpl[1].addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys_fcp_rsp)); - bpl[1].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_rsp)); - bpl[1].tus.f.bdeSize = sizeof(struct fcp_rsp); - bpl[1].tus.f.bdeFlags = BUFF_TYPE_BDE_64; - bpl[1].tus.w = le32_to_cpu(bpl->tus.w); + pdma_phys += sizeof (struct fcp_cmnd); + bpl->addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys)); + bpl->addrLow = le32_to_cpu(putPaddrLow(pdma_phys)); + bpl->tus.f.bdeSize = sizeof (struct fcp_rsp); + bpl->tus.f.bdeFlags = (BUFF_USE_CMND | BUFF_USE_RCV); + bpl->tus.w = le32_to_cpu(bpl->tus.w); /* * Since the IOCB for the FCP I/O is built into this lpfc_scsi_buf, * initialize it with all known data now. */ + pdma_phys += (sizeof (struct fcp_rsp)); iocb = &psb->cur_iocbq.iocb; iocb->un.fcpi64.bdl.ulpIoTag32 = 0; - if (phba->sli_rev == 3) { - /* fill in immediate fcp command BDE */ - iocb->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BDE_IMMED; - iocb->un.fcpi64.bdl.bdeSize = sizeof(struct fcp_cmnd); - iocb->un.fcpi64.bdl.addrLow = offsetof(IOCB_t, - unsli3.fcp_ext.icd); - iocb->un.fcpi64.bdl.addrHigh = 0; - iocb->ulpBdeCount = 0; - iocb->ulpLe = 0; - /* fill in responce BDE */ - iocb->unsli3.fcp_ext.rbde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; - iocb->unsli3.fcp_ext.rbde.tus.f.bdeSize = - sizeof(struct fcp_rsp); - iocb->unsli3.fcp_ext.rbde.addrLow = - putPaddrLow(pdma_phys_fcp_rsp); - iocb->unsli3.fcp_ext.rbde.addrHigh = - putPaddrHigh(pdma_phys_fcp_rsp); - } else { - iocb->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BLP_64; - iocb->un.fcpi64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64)); - iocb->un.fcpi64.bdl.addrLow = putPaddrLow(pdma_phys_bpl); - iocb->un.fcpi64.bdl.addrHigh = putPaddrHigh(pdma_phys_bpl); - iocb->ulpBdeCount = 1; - iocb->ulpLe = 1; - } + iocb->un.fcpi64.bdl.addrHigh = putPaddrHigh(pdma_phys); + iocb->un.fcpi64.bdl.addrLow = putPaddrLow(pdma_phys); + iocb->un.fcpi64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); + iocb->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BDL; + iocb->ulpBdeCount = 1; iocb->ulpClass = CLASS3; return psb; @@ -488,9 +313,8 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl; IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; - struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde; dma_addr_t physaddr; - uint32_t num_bde = 0; + uint32_t i, num_bde = 0; int nseg, datadir = scsi_cmnd->sc_data_direction; /* @@ -528,159 +352,37 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) * during probe that limits the number of sg elements in any * single scsi command. Just run through the seg_cnt and format * the bde's. - * When using SLI-3 the driver will try to fit all the BDEs into - * the IOCB. If it can't then the BDEs get added to a BPL as it - * does for SLI-2 mode. */ - scsi_for_each_sg(scsi_cmnd, sgel, nseg, num_bde) { + scsi_for_each_sg(scsi_cmnd, sgel, nseg, i) { physaddr = sg_dma_address(sgel); - if (phba->sli_rev == 3 && - nseg <= LPFC_EXT_DATA_BDE_COUNT) { - data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; - data_bde->tus.f.bdeSize = sg_dma_len(sgel); - data_bde->addrLow = putPaddrLow(physaddr); - data_bde->addrHigh = putPaddrHigh(physaddr); - data_bde++; - } else { - bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64; - bpl->tus.f.bdeSize = sg_dma_len(sgel); - bpl->tus.w = le32_to_cpu(bpl->tus.w); - bpl->addrLow = - le32_to_cpu(putPaddrLow(physaddr)); - bpl->addrHigh = - le32_to_cpu(putPaddrHigh(physaddr)); - bpl++; - } + bpl->addrLow = le32_to_cpu(putPaddrLow(physaddr)); + bpl->addrHigh = le32_to_cpu(putPaddrHigh(physaddr)); + bpl->tus.f.bdeSize = sg_dma_len(sgel); + if (datadir == DMA_TO_DEVICE) + bpl->tus.f.bdeFlags = 0; + else + bpl->tus.f.bdeFlags = BUFF_USE_RCV; + bpl->tus.w = le32_to_cpu(bpl->tus.w); + bpl++; + num_bde++; } } /* * Finish initializing those IOCB fields that are dependent on the - * scsi_cmnd request_buffer. Note that for SLI-2 the bdeSize is - * explicitly reinitialized and for SLI-3 the extended bde count is - * explicitly reinitialized since all iocb memory resources are reused. + * scsi_cmnd request_buffer. Note that the bdeSize is explicitly + * reinitialized since all iocb memory resources are used many times + * for transmit, receive, and continuation bpl's. */ - if (phba->sli_rev == 3) { - if (num_bde > LPFC_EXT_DATA_BDE_COUNT) { - /* - * The extended IOCB format can only fit 3 BDE or a BPL. - * This I/O has more than 3 BDE so the 1st data bde will - * be a BPL that is filled in here. - */ - physaddr = lpfc_cmd->dma_handle; - data_bde->tus.f.bdeFlags = BUFF_TYPE_BLP_64; - data_bde->tus.f.bdeSize = (num_bde * - sizeof(struct ulp_bde64)); - physaddr += (sizeof(struct fcp_cmnd) + - sizeof(struct fcp_rsp) + - (2 * sizeof(struct ulp_bde64))); - data_bde->addrHigh = putPaddrHigh(physaddr); - data_bde->addrLow = putPaddrLow(physaddr); - /* ebde count includes the responce bde and data bpl */ - iocb_cmd->unsli3.fcp_ext.ebde_count = 2; - } else { - /* ebde count includes the responce bde and data bdes */ - iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1); - } - } else { - iocb_cmd->un.fcpi64.bdl.bdeSize = - ((num_bde + 2) * sizeof(struct ulp_bde64)); - } + iocb_cmd->un.fcpi64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); + iocb_cmd->un.fcpi64.bdl.bdeSize += + (num_bde * sizeof (struct ulp_bde64)); + iocb_cmd->ulpBdeCount = 1; + iocb_cmd->ulpLe = 1; fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); return 0; } -/** - * lpfc_send_scsi_error_event: Posts an event when there is SCSI error. - * @phba: Pointer to hba context object. - * @vport: Pointer to vport object. - * @lpfc_cmd: Pointer to lpfc scsi command which reported the error. - * @rsp_iocb: Pointer to response iocb object which reported error. - * - * This function posts an event when there is a SCSI command reporting - * error from the scsi device. - **/ -static void -lpfc_send_scsi_error_event(struct lpfc_hba *phba, struct lpfc_vport *vport, - struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_iocbq *rsp_iocb) { - struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; - struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp; - uint32_t resp_info = fcprsp->rspStatus2; - uint32_t scsi_status = fcprsp->rspStatus3; - uint32_t fcpi_parm = rsp_iocb->iocb.un.fcpi.fcpi_parm; - struct lpfc_fast_path_event *fast_path_evt = NULL; - struct lpfc_nodelist *pnode = lpfc_cmd->rdata->pnode; - unsigned long flags; - - /* If there is queuefull or busy condition send a scsi event */ - if ((cmnd->result == SAM_STAT_TASK_SET_FULL) || - (cmnd->result == SAM_STAT_BUSY)) { - fast_path_evt = lpfc_alloc_fast_evt(phba); - if (!fast_path_evt) - return; - fast_path_evt->un.scsi_evt.event_type = - FC_REG_SCSI_EVENT; - fast_path_evt->un.scsi_evt.subcategory = - (cmnd->result == SAM_STAT_TASK_SET_FULL) ? - LPFC_EVENT_QFULL : LPFC_EVENT_DEVBSY; - fast_path_evt->un.scsi_evt.lun = cmnd->device->lun; - memcpy(&fast_path_evt->un.scsi_evt.wwpn, - &pnode->nlp_portname, sizeof(struct lpfc_name)); - memcpy(&fast_path_evt->un.scsi_evt.wwnn, - &pnode->nlp_nodename, sizeof(struct lpfc_name)); - } else if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen && - ((cmnd->cmnd[0] == READ_10) || (cmnd->cmnd[0] == WRITE_10))) { - fast_path_evt = lpfc_alloc_fast_evt(phba); - if (!fast_path_evt) - return; - fast_path_evt->un.check_cond_evt.scsi_event.event_type = - FC_REG_SCSI_EVENT; - fast_path_evt->un.check_cond_evt.scsi_event.subcategory = - LPFC_EVENT_CHECK_COND; - fast_path_evt->un.check_cond_evt.scsi_event.lun = - cmnd->device->lun; - memcpy(&fast_path_evt->un.check_cond_evt.scsi_event.wwpn, - &pnode->nlp_portname, sizeof(struct lpfc_name)); - memcpy(&fast_path_evt->un.check_cond_evt.scsi_event.wwnn, - &pnode->nlp_nodename, sizeof(struct lpfc_name)); - fast_path_evt->un.check_cond_evt.sense_key = - cmnd->sense_buffer[2] & 0xf; - fast_path_evt->un.check_cond_evt.asc = cmnd->sense_buffer[12]; - fast_path_evt->un.check_cond_evt.ascq = cmnd->sense_buffer[13]; - } else if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) && - fcpi_parm && - ((be32_to_cpu(fcprsp->rspResId) != fcpi_parm) || - ((scsi_status == SAM_STAT_GOOD) && - !(resp_info & (RESID_UNDER | RESID_OVER))))) { - /* - * If status is good or resid does not match with fcp_param and - * there is valid fcpi_parm, then there is a read_check error - */ - fast_path_evt = lpfc_alloc_fast_evt(phba); - if (!fast_path_evt) - return; - fast_path_evt->un.read_check_error.header.event_type = - FC_REG_FABRIC_EVENT; - fast_path_evt->un.read_check_error.header.subcategory = - LPFC_EVENT_FCPRDCHKERR; - memcpy(&fast_path_evt->un.read_check_error.header.wwpn, - &pnode->nlp_portname, sizeof(struct lpfc_name)); - memcpy(&fast_path_evt->un.read_check_error.header.wwnn, - &pnode->nlp_nodename, sizeof(struct lpfc_name)); - fast_path_evt->un.read_check_error.lun = cmnd->device->lun; - fast_path_evt->un.read_check_error.opcode = cmnd->cmnd[0]; - fast_path_evt->un.read_check_error.fcpiparam = - fcpi_parm; - } else - return; - - fast_path_evt->vport = vport; - spin_lock_irqsave(&phba->hbalock, flags); - list_add_tail(&fast_path_evt->work_evt.evt_listp, &phba->work_list); - spin_unlock_irqrestore(&phba->hbalock, flags); - lpfc_worker_wake_up(phba); - return; -} static void lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) { @@ -709,7 +411,6 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, uint32_t rsplen = 0; uint32_t logit = LOG_FCP | LOG_FCP_ERROR; - /* * If this is a task management command, there is no * scsi packet associated with this lpfc_cmd. The driver @@ -825,7 +526,6 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, out: cmnd->result = ScsiResult(host_status, scsi_status); - lpfc_send_scsi_error_event(vport->phba, vport, lpfc_cmd, rsp_iocb); } static void @@ -842,11 +542,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, struct scsi_device *sdev, *tmp_sdev; int depth = 0; unsigned long flags; - struct lpfc_fast_path_event *fast_path_evt; lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; lpfc_cmd->status = pIocbOut->iocb.ulpStatus; - atomic_dec(&pnode->cmd_pending); if (lpfc_cmd->status) { if (lpfc_cmd->status == IOSTAT_LOCAL_REJECT && @@ -872,36 +570,12 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, break; case IOSTAT_NPORT_BSY: case IOSTAT_FABRIC_BSY: - cmd->result = ScsiResult(DID_TRANSPORT_DISRUPTED, 0); - fast_path_evt = lpfc_alloc_fast_evt(phba); - if (!fast_path_evt) - break; - fast_path_evt->un.fabric_evt.event_type = - FC_REG_FABRIC_EVENT; - fast_path_evt->un.fabric_evt.subcategory = - (lpfc_cmd->status == IOSTAT_NPORT_BSY) ? - LPFC_EVENT_PORT_BUSY : LPFC_EVENT_FABRIC_BUSY; - if (pnode && NLP_CHK_NODE_ACT(pnode)) { - memcpy(&fast_path_evt->un.fabric_evt.wwpn, - &pnode->nlp_portname, - sizeof(struct lpfc_name)); - memcpy(&fast_path_evt->un.fabric_evt.wwnn, - &pnode->nlp_nodename, - sizeof(struct lpfc_name)); - } - fast_path_evt->vport = vport; - fast_path_evt->work_evt.evt = - LPFC_EVT_FASTPATH_MGMT_EVT; - spin_lock_irqsave(&phba->hbalock, flags); - list_add_tail(&fast_path_evt->work_evt.evt_listp, - &phba->work_list); - spin_unlock_irqrestore(&phba->hbalock, flags); - lpfc_worker_wake_up(phba); + cmd->result = ScsiResult(DID_BUS_BUSY, 0); break; case IOSTAT_LOCAL_REJECT: - if (lpfc_cmd->result == IOERR_INVALID_RPI || + if (lpfc_cmd->result == RJT_UNAVAIL_PERM || lpfc_cmd->result == IOERR_NO_RESOURCES || - lpfc_cmd->result == IOERR_ABORT_REQUESTED) { + lpfc_cmd->result == RJT_LOGIN_REQUIRED) { cmd->result = ScsiResult(DID_REQUEUE, 0); break; } /* else: fall through */ @@ -912,8 +586,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, if (!pnode || !NLP_CHK_NODE_ACT(pnode) || (pnode->nlp_state != NLP_STE_MAPPED_NODE)) - cmd->result = ScsiResult(DID_TRANSPORT_DISRUPTED, - SAM_STAT_BUSY); + cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY); } else { cmd->result = ScsiResult(DID_OK, 0); } @@ -929,32 +602,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, scsi_get_resid(cmd)); } - lpfc_update_stats(phba, lpfc_cmd); result = cmd->result; sdev = cmd->device; - if (vport->cfg_max_scsicmpl_time && - time_after(jiffies, lpfc_cmd->start_time + - msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) { - spin_lock_irqsave(sdev->host->host_lock, flags); - if ((pnode->cmd_qdepth > atomic_read(&pnode->cmd_pending) && - (atomic_read(&pnode->cmd_pending) > LPFC_MIN_TGT_QDEPTH) && - ((cmd->cmnd[0] == READ_10) || (cmd->cmnd[0] == WRITE_10)))) - pnode->cmd_qdepth = atomic_read(&pnode->cmd_pending); - - pnode->last_change_time = jiffies; - spin_unlock_irqrestore(sdev->host->host_lock, flags); - } else if ((pnode->cmd_qdepth < LPFC_MAX_TGT_QDEPTH) && - time_after(jiffies, pnode->last_change_time + - msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) { - spin_lock_irqsave(sdev->host->host_lock, flags); - pnode->cmd_qdepth += pnode->cmd_qdepth * - LPFC_TGTQ_RAMPUP_PCENT / 100; - if (pnode->cmd_qdepth > LPFC_MAX_TGT_QDEPTH) - pnode->cmd_qdepth = LPFC_MAX_TGT_QDEPTH; - pnode->last_change_time = jiffies; - spin_unlock_irqrestore(sdev->host->host_lock, flags); - } - lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); cmd->scsi_done(cmd); @@ -998,9 +647,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, pnode->last_ramp_up_time = jiffies; } } - lpfc_send_sdev_queuedepth_change_event(phba, vport, pnode, - 0xFFFFFFFF, - sdev->queue_depth - 1, sdev->queue_depth); } /* @@ -1030,9 +676,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, "0711 detected queue full - lun queue " "depth adjusted to %d.\n", depth); - lpfc_send_sdev_queuedepth_change_event(phba, vport, - pnode, 0xFFFFFFFF, - depth+1, depth); } } @@ -1049,24 +692,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, lpfc_release_scsi_buf(phba, lpfc_cmd); } -/** - * lpfc_fcpcmd_to_iocb - copy the fcp_cmd data into the IOCB. - * @data: A pointer to the immediate command data portion of the IOCB. - * @fcp_cmnd: The FCP Command that is provided by the SCSI layer. - * - * The routine copies the entire FCP command from @fcp_cmnd to @data while - * byte swapping the data to big endian format for transmission on the wire. - **/ -static void -lpfc_fcpcmd_to_iocb(uint8_t *data, struct fcp_cmnd *fcp_cmnd) -{ - int i, j; - for (i = 0, j = 0; i < sizeof(struct fcp_cmnd); - i += sizeof(uint32_t), j++) { - ((uint32_t *)data)[j] = cpu_to_be32(((uint32_t *)fcp_cmnd)[j]); - } -} - static void lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_nodelist *pnode) @@ -1133,8 +758,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, fcp_cmnd->fcpCntl3 = 0; phba->fc4ControlRequests++; } - if (phba->sli_rev == 3) - lpfc_fcpcmd_to_iocb(iocb_cmd->unsli3.fcp_ext.icd, fcp_cmnd); + /* * Finish initializing those IOCB fields that are independent * of the scsi_cmnd request_buffer @@ -1174,13 +798,11 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, piocb = &piocbq->iocb; fcp_cmnd = lpfc_cmd->fcp_cmnd; - /* Clear out any old data in the FCP command area */ - memset(fcp_cmnd, 0, sizeof(struct fcp_cmnd)); - int_to_scsilun(lun, &fcp_cmnd->fcp_lun); + int_to_scsilun(lun, &lpfc_cmd->fcp_cmnd->fcp_lun); fcp_cmnd->fcpCntl2 = task_mgmt_cmd; - if (vport->phba->sli_rev == 3) - lpfc_fcpcmd_to_iocb(piocb->unsli3.fcp_ext.icd, fcp_cmnd); + piocb->ulpCommand = CMD_FCP_ICMND64_CR; + piocb->ulpContext = ndlp->nlp_rpi; if (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { piocb->ulpFCP2Rcvy = 1; @@ -1345,12 +967,9 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) * transport is still transitioning. */ if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { - cmnd->result = ScsiResult(DID_TRANSPORT_DISRUPTED, 0); + cmnd->result = ScsiResult(DID_BUS_BUSY, 0); goto out_fail_command; } - if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth) - goto out_host_busy; - lpfc_cmd = lpfc_get_scsi_buf(phba); if (lpfc_cmd == NULL) { lpfc_adjust_queue_depth(phba); @@ -1361,7 +980,6 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) goto out_host_busy; } - lpfc_cmd->start_time = jiffies; /* * Store the midlayer's command structure for the completion phase * and complete the command initialization. @@ -1369,7 +987,6 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) lpfc_cmd->pCmd = cmnd; lpfc_cmd->rdata = rdata; lpfc_cmd->timeout = 0; - lpfc_cmd->start_time = jiffies; cmnd->host_scribble = (unsigned char *)lpfc_cmd; cmnd->scsi_done = done; @@ -1379,7 +996,6 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) lpfc_scsi_prep_cmnd(vport, lpfc_cmd, ndlp); - atomic_inc(&ndlp->cmd_pending); err = lpfc_sli_issue_iocb(phba, &phba->sli.ring[psli->fcp_ring], &lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB); if (err) @@ -1394,7 +1010,6 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) return 0; out_host_busy_free_buf: - atomic_dec(&ndlp->cmd_pending); lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); lpfc_release_scsi_buf(phba, lpfc_cmd); out_host_busy: @@ -1530,7 +1145,6 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) int ret = SUCCESS; int status; int cnt; - struct lpfc_scsi_event_header scsi_event; lpfc_block_error_handler(cmnd); /* @@ -1549,19 +1163,6 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) break; pnode = rdata->pnode; } - - scsi_event.event_type = FC_REG_SCSI_EVENT; - scsi_event.subcategory = LPFC_EVENT_TGTRESET; - scsi_event.lun = 0; - memcpy(scsi_event.wwpn, &pnode->nlp_portname, sizeof(struct lpfc_name)); - memcpy(scsi_event.wwnn, &pnode->nlp_nodename, sizeof(struct lpfc_name)); - - fc_host_post_vendor_event(shost, - fc_get_event_number(), - sizeof(scsi_event), - (char *)&scsi_event, - SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); - if (!rdata || pnode->nlp_state != NLP_STE_MAPPED_NODE) { lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, "0721 LUN Reset rport " @@ -1641,23 +1242,10 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) struct lpfc_hba *phba = vport->phba; struct lpfc_nodelist *ndlp = NULL; int match; - int ret = SUCCESS, status = SUCCESS, i; + int ret = SUCCESS, status, i; int cnt; struct lpfc_scsi_buf * lpfc_cmd; unsigned long later; - struct lpfc_scsi_event_header scsi_event; - - scsi_event.event_type = FC_REG_SCSI_EVENT; - scsi_event.subcategory = LPFC_EVENT_BUSRESET; - scsi_event.lun = 0; - memcpy(scsi_event.wwpn, &vport->fc_portname, sizeof(struct lpfc_name)); - memcpy(scsi_event.wwnn, &vport->fc_nodename, sizeof(struct lpfc_name)); - - fc_host_post_vendor_event(shost, - fc_get_event_number(), - sizeof(scsi_event), - (char *)&scsi_event, - SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); lpfc_block_error_handler(cmnd); /* diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.h b/trunk/drivers/scsi/lpfc/lpfc_scsi.h index 437f182e2322..daba92374985 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.h +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.h @@ -107,10 +107,6 @@ struct fcp_cmnd { }; -struct lpfc_scsicmd_bkt { - uint32_t cmd_count; -}; - struct lpfc_scsi_buf { struct list_head list; struct scsi_cmnd *pCmd; @@ -143,7 +139,6 @@ struct lpfc_scsi_buf { */ struct lpfc_iocbq cur_iocbq; wait_queue_head_t *waitq; - unsigned long start_time; }; #define LPFC_SCSI_DMA_EXT_SIZE 264 diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index 8ab5babdeebc..50fe07646738 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -32,7 +32,6 @@ #include "lpfc_hw.h" #include "lpfc_sli.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h" @@ -67,16 +66,10 @@ typedef enum _lpfc_iocb_type { LPFC_ABORT_IOCB } lpfc_iocb_type; -/** - * lpfc_cmd_iocb: Get next command iocb entry in the ring. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * - * This function returns pointer to next command iocb entry - * in the command ring. The caller must hold hbalock to prevent - * other threads consume the next command iocb. - * SLI-2/SLI-3 provide different sized iocbs. - **/ + /* SLI-2/SLI-3 provide different sized iocbs. Given a pointer + * to the start of the ring, and the slot number of the + * desired iocb entry, calc a pointer to that entry. + */ static inline IOCB_t * lpfc_cmd_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) { @@ -84,16 +77,6 @@ lpfc_cmd_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) pring->cmdidx * phba->iocb_cmd_size); } -/** - * lpfc_resp_iocb: Get next response iocb entry in the ring. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * - * This function returns pointer to next response iocb entry - * in the response ring. The caller must hold hbalock to make sure - * that no other thread consume the next response iocb. - * SLI-2/SLI-3 provide different sized iocbs. - **/ static inline IOCB_t * lpfc_resp_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) { @@ -101,15 +84,6 @@ lpfc_resp_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) pring->rspidx * phba->iocb_rsp_size); } -/** - * __lpfc_sli_get_iocbq: Allocates an iocb object from iocb pool. - * @phba: Pointer to HBA context object. - * - * This function is called with hbalock held. This function - * allocates a new driver iocb object from the iocb pool. If the - * allocation is successful, it returns pointer to the newly - * allocated iocb object else it returns NULL. - **/ static struct lpfc_iocbq * __lpfc_sli_get_iocbq(struct lpfc_hba *phba) { @@ -120,15 +94,6 @@ __lpfc_sli_get_iocbq(struct lpfc_hba *phba) return iocbq; } -/** - * lpfc_sli_get_iocbq: Allocates an iocb object from iocb pool. - * @phba: Pointer to HBA context object. - * - * This function is called with no lock held. This function - * allocates a new driver iocb object from the iocb pool. If the - * allocation is successful, it returns pointer to the newly - * allocated iocb object else it returns NULL. - **/ struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *phba) { @@ -141,16 +106,6 @@ lpfc_sli_get_iocbq(struct lpfc_hba *phba) return iocbq; } -/** - * __lpfc_sli_release_iocbq: Release iocb to the iocb pool. - * @phba: Pointer to HBA context object. - * @iocbq: Pointer to driver iocb object. - * - * This function is called with hbalock held to release driver - * iocb object to the iocb pool. The iotag in the iocb object - * does not change for each use of the iocb object. This function - * clears all other fields of the iocb object when it is freed. - **/ static void __lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) { @@ -163,14 +118,6 @@ __lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) list_add_tail(&iocbq->list, &phba->lpfc_iocb_list); } -/** - * lpfc_sli_release_iocbq: Release iocb to the iocb pool. - * @phba: Pointer to HBA context object. - * @iocbq: Pointer to driver iocb object. - * - * This function is called with no lock held to release the iocb to - * iocb pool. - **/ void lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) { @@ -184,21 +131,10 @@ lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) spin_unlock_irqrestore(&phba->hbalock, iflags); } -/** - * lpfc_sli_iocb_cmd_type: Get the iocb type. - * @iocb_cmnd : iocb command code. - * - * This function is called by ring event handler function to get the iocb type. - * This function translates the iocb command to an iocb command type used to - * decide the final disposition of each completed IOCB. - * The function returns - * LPFC_UNKNOWN_IOCB if it is an unsupported iocb - * LPFC_SOL_IOCB if it is a solicited iocb completion - * LPFC_ABORT_IOCB if it is an abort iocb - * LPFC_UNSOL_IOCB if it is an unsolicited iocb - * - * The caller is not required to hold any lock. - **/ +/* + * Translate the iocb command to an iocb command type used to decide the final + * disposition of each completed IOCB. + */ static lpfc_iocb_type lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) { @@ -294,17 +230,6 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) return type; } -/** - * lpfc_sli_ring_map: Issue config_ring mbox for all rings. - * @phba: Pointer to HBA context object. - * - * This function is called from SLI initialization code - * to configure every ring of the HBA's SLI interface. The - * caller is not required to hold any lock. This function issues - * a config_ring mailbox command for each ring. - * This function returns zero if successful else returns a negative - * error code. - **/ static int lpfc_sli_ring_map(struct lpfc_hba *phba) { @@ -337,18 +262,6 @@ lpfc_sli_ring_map(struct lpfc_hba *phba) return ret; } -/** - * lpfc_sli_ringtxcmpl_put: Adds new iocb to the txcmplq. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @piocb: Pointer to the driver iocb object. - * - * This function is called with hbalock held. The function adds the - * new iocb to txcmplq of the given ring. This function always returns - * 0. If this function is called for ELS ring, this function checks if - * there is a vport associated with the ELS command. This function also - * starts els_tmofunc timer if this is an ELS command. - **/ static int lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *piocb) @@ -369,16 +282,6 @@ lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return 0; } -/** - * lpfc_sli_ringtx_get: Get first element of the txq. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * - * This function is called with hbalock held to get next - * iocb in txq of the given ring. If there is any iocb in - * the txq, the function returns first iocb in the list after - * removing the iocb from the list, else it returns NULL. - **/ static struct lpfc_iocbq * lpfc_sli_ringtx_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) { @@ -390,25 +293,14 @@ lpfc_sli_ringtx_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) return cmd_iocb; } -/** - * lpfc_sli_next_iocb_slot: Get next iocb slot in the ring. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * - * This function is called with hbalock held and the caller must post the - * iocb without releasing the lock. If the caller releases the lock, - * iocb slot returned by the function is not guaranteed to be available. - * The function returns pointer to the next available iocb slot if there - * is available slot in the ring, else it returns NULL. - * If the get index of the ring is ahead of the put index, the function - * will post an error attention event to the worker thread to take the - * HBA to offline state. - **/ static IOCB_t * lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring) { - struct lpfc_pgp *pgp = &phba->port_gp[pring->ringno]; + struct lpfc_pgp *pgp = (phba->sli_rev == 3) ? + &phba->slim2p->mbx.us.s3_pgp.port[pring->ringno] : + &phba->slim2p->mbx.us.s2.port[pring->ringno]; uint32_t max_cmd_idx = pring->numCiocb; + if ((pring->next_cmdidx == pring->cmdidx) && (++pring->next_cmdidx >= max_cmd_idx)) pring->next_cmdidx = 0; @@ -444,18 +336,6 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring) return lpfc_cmd_iocb(phba, pring); } -/** - * lpfc_sli_next_iotag: Get an iotag for the iocb. - * @phba: Pointer to HBA context object. - * @iocbq: Pointer to driver iocb object. - * - * This function gets an iotag for the iocb. If there is no unused iotag and - * the iocbq_lookup_len < 0xffff, this function allocates a bigger iotag_lookup - * array and assigns a new iotag. - * The function returns the allocated iotag if successful, else returns zero. - * Zero is not a valid iotag. - * The caller is not required to hold any lock. - **/ uint16_t lpfc_sli_next_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) { @@ -519,20 +399,6 @@ lpfc_sli_next_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) return 0; } -/** - * lpfc_sli_submit_iocb: Submit an iocb to the firmware. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @iocb: Pointer to iocb slot in the ring. - * @nextiocb: Pointer to driver iocb object which need to be - * posted to firmware. - * - * This function is called with hbalock held to post a new iocb to - * the firmware. This function copies the new iocb to ring iocb slot and - * updates the ring pointers. It adds the new iocb to txcmplq if there is - * a completion call back for this iocb else the function will free the - * iocb object. - **/ static void lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, IOCB_t *iocb, struct lpfc_iocbq *nextiocb) @@ -575,18 +441,6 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, writel(pring->cmdidx, &phba->host_gp[pring->ringno].cmdPutInx); } -/** - * lpfc_sli_update_full_ring: Update the chip attention register. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * - * The caller is not required to hold any lock for calling this function. - * This function updates the chip attention bits for the ring to inform firmware - * that there are pending work to be done for this ring and requests an - * interrupt when there is space available in the ring. This function is - * called when the driver is unable to post more iocbs to the ring due - * to unavailability of space in the ring. - **/ static void lpfc_sli_update_full_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) { @@ -606,15 +460,6 @@ lpfc_sli_update_full_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) pring->stats.iocb_cmd_full++; } -/** - * lpfc_sli_update_ring: Update chip attention register. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * - * This function updates the chip attention register bit for the - * given ring to inform HBA that there is more work to be done - * in this ring. The caller is not required to hold any lock. - **/ static void lpfc_sli_update_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) { @@ -623,22 +468,11 @@ lpfc_sli_update_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) /* * Tell the HBA that there is work to do in this ring. */ - if (!(phba->sli3_options & LPFC_SLI3_CRP_ENABLED)) { - wmb(); - writel(CA_R0ATT << (ringno * 4), phba->CAregaddr); - readl(phba->CAregaddr); /* flush */ - } + wmb(); + writel(CA_R0ATT << (ringno * 4), phba->CAregaddr); + readl(phba->CAregaddr); /* flush */ } -/** - * lpfc_sli_resume_iocb: Process iocbs in the txq. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * - * This function is called with hbalock held to post pending iocbs - * in the txq to the firmware. This function is called when driver - * detects space available in the ring. - **/ static void lpfc_sli_resume_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) { @@ -670,16 +504,6 @@ lpfc_sli_resume_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) return; } -/** - * lpfc_sli_next_hbq_slot: Get next hbq entry for the HBQ. - * @phba: Pointer to HBA context object. - * @hbqno: HBQ number. - * - * This function is called with hbalock held to get the next - * available slot for the given HBQ. If there is free slot - * available for the HBQ it will return pointer to the next available - * HBQ entry else it will return NULL. - **/ static struct lpfc_hbq_entry * lpfc_sli_next_hbq_slot(struct lpfc_hba *phba, uint32_t hbqno) { @@ -715,15 +539,6 @@ lpfc_sli_next_hbq_slot(struct lpfc_hba *phba, uint32_t hbqno) hbqp->hbqPutIdx; } -/** - * lpfc_sli_hbqbuf_free_all: Free all the hbq buffers. - * @phba: Pointer to HBA context object. - * - * This function is called with no lock held to free all the - * hbq buffers while uninitializing the SLI interface. It also - * frees the HBQ buffers returned by the firmware but not yet - * processed by the upper layers. - **/ void lpfc_sli_hbqbuf_free_all(struct lpfc_hba *phba) { @@ -769,18 +584,6 @@ lpfc_sli_hbqbuf_free_all(struct lpfc_hba *phba) spin_unlock_irqrestore(&phba->hbalock, flags); } -/** - * lpfc_sli_hbq_to_firmware: Post the hbq buffer to firmware. - * @phba: Pointer to HBA context object. - * @hbqno: HBQ number. - * @hbq_buf: Pointer to HBQ buffer. - * - * This function is called with the hbalock held to post a - * hbq buffer to the firmware. If the function finds an empty - * slot in the HBQ, it will post the buffer. The function will return - * pointer to the hbq entry if it successfully post the buffer - * else it will return NULL. - **/ static struct lpfc_hbq_entry * lpfc_sli_hbq_to_firmware(struct lpfc_hba *phba, uint32_t hbqno, struct hbq_dmabuf *hbq_buf) @@ -809,7 +612,6 @@ lpfc_sli_hbq_to_firmware(struct lpfc_hba *phba, uint32_t hbqno, return hbqe; } -/* HBQ for ELS and CT traffic. */ static struct lpfc_hbq_init lpfc_els_hbq = { .rn = 1, .entry_count = 200, @@ -821,7 +623,6 @@ static struct lpfc_hbq_init lpfc_els_hbq = { .add_count = 5, }; -/* HBQ for the extra ring if needed */ static struct lpfc_hbq_init lpfc_extra_hbq = { .rn = 1, .entry_count = 200, @@ -833,81 +634,51 @@ static struct lpfc_hbq_init lpfc_extra_hbq = { .add_count = 5, }; -/* Array of HBQs */ struct lpfc_hbq_init *lpfc_hbq_defs[] = { &lpfc_els_hbq, &lpfc_extra_hbq, }; -/** - * lpfc_sli_hbqbuf_fill_hbqs: Post more hbq buffers to HBQ. - * @phba: Pointer to HBA context object. - * @hbqno: HBQ number. - * @count: Number of HBQ buffers to be posted. - * - * This function is called with no lock held to post more hbq buffers to the - * given HBQ. The function returns the number of HBQ buffers successfully - * posted. - **/ static int lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) { - uint32_t i, posted = 0; + uint32_t i, start, end; unsigned long flags; struct hbq_dmabuf *hbq_buffer; - LIST_HEAD(hbq_buf_list); + if (!phba->hbqs[hbqno].hbq_alloc_buffer) return 0; - if ((phba->hbqs[hbqno].buffer_count + count) > - lpfc_hbq_defs[hbqno]->entry_count) - count = lpfc_hbq_defs[hbqno]->entry_count - - phba->hbqs[hbqno].buffer_count; - if (!count) - return 0; - /* Allocate HBQ entries */ - for (i = 0; i < count; i++) { - hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); - if (!hbq_buffer) - break; - list_add_tail(&hbq_buffer->dbuf.list, &hbq_buf_list); - } + start = phba->hbqs[hbqno].buffer_count; + end = count + start; + if (end > lpfc_hbq_defs[hbqno]->entry_count) + end = lpfc_hbq_defs[hbqno]->entry_count; + /* Check whether HBQ is still in use */ spin_lock_irqsave(&phba->hbalock, flags); if (!phba->hbq_in_use) - goto err; - while (!list_empty(&hbq_buf_list)) { - list_remove_head(&hbq_buf_list, hbq_buffer, struct hbq_dmabuf, - dbuf.list); - hbq_buffer->tag = (phba->hbqs[hbqno].buffer_count | - (hbqno << 16)); - if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) { + goto out; + + /* Populate HBQ entries */ + for (i = start; i < end; i++) { + hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); + if (!hbq_buffer) + goto err; + hbq_buffer->tag = (i | (hbqno << 16)); + if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) phba->hbqs[hbqno].buffer_count++; - posted++; - } else + else (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); } + + out: spin_unlock_irqrestore(&phba->hbalock, flags); - return posted; -err: - spin_unlock_irqrestore(&phba->hbalock, flags); - while (!list_empty(&hbq_buf_list)) { - list_remove_head(&hbq_buf_list, hbq_buffer, struct hbq_dmabuf, - dbuf.list); - (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); - } return 0; + err: + spin_unlock_irqrestore(&phba->hbalock, flags); + return 1; } -/** - * lpfc_sli_hbqbuf_add_hbqs: Post more HBQ buffers to firmware. - * @phba: Pointer to HBA context object. - * @qno: HBQ number. - * - * This function posts more buffers to the HBQ. This function - * is called with no lock held. The function returns the number of HBQ entries - * successfully allocated. - **/ int lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) { @@ -915,15 +686,6 @@ lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) lpfc_hbq_defs[qno]->add_count)); } -/** - * lpfc_sli_hbqbuf_init_hbqs: Post initial buffers to the HBQ. - * @phba: Pointer to HBA context object. - * @qno: HBQ queue number. - * - * This function is called from SLI initialization code path with - * no lock held to post initial HBQ buffers to firmware. The - * function returns the number of HBQ entries successfully allocated. - **/ static int lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) { @@ -931,16 +693,6 @@ lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) lpfc_hbq_defs[qno]->init_count)); } -/** - * lpfc_sli_hbqbuf_find: Find the hbq buffer associated with a tag. - * @phba: Pointer to HBA context object. - * @tag: Tag of the hbq buffer. - * - * This function is called with hbalock held. This function searches - * for the hbq buffer associated with the given tag in the hbq buffer - * list. If it finds the hbq buffer, it returns the hbq_buffer other wise - * it returns NULL. - **/ static struct hbq_dmabuf * lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) { @@ -964,15 +716,6 @@ lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) return NULL; } -/** - * lpfc_sli_free_hbq: Give back the hbq buffer to firmware. - * @phba: Pointer to HBA context object. - * @hbq_buffer: Pointer to HBQ buffer. - * - * This function is called with hbalock. This function gives back - * the hbq buffer to firmware. If the HBQ does not have space to - * post the buffer, it will free the buffer. - **/ void lpfc_sli_free_hbq(struct lpfc_hba *phba, struct hbq_dmabuf *hbq_buffer) { @@ -986,15 +729,6 @@ lpfc_sli_free_hbq(struct lpfc_hba *phba, struct hbq_dmabuf *hbq_buffer) } } -/** - * lpfc_sli_chk_mbx_command: Check if the mailbox is a legitimate mailbox. - * @mbxCommand: mailbox command code. - * - * This function is called by the mailbox event handler function to verify - * that the completed mailbox command is a legitimate mailbox command. If the - * completed mailbox is not known to the function, it will return MBX_SHUTDOWN - * and the mailbox event handler will take the HBA offline. - **/ static int lpfc_sli_chk_mbx_command(uint8_t mbxCommand) { @@ -1051,8 +785,6 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) case MBX_REG_VPI: case MBX_UNREG_VPI: case MBX_HEARTBEAT: - case MBX_PORT_CAPABILITIES: - case MBX_PORT_IOV_CONTROL: ret = mbxCommand; break; default: @@ -1061,19 +793,6 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) } return ret; } - -/** - * lpfc_sli_wake_mbox_wait: Completion handler for mbox issued from - * lpfc_sli_issue_mbox_wait. - * @phba: Pointer to HBA context object. - * @pmboxq: Pointer to mailbox command. - * - * This is completion handler function for mailbox commands issued from - * lpfc_sli_issue_mbox_wait function. This function is called by the - * mailbox event handler function with no lock held. This function - * will wake up thread waiting on the wait queue pointed by context1 - * of the mailbox. - **/ static void lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) { @@ -1093,17 +812,6 @@ lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) return; } - -/** - * lpfc_sli_def_mbox_cmpl: Default mailbox completion handler. - * @phba: Pointer to HBA context object. - * @pmb: Pointer to mailbox object. - * - * This function is the default mailbox completion handler. It - * frees the memory resources associated with the completed mailbox - * command. If the completed command is a REG_LOGIN mailbox command, - * this function will issue a UREG_LOGIN to re-claim the RPI. - **/ void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) { @@ -1138,19 +846,6 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) return; } -/** - * lpfc_sli_handle_mb_event: Handle mailbox completions from firmware. - * @phba: Pointer to HBA context object. - * - * This function is called with no lock held. This function processes all - * the completed mailbox commands and gives it to upper layers. The interrupt - * service routine processes mailbox completion interrupt and adds completed - * mailbox commands to the mboxq_cmpl queue and signals the worker thread. - * Worker thread call lpfc_sli_handle_mb_event, which will return the - * completed mailbox commands in mboxq_cmpl queue to the upper layers. This - * function returns the mailbox commands to the upper layer by calling the - * completion handler function of each mailbox. - **/ int lpfc_sli_handle_mb_event(struct lpfc_hba *phba) { @@ -1258,18 +953,6 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) return 0; } -/** - * lpfc_sli_replace_hbqbuff: Replace the HBQ buffer with a new buffer. - * @phba: Pointer to HBA context object. - * @tag: Tag for the HBQ buffer. - * - * This function is called from unsolicited event handler code path to get the - * HBQ buffer associated with an unsolicited iocb. This function is called with - * no lock held. It returns the buffer associated with the given tag and posts - * another buffer to the firmware. Note that the new buffer must be allocated - * before taking the hbalock and that the hba lock must be held until it is - * finished with the hbq entry swap. - **/ static struct lpfc_dmabuf * lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) { @@ -1279,28 +962,22 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) dma_addr_t phys; /* mapped address */ unsigned long flags; - hbqno = tag >> 16; - new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); /* Check whether HBQ is still in use */ spin_lock_irqsave(&phba->hbalock, flags); if (!phba->hbq_in_use) { - if (new_hbq_entry) - (phba->hbqs[hbqno].hbq_free_buffer)(phba, - new_hbq_entry); spin_unlock_irqrestore(&phba->hbalock, flags); return NULL; } hbq_entry = lpfc_sli_hbqbuf_find(phba, tag); if (hbq_entry == NULL) { - if (new_hbq_entry) - (phba->hbqs[hbqno].hbq_free_buffer)(phba, - new_hbq_entry); spin_unlock_irqrestore(&phba->hbalock, flags); return NULL; } list_del(&hbq_entry->dbuf.list); + hbqno = tag >> 16; + new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); if (new_hbq_entry == NULL) { list_add_tail(&hbq_entry->dbuf.list, &phba->hbqbuf_in_list); spin_unlock_irqrestore(&phba->hbalock, flags); @@ -1320,18 +997,6 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) return &new_hbq_entry->dbuf; } -/** - * lpfc_sli_get_buff: Get the buffer associated with the buffer tag. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @tag: buffer tag. - * - * This function is called with no lock held. When QUE_BUFTAG_BIT bit - * is set in the tag the buffer is posted for a particular exchange, - * the function will return the buffer without replacing the buffer. - * If the buffer is for unsolicited ELS or CT traffic, this function - * returns the buffer and also posts another buffer to the firmware. - **/ static struct lpfc_dmabuf * lpfc_sli_get_buff(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, @@ -1343,21 +1008,6 @@ lpfc_sli_get_buff(struct lpfc_hba *phba, return lpfc_sli_replace_hbqbuff(phba, tag); } - -/** - * lpfc_sli_process_unsol_iocb: Unsolicited iocb handler. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @saveq: Pointer to the unsolicited iocb. - * - * This function is called with no lock held by the ring event handler - * when there is an unsolicited iocb posted to the response ring by the - * firmware. This function gets the buffer associated with the iocbs - * and calls the event handler for the ring. This function handles both - * qring buffers and hbq buffers. - * When the function returns 1 the caller can free the iocb object otherwise - * upper layer functions will free the iocb objects. - **/ static int lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *saveq) @@ -1542,18 +1192,6 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return 1; } -/** - * lpfc_sli_iocbq_lookup: Find command iocb for the given response iocb. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @prspiocb: Pointer to response iocb object. - * - * This function looks up the iocb_lookup table to get the command iocb - * corresponding to the given response iocb using the iotag of the - * response iocb. This function is called with the hbalock held. - * This function returns the command iocb object if it finds the command - * iocb else returns NULL. - **/ static struct lpfc_iocbq * lpfc_sli_iocbq_lookup(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, @@ -1579,23 +1217,6 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba, return NULL; } -/** - * lpfc_sli_process_sol_iocb: process solicited iocb completion. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @saveq: Pointer to the response iocb to be processed. - * - * This function is called by the ring event handler for non-fcp - * rings when there is a new response iocb in the response ring. - * The caller is not required to hold any locks. This function - * gets the command iocb associated with the response iocb and - * calls the completion handler for the command iocb. If there - * is no completion handler, the function will free the resources - * associated with command iocb. If the response iocb is for - * an already aborted command iocb, the status of the completion - * is changed to IOSTAT_LOCAL_REJECT/IOERR_SLI_ABORTED. - * This function always returns 1. - **/ static int lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *saveq) @@ -1611,17 +1232,6 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, if (cmdiocbp) { if (cmdiocbp->iocb_cmpl) { - /* - * If an ELS command failed send an event to mgmt - * application. - */ - if (saveq->iocb.ulpStatus && - (pring->ringno == LPFC_ELS_RING) && - (cmdiocbp->iocb.ulpCommand == - CMD_ELS_REQUEST64_CR)) - lpfc_send_els_failure_event(phba, - cmdiocbp, saveq); - /* * Post all ELS completions to the worker thread. * All other are passed to the completion callback. @@ -1672,20 +1282,12 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return rc; } -/** - * lpfc_sli_rsp_pointers_error: Response ring pointer error handler. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * - * This function is called from the iocb ring event handlers when - * put pointer is ahead of the get pointer for a ring. This function signal - * an error attention condition to the worker thread and the worker - * thread will transition the HBA to offline state. - **/ static void lpfc_sli_rsp_pointers_error(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) { - struct lpfc_pgp *pgp = &phba->port_gp[pring->ringno]; + struct lpfc_pgp *pgp = (phba->sli_rev == 3) ? + &phba->slim2p->mbx.us.s3_pgp.port[pring->ringno] : + &phba->slim2p->mbx.us.s2.port[pring->ringno]; /* * Ring handler: portRspPut is bigger then * rsp ring @@ -1710,51 +1312,6 @@ lpfc_sli_rsp_pointers_error(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) return; } -/** - * lpfc_poll_eratt: Error attention polling timer timeout handler. - * @ptr: Pointer to address of HBA context object. - * - * This function is invoked by the Error Attention polling timer when the - * timer times out. It will check the SLI Error Attention register for - * possible attention events. If so, it will post an Error Attention event - * and wake up worker thread to process it. Otherwise, it will set up the - * Error Attention polling timer for the next poll. - **/ -void lpfc_poll_eratt(unsigned long ptr) -{ - struct lpfc_hba *phba; - uint32_t eratt = 0; - - phba = (struct lpfc_hba *)ptr; - - /* Check chip HA register for error event */ - eratt = lpfc_sli_check_eratt(phba); - - if (eratt) - /* Tell the worker thread there is work to do */ - lpfc_worker_wake_up(phba); - else - /* Restart the timer for next eratt poll */ - mod_timer(&phba->eratt_poll, jiffies + - HZ * LPFC_ERATT_POLL_INTERVAL); - return; -} - -/** - * lpfc_sli_poll_fcp_ring: Handle FCP ring completion in polling mode. - * @phba: Pointer to HBA context object. - * - * This function is called from lpfc_queuecommand, lpfc_poll_timeout, - * lpfc_abort_handler and lpfc_slave_configure when FCP_RING_POLLING - * is enabled. - * - * The caller does not hold any lock. - * The function processes each response iocb in the response ring until it - * finds an iocb with LE bit set and chains all the iocbs upto the iocb with - * LE bit set. The function will call the completion handler of the command iocb - * if the response iocb indicates a completion for a command iocb or it is - * an abort completion. - **/ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) { struct lpfc_sli *psli = &phba->sli; @@ -1763,7 +1320,7 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) IOCB_t *entry = NULL; struct lpfc_iocbq *cmdiocbq = NULL; struct lpfc_iocbq rspiocbq; - struct lpfc_pgp *pgp = &phba->port_gp[pring->ringno]; + struct lpfc_pgp *pgp; uint32_t status; uint32_t portRspPut, portRspMax; int type; @@ -1773,6 +1330,11 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) pring->stats.iocb_event++; + pgp = (phba->sli_rev == 3) ? + &phba->slim2p->mbx.us.s3_pgp.port[pring->ringno] : + &phba->slim2p->mbx.us.s2.port[pring->ringno]; + + /* * The next available response entry should never exceed the maximum * entries. If it does, treat it as an adapter hardware error. @@ -1810,8 +1372,8 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) irsp->un.ulpWord[3], irsp->un.ulpWord[4], irsp->un.ulpWord[5], - *(uint32_t *)&irsp->un1, - *((uint32_t *)&irsp->un1 + 1)); + *(((uint32_t *) irsp) + 6), + *(((uint32_t *) irsp) + 7)); } switch (type) { @@ -1903,28 +1465,17 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) return; } -/** - * lpfc_sli_handle_fast_ring_event: Handle ring events on FCP ring. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @mask: Host attention register mask for this ring. - * - * This function is called from the interrupt context when there is a ring - * event for the fcp ring. The caller does not hold any lock. - * The function processes each response iocb in the response ring until it - * finds an iocb with LE bit set and chains all the iocbs upto the iocb with - * LE bit set. The function will call the completion handler of the command iocb - * if the response iocb indicates a completion for a command iocb or it is - * an abort completion. The function will call lpfc_sli_process_unsol_iocb - * function if this is an unsolicited iocb. +/* * This routine presumes LPFC_FCP_RING handling and doesn't bother - * to check it explicitly. This function always returns 1. - **/ + * to check it explicitly. + */ static int lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, uint32_t mask) { - struct lpfc_pgp *pgp = &phba->port_gp[pring->ringno]; + struct lpfc_pgp *pgp = (phba->sli_rev == 3) ? + &phba->slim2p->mbx.us.s3_pgp.port[pring->ringno] : + &phba->slim2p->mbx.us.s2.port[pring->ringno]; IOCB_t *irsp = NULL; IOCB_t *entry = NULL; struct lpfc_iocbq *cmdiocbq = NULL; @@ -1997,8 +1548,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, irsp->un.ulpWord[3], irsp->un.ulpWord[4], irsp->un.ulpWord[5], - *(uint32_t *)&irsp->un1, - *((uint32_t *)&irsp->un1 + 1)); + *(((uint32_t *) irsp) + 6), + *(((uint32_t *) irsp) + 7)); } switch (type) { @@ -2095,28 +1646,13 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, return rc; } -/** - * lpfc_sli_handle_slow_ring_event: Handle ring events for non-FCP rings. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @mask: Host attention register mask for this ring. - * - * This function is called from the worker thread when there is a ring - * event for non-fcp rings. The caller does not hold any lock . - * The function processes each response iocb in the response ring until it - * finds an iocb with LE bit set and chains all the iocbs upto the iocb with - * LE bit set. The function will call lpfc_sli_process_sol_iocb function if the - * response iocb indicates a completion of a command iocb. The function - * will call lpfc_sli_process_unsol_iocb function if this is an unsolicited - * iocb. The function frees the resources or calls the completion handler if - * this iocb is an abort completion. The function returns 0 when the allocated - * iocbs are not freed, otherwise returns 1. - **/ int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, uint32_t mask) { - struct lpfc_pgp *pgp; + struct lpfc_pgp *pgp = (phba->sli_rev == 3) ? + &phba->slim2p->mbx.us.s3_pgp.port[pring->ringno] : + &phba->slim2p->mbx.us.s2.port[pring->ringno]; IOCB_t *entry; IOCB_t *irsp = NULL; struct lpfc_iocbq *rspiocbp = NULL; @@ -2130,7 +1666,6 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, int rc = 1; unsigned long iflag; - pgp = &phba->port_gp[pring->ringno]; spin_lock_irqsave(&phba->hbalock, iflag); pring->stats.iocb_event++; @@ -2369,16 +1904,6 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, return rc; } -/** - * lpfc_sli_abort_iocb_ring: Abort all iocbs in the ring. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * - * This function aborts all iocbs in the given ring and frees all the iocb - * objects in txq. This function issues an abort iocb for all the iocb commands - * in txcmplq. The iocbs in the txcmplq is not guaranteed to complete before - * the return of this function. The caller is not required to hold any locks. - **/ void lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) { @@ -2418,83 +1943,6 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) } } -/** - * lpfc_sli_flush_fcp_rings: flush all iocbs in the fcp ring. - * @phba: Pointer to HBA context object. - * - * This function flushes all iocbs in the fcp ring and frees all the iocb - * objects in txq and txcmplq. This function will not issue abort iocbs - * for all the iocb commands in txcmplq, they will just be returned with - * IOERR_SLI_DOWN. This function is invoked with EEH when device's PCI - * slot has been permanently disabled. - **/ -void -lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba) -{ - LIST_HEAD(txq); - LIST_HEAD(txcmplq); - struct lpfc_iocbq *iocb; - IOCB_t *cmd = NULL; - struct lpfc_sli *psli = &phba->sli; - struct lpfc_sli_ring *pring; - - /* Currently, only one fcp ring */ - pring = &psli->ring[psli->fcp_ring]; - - spin_lock_irq(&phba->hbalock); - /* Retrieve everything on txq */ - list_splice_init(&pring->txq, &txq); - pring->txq_cnt = 0; - - /* Retrieve everything on the txcmplq */ - list_splice_init(&pring->txcmplq, &txcmplq); - pring->txcmplq_cnt = 0; - spin_unlock_irq(&phba->hbalock); - - /* Flush the txq */ - while (!list_empty(&txq)) { - iocb = list_get_first(&txq, struct lpfc_iocbq, list); - cmd = &iocb->iocb; - list_del_init(&iocb->list); - - if (!iocb->iocb_cmpl) - lpfc_sli_release_iocbq(phba, iocb); - else { - cmd->ulpStatus = IOSTAT_LOCAL_REJECT; - cmd->un.ulpWord[4] = IOERR_SLI_DOWN; - (iocb->iocb_cmpl) (phba, iocb, iocb); - } - } - - /* Flush the txcmpq */ - while (!list_empty(&txcmplq)) { - iocb = list_get_first(&txcmplq, struct lpfc_iocbq, list); - cmd = &iocb->iocb; - list_del_init(&iocb->list); - - if (!iocb->iocb_cmpl) - lpfc_sli_release_iocbq(phba, iocb); - else { - cmd->ulpStatus = IOSTAT_LOCAL_REJECT; - cmd->un.ulpWord[4] = IOERR_SLI_DOWN; - (iocb->iocb_cmpl) (phba, iocb, iocb); - } - } -} - -/** - * lpfc_sli_brdready: Check for host status bits. - * @phba: Pointer to HBA context object. - * @mask: Bit mask to be checked. - * - * This function reads the host status register and compares - * with the provided bit mask to check if HBA completed - * the restart. This function will wait in a loop for the - * HBA to complete restart. If the HBA does not restart within - * 15 iterations, the function will reset the HBA again. The - * function returns 1 when HBA fail to restart otherwise returns - * zero. - **/ int lpfc_sli_brdready(struct lpfc_hba *phba, uint32_t mask) { @@ -2542,13 +1990,6 @@ lpfc_sli_brdready(struct lpfc_hba *phba, uint32_t mask) #define BARRIER_TEST_PATTERN (0xdeadbeef) -/** - * lpfc_reset_barrier: Make HBA ready for HBA reset. - * @phba: Pointer to HBA context object. - * - * This function is called before resetting an HBA. This - * function requests HBA to quiesce DMAs before a reset. - **/ void lpfc_reset_barrier(struct lpfc_hba *phba) { uint32_t __iomem *resp_buf; @@ -2622,17 +2063,6 @@ void lpfc_reset_barrier(struct lpfc_hba *phba) readl(phba->HCregaddr); /* flush */ } -/** - * lpfc_sli_brdkill: Issue a kill_board mailbox command. - * @phba: Pointer to HBA context object. - * - * This function issues a kill_board mailbox command and waits for - * the error attention interrupt. This function is called for stopping - * the firmware processing. The caller is not required to hold any - * locks. This function calls lpfc_hba_down_post function to free - * any pending commands after the kill. The function will return 1 when it - * fails to kill the board else will return 0. - **/ int lpfc_sli_brdkill(struct lpfc_hba *phba) { @@ -2709,17 +2139,6 @@ lpfc_sli_brdkill(struct lpfc_hba *phba) return ha_copy & HA_ERATT ? 0 : 1; } -/** - * lpfc_sli_brdreset: Reset the HBA. - * @phba: Pointer to HBA context object. - * - * This function resets the HBA by writing HC_INITFF to the control - * register. After the HBA resets, this function resets all the iocb ring - * indices. This function disables PCI layer parity checking during - * the reset. - * This function returns 0 always. - * The caller is not required to hold any locks. - **/ int lpfc_sli_brdreset(struct lpfc_hba *phba) { @@ -2772,19 +2191,6 @@ lpfc_sli_brdreset(struct lpfc_hba *phba) return 0; } -/** - * lpfc_sli_brdrestart: Restart the HBA. - * @phba: Pointer to HBA context object. - * - * This function is called in the SLI initialization code path to - * restart the HBA. The caller is not required to hold any lock. - * This function writes MBX_RESTART mailbox command to the SLIM and - * resets the HBA. At the end of the function, it calls lpfc_hba_down_post - * function to free any pending commands. The function enables - * POST only during the first initialization. The function returns zero. - * The function does not guarantee completion of MBX_RESTART mailbox - * command before the return of this function. - **/ int lpfc_sli_brdrestart(struct lpfc_hba *phba) { @@ -2845,16 +2251,6 @@ lpfc_sli_brdrestart(struct lpfc_hba *phba) return 0; } -/** - * lpfc_sli_chipset_init: Wait for the restart of the HBA after a restart. - * @phba: Pointer to HBA context object. - * - * This function is called after a HBA restart to wait for successful - * restart of the HBA. Successful restart of the HBA is indicated by - * HS_FFRDY and HS_MBRDY bits. If the HBA fails to restart even after 15 - * iteration, the function will restart the HBA again. The function returns - * zero if HBA successfully restarted else returns negative error code. - **/ static int lpfc_sli_chipset_init(struct lpfc_hba *phba) { @@ -2940,25 +2336,12 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) return 0; } -/** - * lpfc_sli_hbq_count: Get the number of HBQs to be configured. - * - * This function calculates and returns the number of HBQs required to be - * configured. - **/ int lpfc_sli_hbq_count(void) { return ARRAY_SIZE(lpfc_hbq_defs); } -/** - * lpfc_sli_hbq_entry_count: Calculate total number of hbq entries. - * - * This function adds the number of hbq entries in every HBQ to get - * the total number of hbq entries required for the HBA and returns - * the total count. - **/ static int lpfc_sli_hbq_entry_count(void) { @@ -2971,27 +2354,12 @@ lpfc_sli_hbq_entry_count(void) return count; } -/** - * lpfc_sli_hbq_size: Calculate memory required for all hbq entries. - * - * This function calculates amount of memory required for all hbq entries - * to be configured and returns the total memory required. - **/ int lpfc_sli_hbq_size(void) { return lpfc_sli_hbq_entry_count() * sizeof(struct lpfc_hbq_entry); } -/** - * lpfc_sli_hbq_setup: configure and initialize HBQs. - * @phba: Pointer to HBA context object. - * - * This function is called during the SLI initialization to configure - * all the HBQs and post buffers to the HBQ. The caller is not - * required to hold any locks. This function will return zero if successful - * else it will return negative error code. - **/ static int lpfc_sli_hbq_setup(struct lpfc_hba *phba) { @@ -3047,26 +2415,15 @@ lpfc_sli_hbq_setup(struct lpfc_hba *phba) mempool_free(pmb, phba->mbox_mem_pool); /* Initially populate or replenish the HBQs */ - for (hbqno = 0; hbqno < hbq_count; ++hbqno) - lpfc_sli_hbqbuf_init_hbqs(phba, hbqno); + for (hbqno = 0; hbqno < hbq_count; ++hbqno) { + if (lpfc_sli_hbqbuf_init_hbqs(phba, hbqno)) + return -ENOMEM; + } return 0; } -/** - * lpfc_sli_config_port: Issue config port mailbox command. - * @phba: Pointer to HBA context object. - * @sli_mode: sli mode - 2/3 - * - * This function is called by the sli intialization code path - * to issue config_port mailbox command. This function restarts the - * HBA firmware and issues a config_port mailbox command to configure - * the SLI interface in the sli mode specified by sli_mode - * variable. The caller is not required to hold any locks. - * The function returns 0 if successful, else returns negative error - * code. - **/ -int -lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode) +static int +lpfc_do_config_port(struct lpfc_hba *phba, int sli_mode) { LPFC_MBOXQ_t *pmb; uint32_t resetcount = 0, rc = 0, done = 0; @@ -3103,15 +2460,13 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode) if (rc == -ERESTART) { phba->link_state = LPFC_LINK_UNKNOWN; continue; - } else if (rc) + } else if (rc) { break; + } + phba->link_state = LPFC_INIT_MBX_CMDS; lpfc_config_port(phba, pmb); rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); - phba->sli3_options &= ~(LPFC_SLI3_NPIV_ENABLED | - LPFC_SLI3_HBQ_ENABLED | - LPFC_SLI3_CRP_ENABLED | - LPFC_SLI3_INB_ENABLED); if (rc != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0442 Adapter failed to init, mbxCmd x%x " @@ -3121,64 +2476,30 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode) phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE; spin_unlock_irq(&phba->hbalock); rc = -ENXIO; - } else + } else { done = 1; + phba->max_vpi = (phba->max_vpi && + pmb->mb.un.varCfgPort.gmv) != 0 + ? pmb->mb.un.varCfgPort.max_vpi + : 0; + } } + if (!done) { rc = -EINVAL; goto do_prep_failed; } - if (pmb->mb.un.varCfgPort.sli_mode == 3) { - if (!pmb->mb.un.varCfgPort.cMA) { - rc = -ENXIO; - goto do_prep_failed; - } - if (phba->max_vpi && pmb->mb.un.varCfgPort.gmv) { - phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED; - phba->max_vpi = pmb->mb.un.varCfgPort.max_vpi; - } else - phba->max_vpi = 0; - if (pmb->mb.un.varCfgPort.gerbm) - phba->sli3_options |= LPFC_SLI3_HBQ_ENABLED; - if (pmb->mb.un.varCfgPort.gcrp) - phba->sli3_options |= LPFC_SLI3_CRP_ENABLED; - if (pmb->mb.un.varCfgPort.ginb) { - phba->sli3_options |= LPFC_SLI3_INB_ENABLED; - phba->port_gp = phba->mbox->us.s3_inb_pgp.port; - phba->inb_ha_copy = &phba->mbox->us.s3_inb_pgp.ha_copy; - phba->inb_counter = &phba->mbox->us.s3_inb_pgp.counter; - phba->inb_last_counter = - phba->mbox->us.s3_inb_pgp.counter; - } else { - phba->port_gp = phba->mbox->us.s3_pgp.port; - phba->inb_ha_copy = NULL; - phba->inb_counter = NULL; - } - } else { - phba->port_gp = phba->mbox->us.s2.port; - phba->inb_ha_copy = NULL; - phba->inb_counter = NULL; - phba->max_vpi = 0; + + if ((pmb->mb.un.varCfgPort.sli_mode == 3) && + (!pmb->mb.un.varCfgPort.cMA)) { + rc = -ENXIO; } + do_prep_failed: mempool_free(pmb, phba->mbox_mem_pool); return rc; } - -/** - * lpfc_sli_hba_setup: SLI intialization function. - * @phba: Pointer to HBA context object. - * - * This function is the main SLI intialization function. This function - * is called by the HBA intialization code, HBA reset code and HBA - * error attention handler code. Caller is not required to hold any - * locks. This function issues config_port mailbox command to configure - * the SLI, setup iocb rings and HBQ rings. In the end the function - * calls the config_port_post function to issue init_link mailbox - * command and to start the discovery. The function will return zero - * if successful, else it will return negative error code. - **/ int lpfc_sli_hba_setup(struct lpfc_hba *phba) { @@ -3207,20 +2528,22 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) break; } - rc = lpfc_sli_config_port(phba, mode); - + rc = lpfc_do_config_port(phba, mode); if (rc && lpfc_sli_mode == 3) lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT, "1820 Unable to select SLI-3. " "Not supported by adapter.\n"); if (rc && mode != 2) - rc = lpfc_sli_config_port(phba, 2); + rc = lpfc_do_config_port(phba, 2); if (rc) goto lpfc_sli_hba_setup_error; if (phba->sli_rev == 3) { phba->iocb_cmd_size = SLI3_IOCB_CMD_SIZE; phba->iocb_rsp_size = SLI3_IOCB_RSP_SIZE; + phba->sli3_options |= LPFC_SLI3_ENABLED; + phba->sli3_options |= LPFC_SLI3_HBQ_ENABLED; + } else { phba->iocb_cmd_size = SLI2_IOCB_CMD_SIZE; phba->iocb_rsp_size = SLI2_IOCB_RSP_SIZE; @@ -3235,7 +2558,8 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) if (rc) goto lpfc_sli_hba_setup_error; - /* Init HBQs */ + /* Init HBQs */ + if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { rc = lpfc_sli_hbq_setup(phba); if (rc) @@ -3257,19 +2581,19 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) return rc; } - -/** - * lpfc_mbox_timeout: Timeout call back function for mbox timer. - * @ptr: context object - pointer to hba structure. +/*! lpfc_mbox_timeout + * + * \pre + * \post + * \param hba Pointer to per struct lpfc_hba structure + * \param l1 Pointer to the driver's mailbox queue. + * \return + * void * - * This is the callback function for mailbox timer. The mailbox - * timer is armed when a new mailbox command is issued and the timer - * is deleted when the mailbox complete. The function is called by - * the kernel timer code when a mailbox does not complete within - * expected time. This function wakes up the worker thread to - * process the mailbox timeout and returns. All the processing is - * done by the worker thread function lpfc_mbox_timeout_handler. - **/ + * \b Description: + * + * This routine handles mailbox timeout events at timer interrupt context. + */ void lpfc_mbox_timeout(unsigned long ptr) { @@ -3288,15 +2612,6 @@ lpfc_mbox_timeout(unsigned long ptr) return; } - -/** - * lpfc_mbox_timeout_handler: Worker thread function to handle mailbox timeout. - * @phba: Pointer to HBA context object. - * - * This function is called from worker thread when a mailbox command times out. - * The caller is not required to hold any locks. This function will reset the - * HBA and recover all the pending commands. - **/ void lpfc_mbox_timeout_handler(struct lpfc_hba *phba) { @@ -3351,32 +2666,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) return; } -/** - * lpfc_sli_issue_mbox: Issue a mailbox command to firmware. - * @phba: Pointer to HBA context object. - * @pmbox: Pointer to mailbox object. - * @flag: Flag indicating how the mailbox need to be processed. - * - * This function is called by discovery code and HBA management code - * to submit a mailbox command to firmware. This function gets the - * hbalock to protect the data structures. - * The mailbox command can be submitted in polling mode, in which case - * this function will wait in a polling loop for the completion of the - * mailbox. - * If the mailbox is submitted in no_wait mode (not polling) the - * function will submit the command and returns immediately without waiting - * for the mailbox completion. The no_wait is supported only when HBA - * is in SLI2/SLI3 mode - interrupts are enabled. - * The SLI interface allows only one mailbox pending at a time. If the - * mailbox is issued in polling mode and there is already a mailbox - * pending, then the function will return an error. If the mailbox is issued - * in NO_WAIT mode and there is a mailbox pending already, the function - * will return MBX_BUSY after queuing the mailbox into mailbox queue. - * The sli layer owns the mailbox object until the completion of mailbox - * command if this function return MBX_BUSY or MBX_SUCCESS. For all other - * return codes the caller owns the mailbox command after the return of - * the function. - **/ int lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) { @@ -3387,7 +2676,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) int i; unsigned long timeout; unsigned long drvr_flag = 0; - uint32_t word0, ldata; + volatile uint32_t word0, ldata; void __iomem *to_slim; int processing_queue = 0; @@ -3547,11 +2836,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) if (psli->sli_flag & LPFC_SLI2_ACTIVE) { /* First copy command data to host SLIM area */ - lpfc_sli_pcimem_bcopy(mb, phba->mbox, MAILBOX_CMD_SIZE); + lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx, MAILBOX_CMD_SIZE); } else { if (mb->mbxCommand == MBX_CONFIG_PORT) { /* copy command data into host mbox for cmpl */ - lpfc_sli_pcimem_bcopy(mb, phba->mbox, MAILBOX_CMD_SIZE); + lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx, + MAILBOX_CMD_SIZE); } /* First copy mbox command data to HBA SLIM, skip past first @@ -3561,7 +2851,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) MAILBOX_CMD_SIZE - sizeof (uint32_t)); /* Next copy over first word, with mbxOwner set */ - ldata = *((uint32_t *)mb); + ldata = *((volatile uint32_t *)mb); to_slim = phba->MBslimaddr; writel(ldata, to_slim); readl(to_slim); /* flush */ @@ -3593,7 +2883,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) if (psli->sli_flag & LPFC_SLI2_ACTIVE) { /* First read mbox status word */ - word0 = *((uint32_t *)phba->mbox); + word0 = *((volatile uint32_t *)&phba->slim2p->mbx); word0 = le32_to_cpu(word0); } else { /* First read mbox status word */ @@ -3632,11 +2922,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) if (psli->sli_flag & LPFC_SLI2_ACTIVE) { /* First copy command data */ - word0 = *((uint32_t *)phba->mbox); + word0 = *((volatile uint32_t *) + &phba->slim2p->mbx); word0 = le32_to_cpu(word0); if (mb->mbxCommand == MBX_CONFIG_PORT) { MAILBOX_t *slimmb; - uint32_t slimword0; + volatile uint32_t slimword0; /* Check real SLIM for any errors */ slimword0 = readl(phba->MBslimaddr); slimmb = (MAILBOX_t *) & slimword0; @@ -3657,7 +2948,8 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) if (psli->sli_flag & LPFC_SLI2_ACTIVE) { /* copy results back to user */ - lpfc_sli_pcimem_bcopy(phba->mbox, mb, MAILBOX_CMD_SIZE); + lpfc_sli_pcimem_bcopy(&phba->slim2p->mbx, mb, + MAILBOX_CMD_SIZE); } else { /* First copy command data */ lpfc_memcpy_from_slim(mb, phba->MBslimaddr, @@ -3688,16 +2980,9 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) return MBX_NOT_FINISHED; } -/** - * __lpfc_sli_ringtx_put: Add an iocb to the txq. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @piocb: Pointer to address of newly added command iocb. - * - * This function is called with hbalock held to add a command - * iocb to the txq when SLI layer cannot submit the command iocb - * to the ring. - **/ +/* + * Caller needs to hold lock. + */ static void __lpfc_sli_ringtx_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *piocb) @@ -3707,23 +2992,6 @@ __lpfc_sli_ringtx_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, pring->txq_cnt++; } -/** - * lpfc_sli_next_iocb: Get the next iocb in the txq. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @piocb: Pointer to address of newly added command iocb. - * - * This function is called with hbalock held before a new - * iocb is submitted to the firmware. This function checks - * txq to flush the iocbs in txq to Firmware before - * submitting new iocbs to the Firmware. - * If there are iocbs in the txq which need to be submitted - * to firmware, lpfc_sli_next_iocb returns the first element - * of the txq after dequeuing it from txq. - * If there is no iocb in the txq then the function will return - * *piocb and *piocb is set to NULL. Caller needs to check - * *piocb to find if there are more commands in the txq. - **/ static struct lpfc_iocbq * lpfc_sli_next_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq **piocb) @@ -3739,30 +3007,9 @@ lpfc_sli_next_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return nextiocb; } -/** - * __lpfc_sli_issue_iocb: Lockless version of lpfc_sli_issue_iocb. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @piocb: Pointer to command iocb. - * @flag: Flag indicating if this command can be put into txq. - * - * __lpfc_sli_issue_iocb is used by other functions in the driver - * to issue an iocb command to the HBA. If the PCI slot is recovering - * from error state or if HBA is resetting or if LPFC_STOP_IOCB_EVENT - * flag is turned on, the function returns IOCB_ERROR. - * When the link is down, this function allows only iocbs for - * posting buffers. - * This function finds next available slot in the command ring and - * posts the command to the available slot and writes the port - * attention register to request HBA start processing new iocb. - * If there is no slot available in the ring and - * flag & SLI_IOCB_RET_IOCB is set, the new iocb is added to the - * txq, otherwise the function returns IOCB_BUSY. - * - * This function is called with hbalock held. - * The function will return success after it successfully submit the - * iocb to firmware or after adding to the txq. - **/ +/* + * Lockless version of lpfc_sli_issue_iocb. + */ static int __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *piocb, uint32_t flag) @@ -3805,16 +3052,6 @@ __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, * can be issued if the link is not up. */ switch (piocb->iocb.ulpCommand) { - case CMD_GEN_REQUEST64_CR: - case CMD_GEN_REQUEST64_CX: - if (!(phba->sli.sli_flag & LPFC_MENLO_MAINT) || - (piocb->iocb.un.genreq64.w5.hcsw.Rctl != - FC_FCP_CMND) || - (piocb->iocb.un.genreq64.w5.hcsw.Type != - MENLO_TRANSPORT_TYPE)) - - goto iocb_busy; - break; case CMD_QUE_RING_BUF_CN: case CMD_QUE_RING_BUF64_CN: /* @@ -3869,19 +3106,6 @@ __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } -/** - * lpfc_sli_issue_iocb: Wrapper function for __lpfc_sli_issue_iocb. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @piocb: Pointer to command iocb. - * @flag: Flag indicating if this command can be put into txq. - * - * lpfc_sli_issue_iocb is a wrapper around __lpfc_sli_issue_iocb - * function. This function gets the hbalock and calls - * __lpfc_sli_issue_iocb function and will return the error returned - * by __lpfc_sli_issue_iocb function. This wrapper is used by - * functions which do not hold hbalock. - **/ int lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *piocb, uint32_t flag) @@ -3896,17 +3120,6 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return rc; } -/** - * lpfc_extra_ring_setup: Extra ring setup function. - * @phba: Pointer to HBA context object. - * - * This function is called while driver attaches with the - * HBA to setup the extra ring. The extra ring is used - * only when driver needs to support target mode functionality - * or IP over FC functionalities. - * - * This function is called with no lock held. - **/ static int lpfc_extra_ring_setup( struct lpfc_hba *phba) { @@ -3942,19 +3155,6 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba) return 0; } -/** - * lpfc_sli_async_event_handler: ASYNC iocb handler function. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @iocbq: Pointer to iocb object. - * - * This function is called by the slow ring event handler - * function when there is an ASYNC event iocb in the ring. - * This function is called with no lock held. - * Currently this function handles only temperature related - * ASYNC events. The function decodes the temperature sensor - * event message and posts events for the management applications. - **/ static void lpfc_sli_async_event_handler(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, struct lpfc_iocbq * iocbq) @@ -4010,17 +3210,6 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba, } -/** - * lpfc_sli_setup: SLI ring setup function. - * @phba: Pointer to HBA context object. - * - * lpfc_sli_setup sets up rings of the SLI interface with - * number of iocbs per ring and iotags. This function is - * called while driver attach to the HBA and before the - * interrupts are enabled. So there is no need for locking. - * - * This function always returns 0. - **/ int lpfc_sli_setup(struct lpfc_hba *phba) { @@ -4132,17 +3321,6 @@ lpfc_sli_setup(struct lpfc_hba *phba) return 0; } -/** - * lpfc_sli_queue_setup: Queue initialization function. - * @phba: Pointer to HBA context object. - * - * lpfc_sli_queue_setup sets up mailbox queues and iocb queues for each - * ring. This function also initializes ring indices of each ring. - * This function is called during the initialization of the SLI - * interface of an HBA. - * This function is called with no lock held and always returns - * 1. - **/ int lpfc_sli_queue_setup(struct lpfc_hba *phba) { @@ -4171,23 +3349,6 @@ lpfc_sli_queue_setup(struct lpfc_hba *phba) return 1; } -/** - * lpfc_sli_host_down: Vport cleanup function. - * @vport: Pointer to virtual port object. - * - * lpfc_sli_host_down is called to clean up the resources - * associated with a vport before destroying virtual - * port data structures. - * This function does following operations: - * - Free discovery resources associated with this virtual - * port. - * - Free iocbs associated with this virtual port in - * the txq. - * - Send abort for all iocb commands associated with this - * vport in txcmplq. - * - * This function is called with no lock held and always returns 1. - **/ int lpfc_sli_host_down(struct lpfc_vport *vport) { @@ -4250,21 +3411,6 @@ lpfc_sli_host_down(struct lpfc_vport *vport) return 1; } -/** - * lpfc_sli_hba_down: Resource cleanup function for the HBA. - * @phba: Pointer to HBA context object. - * - * This function cleans up all iocb, buffers, mailbox commands - * while shutting down the HBA. This function is called with no - * lock held and always returns 1. - * This function does the following to cleanup driver resources: - * - Free discovery resources for each virtual port - * - Cleanup any pending fabric iocbs - * - Iterate through the iocb txq and free each entry - * in the list. - * - Free up any buffer posted to the HBA - * - Free mailbox commands in the mailbox queue. - **/ int lpfc_sli_hba_down(struct lpfc_hba *phba) { @@ -4355,18 +3501,6 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) return 1; } -/** - * lpfc_sli_pcimem_bcopy: SLI memory copy function. - * @srcp: Source memory pointer. - * @destp: Destination memory pointer. - * @cnt: Number of words required to be copied. - * - * This function is used for copying data between driver memory - * and the SLI memory. This function also changes the endianness - * of each word if native endianness is different from SLI - * endianness. This function can be called with or without - * lock. - **/ void lpfc_sli_pcimem_bcopy(void *srcp, void *destp, uint32_t cnt) { @@ -4384,17 +3518,6 @@ lpfc_sli_pcimem_bcopy(void *srcp, void *destp, uint32_t cnt) } } - -/** - * lpfc_sli_ringpostbuf_put: Function to add a buffer to postbufq. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @mp: Pointer to driver buffer object. - * - * This function is called with no lock held. - * It always return zero after adding the buffer to the postbufq - * buffer list. - **/ int lpfc_sli_ringpostbuf_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_dmabuf *mp) @@ -4408,18 +3531,6 @@ lpfc_sli_ringpostbuf_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return 0; } -/** - * lpfc_sli_get_buffer_tag: Tag allocation function for a buffer posted - * using CMD_QUE_XRI64_CX iocb. - * @phba: Pointer to HBA context object. - * - * When HBQ is enabled, buffers are searched based on tags. This function - * allocates a tag for buffer posted using CMD_QUE_XRI64_CX iocb. The - * tag is bit wise or-ed with QUE_BUFTAG_BIT to make sure that the tag - * does not conflict with tags of buffer posted for unsolicited events. - * The function returns the allocated tag. The function is called with - * no locks held. - **/ uint32_t lpfc_sli_get_buffer_tag(struct lpfc_hba *phba) { @@ -4434,22 +3545,6 @@ lpfc_sli_get_buffer_tag(struct lpfc_hba *phba) return phba->buffer_tag_count; } -/** - * lpfc_sli_ring_taggedbuf_get: Search HBQ buffer associated with - * posted using CMD_QUE_XRI64_CX iocb. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @tag: Buffer tag. - * - * Buffers posted using CMD_QUE_XRI64_CX iocb are in pring->postbufq - * list. After HBA DMA data to these buffers, CMD_IOCB_RET_XRI64_CX - * iocb is posted to the response ring with the tag of the buffer. - * This function searches the pring->postbufq list using the tag - * to find buffer associated with CMD_IOCB_RET_XRI64_CX - * iocb. If the buffer is found then lpfc_dmabuf object of the - * buffer is returned to the caller else NULL is returned. - * This function is called with no lock held. - **/ struct lpfc_dmabuf * lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, uint32_t tag) @@ -4470,7 +3565,7 @@ lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, spin_unlock_irq(&phba->hbalock); lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0402 Cannot find virtual addr for buffer tag on " + "0410 Cannot find virtual addr for buffer tag on " "ring %d Data x%lx x%p x%p x%x\n", pring->ringno, (unsigned long) tag, slp->next, slp->prev, pring->postbufq_cnt); @@ -4478,23 +3573,6 @@ lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return NULL; } -/** - * lpfc_sli_ringpostbuf_get: SLI2 buffer search function for - * unsolicited ct and els events. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @phys: DMA address of the buffer. - * - * This function searches the buffer list using the dma_address - * of unsolicited event to find the driver's lpfc_dmabuf object - * corresponding to the dma_address. The function returns the - * lpfc_dmabuf object if a buffer is found else it returns NULL. - * This function is called by the ct and els unsolicited event - * handlers to get the buffer associated with the unsolicited - * event. - * - * This function is called with no lock held. - **/ struct lpfc_dmabuf * lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, dma_addr_t phys) @@ -4522,17 +3600,6 @@ lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return NULL; } -/** - * lpfc_sli_abort_els_cmpl: Completion handler for the els abort iocbs. - * @phba: Pointer to HBA context object. - * @cmdiocb: Pointer to driver command iocb object. - * @rspiocb: Pointer to driver response iocb object. - * - * This function is the completion handler for the abort iocbs for - * ELS commands. This function is called from the ELS ring event - * handler with no lock held. This function frees memory resources - * associated with the abort iocb. - **/ static void lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -4598,17 +3665,6 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; } -/** - * lpfc_ignore_els_cmpl: Completion handler for aborted ELS command. - * @phba: Pointer to HBA context object. - * @cmdiocb: Pointer to driver command iocb object. - * @rspiocb: Pointer to driver response iocb object. - * - * The function is called from SLI ring event handler with no - * lock held. This function is the completion handler for ELS commands - * which are aborted. The function frees memory resources used for - * the aborted ELS commands. - **/ static void lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -4617,7 +3673,7 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* ELS cmd tag completes */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "0139 Ignoring ELS cmd tag x%x completion Data: " + "0133 Ignoring ELS cmd tag x%x completion Data: " "x%x x%x x%x\n", irsp->ulpIoTag, irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout); @@ -4628,17 +3684,6 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; } -/** - * lpfc_sli_issue_abort_iotag: Abort function for a command iocb. - * @phba: Pointer to HBA context object. - * @pring: Pointer to driver SLI ring object. - * @cmdiocb: Pointer to driver command iocb object. - * - * This function issues an abort iocb for the provided command - * iocb. This function is called with hbalock held. - * The function returns 0 when it fails due to memory allocation - * failure or when the command iocb is an abort request. - **/ int lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *cmdiocb) @@ -4703,8 +3748,6 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, iabt->un.acxri.abortIoTag, abtsiocbp->iotag); retval = __lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0); - if (retval) - __lpfc_sli_release_iocbq(phba, abtsiocbp); abort_iotag_exit: /* * Caller to this routine should check for IOCB_ERROR @@ -4714,29 +3757,6 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return retval; } -/** - * lpfc_sli_validate_fcp_iocb: Filtering function, used to find commands - * associated with a vport/SCSI target/lun. - * @iocbq: Pointer to driver iocb object. - * @vport: Pointer to driver virtual port object. - * @tgt_id: SCSI ID of the target. - * @lun_id: LUN ID of the scsi device. - * @ctx_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST - * - * This function acts as iocb filter for functions which abort or count - * all FCP iocbs pending on a lun/SCSI target/SCSI host. It will return - * 0 if the filtering criteria is met for the given iocb and will return - * 1 if the filtering criteria is not met. - * If ctx_cmd == LPFC_CTX_LUN, the function returns 0 only if the - * given iocb is for the SCSI device specified by vport, tgt_id and - * lun_id parameter. - * If ctx_cmd == LPFC_CTX_TGT, the function returns 0 only if the - * given iocb is for the SCSI target specified by vport and tgt_id - * parameters. - * If ctx_cmd == LPFC_CTX_HOST, the function returns 0 only if the - * given iocb is for the SCSI host associated with the given vport. - * This function is called with no locks held. - **/ static int lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id, @@ -4780,25 +3800,6 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport, return rc; } -/** - * lpfc_sli_sum_iocb: Function to count the number of FCP iocbs pending. - * @vport: Pointer to virtual port. - * @tgt_id: SCSI ID of the target. - * @lun_id: LUN ID of the scsi device. - * @ctx_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST. - * - * This function returns number of FCP commands pending for the vport. - * When ctx_cmd == LPFC_CTX_LUN, the function returns number of FCP - * commands pending on the vport associated with SCSI device specified - * by tgt_id and lun_id parameters. - * When ctx_cmd == LPFC_CTX_TGT, the function returns number of FCP - * commands pending on the vport associated with SCSI target specified - * by tgt_id parameter. - * When ctx_cmd == LPFC_CTX_HOST, the function returns number of FCP - * commands pending on the vport. - * This function returns the number of iocbs which satisfy the filter. - * This function is called without any lock held. - **/ int lpfc_sli_sum_iocb(struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd) @@ -4818,17 +3819,6 @@ lpfc_sli_sum_iocb(struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id, return sum; } -/** - * lpfc_sli_abort_fcp_cmpl: Completion handler function for an aborted - * FCP iocb. - * @phba: Pointer to HBA context object - * @cmdiocb: Pointer to command iocb object. - * @rspiocb: Pointer to response iocb object. - * - * This function is called when an aborted FCP iocb completes. This - * function is called by the ring event handler with no lock held. - * This function frees the iocb. - **/ void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) @@ -4837,28 +3827,6 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; } -/** - * lpfc_sli_abort_iocb: This function issue abort for all SCSI commands - * pending on a SCSI host(vport)/target/lun. - * @vport: Pointer to virtual port. - * @pring: Pointer to driver SLI ring object. - * @tgt_id: SCSI ID of the target. - * @lun_id: LUN ID of the scsi device. - * @abort_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST. - * - * This function sends an abort command for every SCSI command - * associated with the given virtual port pending on the ring - * filtered by lpfc_sli_validate_fcp_iocb function. - * When abort_cmd == LPFC_CTX_LUN, the function sends abort only to the - * FCP iocbs associated with lun specified by tgt_id and lun_id - * parameters - * When abort_cmd == LPFC_CTX_TGT, the function sends abort only to the - * FCP iocbs associated with SCSI target specified by tgt_id parameter. - * When abort_cmd == LPFC_CTX_HOST, the function sends abort to all - * FCP iocbs associated with virtual port. - * This function returns number of iocbs it failed to abort. - * This function is called with no locks held. - **/ int lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd abort_cmd) @@ -4910,24 +3878,6 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, return errcnt; } -/** - * lpfc_sli_wake_iocb_wait: iocb completion handler for iocb issued using - * lpfc_sli_issue_iocb_wait. - * @phba: Pointer to HBA context object. - * @cmdiocbq: Pointer to command iocb. - * @rspiocbq: Pointer to response iocb. - * - * This function is the completion handler for iocbs issued using - * lpfc_sli_issue_iocb_wait function. This function is called by the - * ring event handler function without any lock held. This function - * can be called from both worker thread context and interrupt - * context. This function also can be called from other thread which - * cleans up the SLI layer objects. - * This function copy the contents of the response iocb to the - * response iocb memory object provided by the caller of - * lpfc_sli_issue_iocb_wait and then wakes up the thread which - * sleeps for the iocb completion. - **/ static void lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocbq, @@ -4949,36 +3899,13 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, return; } -/** - * lpfc_sli_issue_iocb_wait: Synchronous function to issue iocb commands. - * @phba: Pointer to HBA context object.. - * @pring: Pointer to sli ring. - * @piocb: Pointer to command iocb. - * @prspiocbq: Pointer to response iocb. - * @timeout: Timeout in number of seconds. - * - * This function issues the iocb to firmware and waits for the - * iocb to complete. If the iocb command is not - * completed within timeout seconds, it returns IOCB_TIMEDOUT. - * Caller should not free the iocb resources if this function - * returns IOCB_TIMEDOUT. - * The function waits for the iocb completion using an - * non-interruptible wait. - * This function will sleep while waiting for iocb completion. - * So, this function should not be called from any context which - * does not allow sleeping. Due to the same reason, this function - * cannot be called with interrupt disabled. - * This function assumes that the iocb completions occur while - * this function sleep. So, this function cannot be called from - * the thread which process iocb completion for this ring. - * This function clears the iocb_flag of the iocb object before - * issuing the iocb and the iocb completion handler sets this - * flag and wakes this thread when the iocb completes. - * The contents of the response iocb will be copied to prspiocbq - * by the completion handler when the command completes. - * This function returns IOCB_SUCCESS when success. - * This function is called with no lock held. - **/ +/* + * Issue the caller's iocb and wait for its completion, but no longer than the + * caller's timeout. Note that iocb_flags is cleared before the + * lpfc_sli_issue_call since the wake routine sets a unique value and by + * definition this is a wait function. + */ + int lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, @@ -5036,7 +3963,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba, } } else { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "0332 IOCB wait issue failed, Data x%x\n", + ":0332 IOCB wait issue failed, Data x%x\n", retval); retval = IOCB_ERROR; } @@ -5056,32 +3983,6 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba, return retval; } -/** - * lpfc_sli_issue_mbox_wait: Synchronous function to issue mailbox. - * @phba: Pointer to HBA context object. - * @pmboxq: Pointer to driver mailbox object. - * @timeout: Timeout in number of seconds. - * - * This function issues the mailbox to firmware and waits for the - * mailbox command to complete. If the mailbox command is not - * completed within timeout seconds, it returns MBX_TIMEOUT. - * The function waits for the mailbox completion using an - * interruptible wait. If the thread is woken up due to a - * signal, MBX_TIMEOUT error is returned to the caller. Caller - * should not free the mailbox resources, if this function returns - * MBX_TIMEOUT. - * This function will sleep while waiting for mailbox completion. - * So, this function should not be called from any context which - * does not allow sleeping. Due to the same reason, this function - * cannot be called with interrupt disabled. - * This function assumes that the mailbox completion occurs while - * this function sleep. So, this function cannot be called from - * the worker thread which processes mailbox completion. - * This function is called in the context of HBA management - * applications. - * This function returns MBX_SUCCESS when successful. - * This function is called with no lock held. - **/ int lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, uint32_t timeout) @@ -5126,18 +4027,6 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, return retval; } -/** - * lpfc_sli_flush_mbox_queue: mailbox queue cleanup function. - * @phba: Pointer to HBA context. - * - * This function is called to cleanup any pending mailbox - * objects in the driver queue before bringing the HBA offline. - * This function is called while resetting the HBA. - * The function is called without any lock held. The function - * takes hbalock to update SLI data structure. - * This function returns 1 when there is an active mailbox - * command pending else returns 0. - **/ int lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba) { @@ -5169,74 +4058,8 @@ lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba) return (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) ? 1 : 0; } -/** - * lpfc_sli_check_eratt: check error attention events - * @phba: Pointer to HBA context. - * - * This function is called form timer soft interrupt context to check HBA's - * error attention register bit for error attention events. - * - * This fucntion returns 1 when there is Error Attention in the Host Attention - * Register and returns 0 otherwise. - **/ -int -lpfc_sli_check_eratt(struct lpfc_hba *phba) -{ - uint32_t ha_copy; - - /* If somebody is waiting to handle an eratt, don't process it - * here. The brdkill function will do this. - */ - if (phba->link_flag & LS_IGNORE_ERATT) - return 0; - - /* Check if interrupt handler handles this ERATT */ - spin_lock_irq(&phba->hbalock); - if (phba->hba_flag & HBA_ERATT_HANDLED) { - /* Interrupt handler has handled ERATT */ - spin_unlock_irq(&phba->hbalock); - return 0; - } - - /* Read chip Host Attention (HA) register */ - ha_copy = readl(phba->HAregaddr); - if (ha_copy & HA_ERATT) { - /* Read host status register to retrieve error event */ - lpfc_sli_read_hs(phba); - /* Set the driver HA work bitmap */ - phba->work_ha |= HA_ERATT; - /* Indicate polling handles this ERATT */ - phba->hba_flag |= HBA_ERATT_HANDLED; - spin_unlock_irq(&phba->hbalock); - return 1; - } - spin_unlock_irq(&phba->hbalock); - return 0; -} - -/** - * lpfc_sp_intr_handler: The slow-path interrupt handler of lpfc driver. - * @irq: Interrupt number. - * @dev_id: The device context pointer. - * - * This function is directly called from the PCI layer as an interrupt - * service routine when the device is enabled with MSI-X multi-message - * interrupt mode and there are slow-path events in the HBA. However, - * when the device is enabled with either MSI or Pin-IRQ interrupt mode, - * this function is called as part of the device-level interrupt handler. - * When the PCI slot is in error recovery or the HBA is undergoing - * initialization, the interrupt handler will not process the interrupt. - * The link attention and ELS ring attention events are handled by the - * worker thread. The interrupt handler signals the worker thread and - * and returns for these events. This function is called without any - * lock held. It gets the hbalock to access and update SLI data - * structures. - * - * This function returns IRQ_HANDLED when interrupt is handled else it - * returns IRQ_NONE. - **/ irqreturn_t -lpfc_sp_intr_handler(int irq, void *dev_id) +lpfc_intr_handler(int irq, void *dev_id) { struct lpfc_hba *phba; uint32_t ha_copy; @@ -5255,52 +4078,48 @@ lpfc_sp_intr_handler(int irq, void *dev_id) * Get the driver's phba structure from the dev_id and * assume the HBA is not interrupting. */ - phba = (struct lpfc_hba *)dev_id; + phba = (struct lpfc_hba *) dev_id; if (unlikely(!phba)) return IRQ_NONE; + /* If the pci channel is offline, ignore all the interrupts. */ + if (unlikely(pci_channel_offline(phba->pcidev))) + return IRQ_NONE; + + phba->sli.slistat.sli_intr++; + /* - * Stuff needs to be attented to when this function is invoked as an - * individual interrupt handler in MSI-X multi-message interrupt mode + * Call the HBA to see if it is interrupting. If not, don't claim + * the interrupt */ - if (phba->intr_type == MSIX) { - /* If the pci channel is offline, ignore all the interrupts */ - if (unlikely(pci_channel_offline(phba->pcidev))) - return IRQ_NONE; - /* Update device-level interrupt statistics */ - phba->sli.slistat.sli_intr++; - /* Ignore all interrupts during initialization. */ - if (unlikely(phba->link_state < LPFC_LINK_DOWN)) - return IRQ_NONE; - /* Need to read HA REG for slow-path events */ - spin_lock(&phba->hbalock); - ha_copy = readl(phba->HAregaddr); - /* If somebody is waiting to handle an eratt don't process it - * here. The brdkill function will do this. - */ - if (phba->link_flag & LS_IGNORE_ERATT) - ha_copy &= ~HA_ERATT; - /* Check the need for handling ERATT in interrupt handler */ - if (ha_copy & HA_ERATT) { - if (phba->hba_flag & HBA_ERATT_HANDLED) - /* ERATT polling has handled ERATT */ - ha_copy &= ~HA_ERATT; - else - /* Indicate interrupt handler handles ERATT */ - phba->hba_flag |= HBA_ERATT_HANDLED; - } - /* Clear up only attention source related to slow-path */ - writel((ha_copy & (HA_MBATT | HA_R2_CLR_MSK)), - phba->HAregaddr); - readl(phba->HAregaddr); /* flush */ - spin_unlock(&phba->hbalock); - } else - ha_copy = phba->ha_copy; + + /* Ignore all interrupts during initialization. */ + if (unlikely(phba->link_state < LPFC_LINK_DOWN)) + return IRQ_NONE; + + /* + * Read host attention register to determine interrupt source + * Clear Attention Sources, except Error Attention (to + * preserve status) and Link Attention + */ + spin_lock(&phba->hbalock); + ha_copy = readl(phba->HAregaddr); + /* If somebody is waiting to handle an eratt don't process it + * here. The brdkill function will do this. + */ + if (phba->link_flag & LS_IGNORE_ERATT) + ha_copy &= ~HA_ERATT; + writel((ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr); + readl(phba->HAregaddr); /* flush */ + spin_unlock(&phba->hbalock); + + if (unlikely(!ha_copy)) + return IRQ_NONE; work_ha_copy = ha_copy & phba->work_ha_mask; - if (work_ha_copy) { + if (unlikely(work_ha_copy)) { if (work_ha_copy & HA_LATT) { if (phba->sli.sli_flag & LPFC_PROCESS_LA) { /* @@ -5319,7 +4138,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id) work_ha_copy &= ~HA_LATT; } - if (work_ha_copy & ~(HA_ERATT | HA_MBATT | HA_LATT)) { + if (work_ha_copy & ~(HA_ERATT|HA_MBATT|HA_LATT)) { /* * Turn off Slow Rings interrupts, LPFC_ELS_RING is * the only slow ring. @@ -5360,13 +4179,31 @@ lpfc_sp_intr_handler(int irq, void *dev_id) spin_unlock(&phba->hbalock); } } + + if (work_ha_copy & HA_ERATT) { + /* + * There was a link/board error. Read the + * status register to retrieve the error event + * and process it. + */ + phba->sli.slistat.err_attn_event++; + /* Save status info */ + phba->work_hs = readl(phba->HSregaddr); + phba->work_status[0] = readl(phba->MBslimaddr + 0xa8); + phba->work_status[1] = readl(phba->MBslimaddr + 0xac); + + /* Clear Chip error bit */ + writel(HA_ERATT, phba->HAregaddr); + readl(phba->HAregaddr); /* flush */ + phba->pport->stopped = 1; + } + spin_lock(&phba->hbalock); - if (work_ha_copy & HA_ERATT) - lpfc_sli_read_hs(phba); - if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active)) { + if ((work_ha_copy & HA_MBATT) && + (phba->sli.mbox_active)) { pmb = phba->sli.mbox_active; pmbox = &pmb->mb; - mbox = phba->mbox; + mbox = &phba->slim2p->mbx; vport = pmb->vport; /* First check out the status word */ @@ -5433,7 +4270,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id) lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, - "0350 rc should have" + "0306 rc should have" "been MBX_BUSY"); goto send_current_mbox; } @@ -5446,7 +4283,6 @@ lpfc_sp_intr_handler(int irq, void *dev_id) } } else spin_unlock(&phba->hbalock); - if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active == NULL)) { send_current_mbox: @@ -5466,74 +4302,15 @@ lpfc_sp_intr_handler(int irq, void *dev_id) spin_unlock(&phba->hbalock); lpfc_worker_wake_up(phba); } - return IRQ_HANDLED; - -} /* lpfc_sp_intr_handler */ - -/** - * lpfc_fp_intr_handler: The fast-path interrupt handler of lpfc driver. - * @irq: Interrupt number. - * @dev_id: The device context pointer. - * - * This function is directly called from the PCI layer as an interrupt - * service routine when the device is enabled with MSI-X multi-message - * interrupt mode and there is a fast-path FCP IOCB ring event in the - * HBA. However, when the device is enabled with either MSI or Pin-IRQ - * interrupt mode, this function is called as part of the device-level - * interrupt handler. When the PCI slot is in error recovery or the HBA - * is undergoing initialization, the interrupt handler will not process - * the interrupt. The SCSI FCP fast-path ring event are handled in the - * intrrupt context. This function is called without any lock held. It - * gets the hbalock to access and update SLI data structures. - * - * This function returns IRQ_HANDLED when interrupt is handled else it - * returns IRQ_NONE. - **/ -irqreturn_t -lpfc_fp_intr_handler(int irq, void *dev_id) -{ - struct lpfc_hba *phba; - uint32_t ha_copy; - unsigned long status; - - /* Get the driver's phba structure from the dev_id and - * assume the HBA is not interrupting. - */ - phba = (struct lpfc_hba *) dev_id; - - if (unlikely(!phba)) - return IRQ_NONE; - /* - * Stuff needs to be attented to when this function is invoked as an - * individual interrupt handler in MSI-X multi-message interrupt mode - */ - if (phba->intr_type == MSIX) { - /* If pci channel is offline, ignore all the interrupts */ - if (unlikely(pci_channel_offline(phba->pcidev))) - return IRQ_NONE; - /* Update device-level interrupt statistics */ - phba->sli.slistat.sli_intr++; - /* Ignore all interrupts during initialization. */ - if (unlikely(phba->link_state < LPFC_LINK_DOWN)) - return IRQ_NONE; - /* Need to read HA REG for FCP ring and other ring events */ - ha_copy = readl(phba->HAregaddr); - /* Clear up only attention source related to fast-path */ - spin_lock(&phba->hbalock); - writel((ha_copy & (HA_R0_CLR_MSK | HA_R1_CLR_MSK)), - phba->HAregaddr); - readl(phba->HAregaddr); /* flush */ - spin_unlock(&phba->hbalock); - } else - ha_copy = phba->ha_copy; + ha_copy &= ~(phba->work_ha_mask); /* - * Process all events on FCP ring. Take the optimized path for FCP IO. + * Process all events on FCP ring. Take the optimized path for + * FCP IO. Any other IO is slow path and is handled by + * the worker thread. */ - ha_copy &= ~(phba->work_ha_mask); - - status = (ha_copy & (HA_RXMASK << (4*LPFC_FCP_RING))); + status = (ha_copy & (HA_RXMASK << (4*LPFC_FCP_RING))); status >>= (4*LPFC_FCP_RING); if (status & HA_RXMASK) lpfc_sli_handle_fast_ring_event(phba, @@ -5542,10 +4319,11 @@ lpfc_fp_intr_handler(int irq, void *dev_id) if (phba->cfg_multi_ring_support == 2) { /* - * Process all events on extra ring. Take the optimized path - * for extra ring IO. + * Process all events on extra ring. Take the optimized path + * for extra ring IO. Any other IO is slow path and is handled + * by the worker thread. */ - status = (ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING))); + status = (ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING))); status >>= (4*LPFC_EXTRA_RING); if (status & HA_RXMASK) { lpfc_sli_handle_fast_ring_event(phba, @@ -5554,106 +4332,5 @@ lpfc_fp_intr_handler(int irq, void *dev_id) } } return IRQ_HANDLED; -} /* lpfc_fp_intr_handler */ - -/** - * lpfc_intr_handler: The device-level interrupt handler of lpfc driver. - * @irq: Interrupt number. - * @dev_id: The device context pointer. - * - * This function is the device-level interrupt handler called from the PCI - * layer when either MSI or Pin-IRQ interrupt mode is enabled and there is - * an event in the HBA which requires driver attention. This function - * invokes the slow-path interrupt attention handling function and fast-path - * interrupt attention handling function in turn to process the relevant - * HBA attention events. This function is called without any lock held. It - * gets the hbalock to access and update SLI data structures. - * - * This function returns IRQ_HANDLED when interrupt is handled, else it - * returns IRQ_NONE. - **/ -irqreturn_t -lpfc_intr_handler(int irq, void *dev_id) -{ - struct lpfc_hba *phba; - irqreturn_t sp_irq_rc, fp_irq_rc; - unsigned long status1, status2; - - /* - * Get the driver's phba structure from the dev_id and - * assume the HBA is not interrupting. - */ - phba = (struct lpfc_hba *) dev_id; - - if (unlikely(!phba)) - return IRQ_NONE; - - /* If the pci channel is offline, ignore all the interrupts. */ - if (unlikely(pci_channel_offline(phba->pcidev))) - return IRQ_NONE; - - /* Update device level interrupt statistics */ - phba->sli.slistat.sli_intr++; - - /* Ignore all interrupts during initialization. */ - if (unlikely(phba->link_state < LPFC_LINK_DOWN)) - return IRQ_NONE; - - spin_lock(&phba->hbalock); - phba->ha_copy = readl(phba->HAregaddr); - if (unlikely(!phba->ha_copy)) { - spin_unlock(&phba->hbalock); - return IRQ_NONE; - } else if (phba->ha_copy & HA_ERATT) { - if (phba->hba_flag & HBA_ERATT_HANDLED) - /* ERATT polling has handled ERATT */ - phba->ha_copy &= ~HA_ERATT; - else - /* Indicate interrupt handler handles ERATT */ - phba->hba_flag |= HBA_ERATT_HANDLED; - } - - /* Clear attention sources except link and error attentions */ - writel((phba->ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr); - readl(phba->HAregaddr); /* flush */ - spin_unlock(&phba->hbalock); - - /* - * Invokes slow-path host attention interrupt handling as appropriate. - */ - - /* status of events with mailbox and link attention */ - status1 = phba->ha_copy & (HA_MBATT | HA_LATT | HA_ERATT); - - /* status of events with ELS ring */ - status2 = (phba->ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING))); - status2 >>= (4*LPFC_ELS_RING); - - if (status1 || (status2 & HA_RXMASK)) - sp_irq_rc = lpfc_sp_intr_handler(irq, dev_id); - else - sp_irq_rc = IRQ_NONE; - - /* - * Invoke fast-path host attention interrupt handling as appropriate. - */ - - /* status of events with FCP ring */ - status1 = (phba->ha_copy & (HA_RXMASK << (4*LPFC_FCP_RING))); - status1 >>= (4*LPFC_FCP_RING); - - /* status of events with extra ring */ - if (phba->cfg_multi_ring_support == 2) { - status2 = (phba->ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING))); - status2 >>= (4*LPFC_EXTRA_RING); - } else - status2 = 0; - - if ((status1 & HA_RXMASK) || (status2 & HA_RXMASK)) - fp_irq_rc = lpfc_fp_intr_handler(irq, dev_id); - else - fp_irq_rc = IRQ_NONE; - /* Return device-level interrupt handling status */ - return (sp_irq_rc == IRQ_HANDLED) ? sp_irq_rc : fp_irq_rc; -} /* lpfc_intr_handler */ +} /* lpfc_intr_handler */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.h b/trunk/drivers/scsi/lpfc/lpfc_sli.h index 883938652a6a..7249fd252cbb 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.h +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.h @@ -233,7 +233,6 @@ struct lpfc_sli { #define LPFC_SLI2_ACTIVE 0x200 /* SLI2 overlay in firmware is active */ #define LPFC_PROCESS_LA 0x400 /* Able to process link attention */ #define LPFC_BLOCK_MGMT_IO 0x800 /* Don't allow mgmt mbx or iocb cmds */ -#define LPFC_MENLO_MAINT 0x1000 /* need for menl fw download */ struct lpfc_sli_ring ring[LPFC_MAX_RING]; int fcp_ring; /* ring used for FCP initiator commands */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_version.h b/trunk/drivers/scsi/lpfc/lpfc_version.h index cc43e9de22cc..ad24cacfbe10 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_version.h +++ b/trunk/drivers/scsi/lpfc/lpfc_version.h @@ -18,11 +18,9 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.2.8" +#define LPFC_DRIVER_VERSION "8.2.7" -#define LPFC_DRIVER_NAME "lpfc" -#define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" -#define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" +#define LPFC_DRIVER_NAME "lpfc" #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ LPFC_DRIVER_VERSION diff --git a/trunk/drivers/scsi/lpfc/lpfc_vport.c b/trunk/drivers/scsi/lpfc/lpfc_vport.c index a7de1cc02b40..109f89d98830 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_vport.c +++ b/trunk/drivers/scsi/lpfc/lpfc_vport.c @@ -34,7 +34,6 @@ #include #include "lpfc_hw.h" #include "lpfc_sli.h" -#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h" @@ -205,77 +204,6 @@ lpfc_unique_wwpn(struct lpfc_hba *phba, struct lpfc_vport *new_vport) return 1; } -/** - * lpfc_discovery_wait: Wait for driver discovery to quiesce. - * @vport: The virtual port for which this call is being executed. - * - * This driver calls this routine specifically from lpfc_vport_delete - * to enforce a synchronous execution of vport - * delete relative to discovery activities. The - * lpfc_vport_delete routine should not return until it - * can reasonably guarantee that discovery has quiesced. - * Post FDISC LOGO, the driver must wait until its SAN teardown is - * complete and all resources recovered before allowing - * cleanup. - * - * This routine does not require any locks held. - **/ -static void lpfc_discovery_wait(struct lpfc_vport *vport) -{ - struct lpfc_hba *phba = vport->phba; - uint32_t wait_flags = 0; - unsigned long wait_time_max; - unsigned long start_time; - - wait_flags = FC_RSCN_MODE | FC_RSCN_DISCOVERY | FC_NLP_MORE | - FC_RSCN_DEFERRED | FC_NDISC_ACTIVE | FC_DISC_TMO; - - /* - * The time constraint on this loop is a balance between the - * fabric RA_TOV value and dev_loss tmo. The driver's - * devloss_tmo is 10 giving this loop a 3x multiplier minimally. - */ - wait_time_max = msecs_to_jiffies(((phba->fc_ratov * 3) + 3) * 1000); - wait_time_max += jiffies; - start_time = jiffies; - while (time_before(jiffies, wait_time_max)) { - if ((vport->num_disc_nodes > 0) || - (vport->fc_flag & wait_flags) || - ((vport->port_state > LPFC_VPORT_FAILED) && - (vport->port_state < LPFC_VPORT_READY))) { - lpfc_printf_log(phba, KERN_INFO, LOG_VPORT, - "1833 Vport discovery quiesce Wait:" - " vpi x%x state x%x fc_flags x%x" - " num_nodes x%x, waiting 1000 msecs" - " total wait msecs x%x\n", - vport->vpi, vport->port_state, - vport->fc_flag, vport->num_disc_nodes, - jiffies_to_msecs(jiffies - start_time)); - msleep(1000); - } else { - /* Base case. Wait variants satisfied. Break out */ - lpfc_printf_log(phba, KERN_INFO, LOG_VPORT, - "1834 Vport discovery quiesced:" - " vpi x%x state x%x fc_flags x%x" - " wait msecs x%x\n", - vport->vpi, vport->port_state, - vport->fc_flag, - jiffies_to_msecs(jiffies - - start_time)); - break; - } - } - - if (time_after(jiffies, wait_time_max)) - lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, - "1835 Vport discovery quiesce failed:" - " vpi x%x state x%x fc_flags x%x" - " wait msecs x%x\n", - vport->vpi, vport->port_state, - vport->fc_flag, - jiffies_to_msecs(jiffies - start_time)); -} - int lpfc_vport_create(struct fc_vport *fc_vport, bool disable) { @@ -578,12 +506,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport) * initiated after we've disposed of all other resources associated * with the port. */ - if (!scsi_host_get(shost)) - return VPORT_INVAL; - if (!scsi_host_get(shost)) { - scsi_host_put(shost); + if (!scsi_host_get(shost) || !scsi_host_get(shost)) return VPORT_INVAL; - } spin_lock_irq(&phba->hbalock); vport->load_flag |= FC_UNLOADING; spin_unlock_irq(&phba->hbalock); @@ -673,16 +597,11 @@ lpfc_vport_delete(struct fc_vport *fc_vport) } vport->unreg_vpi_cmpl = VPORT_INVAL; timeout = msecs_to_jiffies(phba->fc_ratov * 2000); - if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) - goto skip_logo; if (!lpfc_issue_els_npiv_logo(vport, ndlp)) while (vport->unreg_vpi_cmpl == VPORT_INVAL && timeout) timeout = schedule_timeout(timeout); } - if (!(phba->pport->load_flag & FC_UNLOADING)) - lpfc_discovery_wait(vport); - skip_logo: lpfc_cleanup(vport); lpfc_sli_host_down(vport); @@ -696,10 +615,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport) * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) * does the scsi_host_put() to release the vport. */ - if (lpfc_mbx_unreg_vpi(vport)) - scsi_host_put(shost); - } else - scsi_host_put(shost); + lpfc_mbx_unreg_vpi(vport); + } lpfc_free_vpi(phba, vport->vpi); vport->work_port_events = 0; @@ -746,82 +663,3 @@ lpfc_destroy_vport_work_array(struct lpfc_hba *phba, struct lpfc_vport **vports) scsi_host_put(lpfc_shost_from_vport(vports[i])); kfree(vports); } - - -/** - * lpfc_vport_reset_stat_data: Reset the statistical data for the vport. - * @vport: Pointer to vport object. - * - * This function resets the statistical data for the vport. This function - * is called with the host_lock held - **/ -void -lpfc_vport_reset_stat_data(struct lpfc_vport *vport) -{ - struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL; - - list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { - if (!NLP_CHK_NODE_ACT(ndlp)) - continue; - if (ndlp->lat_data) - memset(ndlp->lat_data, 0, LPFC_MAX_BUCKET_COUNT * - sizeof(struct lpfc_scsicmd_bkt)); - } -} - - -/** - * lpfc_alloc_bucket: Allocate data buffer required for collecting - * statistical data. - * @vport: Pointer to vport object. - * - * This function allocates data buffer required for all the FC - * nodes of the vport to collect statistical data. - **/ -void -lpfc_alloc_bucket(struct lpfc_vport *vport) -{ - struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL; - - list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { - if (!NLP_CHK_NODE_ACT(ndlp)) - continue; - - kfree(ndlp->lat_data); - ndlp->lat_data = NULL; - - if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) { - ndlp->lat_data = kcalloc(LPFC_MAX_BUCKET_COUNT, - sizeof(struct lpfc_scsicmd_bkt), - GFP_ATOMIC); - - if (!ndlp->lat_data) - lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE, - "0287 lpfc_alloc_bucket failed to " - "allocate statistical data buffer DID " - "0x%x\n", ndlp->nlp_DID); - } - } -} - -/** - * lpfc_free_bucket: Free data buffer required for collecting - * statistical data. - * @vport: Pointer to vport object. - * - * Th function frees statistical data buffer of all the FC - * nodes of the vport. - **/ -void -lpfc_free_bucket(struct lpfc_vport *vport) -{ - struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL; - - list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { - if (!NLP_CHK_NODE_ACT(ndlp)) - continue; - - kfree(ndlp->lat_data); - ndlp->lat_data = NULL; - } -} diff --git a/trunk/drivers/scsi/lpfc/lpfc_vport.h b/trunk/drivers/scsi/lpfc/lpfc_vport.h index 90828340acea..96c445333b69 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_vport.h +++ b/trunk/drivers/scsi/lpfc/lpfc_vport.h @@ -112,8 +112,4 @@ struct vport_cmd_tag { void lpfc_vport_set_state(struct lpfc_vport *vport, enum fc_vport_state new_state); -void lpfc_vport_reset_stat_data(struct lpfc_vport *); -void lpfc_alloc_bucket(struct lpfc_vport *); -void lpfc_free_bucket(struct lpfc_vport *); - #endif /* H_LPFC_VPORT */ diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index ed731968f15f..0ddfe7106b3b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -1006,6 +1006,7 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) } qla2x00_abort_fcport_cmds(fcport); + scsi_target_unblock(&rport->dev); } static int diff --git a/trunk/drivers/scsi/qla2xxx/qla_isr.c b/trunk/drivers/scsi/qla2xxx/qla_isr.c index a76efd99d007..fc4bfa7f839c 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_isr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_isr.c @@ -1187,12 +1187,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) cp->serial_number, comp_status, atomic_read(&fcport->state))); - /* - * We are going to have the fc class block the rport - * while we try to recover so instruct the mid layer - * to requeue until the class decides how to handle this. - */ - cp->result = DID_TRANSPORT_DISRUPTED << 16; + cp->result = DID_BUS_BUSY << 16; if (atomic_read(&fcport->state) == FCS_ONLINE) qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1); break; @@ -1219,12 +1214,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) break; case CS_TIMEOUT: - /* - * We are going to have the fc class block the rport - * while we try to recover so instruct the mid layer - * to requeue until the class decides how to handle this. - */ - cp->result = DID_TRANSPORT_DISRUPTED << 16; + cp->result = DID_BUS_BUSY << 16; if (IS_FWI2_CAPABLE(ha)) { DEBUG2(printk(KERN_INFO diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 2aed4721c0d0..3433441b956a 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -394,8 +394,10 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) } /* Close window on fcport/rport state-transitioning. */ - if (fcport->drport) - goto qc_target_busy; + if (fcport->drport) { + cmd->result = DID_IMM_RETRY << 16; + goto qc_fail_command; + } if (atomic_read(&fcport->state) != FCS_ONLINE) { if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || @@ -403,7 +405,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) cmd->result = DID_NO_CONNECT << 16; goto qc_fail_command; } - goto qc_target_busy; + goto qc_host_busy; } spin_unlock_irq(ha->host->host_lock); @@ -426,10 +428,9 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) qc_host_busy_lock: spin_lock_irq(ha->host->host_lock); - return SCSI_MLQUEUE_HOST_BUSY; -qc_target_busy: - return SCSI_MLQUEUE_TARGET_BUSY; +qc_host_busy: + return SCSI_MLQUEUE_HOST_BUSY; qc_fail_command: done(cmd); @@ -460,8 +461,10 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) } /* Close window on fcport/rport state-transitioning. */ - if (fcport->drport) - goto qc24_target_busy; + if (fcport->drport) { + cmd->result = DID_IMM_RETRY << 16; + goto qc24_fail_command; + } if (atomic_read(&fcport->state) != FCS_ONLINE) { if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || @@ -469,7 +472,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) cmd->result = DID_NO_CONNECT << 16; goto qc24_fail_command; } - goto qc24_target_busy; + goto qc24_host_busy; } spin_unlock_irq(ha->host->host_lock); @@ -492,10 +495,9 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) qc24_host_busy_lock: spin_lock_irq(ha->host->host_lock); - return SCSI_MLQUEUE_HOST_BUSY; -qc24_target_busy: - return SCSI_MLQUEUE_TARGET_BUSY; +qc24_host_busy: + return SCSI_MLQUEUE_HOST_BUSY; qc24_fail_command: done(cmd); diff --git a/trunk/drivers/scsi/qla4xxx/ql4_isr.c b/trunk/drivers/scsi/qla4xxx/ql4_isr.c index 799120fcb9be..a91a57c57bff 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_isr.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_isr.c @@ -139,7 +139,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, ha->host_no, cmd->device->channel, cmd->device->id, cmd->device->lun)); - cmd->result = DID_TRANSPORT_DISRUPTED << 16; + cmd->result = DID_BUS_BUSY << 16; /* * Mark device missing so that we won't continue to send @@ -243,7 +243,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) qla4xxx_mark_device_missing(ha, ddb_entry); - cmd->result = DID_TRANSPORT_DISRUPTED << 16; + cmd->result = DID_BUS_BUSY << 16; break; case SCS_QUEUE_FULL: diff --git a/trunk/drivers/scsi/qla4xxx/ql4_os.c b/trunk/drivers/scsi/qla4xxx/ql4_os.c index db7ea3bb4e83..de8279ad7d89 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_os.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_os.c @@ -353,7 +353,7 @@ void qla4xxx_mark_device_missing(struct scsi_qla_host *ha, ha->host_no, ddb_entry->bus, ddb_entry->target, ddb_entry->fw_ddb_index)); iscsi_block_session(ddb_entry->sess); - iscsi_conn_error_event(ddb_entry->conn, ISCSI_ERR_CONN_FAILED); + iscsi_conn_error(ddb_entry->conn, ISCSI_ERR_CONN_FAILED); } static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha, @@ -439,7 +439,7 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, cmd->result = DID_NO_CONNECT << 16; goto qc_fail_command; } - return SCSI_MLQUEUE_TARGET_BUSY; + goto qc_host_busy; } if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index f8b79d401d58..2ac3cb2b9081 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -754,12 +754,8 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) } spin_unlock_irqrestore(host->host_lock, flags); if (rtn) { - if (rtn != SCSI_MLQUEUE_DEVICE_BUSY && - rtn != SCSI_MLQUEUE_TARGET_BUSY) - rtn = SCSI_MLQUEUE_HOST_BUSY; - - scsi_queue_insert(cmd, rtn); - + scsi_queue_insert(cmd, (rtn == SCSI_MLQUEUE_DEVICE_BUSY) ? + rtn : SCSI_MLQUEUE_HOST_BUSY); SCSI_LOG_MLQUEUE(3, printk("queuecommand : request rejected\n")); } @@ -804,7 +800,6 @@ static struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) void scsi_finish_command(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; - struct scsi_target *starget = scsi_target(sdev); struct Scsi_Host *shost = sdev->host; struct scsi_driver *drv; unsigned int good_bytes; @@ -820,7 +815,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd) * XXX(hch): What about locking? */ shost->host_blocked = 0; - starget->target_blocked = 0; sdev->device_blocked = 0; /* diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index 94ed262bdf0c..fecefa05cb62 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -1065,10 +1065,10 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost, struct list_head *done_q) { struct scsi_cmnd *scmd, *tgtr_scmd, *next; - unsigned int id = 0; + unsigned int id; int rtn; - do { + for (id = 0; id <= shost->max_id; id++) { tgtr_scmd = NULL; list_for_each_entry(scmd, work_q, eh_entry) { if (id == scmd_id(scmd)) { @@ -1076,18 +1076,8 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost, break; } } - if (!tgtr_scmd) { - /* not one exactly equal; find the next highest */ - list_for_each_entry(scmd, work_q, eh_entry) { - if (scmd_id(scmd) > id && - (!tgtr_scmd || - scmd_id(tgtr_scmd) > scmd_id(scmd))) - tgtr_scmd = scmd; - } - } if (!tgtr_scmd) - /* no more commands, that's it */ - break; + continue; SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset " "to target %d\n", @@ -1106,8 +1096,7 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost, " failed target: " "%d\n", current->comm, id)); - id++; - } while(id != 0); + } return list_empty(work_q); } @@ -1229,40 +1218,6 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q, return; } -/** - * scsi_noretry_cmd - determinte if command should be failed fast - * @scmd: SCSI cmd to examine. - */ -int scsi_noretry_cmd(struct scsi_cmnd *scmd) -{ - switch (host_byte(scmd->result)) { - case DID_OK: - break; - case DID_BUS_BUSY: - return blk_failfast_transport(scmd->request); - case DID_PARITY: - return blk_failfast_dev(scmd->request); - case DID_ERROR: - if (msg_byte(scmd->result) == COMMAND_COMPLETE && - status_byte(scmd->result) == RESERVATION_CONFLICT) - return 0; - /* fall through */ - case DID_SOFT_ERROR: - return blk_failfast_driver(scmd->request); - } - - switch (status_byte(scmd->result)) { - case CHECK_CONDITION: - /* - * assume caller has checked sense and determinted - * the check condition was retryable. - */ - return blk_failfast_dev(scmd->request); - } - - return 0; -} - /** * scsi_decide_disposition - Disposition a cmd on return from LLD. * @scmd: SCSI cmd to examine. @@ -1335,20 +1290,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) case DID_REQUEUE: return ADD_TO_MLQUEUE; - case DID_TRANSPORT_DISRUPTED: - /* - * LLD/transport was disrupted during processing of the IO. - * The transport class is now blocked/blocking, - * and the transport will decide what to do with the IO - * based on its timers and recovery capablilities. - */ - return ADD_TO_MLQUEUE; - case DID_TRANSPORT_FAILFAST: - /* - * The transport decided to failfast the IO (most likely - * the fast io fail tmo fired), so send IO directly upwards. - */ - return SUCCESS; + case DID_ERROR: if (msg_byte(scmd->result) == COMMAND_COMPLETE && status_byte(scmd->result) == RESERVATION_CONFLICT) @@ -1441,7 +1383,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) * even if the request is marked fast fail, we still requeue * for queue congestion conditions (QUEUE_FULL or BUSY) */ if ((++scmd->retries) <= scmd->allowed - && !scsi_noretry_cmd(scmd)) { + && !blk_noretry_request(scmd->request)) { return NEEDS_RETRY; } else { /* @@ -1566,7 +1508,7 @@ void scsi_eh_flush_done_q(struct list_head *done_q) list_for_each_entry_safe(scmd, next, done_q, eh_entry) { list_del_init(&scmd->eh_entry); if (scsi_device_online(scmd->device) && - !scsi_noretry_cmd(scmd) && + !blk_noretry_request(scmd->request) && (++scmd->retries <= scmd->allowed)) { SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush" " retry cmd: %p\n", diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index e5a9526d2037..98ee55ced592 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -114,7 +114,6 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) { struct Scsi_Host *host = cmd->device->host; struct scsi_device *device = cmd->device; - struct scsi_target *starget = scsi_target(device); struct request_queue *q = device->request_queue; unsigned long flags; @@ -134,17 +133,10 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) * if a command is requeued with no other commands outstanding * either for the device or for the host. */ - switch (reason) { - case SCSI_MLQUEUE_HOST_BUSY: + if (reason == SCSI_MLQUEUE_HOST_BUSY) host->host_blocked = host->max_host_blocked; - break; - case SCSI_MLQUEUE_DEVICE_BUSY: + else if (reason == SCSI_MLQUEUE_DEVICE_BUSY) device->device_blocked = device->max_device_blocked; - break; - case SCSI_MLQUEUE_TARGET_BUSY: - starget->target_blocked = starget->max_target_blocked; - break; - } /* * Decrement the counters, since these commands are no longer @@ -468,12 +460,10 @@ static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) void scsi_device_unbusy(struct scsi_device *sdev) { struct Scsi_Host *shost = sdev->host; - struct scsi_target *starget = scsi_target(sdev); unsigned long flags; spin_lock_irqsave(shost->host_lock, flags); shost->host_busy--; - starget->target_busy--; if (unlikely(scsi_host_in_recovery(shost) && (shost->host_failed || shost->host_eh_scheduled))) scsi_eh_wakeup(shost); @@ -529,13 +519,6 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev) spin_unlock_irqrestore(shost->host_lock, flags); } -static inline int scsi_target_is_busy(struct scsi_target *starget) -{ - return ((starget->can_queue > 0 && - starget->target_busy >= starget->can_queue) || - starget->target_blocked); -} - /* * Function: scsi_run_queue() * @@ -550,7 +533,7 @@ static inline int scsi_target_is_busy(struct scsi_target *starget) */ static void scsi_run_queue(struct request_queue *q) { - struct scsi_device *starved_head = NULL, *sdev = q->queuedata; + struct scsi_device *sdev = q->queuedata; struct Scsi_Host *shost = sdev->host; unsigned long flags; @@ -577,21 +560,6 @@ static void scsi_run_queue(struct request_queue *q) */ sdev = list_entry(shost->starved_list.next, struct scsi_device, starved_entry); - /* - * The *queue_ready functions can add a device back onto the - * starved list's tail, so we must check for a infinite loop. - */ - if (sdev == starved_head) - break; - if (!starved_head) - starved_head = sdev; - - if (scsi_target_is_busy(scsi_target(sdev))) { - list_move_tail(&sdev->starved_entry, - &shost->starved_list); - continue; - } - list_del_init(&sdev->starved_entry); spin_unlock(shost->host_lock); @@ -607,6 +575,13 @@ static void scsi_run_queue(struct request_queue *q) spin_unlock(sdev->request_queue->queue_lock); spin_lock(shost->host_lock); + if (unlikely(!list_empty(&sdev->starved_entry))) + /* + * sdev lost a race, and was put back on the + * starved list. This is unlikely but without this + * in theory we could loop forever. + */ + break; } spin_unlock_irqrestore(shost->host_lock, flags); @@ -706,7 +681,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error, leftover = req->data_len; /* kill remainder if no retrys */ - if (error && scsi_noretry_cmd(cmd)) + if (error && blk_noretry_request(req)) blk_end_request(req, error, leftover); else { if (requeue) { @@ -1369,52 +1344,6 @@ static inline int scsi_dev_queue_ready(struct request_queue *q, return 1; } - -/* - * scsi_target_queue_ready: checks if there we can send commands to target - * @sdev: scsi device on starget to check. - * - * Called with the host lock held. - */ -static inline int scsi_target_queue_ready(struct Scsi_Host *shost, - struct scsi_device *sdev) -{ - struct scsi_target *starget = scsi_target(sdev); - - if (starget->single_lun) { - if (starget->starget_sdev_user && - starget->starget_sdev_user != sdev) - return 0; - starget->starget_sdev_user = sdev; - } - - if (starget->target_busy == 0 && starget->target_blocked) { - /* - * unblock after target_blocked iterates to zero - */ - if (--starget->target_blocked == 0) { - SCSI_LOG_MLQUEUE(3, starget_printk(KERN_INFO, starget, - "unblocking target at zero depth\n")); - } else { - blk_plug_device(sdev->request_queue); - return 0; - } - } - - if (scsi_target_is_busy(starget)) { - if (list_empty(&sdev->starved_entry)) { - list_add_tail(&sdev->starved_entry, - &shost->starved_list); - return 0; - } - } - - /* We're OK to process the command, so we can't be starved */ - if (!list_empty(&sdev->starved_entry)) - list_del_init(&sdev->starved_entry); - return 1; -} - /* * scsi_host_queue_ready: if we can send requests to shost, return 1 else * return 0. We must end up running the queue again whenever 0 is @@ -1461,7 +1390,6 @@ static void scsi_kill_request(struct request *req, struct request_queue *q) { struct scsi_cmnd *cmd = req->special; struct scsi_device *sdev = cmd->device; - struct scsi_target *starget = scsi_target(sdev); struct Scsi_Host *shost = sdev->host; blkdev_dequeue_request(req); @@ -1485,7 +1413,6 @@ static void scsi_kill_request(struct request *req, struct request_queue *q) spin_unlock(sdev->request_queue->queue_lock); spin_lock(shost->host_lock); shost->host_busy++; - starget->target_busy++; spin_unlock(shost->host_lock); spin_lock(sdev->request_queue->queue_lock); @@ -1623,13 +1550,14 @@ static void scsi_request_fn(struct request_queue *q) goto not_ready; } - if (!scsi_target_queue_ready(shost, sdev)) - goto not_ready; - if (!scsi_host_queue_ready(q, shost, sdev)) goto not_ready; - - scsi_target(sdev)->target_busy++; + if (scsi_target(sdev)->single_lun) { + if (scsi_target(sdev)->starget_sdev_user && + scsi_target(sdev)->starget_sdev_user != sdev) + goto not_ready; + scsi_target(sdev)->starget_sdev_user = sdev; + } shost->host_busy++; /* diff --git a/trunk/drivers/scsi/scsi_priv.h b/trunk/drivers/scsi/scsi_priv.h index e1850904ff73..6cddd5dd323c 100644 --- a/trunk/drivers/scsi/scsi_priv.h +++ b/trunk/drivers/scsi/scsi_priv.h @@ -59,7 +59,6 @@ void scsi_eh_ready_devs(struct Scsi_Host *shost, struct list_head *done_q); int scsi_eh_get_sense(struct list_head *work_q, struct list_head *done_q); -int scsi_noretry_cmd(struct scsi_cmnd *scmd); /* scsi_lib.c */ extern int scsi_maybe_unblock_host(struct scsi_device *sdev); diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c index b14dc02c3ded..334862e26a1b 100644 --- a/trunk/drivers/scsi/scsi_scan.c +++ b/trunk/drivers/scsi/scsi_scan.c @@ -419,7 +419,6 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, dev->type = &scsi_target_type; starget->id = id; starget->channel = channel; - starget->can_queue = 0; INIT_LIST_HEAD(&starget->siblings); INIT_LIST_HEAD(&starget->devices); starget->state = STARGET_CREATED; diff --git a/trunk/drivers/scsi/scsi_transport_fc.c b/trunk/drivers/scsi/scsi_transport_fc.c index 1e71abf0607a..d5f7653bb94b 100644 --- a/trunk/drivers/scsi/scsi_transport_fc.c +++ b/trunk/drivers/scsi/scsi_transport_fc.c @@ -2133,7 +2133,8 @@ fc_attach_transport(struct fc_function_template *ft) SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles); SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state); SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id); - SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo); + if (ft->terminate_rport_io) + SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo); BUG_ON(count > FC_RPORT_NUM_ATTRS); @@ -2327,22 +2328,6 @@ fc_remove_host(struct Scsi_Host *shost) } EXPORT_SYMBOL(fc_remove_host); -static void fc_terminate_rport_io(struct fc_rport *rport) -{ - struct Scsi_Host *shost = rport_to_shost(rport); - struct fc_internal *i = to_fc_internal(shost->transportt); - - /* Involve the LLDD if possible to terminate all io on the rport. */ - if (i->f->terminate_rport_io) - i->f->terminate_rport_io(rport); - - /* - * must unblock to flush queued IO. The caller will have set - * the port_state or flags, so that fc_remote_port_chkready will - * fail IO. - */ - scsi_target_unblock(&rport->dev); -} /** * fc_starget_delete - called to delete the scsi decendents of an rport @@ -2355,8 +2340,13 @@ fc_starget_delete(struct work_struct *work) { struct fc_rport *rport = container_of(work, struct fc_rport, stgt_delete_work); + struct Scsi_Host *shost = rport_to_shost(rport); + struct fc_internal *i = to_fc_internal(shost->transportt); + + /* Involve the LLDD if possible to terminate all io on the rport. */ + if (i->f->terminate_rport_io) + i->f->terminate_rport_io(rport); - fc_terminate_rport_io(rport); scsi_remove_target(&rport->dev); } @@ -2382,7 +2372,10 @@ fc_rport_final_delete(struct work_struct *work) if (rport->flags & FC_RPORT_SCAN_PENDING) scsi_flush_work(shost); - fc_terminate_rport_io(rport); + /* involve the LLDD to terminate all pending i/o */ + if (i->f->terminate_rport_io) + i->f->terminate_rport_io(rport); + /* * Cancel any outstanding timers. These should really exist * only when rmmod'ing the LLDD and we're asking for @@ -2646,8 +2639,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, spin_lock_irqsave(shost->host_lock, flags); - rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT | - FC_RPORT_DEVLOSS_PENDING); + rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; /* if target, initiate a scan */ if (rport->scsi_target_id != -1) { @@ -2710,7 +2702,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, rport->port_id = ids->port_id; rport->roles = ids->roles; rport->port_state = FC_PORTSTATE_ONLINE; - rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT; if (fci->f->dd_fcrport_size) memset(rport->dd_data, 0, @@ -2793,6 +2784,7 @@ void fc_remote_port_delete(struct fc_rport *rport) { struct Scsi_Host *shost = rport_to_shost(rport); + struct fc_internal *i = to_fc_internal(shost->transportt); int timeout = rport->dev_loss_tmo; unsigned long flags; @@ -2838,7 +2830,7 @@ fc_remote_port_delete(struct fc_rport *rport) /* see if we need to kill io faster than waiting for device loss */ if ((rport->fast_io_fail_tmo != -1) && - (rport->fast_io_fail_tmo < timeout)) + (rport->fast_io_fail_tmo < timeout) && (i->f->terminate_rport_io)) fc_queue_devloss_work(shost, &rport->fail_io_work, rport->fast_io_fail_tmo * HZ); @@ -2914,8 +2906,7 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) fc_flush_devloss(shost); spin_lock_irqsave(shost->host_lock, flags); - rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT | - FC_RPORT_DEVLOSS_PENDING); + rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; spin_unlock_irqrestore(shost->host_lock, flags); /* ensure any stgt delete functions are done */ @@ -3010,7 +3001,6 @@ fc_timeout_deleted_rport(struct work_struct *work) rport->supported_classes = FC_COS_UNSPECIFIED; rport->roles = FC_PORT_ROLE_UNKNOWN; rport->port_state = FC_PORTSTATE_NOTPRESENT; - rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT; /* remove the identifiers that aren't used in the consisting binding */ switch (fc_host->tgtid_bind_type) { @@ -3053,12 +3043,13 @@ fc_timeout_fail_rport_io(struct work_struct *work) { struct fc_rport *rport = container_of(work, struct fc_rport, fail_io_work.work); + struct Scsi_Host *shost = rport_to_shost(rport); + struct fc_internal *i = to_fc_internal(shost->transportt); if (rport->port_state != FC_PORTSTATE_BLOCKED) return; - rport->flags |= FC_RPORT_FAST_FAIL_TIMEDOUT; - fc_terminate_rport_io(rport); + i->f->terminate_rport_io(rport); } /** diff --git a/trunk/drivers/scsi/scsi_transport_iscsi.c b/trunk/drivers/scsi/scsi_transport_iscsi.c index 4a803ebaf508..0ce5f7cdfe2a 100644 --- a/trunk/drivers/scsi/scsi_transport_iscsi.c +++ b/trunk/drivers/scsi/scsi_transport_iscsi.c @@ -138,7 +138,7 @@ static ssize_t show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf) { struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); - return sprintf(buf, "%llu\n", (unsigned long long) ep->id); + return sprintf(buf, "%u\n", ep->id); } static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL); @@ -156,7 +156,7 @@ static struct attribute_group iscsi_endpoint_group = { static int iscsi_match_epid(struct device *dev, void *data) { struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); - uint64_t *epid = (uint64_t *) data; + unsigned int *epid = (unsigned int *) data; return *epid == ep->id; } @@ -166,7 +166,7 @@ iscsi_create_endpoint(int dd_size) { struct device *dev; struct iscsi_endpoint *ep; - uint64_t id; + unsigned int id; int err; for (id = 1; id < ISCSI_MAX_EPID; id++) { @@ -187,8 +187,7 @@ iscsi_create_endpoint(int dd_size) ep->id = id; ep->dev.class = &iscsi_endpoint_class; - snprintf(ep->dev.bus_id, BUS_ID_SIZE, "ep-%llu", - (unsigned long long) id); + snprintf(ep->dev.bus_id, BUS_ID_SIZE, "ep-%u", id); err = device_register(&ep->dev); if (err) goto free_ep; @@ -375,10 +374,10 @@ int iscsi_session_chkready(struct iscsi_cls_session *session) err = 0; break; case ISCSI_SESSION_FAILED: - err = DID_TRANSPORT_DISRUPTED << 16; + err = DID_IMM_RETRY << 16; break; case ISCSI_SESSION_FREE: - err = DID_TRANSPORT_FAILFAST << 16; + err = DID_NO_CONNECT << 16; break; default: err = DID_NO_CONNECT << 16; @@ -1011,7 +1010,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, skb = alloc_skb(len, GFP_ATOMIC); if (!skb) { - iscsi_conn_error_event(conn, ISCSI_ERR_CONN_FAILED); + iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED); iscsi_cls_conn_printk(KERN_ERR, conn, "can not deliver " "control PDU: OOM\n"); return -ENOMEM; @@ -1032,7 +1031,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, } EXPORT_SYMBOL_GPL(iscsi_recv_pdu); -void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) +void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) { struct nlmsghdr *nlh; struct sk_buff *skb; @@ -1064,7 +1063,7 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn error (%d)\n", error); } -EXPORT_SYMBOL_GPL(iscsi_conn_error_event); +EXPORT_SYMBOL_GPL(iscsi_conn_error); static int iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, diff --git a/trunk/drivers/scsi/scsi_transport_spi.c b/trunk/drivers/scsi/scsi_transport_spi.c index 7c2d28924d2a..b29360ed0bdc 100644 --- a/trunk/drivers/scsi/scsi_transport_spi.c +++ b/trunk/drivers/scsi/scsi_transport_spi.c @@ -109,9 +109,7 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd, for(i = 0; i < DV_RETRIES; i++) { result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense, DV_TIMEOUT, /* retries */ 1, - REQ_FAILFAST_DEV | - REQ_FAILFAST_TRANSPORT | - REQ_FAILFAST_DRIVER); + REQ_FAILFAST); if (result & DRIVER_SENSE) { struct scsi_sense_hdr sshdr_tmp; if (!sshdr) diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 7c4d2e68df1c..a7b53be63367 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -384,7 +384,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) sector_t block = rq->sector; sector_t threshold; unsigned int this_count = rq->nr_sectors; - int ret, host_dif; + int ret; if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { ret = scsi_setup_blk_pc_cmnd(sdp, rq); @@ -515,8 +515,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) rq->nr_sectors)); /* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */ - host_dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type); - if (host_dif) + if (scsi_host_dif_capable(sdp->host, sdkp->protection_type)) SCpnt->cmnd[1] = 1 << 5; else SCpnt->cmnd[1] = 0; @@ -574,9 +573,8 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->sdb.length = this_count * sdp->sector_size; /* If DIF or DIX is enabled, tell HBA how to handle request */ - if (host_dif || scsi_prot_sg_count(SCpnt)) - sd_dif_op(SCpnt, host_dif, scsi_prot_sg_count(SCpnt), - sdkp->protection_type); + if (sdkp->protection_type || scsi_prot_sg_count(SCpnt)) + sd_dif_op(SCpnt, sdkp->protection_type, scsi_prot_sg_count(SCpnt)); /* * We shouldn't disconnect in the middle of a sector, so with a dumb @@ -1254,12 +1252,14 @@ void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer) else type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ - sdkp->protection_type = type; - switch (type) { case SD_DIF_TYPE0_PROTECTION: + sdkp->protection_type = 0; + break; + case SD_DIF_TYPE1_PROTECTION: case SD_DIF_TYPE3_PROTECTION: + sdkp->protection_type = type; break; case SD_DIF_TYPE2_PROTECTION: @@ -1277,6 +1277,7 @@ void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer) return; disable: + sdkp->protection_type = 0; sdkp->capacity = 0; } diff --git a/trunk/drivers/scsi/sd.h b/trunk/drivers/scsi/sd.h index 75638e7d3f66..95b9f06534d5 100644 --- a/trunk/drivers/scsi/sd.h +++ b/trunk/drivers/scsi/sd.h @@ -97,28 +97,19 @@ struct sd_dif_tuple { __be32 ref_tag; /* Target LBA or indirect LBA */ }; -#ifdef CONFIG_BLK_DEV_INTEGRITY +#if defined(CONFIG_BLK_DEV_INTEGRITY) -extern void sd_dif_op(struct scsi_cmnd *, unsigned int, unsigned int, unsigned int); +extern void sd_dif_op(struct scsi_cmnd *, unsigned int, unsigned int); extern void sd_dif_config_host(struct scsi_disk *); extern int sd_dif_prepare(struct request *rq, sector_t, unsigned int); extern void sd_dif_complete(struct scsi_cmnd *, unsigned int); #else /* CONFIG_BLK_DEV_INTEGRITY */ -static inline void sd_dif_op(struct scsi_cmnd *cmd, unsigned int a, unsigned int b, unsigned int c) -{ -} -static inline void sd_dif_config_host(struct scsi_disk *disk) -{ -} -static inline int sd_dif_prepare(struct request *rq, sector_t s, unsigned int a) -{ - return 0; -} -static inline void sd_dif_complete(struct scsi_cmnd *cmd, unsigned int a) -{ -} +#define sd_dif_op(a, b, c) do { } while (0) +#define sd_dif_config_host(a) do { } while (0) +#define sd_dif_prepare(a, b, c) (0) +#define sd_dif_complete(a, b) (0) #endif /* CONFIG_BLK_DEV_INTEGRITY */ diff --git a/trunk/drivers/scsi/sd_dif.c b/trunk/drivers/scsi/sd_dif.c index 3ebb1f289490..4d17f3d35aac 100644 --- a/trunk/drivers/scsi/sd_dif.c +++ b/trunk/drivers/scsi/sd_dif.c @@ -311,26 +311,25 @@ void sd_dif_config_host(struct scsi_disk *sdkp) struct scsi_device *sdp = sdkp->device; struct gendisk *disk = sdkp->disk; u8 type = sdkp->protection_type; - int dif, dix; - dif = scsi_host_dif_capable(sdp->host, type); - dix = scsi_host_dix_capable(sdp->host, type); + /* If this HBA doesn't support DIX, resort to normal I/O or DIF */ + if (scsi_host_dix_capable(sdp->host, type) == 0) { - if (!dix && scsi_host_dix_capable(sdp->host, 0)) { - dif = 0; dix = 1; - } + if (type == SD_DIF_TYPE0_PROTECTION) + return; - if (type) { - if (dif) - sd_printk(KERN_NOTICE, sdkp, - "Enabling DIF Type %d protection\n", type); - else - sd_printk(KERN_NOTICE, sdkp, - "Disabling DIF Type %d protection\n", type); - } + if (scsi_host_dif_capable(sdp->host, type) == 0) { + sd_printk(KERN_INFO, sdkp, "Type %d protection " \ + "unsupported by HBA. Disabling DIF.\n", type); + sdkp->protection_type = 0; + return; + } + + sd_printk(KERN_INFO, sdkp, "Enabling DIF Type %d protection\n", + type); - if (!dix) return; + } /* Enable DMA of protection information */ if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) @@ -344,17 +343,17 @@ void sd_dif_config_host(struct scsi_disk *sdkp) else blk_integrity_register(disk, &dif_type1_integrity_crc); - sd_printk(KERN_NOTICE, sdkp, - "Enabling DIX %s protection\n", disk->integrity->name); + sd_printk(KERN_INFO, sdkp, + "Enabling %s integrity protection\n", disk->integrity->name); /* Signal to block layer that we support sector tagging */ - if (dif && type && sdkp->ATO) { + if (type && sdkp->ATO) { if (type == SD_DIF_TYPE3_PROTECTION) disk->integrity->tag_size = sizeof(u16) + sizeof(u32); else disk->integrity->tag_size = sizeof(u16); - sd_printk(KERN_NOTICE, sdkp, "DIF application tag size %u\n", + sd_printk(KERN_INFO, sdkp, "DIF application tag size %u\n", disk->integrity->tag_size); } } @@ -362,7 +361,7 @@ void sd_dif_config_host(struct scsi_disk *sdkp) /* * DIF DMA operation magic decoder ring. */ -void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix, unsigned int type) +void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix) { int csum_convert, prot_op; @@ -407,8 +406,7 @@ void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix, unsig } scsi_set_prot_op(scmd, prot_op); - if (dif) - scsi_set_prot_type(scmd, type); + scsi_set_prot_type(scmd, dif); } /* diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 218408eed1bb..d84f0469a016 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -1262,7 +1262,7 @@ EXPORT_SYMBOL(ioctl_by_bdev); /** * lookup_bdev - lookup a struct block_device by name - * @path: special file representing the block device + * @pathname: special file representing the block device * * Get a reference to the blockdevice at @pathname in the current * namespace if possible and return it. Return ERR_PTR(error) diff --git a/trunk/fs/partitions/check.c b/trunk/fs/partitions/check.c index cfb0c80690aa..fbeb2f372a93 100644 --- a/trunk/fs/partitions/check.c +++ b/trunk/fs/partitions/check.c @@ -195,14 +195,6 @@ check_partition(struct gendisk *hd, struct block_device *bdev) return ERR_PTR(res); } -static ssize_t part_partition_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct hd_struct *p = dev_to_part(dev); - - return sprintf(buf, "%d\n", p->partno); -} - static ssize_t part_start_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -268,7 +260,6 @@ ssize_t part_fail_store(struct device *dev, } #endif -static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL); static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); @@ -278,7 +269,6 @@ static struct device_attribute dev_attr_fail = #endif static struct attribute *part_attrs[] = { - &dev_attr_partition.attr, &dev_attr_start.attr, &dev_attr_size.attr, &dev_attr_stat.attr, diff --git a/trunk/include/linux/bio.h b/trunk/include/linux/bio.h index 1c91a176b9ae..ff5b4cf9e2da 100644 --- a/trunk/include/linux/bio.h +++ b/trunk/include/linux/bio.h @@ -79,13 +79,6 @@ struct bio { unsigned int bi_size; /* residual I/O count */ - /* - * To keep track of the max segment size, we account for the - * sizes of the first and last mergeable segments in this bio. - */ - unsigned int bi_seg_front_size; - unsigned int bi_seg_back_size; - unsigned int bi_max_vecs; /* max bvl_vecs we can hold */ unsigned int bi_comp_cpu; /* completion CPU */ @@ -136,30 +129,25 @@ struct bio { * bit 2 -- barrier * Insert a serialization point in the IO queue, forcing previously * submitted IO to be completed before this oen is issued. - * bit 3 -- synchronous I/O hint: the block layer will unplug immediately + * bit 3 -- fail fast, don't want low level driver retries + * bit 4 -- synchronous I/O hint: the block layer will unplug immediately * Note that this does NOT indicate that the IO itself is sync, just * that the block layer will not postpone issue of this IO by plugging. - * bit 4 -- metadata request + * bit 5 -- metadata request * Used for tracing to differentiate metadata and data IO. May also * get some preferential treatment in the IO scheduler - * bit 5 -- discard sectors + * bit 6 -- discard sectors * Informs the lower level device that this range of sectors is no longer * used by the file system and may thus be freed by the device. Used * for flash based storage. - * bit 6 -- fail fast device errors - * bit 7 -- fail fast transport errors - * bit 8 -- fail fast driver errors - * Don't want driver retries for any fast fail whatever the reason. */ #define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */ #define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */ #define BIO_RW_BARRIER 2 -#define BIO_RW_SYNC 3 -#define BIO_RW_META 4 -#define BIO_RW_DISCARD 5 -#define BIO_RW_FAILFAST_DEV 6 -#define BIO_RW_FAILFAST_TRANSPORT 7 -#define BIO_RW_FAILFAST_DRIVER 8 +#define BIO_RW_FAILFAST 3 +#define BIO_RW_SYNC 4 +#define BIO_RW_META 5 +#define BIO_RW_DISCARD 6 /* * upper 16 bits of bi_rw define the io priority of this bio @@ -186,10 +174,7 @@ struct bio { #define bio_sectors(bio) ((bio)->bi_size >> 9) #define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER)) #define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC)) -#define bio_failfast_dev(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_DEV)) -#define bio_failfast_transport(bio) \ - ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_TRANSPORT)) -#define bio_failfast_driver(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_DRIVER)) +#define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST)) #define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD)) #define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META)) #define bio_discard(bio) ((bio)->bi_rw & (1 << BIO_RW_DISCARD)) diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index b4fe68fe3a57..a92d9e4ea96e 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -87,9 +87,7 @@ enum { */ enum rq_flag_bits { __REQ_RW, /* not set, read. set, write */ - __REQ_FAILFAST_DEV, /* no driver retries of device errors */ - __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */ - __REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */ + __REQ_FAILFAST, /* no low level driver retries */ __REQ_DISCARD, /* request to discard sectors */ __REQ_SORTED, /* elevator knows about this request */ __REQ_SOFTBARRIER, /* may not be passed by ioscheduler */ @@ -113,10 +111,8 @@ enum rq_flag_bits { }; #define REQ_RW (1 << __REQ_RW) -#define REQ_FAILFAST_DEV (1 << __REQ_FAILFAST_DEV) -#define REQ_FAILFAST_TRANSPORT (1 << __REQ_FAILFAST_TRANSPORT) -#define REQ_FAILFAST_DRIVER (1 << __REQ_FAILFAST_DRIVER) #define REQ_DISCARD (1 << __REQ_DISCARD) +#define REQ_FAILFAST (1 << __REQ_FAILFAST) #define REQ_SORTED (1 << __REQ_SORTED) #define REQ_SOFTBARRIER (1 << __REQ_SOFTBARRIER) #define REQ_HARDBARRIER (1 << __REQ_HARDBARRIER) @@ -564,12 +560,7 @@ enum { #define blk_special_request(rq) ((rq)->cmd_type == REQ_TYPE_SPECIAL) #define blk_sense_request(rq) ((rq)->cmd_type == REQ_TYPE_SENSE) -#define blk_failfast_dev(rq) ((rq)->cmd_flags & REQ_FAILFAST_DEV) -#define blk_failfast_transport(rq) ((rq)->cmd_flags & REQ_FAILFAST_TRANSPORT) -#define blk_failfast_driver(rq) ((rq)->cmd_flags & REQ_FAILFAST_DRIVER) -#define blk_noretry_request(rq) (blk_failfast_dev(rq) || \ - blk_failfast_transport(rq) || \ - blk_failfast_driver(rq)) +#define blk_noretry_request(rq) ((rq)->cmd_flags & REQ_FAILFAST) #define blk_rq_started(rq) ((rq)->cmd_flags & REQ_STARTED) #define blk_account_rq(rq) (blk_rq_started(rq) && (blk_fs_request(rq) || blk_discard_rq(rq))) @@ -865,6 +856,7 @@ extern void blk_ordered_complete_seq(struct request_queue *, unsigned, int); extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); extern void blk_dump_rq_flags(struct request *, char *); extern void generic_unplug_device(struct request_queue *); +extern void __generic_unplug_device(struct request_queue *); extern long nr_blockdev_pages(void); int blk_get_queue(struct request_queue *); diff --git a/trunk/include/linux/blktrace_api.h b/trunk/include/linux/blktrace_api.h index bdf505d33e77..3a31eb506164 100644 --- a/trunk/include/linux/blktrace_api.h +++ b/trunk/include/linux/blktrace_api.h @@ -24,7 +24,6 @@ enum blktrace_cat { BLK_TC_AHEAD = 1 << 11, /* readahead */ BLK_TC_META = 1 << 12, /* metadata */ BLK_TC_DISCARD = 1 << 13, /* discard requests */ - BLK_TC_DRV_DATA = 1 << 14, /* binary per-driver data */ BLK_TC_END = 1 << 15, /* only 16-bits, reminder */ }; @@ -52,7 +51,6 @@ enum blktrace_act { __BLK_TA_BOUNCE, /* bio was bounced */ __BLK_TA_REMAP, /* bio was remapped */ __BLK_TA_ABORT, /* request aborted */ - __BLK_TA_DRV_DATA, /* driver-specific binary data */ }; /* @@ -84,7 +82,6 @@ enum blktrace_notify { #define BLK_TA_BOUNCE (__BLK_TA_BOUNCE) #define BLK_TA_REMAP (__BLK_TA_REMAP | BLK_TC_ACT(BLK_TC_QUEUE)) #define BLK_TA_ABORT (__BLK_TA_ABORT | BLK_TC_ACT(BLK_TC_QUEUE)) -#define BLK_TA_DRV_DATA (__BLK_TA_DRV_DATA | BLK_TC_ACT(BLK_TC_DRV_DATA)) #define BLK_TN_PROCESS (__BLK_TN_PROCESS | BLK_TC_ACT(BLK_TC_NOTIFY)) #define BLK_TN_TIMESTAMP (__BLK_TN_TIMESTAMP | BLK_TC_ACT(BLK_TC_NOTIFY)) @@ -320,34 +317,6 @@ static inline void blk_add_trace_remap(struct request_queue *q, struct bio *bio, __blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP, !bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r); } -/** - * blk_add_driver_data - Add binary message with driver-specific data - * @q: queue the io is for - * @rq: io request - * @data: driver-specific data - * @len: length of driver-specific data - * - * Description: - * Some drivers might want to write driver-specific data per request. - * - **/ -static inline void blk_add_driver_data(struct request_queue *q, - struct request *rq, - void *data, size_t len) -{ - struct blk_trace *bt = q->blk_trace; - - if (likely(!bt)) - return; - - if (blk_pc_request(rq)) - __blk_add_trace(bt, 0, rq->data_len, 0, BLK_TA_DRV_DATA, - rq->errors, len, data); - else - __blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9, - 0, BLK_TA_DRV_DATA, rq->errors, len, data); -} - extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, char __user *arg); extern int blk_trace_startstop(struct request_queue *q, int start); @@ -361,7 +330,6 @@ extern int blk_trace_remove(struct request_queue *q); #define blk_add_trace_generic(q, rq, rw, what) do { } while (0) #define blk_add_trace_pdu_int(q, what, bio, pdu) do { } while (0) #define blk_add_trace_remap(q, bio, dev, f, t) do {} while (0) -#define blk_add_driver_data(q, rq, data, len) do {} while (0) #define do_blk_trace_setup(q, name, dev, buts) (-ENOTTY) #define blk_trace_setup(q, name, dev, arg) (-ENOTTY) #define blk_trace_startstop(q, start) (-ENOTTY) diff --git a/trunk/include/linux/interrupt.h b/trunk/include/linux/interrupt.h index 35a61dc60d51..54b3623434ec 100644 --- a/trunk/include/linux/interrupt.h +++ b/trunk/include/linux/interrupt.h @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include #include #include @@ -275,25 +273,6 @@ extern void softirq_init(void); extern void raise_softirq_irqoff(unsigned int nr); extern void raise_softirq(unsigned int nr); -/* This is the worklist that queues up per-cpu softirq work. - * - * send_remote_sendirq() adds work to these lists, and - * the softirq handler itself dequeues from them. The queues - * are protected by disabling local cpu interrupts and they must - * only be accessed by the local cpu that they are for. - */ -DECLARE_PER_CPU(struct list_head [NR_SOFTIRQS], softirq_work_list); - -/* Try to send a softirq to a remote cpu. If this cannot be done, the - * work will be queued to the local cpu. - */ -extern void send_remote_softirq(struct call_single_data *cp, int cpu, int softirq); - -/* Like send_remote_softirq(), but the caller must disable local cpu interrupts - * and compute the current cpu, passed in as 'this_cpu'. - */ -extern void __send_remote_softirq(struct call_single_data *cp, int cpu, - int this_cpu, int softirq); /* Tasklets --- multithreaded analogue of BHs. diff --git a/trunk/include/linux/smp.h b/trunk/include/linux/smp.h index 2e4d58b26c06..66484d4a8459 100644 --- a/trunk/include/linux/smp.h +++ b/trunk/include/linux/smp.h @@ -7,7 +7,6 @@ */ #include -#include #include #include @@ -17,8 +16,7 @@ struct call_single_data { struct list_head list; void (*func) (void *info); void *info; - u16 flags; - u16 priv; + unsigned int flags; }; #ifdef CONFIG_SMP diff --git a/trunk/include/scsi/iscsi_if.h b/trunk/include/scsi/iscsi_if.h index 0c9514de5df7..16be12f1cbe8 100644 --- a/trunk/include/scsi/iscsi_if.h +++ b/trunk/include/scsi/iscsi_if.h @@ -213,8 +213,6 @@ enum iscsi_err { ISCSI_ERR_DATA_DGST = ISCSI_ERR_BASE + 15, ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16, ISCSI_ERR_NO_SCSI_CMD = ISCSI_ERR_BASE + 17, - ISCSI_ERR_INVALID_HOST = ISCSI_ERR_BASE + 18, - ISCSI_ERR_XMIT_FAILED = ISCSI_ERR_BASE + 19, }; /* diff --git a/trunk/include/scsi/libiscsi.h b/trunk/include/scsi/libiscsi.h index 61e53f14f7e1..5e75bb7f311c 100644 --- a/trunk/include/scsi/libiscsi.h +++ b/trunk/include/scsi/libiscsi.h @@ -287,11 +287,6 @@ struct iscsi_session { struct iscsi_pool cmdpool; /* PDU's pool */ }; -enum { - ISCSI_HOST_SETUP, - ISCSI_HOST_REMOVED, -}; - struct iscsi_host { char *initiatorname; /* hw address or netdev iscsi connection is bound to */ @@ -300,12 +295,6 @@ struct iscsi_host { /* local address */ int local_port; char local_address[ISCSI_ADDRESS_BUF_LEN]; - - wait_queue_head_t session_removal_wq; - /* protects sessions and state */ - spinlock_t lock; - int num_sessions; - int state; }; /* @@ -313,7 +302,7 @@ struct iscsi_host { */ extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth); extern int iscsi_eh_abort(struct scsi_cmnd *sc); -extern int iscsi_eh_target_reset(struct scsi_cmnd *sc); +extern int iscsi_eh_host_reset(struct scsi_cmnd *sc); extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); extern int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)); @@ -362,8 +351,6 @@ extern void iscsi_conn_stop(struct iscsi_cls_conn *, int); extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, int); extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); -extern void iscsi_session_failure(struct iscsi_cls_session *cls_session, - enum iscsi_err err); extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, char *buf); extern void iscsi_suspend_tx(struct iscsi_conn *conn); diff --git a/trunk/include/scsi/scsi.h b/trunk/include/scsi/scsi.h index a109165714d6..192f8716aa9e 100644 --- a/trunk/include/scsi/scsi.h +++ b/trunk/include/scsi/scsi.h @@ -381,11 +381,6 @@ static inline int scsi_is_wlun(unsigned int lun) #define DID_IMM_RETRY 0x0c /* Retry without decrementing retry count */ #define DID_REQUEUE 0x0d /* Requeue command (no immediate retry) also * without decrementing the retry count */ -#define DID_TRANSPORT_DISRUPTED 0x0e /* Transport error disrupted execution - * and the driver blocked the port to - * recover the link. Transport class will - * retry or fail IO */ -#define DID_TRANSPORT_FAILFAST 0x0f /* Transport class fastfailed the io */ #define DRIVER_OK 0x00 /* Driver status */ /* @@ -431,7 +426,6 @@ static inline int scsi_is_wlun(unsigned int lun) #define SCSI_MLQUEUE_HOST_BUSY 0x1055 #define SCSI_MLQUEUE_DEVICE_BUSY 0x1056 #define SCSI_MLQUEUE_EH_RETRY 0x1057 -#define SCSI_MLQUEUE_TARGET_BUSY 0x1058 /* * Use these to separate status msg and our bytes diff --git a/trunk/include/scsi/scsi_device.h b/trunk/include/scsi/scsi_device.h index a37a8148a310..b49e725be039 100644 --- a/trunk/include/scsi/scsi_device.h +++ b/trunk/include/scsi/scsi_device.h @@ -238,16 +238,6 @@ struct scsi_target { * for the device at a time. */ unsigned int pdt_1f_for_no_lun; /* PDT = 0x1f */ /* means no lun present */ - /* commands actually active on LLD. protected by host lock. */ - unsigned int target_busy; - /* - * LLDs should set this in the slave_alloc host template callout. - * If set to zero then there is not limit. - */ - unsigned int can_queue; - unsigned int target_blocked; - unsigned int max_target_blocked; -#define SCSI_DEFAULT_TARGET_BLOCKED 3 char scsi_level; struct execute_work ew; diff --git a/trunk/include/scsi/scsi_transport_fc.h b/trunk/include/scsi/scsi_transport_fc.h index 49d8913c4f86..21018a4df452 100644 --- a/trunk/include/scsi/scsi_transport_fc.h +++ b/trunk/include/scsi/scsi_transport_fc.h @@ -357,7 +357,6 @@ struct fc_rport { /* aka fc_starget_attrs */ /* bit field values for struct fc_rport "flags" field: */ #define FC_RPORT_DEVLOSS_PENDING 0x01 #define FC_RPORT_SCAN_PENDING 0x02 -#define FC_RPORT_FAST_FAIL_TIMEDOUT 0x03 #define dev_to_rport(d) \ container_of(d, struct fc_rport, dev) @@ -679,15 +678,12 @@ fc_remote_port_chkready(struct fc_rport *rport) if (rport->roles & FC_PORT_ROLE_FCP_TARGET) result = 0; else if (rport->flags & FC_RPORT_DEVLOSS_PENDING) - result = DID_TRANSPORT_DISRUPTED << 16; + result = DID_IMM_RETRY << 16; else result = DID_NO_CONNECT << 16; break; case FC_PORTSTATE_BLOCKED: - if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT) - result = DID_TRANSPORT_FAILFAST << 16; - else - result = DID_TRANSPORT_DISRUPTED << 16; + result = DID_IMM_RETRY << 16; break; default: result = DID_NO_CONNECT << 16; diff --git a/trunk/include/scsi/scsi_transport_iscsi.h b/trunk/include/scsi/scsi_transport_iscsi.h index c667cc396545..8b6c91df4c7a 100644 --- a/trunk/include/scsi/scsi_transport_iscsi.h +++ b/trunk/include/scsi/scsi_transport_iscsi.h @@ -135,8 +135,7 @@ extern int iscsi_unregister_transport(struct iscsi_transport *tt); /* * control plane upcalls */ -extern void iscsi_conn_error_event(struct iscsi_cls_conn *conn, - enum iscsi_err error); +extern void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error); extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, char *data, uint32_t data_size); @@ -208,7 +207,7 @@ extern void iscsi_host_for_each_session(struct Scsi_Host *shost, struct iscsi_endpoint { void *dd_data; /* LLD private data */ struct device dev; - uint64_t id; + unsigned int id; }; /* diff --git a/trunk/kernel/softirq.c b/trunk/kernel/softirq.c index 83ba21a13bd4..37d67aa2d56f 100644 --- a/trunk/kernel/softirq.c +++ b/trunk/kernel/softirq.c @@ -6,8 +6,6 @@ * Distribute under GPLv2. * * Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903) - * - * Remote softirq infrastructure is by Jens Axboe. */ #include @@ -476,144 +474,17 @@ void tasklet_kill(struct tasklet_struct *t) EXPORT_SYMBOL(tasklet_kill); -DEFINE_PER_CPU(struct list_head [NR_SOFTIRQS], softirq_work_list); -EXPORT_PER_CPU_SYMBOL(softirq_work_list); - -static void __local_trigger(struct call_single_data *cp, int softirq) -{ - struct list_head *head = &__get_cpu_var(softirq_work_list[softirq]); - - list_add_tail(&cp->list, head); - - /* Trigger the softirq only if the list was previously empty. */ - if (head->next == &cp->list) - raise_softirq_irqoff(softirq); -} - -#ifdef CONFIG_USE_GENERIC_SMP_HELPERS -static void remote_softirq_receive(void *data) -{ - struct call_single_data *cp = data; - unsigned long flags; - int softirq; - - softirq = cp->priv; - - local_irq_save(flags); - __local_trigger(cp, softirq); - local_irq_restore(flags); -} - -static int __try_remote_softirq(struct call_single_data *cp, int cpu, int softirq) -{ - if (cpu_online(cpu)) { - cp->func = remote_softirq_receive; - cp->info = cp; - cp->flags = 0; - cp->priv = softirq; - - __smp_call_function_single(cpu, cp); - return 0; - } - return 1; -} -#else /* CONFIG_USE_GENERIC_SMP_HELPERS */ -static int __try_remote_softirq(struct call_single_data *cp, int cpu, int softirq) -{ - return 1; -} -#endif - -/** - * __send_remote_softirq - try to schedule softirq work on a remote cpu - * @cp: private SMP call function data area - * @cpu: the remote cpu - * @this_cpu: the currently executing cpu - * @softirq: the softirq for the work - * - * Attempt to schedule softirq work on a remote cpu. If this cannot be - * done, the work is instead queued up on the local cpu. - * - * Interrupts must be disabled. - */ -void __send_remote_softirq(struct call_single_data *cp, int cpu, int this_cpu, int softirq) -{ - if (cpu == this_cpu || __try_remote_softirq(cp, cpu, softirq)) - __local_trigger(cp, softirq); -} -EXPORT_SYMBOL(__send_remote_softirq); - -/** - * send_remote_softirq - try to schedule softirq work on a remote cpu - * @cp: private SMP call function data area - * @cpu: the remote cpu - * @softirq: the softirq for the work - * - * Like __send_remote_softirq except that disabling interrupts and - * computing the current cpu is done for the caller. - */ -void send_remote_softirq(struct call_single_data *cp, int cpu, int softirq) -{ - unsigned long flags; - int this_cpu; - - local_irq_save(flags); - this_cpu = smp_processor_id(); - __send_remote_softirq(cp, cpu, this_cpu, softirq); - local_irq_restore(flags); -} -EXPORT_SYMBOL(send_remote_softirq); - -static int __cpuinit remote_softirq_cpu_notify(struct notifier_block *self, - unsigned long action, void *hcpu) -{ - /* - * If a CPU goes away, splice its entries to the current CPU - * and trigger a run of the softirq - */ - if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { - int cpu = (unsigned long) hcpu; - int i; - - local_irq_disable(); - for (i = 0; i < NR_SOFTIRQS; i++) { - struct list_head *head = &per_cpu(softirq_work_list[i], cpu); - struct list_head *local_head; - - if (list_empty(head)) - continue; - - local_head = &__get_cpu_var(softirq_work_list[i]); - list_splice_init(head, local_head); - raise_softirq_irqoff(i); - } - local_irq_enable(); - } - - return NOTIFY_OK; -} - -static struct notifier_block __cpuinitdata remote_softirq_cpu_notifier = { - .notifier_call = remote_softirq_cpu_notify, -}; - void __init softirq_init(void) { int cpu; for_each_possible_cpu(cpu) { - int i; - per_cpu(tasklet_vec, cpu).tail = &per_cpu(tasklet_vec, cpu).head; per_cpu(tasklet_hi_vec, cpu).tail = &per_cpu(tasklet_hi_vec, cpu).head; - for (i = 0; i < NR_SOFTIRQS; i++) - INIT_LIST_HEAD(&per_cpu(softirq_work_list[i], cpu)); } - register_hotcpu_notifier(&remote_softirq_cpu_notifier); - open_softirq(TASKLET_SOFTIRQ, tasklet_action); open_softirq(HI_SOFTIRQ, tasklet_hi_action); } diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index b0f239e443bc..31d784dd80d0 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -652,11 +652,6 @@ config DEBUG_BLOCK_EXT_DEVT depends on BLOCK default n help - BIG FAT WARNING: ENABLING THIS OPTION MIGHT BREAK BOOTING ON - SOME DISTRIBUTIONS. DO NOT ENABLE THIS UNLESS YOU KNOW WHAT - YOU ARE DOING. Distros, please enable this and fix whatever - is broken. - Conventionally, block device numbers are allocated from predetermined contiguous area. However, extended block area may introduce non-contiguous block device numbers. This diff --git a/trunk/net/bluetooth/af_bluetooth.c b/trunk/net/bluetooth/af_bluetooth.c index 8f9431a12c6f..f6348e078aa4 100644 --- a/trunk/net/bluetooth/af_bluetooth.c +++ b/trunk/net/bluetooth/af_bluetooth.c @@ -37,7 +37,10 @@ #include #include #include + +#if defined(CONFIG_KMOD) #include +#endif #include @@ -142,8 +145,11 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto) if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; - if (!bt_proto[proto]) +#if defined(CONFIG_KMOD) + if (!bt_proto[proto]) { request_module("bt-proto-%d", proto); + } +#endif err = -EPROTONOSUPPORT; diff --git a/trunk/net/bridge/netfilter/ebtables.c b/trunk/net/bridge/netfilter/ebtables.c index 0fa208e86405..5bb88eb0aad4 100644 --- a/trunk/net/bridge/netfilter/ebtables.c +++ b/trunk/net/bridge/netfilter/ebtables.c @@ -305,14 +305,23 @@ find_inlist_lock_noload(struct list_head *head, const char *name, int *error, return NULL; } +#ifndef CONFIG_KMOD +#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m)) +#else static void * find_inlist_lock(struct list_head *head, const char *name, const char *prefix, int *error, struct mutex *mutex) { - return try_then_request_module( - find_inlist_lock_noload(head, name, error, mutex), - "%s%s", prefix, name); + void *ret; + + ret = find_inlist_lock_noload(head, name, error, mutex); + if (!ret) { + request_module("%s%s", prefix, name); + ret = find_inlist_lock_noload(head, name, error, mutex); + } + return ret; } +#endif static inline struct ebt_table * find_table_lock(const char *name, int *error, struct mutex *mutex) diff --git a/trunk/net/can/af_can.c b/trunk/net/can/af_can.c index 7d4d2b3c137e..8035fbf526ae 100644 --- a/trunk/net/can/af_can.c +++ b/trunk/net/can/af_can.c @@ -128,8 +128,8 @@ static int can_create(struct net *net, struct socket *sock, int protocol) if (net != &init_net) return -EAFNOSUPPORT; -#ifdef CONFIG_MODULES - /* try to load protocol module kernel is modular */ +#ifdef CONFIG_KMOD + /* try to load protocol module, when CONFIG_KMOD is defined */ if (!proto_tab[protocol]) { err = request_module("can-proto-%d", protocol); diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 868ec0ba8b77..1408a083fe4e 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -4956,6 +4956,8 @@ EXPORT_SYMBOL(br_fdb_get_hook); EXPORT_SYMBOL(br_fdb_put_hook); #endif +#ifdef CONFIG_KMOD EXPORT_SYMBOL(dev_load); +#endif EXPORT_PER_CPU_SYMBOL(softnet_data); diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index 31f29d2989fd..3630131fa1fa 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -1040,7 +1040,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct nlattr *linkinfo[IFLA_INFO_MAX+1]; int err; -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD replay: #endif err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); @@ -1129,7 +1129,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) return -EOPNOTSUPP; if (!ops) { -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD if (kind[0]) { __rtnl_unlock(); request_module("rtnl-link-%s", kind); diff --git a/trunk/net/dccp/ccid.c b/trunk/net/dccp/ccid.c index 8fe931a3d7a1..4809753d12ae 100644 --- a/trunk/net/dccp/ccid.c +++ b/trunk/net/dccp/ccid.c @@ -154,7 +154,7 @@ struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp) struct ccid *ccid = NULL; ccids_read_lock(); -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD if (ccids[id] == NULL) { /* We only try to load if in process context */ ccids_read_unlock(); diff --git a/trunk/net/decnet/dn_dev.c b/trunk/net/decnet/dn_dev.c index 28e26bd08e24..8008c8613027 100644 --- a/trunk/net/decnet/dn_dev.c +++ b/trunk/net/decnet/dn_dev.c @@ -490,7 +490,9 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg) return -EFAULT; ifr->ifr_name[IFNAMSIZ-1] = 0; +#ifdef CONFIG_KMOD dev_load(&init_net, ifr->ifr_name); +#endif switch(cmd) { case SIOCGIFADDR: diff --git a/trunk/net/ipv4/devinet.c b/trunk/net/ipv4/devinet.c index 56fce3ab6c55..5154e729cf16 100644 --- a/trunk/net/ipv4/devinet.c +++ b/trunk/net/ipv4/devinet.c @@ -613,7 +613,9 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg) if (colon) *colon = 0; +#ifdef CONFIG_KMOD dev_load(net, ifr.ifr_name); +#endif switch (cmd) { case SIOCGIFADDR: /* Get interface address */ diff --git a/trunk/net/ipv4/inet_diag.c b/trunk/net/ipv4/inet_diag.c index 564230dabcb8..89cb047ab314 100644 --- a/trunk/net/ipv4/inet_diag.c +++ b/trunk/net/ipv4/inet_diag.c @@ -53,9 +53,11 @@ static DEFINE_MUTEX(inet_diag_table_mutex); static const struct inet_diag_handler *inet_diag_lock_handler(int type) { +#ifdef CONFIG_KMOD if (!inet_diag_table[type]) request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, NETLINK_INET_DIAG, type); +#endif mutex_lock(&inet_diag_table_mutex); if (!inet_diag_table[type]) diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 2ea6dcc3e2cc..942be04e7955 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -1109,12 +1109,7 @@ static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp) printk("\n"); } #endif - /* - * Since lookup is lockfree, we must make sure - * previous writes to rt are comitted to memory - * before making rt visible to other CPUS. - */ - rcu_assign_pointer(rt_hash_table[hash].chain, rt); + rt_hash_table[hash].chain = rt; spin_unlock_bh(rt_hash_lock_addr(hash)); *rp = rt; return 0; diff --git a/trunk/net/ipv4/tcp_cong.c b/trunk/net/ipv4/tcp_cong.c index 4ec5b4e97c4e..6a250828b767 100644 --- a/trunk/net/ipv4/tcp_cong.c +++ b/trunk/net/ipv4/tcp_cong.c @@ -115,7 +115,7 @@ int tcp_set_default_congestion_control(const char *name) spin_lock(&tcp_cong_list_lock); ca = tcp_ca_find(name); -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD if (!ca && capable(CAP_SYS_MODULE)) { spin_unlock(&tcp_cong_list_lock); @@ -244,7 +244,7 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) if (ca == icsk->icsk_ca_ops) goto out; -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD /* not found attempt to autoload module */ if (!ca && capable(CAP_SYS_MODULE)) { rcu_read_unlock(); diff --git a/trunk/net/netfilter/nf_conntrack_netlink.c b/trunk/net/netfilter/nf_conntrack_netlink.c index 2e4ad9671e19..08e82d64eb6f 100644 --- a/trunk/net/netfilter/nf_conntrack_netlink.c +++ b/trunk/net/netfilter/nf_conntrack_netlink.c @@ -822,7 +822,7 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct, parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook); if (!parse_nat_setup) { -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD rcu_read_unlock(); nfnl_unlock(); if (request_module("nf-nat-ipv4") < 0) { diff --git a/trunk/net/netfilter/nfnetlink.c b/trunk/net/netfilter/nfnetlink.c index 9c0ba17a1ddb..4739f9f961d8 100644 --- a/trunk/net/netfilter/nfnetlink.c +++ b/trunk/net/netfilter/nfnetlink.c @@ -137,7 +137,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) replay: ss = nfnetlink_get_subsys(type); if (!ss) { -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD nfnl_unlock(); request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type)); nfnl_lock(); diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index 480184a857d2..2fd8afac5f71 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -435,7 +435,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol) return -EPROTONOSUPPORT; netlink_lock_table(); -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD if (!nl_table[protocol].registered) { netlink_unlock_table(); request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol); diff --git a/trunk/net/phonet/af_phonet.c b/trunk/net/phonet/af_phonet.c index b9d97effebe3..9e9c6fce11aa 100644 --- a/trunk/net/phonet/af_phonet.c +++ b/trunk/net/phonet/af_phonet.c @@ -67,10 +67,11 @@ static int pn_socket_create(struct net *net, struct socket *sock, int protocol) } pnp = phonet_proto_get(protocol); +#ifdef CONFIG_KMOD if (pnp == NULL && request_module("net-pf-%d-proto-%d", PF_PHONET, protocol) == 0) pnp = phonet_proto_get(protocol); - +#endif if (pnp == NULL) return -EPROTONOSUPPORT; if (sock->type != pnp->sock_type) { diff --git a/trunk/net/sched/act_api.c b/trunk/net/sched/act_api.c index 8f457f1e0acf..9974b3f04f05 100644 --- a/trunk/net/sched/act_api.c +++ b/trunk/net/sched/act_api.c @@ -494,7 +494,7 @@ struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, a_o = tc_lookup_action_n(act_name); if (a_o == NULL) { -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD rtnl_unlock(); request_module("act_%s", act_name); rtnl_lock(); diff --git a/trunk/net/sched/cls_api.c b/trunk/net/sched/cls_api.c index 16e7ac9774e5..8eb79e92e94c 100644 --- a/trunk/net/sched/cls_api.c +++ b/trunk/net/sched/cls_api.c @@ -227,7 +227,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) err = -ENOENT; tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND]); if (tp_ops == NULL) { -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD struct nlattr *kind = tca[TCA_KIND]; char name[IFNAMSIZ]; diff --git a/trunk/net/sched/ematch.c b/trunk/net/sched/ematch.c index e82519e548d7..5e6f82e0e6f3 100644 --- a/trunk/net/sched/ematch.c +++ b/trunk/net/sched/ematch.c @@ -224,7 +224,7 @@ static int tcf_em_validate(struct tcf_proto *tp, if (em->ops == NULL) { err = -ENOENT; -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD __rtnl_unlock(); request_module("ematch-kind-%u", em_hdr->kind); rtnl_lock(); diff --git a/trunk/net/sched/sch_api.c b/trunk/net/sched/sch_api.c index b16ad2972c6b..1122c952aa99 100644 --- a/trunk/net/sched/sch_api.c +++ b/trunk/net/sched/sch_api.c @@ -764,7 +764,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, struct qdisc_size_table *stab; ops = qdisc_lookup_ops(kind); -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD if (ops == NULL && kind != NULL) { char name[IFNAMSIZ]; if (nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) { diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 2b7a4b5c9b72..3e8d4e35c08f 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -1142,7 +1142,7 @@ static int __sock_create(struct net *net, int family, int type, int protocol, sock->type = type; -#ifdef CONFIG_MODULES +#if defined(CONFIG_KMOD) /* Attempt to load a protocol module if the find failed. * * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user diff --git a/trunk/net/sunrpc/auth.c b/trunk/net/sunrpc/auth.c index 436bf1b4b76c..6bfea9ed6869 100644 --- a/trunk/net/sunrpc/auth.c +++ b/trunk/net/sunrpc/auth.c @@ -83,8 +83,10 @@ rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) if (flavor >= RPC_AUTH_MAXFLAVOR) goto out; +#ifdef CONFIG_KMOD if ((ops = auth_flavors[flavor]) == NULL) request_module("rpc-auth-%u", flavor); +#endif spin_lock(&rpc_authflavor_lock); ops = auth_flavors[flavor]; if (ops == NULL || !try_module_get(ops->owner)) { diff --git a/trunk/sound/core/jack.c b/trunk/sound/core/jack.c index bd2d9e6b55e9..8133a2b173a5 100644 --- a/trunk/sound/core/jack.c +++ b/trunk/sound/core/jack.c @@ -147,9 +147,6 @@ EXPORT_SYMBOL(snd_jack_set_parent); */ void snd_jack_report(struct snd_jack *jack, int status) { - if (!jack) - return; - if (jack->type & SND_JACK_HEADPHONE) input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT, status & SND_JACK_HEADPHONE); diff --git a/trunk/sound/core/pcm_lib.c b/trunk/sound/core/pcm_lib.c index 921691080f35..6ea5cfb83998 100644 --- a/trunk/sound/core/pcm_lib.c +++ b/trunk/sound/core/pcm_lib.c @@ -908,12 +908,12 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, EXPORT_SYMBOL(snd_pcm_hw_rule_add); /** - * snd_pcm_hw_constraint_mask - apply the given bitmap mask constraint + * snd_pcm_hw_constraint_mask * @runtime: PCM runtime instance * @var: hw_params variable to apply the mask * @mask: the bitmap mask * - * Apply the constraint of the given bitmap mask to a 32-bit mask parameter. + * Apply the constraint of the given bitmap mask to a mask parameter. */ int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, u_int32_t mask) @@ -928,12 +928,12 @@ int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param } /** - * snd_pcm_hw_constraint_mask64 - apply the given bitmap mask constraint + * snd_pcm_hw_constraint_mask64 * @runtime: PCM runtime instance * @var: hw_params variable to apply the mask * @mask: the 64bit bitmap mask * - * Apply the constraint of the given bitmap mask to a 64-bit mask parameter. + * Apply the constraint of the given bitmap mask to a mask parameter. */ int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, u_int64_t mask) @@ -949,7 +949,7 @@ int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_par } /** - * snd_pcm_hw_constraint_integer - apply an integer constraint to an interval + * snd_pcm_hw_constraint_integer * @runtime: PCM runtime instance * @var: hw_params variable to apply the integer constraint * @@ -964,7 +964,7 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa EXPORT_SYMBOL(snd_pcm_hw_constraint_integer); /** - * snd_pcm_hw_constraint_minmax - apply a min/max range constraint to an interval + * snd_pcm_hw_constraint_minmax * @runtime: PCM runtime instance * @var: hw_params variable to apply the range * @min: the minimal value @@ -995,7 +995,7 @@ static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, /** - * snd_pcm_hw_constraint_list - apply a list of constraints to a parameter + * snd_pcm_hw_constraint_list * @runtime: PCM runtime instance * @cond: condition bits * @var: hw_params variable to apply the list constraint @@ -1031,7 +1031,7 @@ static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, } /** - * snd_pcm_hw_constraint_ratnums - apply ratnums constraint to a parameter + * snd_pcm_hw_constraint_ratnums * @runtime: PCM runtime instance * @cond: condition bits * @var: hw_params variable to apply the ratnums constraint @@ -1064,7 +1064,7 @@ static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, } /** - * snd_pcm_hw_constraint_ratdens - apply ratdens constraint to a parameter + * snd_pcm_hw_constraint_ratdens * @runtime: PCM runtime instance * @cond: condition bits * @var: hw_params variable to apply the ratdens constraint @@ -1095,7 +1095,7 @@ static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, } /** - * snd_pcm_hw_constraint_msbits - add a hw constraint msbits rule + * snd_pcm_hw_constraint_msbits * @runtime: PCM runtime instance * @cond: condition bits * @width: sample bits width @@ -1123,7 +1123,7 @@ static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, } /** - * snd_pcm_hw_constraint_step - add a hw constraint step rule + * snd_pcm_hw_constraint_step * @runtime: PCM runtime instance * @cond: condition bits * @var: hw_params variable to apply the step constraint @@ -1154,7 +1154,7 @@ static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm } /** - * snd_pcm_hw_constraint_pow2 - add a hw constraint power-of-2 rule + * snd_pcm_hw_constraint_pow2 * @runtime: PCM runtime instance * @cond: condition bits * @var: hw_params variable to apply the power-of-2 constraint @@ -1202,13 +1202,13 @@ void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params) EXPORT_SYMBOL(_snd_pcm_hw_params_any); /** - * snd_pcm_hw_param_value - return @params field @var value + * snd_pcm_hw_param_value * @params: the hw_params instance * @var: parameter to retrieve - * @dir: pointer to the direction (-1,0,1) or %NULL + * @dir: pointer to the direction (-1,0,1) or NULL * - * Return the value for field @var if it's fixed in configuration space - * defined by @params. Return -%EINVAL otherwise. + * Return the value for field PAR if it's fixed in configuration space + * defined by PARAMS. Return -EINVAL otherwise */ int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var, int *dir) @@ -1271,13 +1271,13 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, /** - * snd_pcm_hw_param_first - refine config space and return minimum value + * snd_pcm_hw_param_first * @pcm: PCM instance * @params: the hw_params instance * @var: parameter to retrieve - * @dir: pointer to the direction (-1,0,1) or %NULL + * @dir: pointer to the direction (-1,0,1) or NULL * - * Inside configuration space defined by @params remove from @var all + * Inside configuration space defined by PARAMS remove from PAR all * values > minimum. Reduce configuration space accordingly. * Return the minimum. */ @@ -1317,13 +1317,13 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, /** - * snd_pcm_hw_param_last - refine config space and return maximum value + * snd_pcm_hw_param_last * @pcm: PCM instance * @params: the hw_params instance * @var: parameter to retrieve - * @dir: pointer to the direction (-1,0,1) or %NULL + * @dir: pointer to the direction (-1,0,1) or NULL * - * Inside configuration space defined by @params remove from @var all + * Inside configuration space defined by PARAMS remove from PAR all * values < maximum. Reduce configuration space accordingly. * Return the maximum. */ @@ -1345,11 +1345,11 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, EXPORT_SYMBOL(snd_pcm_hw_param_last); /** - * snd_pcm_hw_param_choose - choose a configuration defined by @params + * snd_pcm_hw_param_choose * @pcm: PCM instance * @params: the hw_params instance * - * Choose one configuration from configuration space defined by @params. + * Choose one configuration from configuration space defined by PARAMS * The configuration chosen is that obtained fixing in this order: * first access, first format, first subformat, min channels, * min rate, min period time, max buffer size, min tick time diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index aef18682c035..e61e12506ded 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -875,8 +875,10 @@ static struct action_ops snd_pcm_action_start = { }; /** - * snd_pcm_start - start all linked streams + * snd_pcm_start * @substream: the PCM substream instance + * + * Start all linked streams. */ int snd_pcm_start(struct snd_pcm_substream *substream) { @@ -924,11 +926,12 @@ static struct action_ops snd_pcm_action_stop = { }; /** - * snd_pcm_stop - try to stop all running streams in the substream group + * snd_pcm_stop * @substream: the PCM substream instance * @state: PCM state after stopping the stream * - * The state of each stream is then changed to the given state unconditionally. + * Try to stop all running streams in the substream group. + * The state of each stream is changed to the given value after that unconditionally. */ int snd_pcm_stop(struct snd_pcm_substream *substream, int state) { @@ -938,10 +941,11 @@ int snd_pcm_stop(struct snd_pcm_substream *substream, int state) EXPORT_SYMBOL(snd_pcm_stop); /** - * snd_pcm_drain_done - stop the DMA only when the given stream is playback + * snd_pcm_drain_done * @substream: the PCM substream * - * After stopping, the state is changed to SETUP. + * Stop the DMA only when the given stream is playback. + * The state is changed to SETUP. * Unlike snd_pcm_stop(), this affects only the given stream. */ int snd_pcm_drain_done(struct snd_pcm_substream *substream) @@ -1061,9 +1065,10 @@ static struct action_ops snd_pcm_action_suspend = { }; /** - * snd_pcm_suspend - trigger SUSPEND to all linked streams + * snd_pcm_suspend * @substream: the PCM substream * + * Trigger SUSPEND to all linked streams. * After this call, all streams are changed to SUSPENDED state. */ int snd_pcm_suspend(struct snd_pcm_substream *substream) @@ -1083,9 +1088,10 @@ int snd_pcm_suspend(struct snd_pcm_substream *substream) EXPORT_SYMBOL(snd_pcm_suspend); /** - * snd_pcm_suspend_all - trigger SUSPEND to all substreams in the given pcm + * snd_pcm_suspend_all * @pcm: the PCM instance * + * Trigger SUSPEND to all substreams in the given pcm. * After this call, all streams are changed to SUSPENDED state. */ int snd_pcm_suspend_all(struct snd_pcm *pcm) @@ -1307,9 +1313,11 @@ static struct action_ops snd_pcm_action_prepare = { }; /** - * snd_pcm_prepare - prepare the PCM substream to be triggerable + * snd_pcm_prepare * @substream: the PCM substream instance * @file: file to refer f_flags + * + * Prepare the PCM substream to be triggerable. */ static int snd_pcm_prepare(struct snd_pcm_substream *substream, struct file *file) diff --git a/trunk/sound/pci/hda/patch_nvhdmi.c b/trunk/sound/pci/hda/patch_nvhdmi.c index 2eed2c8b98da..1a65775d28e1 100644 --- a/trunk/sound/pci/hda/patch_nvhdmi.c +++ b/trunk/sound/pci/hda/patch_nvhdmi.c @@ -116,7 +116,6 @@ static int nvhdmi_build_pcms(struct hda_codec *codec) codec->pcm_info = info; info->name = "NVIDIA HDMI"; - info->pcm_type = HDA_PCM_TYPE_HDMI; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = nvhdmi_pcm_digital_playback; return 0; diff --git a/trunk/sound/soc/at32/playpaq_wm8510.c b/trunk/sound/soc/at32/playpaq_wm8510.c index b1966e4dfcd3..98a2d5826a85 100644 --- a/trunk/sound/soc/at32/playpaq_wm8510.c +++ b/trunk/sound/soc/at32/playpaq_wm8510.c @@ -304,7 +304,7 @@ static const struct snd_soc_dapm_widget playpaq_dapm_widgets[] = { -static const struct snd_soc_dapm_route intercon[] = { +static const char *intercon[][3] = { /* speaker connected to SPKOUT */ {"Ext Spk", NULL, "SPKOUTP"}, {"Ext Spk", NULL, "SPKOUTN"}, @@ -312,6 +312,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"Mic Bias", NULL, "Int Mic"}, {"MICN", NULL, "Mic Bias"}, {"MICP", NULL, "Mic Bias"}, + + /* Terminator */ + {NULL, NULL, NULL}, }; @@ -331,8 +334,11 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec) /* * Setup audio path interconnects */ - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); - + for (i = 0; intercon[i][0] != NULL; i++) { + snd_soc_dapm_connect_input(codec, + intercon[i][0], + intercon[i][1], intercon[i][2]); + } /* always connected pins */ diff --git a/trunk/sound/soc/soc-dapm.c b/trunk/sound/soc/soc-dapm.c index 7351db9606e4..efbd0b37810a 100644 --- a/trunk/sound/soc/soc-dapm.c +++ b/trunk/sound/soc/soc-dapm.c @@ -831,7 +831,7 @@ int snd_soc_dapm_sys_add(struct device *dev) return ret; asoc_debugfs = debugfs_create_dir("asoc", NULL); - if (!IS_ERR(asoc_debugfs) && asoc_debugfs) + if (!IS_ERR(asoc_debugfs)) debugfs_create_u32("dapm_pop_time", 0744, asoc_debugfs, &pop_time); else