- printk(KERN_ERR "megasas: cannot recover from previous reset "
- "failures\n");
- return FAILED;
-@@ -1008,7 +2853,7 @@ static int megasas_generic_reset(struct
- * cmd has not been completed within the timeout period.
- */
- static enum
--scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
-+blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
- {
- struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;
- struct megasas_instance *instance;
-@@ -1016,7 +2861,7 @@ scsi_eh_timer_return megasas_reset_timer
-
- if (time_after(jiffies, scmd->jiffies_at_alloc +
- (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
-- return EH_NOT_HANDLED;
-+ return BLK_EH_NOT_HANDLED;
- }
-
- instance = cmd->instance;
-@@ -1030,7 +2875,7 @@ scsi_eh_timer_return megasas_reset_timer
-
- spin_unlock_irqrestore(instance->host->host_lock, flags);
- }
-- return EH_RESET_TIMER;
-+ return BLK_EH_RESET_TIMER;
- }
-
- /**
-@@ -1106,6 +2951,8 @@ megasas_bios_param(struct scsi_device *s
- return 0;
- }
-
++ printk(KERN_ERR "megasas: cannot recover from previous reset "
++ "failures\n");
++ return FAILED;
++ }
++
++ ret_val = megasas_wait_for_outstanding(instance);
++ if (ret_val == SUCCESS)
++ printk(KERN_NOTICE "megasas: reset successful \n");
++ else
++ printk(KERN_ERR "megasas: failed to do reset\n");
++
++ return ret_val;
++}
++
++/**
++ * megasas_reset_timer - quiesce the adapter if required
++ * @scmd: scsi cmnd
++ *
++ * Sets the FW busy flag and reduces the host->can_queue if the
++ * cmd has not been completed within the timeout period.
++ */
++static enum
++scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
++{
++ struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;
++ struct megasas_instance *instance;
++ unsigned long flags;
++
++ if (time_after(jiffies, scmd->jiffies_at_alloc +
++ (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
++ return EH_NOT_HANDLED;
++ }
++
++ instance = cmd->instance;
++ if (!(instance->flag & MEGASAS_FW_BUSY)) {
++ /* FW is busy, throttle IO */
++ spin_lock_irqsave(instance->host->host_lock, flags);
++
++ instance->host->can_queue = 16;
++ instance->last_time = jiffies;
++ instance->flag |= MEGASAS_FW_BUSY;
++
++ spin_unlock_irqrestore(instance->host->host_lock, flags);
++ }
++ return EH_RESET_TIMER;
++}
++
++/**
++ * megasas_reset_device - Device reset handler entry point
++ */
++static int megasas_reset_device(struct scsi_cmnd *scmd)
++{
++ int ret;
++
++ /*
++ * First wait for all commands to complete
++ */
++ ret = megasas_generic_reset(scmd);
++
++ return ret;
++}
++
++/**
++ * megasas_reset_bus_host - Bus & host reset handler entry point
++ */
++static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
++{
++ int ret;
++
++ /*
++ * First wait for all commands to complete
++ */
++ ret = megasas_generic_reset(scmd);
++
++ return ret;
++}
++
++/**
++ * megasas_bios_param - Returns disk geometry for a disk
++ * @sdev: device handle
++ * @bdev: block device
++ * @capacity: drive capacity
++ * @geom: geometry parameters
++ */
++static int
++megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
++ sector_t capacity, int geom[])
++{
++ int heads;
++ int sectors;
++ sector_t cylinders;
++ unsigned long tmp;
++ /* Default heads (64) & sectors (32) */
++ heads = 64;
++ sectors = 32;
++
++ tmp = heads * sectors;
++ cylinders = capacity;
++
++ sector_div(cylinders, tmp);
++
++ /*
++ * Handle extended translation size for logical drives > 1Gb
++ */
++
++ if (capacity >= 0x200000) {
++ heads = 255;
++ sectors = 63;
++ tmp = heads*sectors;
++ cylinders = capacity;
++ sector_div(cylinders, tmp);
++ }
++
++ geom[0] = heads;
++ geom[1] = sectors;
++ geom[2] = cylinders;
++
++ return 0;
++}
++