Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2132a544 authored by Asai Thambi SP's avatar Asai Thambi SP Committed by Jens Axboe
Browse files

mtip32xx: fix crash on surprise removal of the drive



pci and block layers have changed a lot compared to when SRSI support was added.
Given the current state of pci and block layers, this driver do not have to do
any specific handling.

Signed-off-by: default avatarAsai Thambi S P <asamymuthupa@micron.com>
Signed-off-by: default avatarSelvan Mani <smani@micron.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 686d8e0b
Loading
Loading
Loading
Loading
+45 −98
Original line number Diff line number Diff line
@@ -895,6 +895,10 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data)

		/* Acknowledge the interrupt status on the port.*/
		port_stat = readl(port->mmio + PORT_IRQ_STAT);
		if (unlikely(port_stat == 0xFFFFFFFF)) {
			mtip_check_surprise_removal(dd->pdev);
			return IRQ_HANDLED;
		}
		writel(port_stat, port->mmio + PORT_IRQ_STAT);

		/* Demux port status */
@@ -2765,49 +2769,6 @@ static void mtip_hw_debugfs_exit(struct driver_data *dd)
		debugfs_remove_recursive(dd->dfs_node);
}

static int mtip_free_orphan(struct driver_data *dd)
{
	struct kobject *kobj;

	if (dd->bdev) {
		if (dd->bdev->bd_holders >= 1)
			return -2;

		bdput(dd->bdev);
		dd->bdev = NULL;
	}

	mtip_hw_debugfs_exit(dd);

	spin_lock(&rssd_index_lock);
	ida_remove(&rssd_index_ida, dd->index);
	spin_unlock(&rssd_index_lock);

	if (!test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag) &&
			test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag)) {
		put_disk(dd->disk);
	} else {
		if (dd->disk) {
			kobj = kobject_get(&disk_to_dev(dd->disk)->kobj);
			if (kobj) {
				mtip_hw_sysfs_exit(dd, kobj);
				kobject_put(kobj);
			}
			del_gendisk(dd->disk);
			put_disk(dd->disk);
			dd->disk = NULL;
		}
		if (dd->queue) {
			dd->queue->queuedata = NULL;
			blk_cleanup_queue(dd->queue);
			blk_mq_free_tag_set(&dd->tags);
			dd->queue = NULL;
		}
	}
	kfree(dd);
	return 0;
}

/*
 * Perform any init/resume time hardware setup
 *
@@ -2955,7 +2916,6 @@ static int mtip_service_thread(void *data)
	unsigned long slot, slot_start, slot_wrap;
	unsigned int num_cmd_slots = dd->slot_groups * 32;
	struct mtip_port *port = dd->port;
	int ret;

	while (1) {
		if (kthread_should_stop() ||
@@ -3041,18 +3001,6 @@ static int mtip_service_thread(void *data)
		if (kthread_should_stop())
			goto st_out;
	}

	while (1) {
		ret = mtip_free_orphan(dd);
		if (!ret) {
			/* NOTE: All data structures are invalid, do not
			 * access any here */
			return 0;
		}
		msleep_interruptible(1000);
		if (kthread_should_stop())
			goto st_out;
	}
st_out:
	return 0;
}
@@ -3380,6 +3328,7 @@ static int mtip_hw_exit(struct driver_data *dd)
	/* Release the IRQ. */
	irq_set_affinity_hint(dd->pdev->irq, NULL);
	devm_free_irq(&dd->pdev->dev, dd->pdev->irq, dd);
	msleep(1000);

	/* Free dma regions */
	mtip_dma_free(dd);
@@ -4075,7 +4024,6 @@ static int mtip_block_remove(struct driver_data *dd)
{
	struct kobject *kobj;

	if (!dd->sr) {
	mtip_hw_debugfs_exit(dd);

	if (dd->mtip_svc_handler) {
@@ -4093,7 +4041,11 @@ static int mtip_block_remove(struct driver_data *dd)
		}
	}

	if (!dd->sr)
		mtip_standby_drive(dd);
	else
		dev_info(&dd->pdev->dev, "device %s surprise removal\n",
						dd->disk->disk_name);

	/*
	 * Delete our gendisk structure. This also removes the device
@@ -4117,10 +4069,6 @@ static int mtip_block_remove(struct driver_data *dd)
	spin_lock(&rssd_index_lock);
	ida_remove(&rssd_index_ida, dd->index);
	spin_unlock(&rssd_index_lock);
	} else {
		dev_info(&dd->pdev->dev, "device %s surprise removal\n",
						dd->disk->disk_name);
	}

	/* De-initialize the protocol layer. */
	mtip_hw_exit(dd);
@@ -4516,6 +4464,7 @@ static void mtip_pci_remove(struct pci_dev *pdev)
			"Completion workers still active!\n");
	}

	blk_mq_stop_hw_queues(dd->queue);
	/* Clean up the block layer. */
	mtip_block_remove(dd);

@@ -4533,9 +4482,7 @@ static void mtip_pci_remove(struct pci_dev *pdev)
	list_del_init(&dd->remove_list);
	spin_unlock_irqrestore(&dev_lock, flags);

	if (!dd->sr)
	kfree(dd);
	else
	set_bit(MTIP_DDF_REMOVE_DONE_BIT, &dd->dd_flag);

	pcim_iounmap_regions(pdev, 1 << MTIP_ABAR);